Use RedBlackTree for better efficiency
gnunn1
6 years ago
1043 | 1043 | if (event.key.keyval == GdkKeysyms.GDK_Return && checkVTEFeature(TerminalFeature.EVENT_SCREEN_CHANGED) && currentScreen == TerminalScreen.NORMAL) { |
1044 | 1044 | long row, column; |
1045 | 1045 | vte.getCursorPosition(column, row); |
1046 | promptPosition ~= [row]; | |
1046 | addPromptPosition(row); | |
1047 | 1047 | tracef("Added prompt position %d", row); |
1048 | 1048 | } |
1049 | 1049 | |
1506 | 1506 | |
1507 | 1507 | // Block for handling cycling between command prompts |
1508 | 1508 | private: |
1509 | long[] promptPosition; | |
1509 | ||
1510 | import std.container.rbtree; | |
1511 | ||
1512 | RedBlackTree!long promptPosition = redBlackTree!long(); | |
1513 | ||
1514 | void addPromptPosition(long position) { | |
1515 | promptPosition.insert(position); | |
1516 | } | |
1510 | 1517 | |
1511 | 1518 | void moveToPrompt(int direction) { |
1512 | 1519 | if (!checkVTEFeature(TerminalFeature.EVENT_SCREEN_CHANGED) || currentScreen != TerminalScreen.NORMAL) return; |
1513 | 1520 | long lower = to!long(vte.getVadjustment.getLower()); |
1514 | 1521 | long upper = to!long(vte.getVadjustment.getUpper()); |
1515 | 1522 | long result; |
1523 | ||
1524 | //debugPromptPositions(); | |
1525 | ||
1516 | 1526 | tracef("promptPosition length %d, lower bound %d, upper bound %d",promptPosition.length, lower, upper); |
1517 | 1527 | long row = to!long(vte.getVadjustment().getValue()); |
1518 | auto sorted = assumeSorted(promptPosition); | |
1528 | RBRange!(RBNode!long*) range; | |
1519 | 1529 | if (direction < 0) { |
1520 | auto range = sorted.lowerBound(row); | |
1521 | if (range.length > 0) { | |
1522 | result = range[range.length -1]; | |
1523 | } else result = lower; | |
1530 | range = promptPosition.lowerBound(row); | |
1531 | if (range.empty) result = lower; | |
1532 | else result = range.back; | |
1524 | 1533 | } else { |
1525 | auto range = sorted.upperBound(row); | |
1526 | if (range.length > 0) { | |
1527 | result = range[0]; | |
1528 | } else result = upper; | |
1534 | range = promptPosition.upperBound(row); | |
1535 | if (range.empty) result = upper; | |
1536 | else result = range.front(); | |
1529 | 1537 | } |
1530 | 1538 | if (result >= lower) { |
1531 | 1539 | tracef("Current row %d, Moving to command prompt at %d", row, result); |
1532 | 1540 | vte.getVadjustment.setValue(to!double(result)); |
1533 | 1541 | } else { |
1534 | 1542 | tracef("Cannot move to command prompt at %d, buffer doesn't go that far back", result); |
1535 | } | |
1536 | } | |
1543 | //debugPromptPositions(); | |
1544 | promptPosition.remove(range); | |
1545 | //debugPromptPositions(); | |
1546 | } | |
1547 | } | |
1548 | ||
1549 | // void debugPromptPositions() { | |
1550 | // string prompts; | |
1551 | // foreach(p; promptPosition) prompts = prompts ~ "," ~ to!string(p); | |
1552 | // tracef("Prompts: " ~ prompts); | |
1553 | // } | |
1537 | 1554 | |
1538 | 1555 | void checkPromptBuffer() { |
1539 | 1556 | if (!checkVTEFeature(TerminalFeature.EVENT_SCREEN_CHANGED) || currentScreen != TerminalScreen.NORMAL) return; |
1540 | if (promptPosition.length == 0) return; | |
1557 | if (promptPosition.empty) return; | |
1558 | ||
1559 | //debugPromptPositions(); | |
1560 | ||
1541 | 1561 | // If upper bound of last recorded prompt is bigger then current upper bound of rows user must have cleared buffer, i.e. clear command |
1542 | tracef("Check position %d against buffer size %f", promptPosition[promptPosition.length -1], vte.getVadjustment().getUpper()); | |
1543 | if (promptPosition[promptPosition.length -1] < vte.getVadjustment().getUpper()) { | |
1544 | promptPosition = []; | |
1562 | tracef("Check position %d against buffer size %f", promptPosition.back, vte.getVadjustment().getLower()); | |
1563 | if (promptPosition.back < to!long(vte.getVadjustment().getLower())) { | |
1564 | promptPosition.clear(); | |
1545 | 1565 | trace("Cleared prompt positions"); |
1546 | 1566 | } |
1547 | 1567 | } |