Skip to content

Commit

Permalink
Merge pull request #3952 from Tyriar/v5_buffer_range
Browse files Browse the repository at this point in the history
Replace ISelectionPosition with IBufferRange
  • Loading branch information
Tyriar authored Jul 28, 2022
2 parents 940c93e + 520a270 commit 09df783
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 117 deletions.
20 changes: 10 additions & 10 deletions addons/xterm-addon-search/src/SearchAddon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { Terminal, IDisposable, ITerminalAddon, ISelectionPosition, IDecoration } from 'xterm';
import { Terminal, IDisposable, ITerminalAddon, IBufferRange, IDecoration } from 'xterm';
import { EventEmitter } from 'common/EventEmitter';

export interface ISearchOptions {
Expand Down Expand Up @@ -235,14 +235,14 @@ export class SearchAddon implements ITerminalAddon {

let startCol = 0;
let startRow = 0;
let currentSelection: ISelectionPosition | undefined;
let currentSelection: IBufferRange | undefined;
if (this._terminal.hasSelection()) {
const incremental = searchOptions ? searchOptions.incremental : false;
// Start from the selection end if there is a selection
// For incremental search, use existing row
currentSelection = this._terminal.getSelectionPosition()!;
startRow = incremental ? currentSelection.startRow : currentSelection.endRow;
startCol = incremental ? currentSelection.startColumn : currentSelection.endColumn;
startRow = incremental ? currentSelection.start.y : currentSelection.end.y;
startCol = incremental ? currentSelection.start.x : currentSelection.end.x;
}

this._initLinesCache();
Expand Down Expand Up @@ -282,7 +282,7 @@ export class SearchAddon implements ITerminalAddon {

// If there is only one result, wrap back and return selection if it exists.
if (!result && currentSelection) {
searchPosition.startRow = currentSelection.startRow;
searchPosition.startRow = currentSelection.start.y;
searchPosition.startCol = 0;
result = this._findInLine(term, searchPosition, searchOptions);
}
Expand Down Expand Up @@ -357,12 +357,12 @@ export class SearchAddon implements ITerminalAddon {
const isReverseSearch = true;

const incremental = searchOptions ? searchOptions.incremental : false;
let currentSelection: ISelectionPosition | undefined;
let currentSelection: IBufferRange | undefined;
if (this._terminal.hasSelection()) {
currentSelection = this._terminal.getSelectionPosition()!;
// Start from selection start if there is a selection
startRow = currentSelection.startRow;
startCol = currentSelection.startColumn;
startRow = currentSelection.start.y;
startCol = currentSelection.start.x;
}

this._initLinesCache();
Expand All @@ -378,8 +378,8 @@ export class SearchAddon implements ITerminalAddon {
if (!isOldResultHighlighted) {
// If selection was not able to be expanded to the right, then try reverse search
if (currentSelection) {
searchPosition.startRow = currentSelection.endRow;
searchPosition.startCol = currentSelection.endColumn;
searchPosition.startRow = currentSelection.end.y;
searchPosition.startCol = currentSelection.end.x;
}
result = this._findInLine(term, searchPosition, searchOptions, true);
}
Expand Down
79 changes: 42 additions & 37 deletions addons/xterm-addon-search/test/SearchAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,35 +60,35 @@ describe('Search Tests', function (): void {
await page.evaluate(`window.term.writeln('package.jsonc\\n')`);
await writeSync(page, 'package.json pack package.lock');
await page.evaluate(`window.search.findPrevious('pack', {incremental: true})`);
let line: string = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().startRow).translateToString()`);
let selectionPosition: { startColumn: number, startRow: number, endColumn: number, endRow: number } = await page.evaluate(`window.term.getSelectionPosition()`);
let line: string = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().start.y).translateToString()`);
let selectionPosition: { start: { x: number, y: number }, end: { x: number, y: number } } = await page.evaluate(`window.term.getSelectionPosition()`);
// We look further ahead in the line to ensure that pack was selected from package.lock
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn + 8), 'package.lock');
assert.deepEqual(line.substring(selectionPosition.start.x, selectionPosition.end.x + 8), 'package.lock');
await page.evaluate(`window.search.findPrevious('package.j', {incremental: true})`);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn + 3), 'package.json');
assert.deepEqual(line.substring(selectionPosition.start.x, selectionPosition.end.x + 3), 'package.json');
await page.evaluate(`window.search.findPrevious('package.jsonc', {incremental: true})`);
// We have to reevaluate line because it should have switched starting rows at this point
line = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().startRow).translateToString()`);
line = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().start.y).translateToString()`);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn), 'package.jsonc');
assert.deepEqual(line.substring(selectionPosition.start.x, selectionPosition.end.x), 'package.jsonc');
});
it('Incremental Find Next', async () => {
await page.evaluate(`window.term.writeln('package.lock pack package.json package.ups\\n')`);
await writeSync(page, 'package.jsonc');
await page.evaluate(`window.search.findNext('pack', {incremental: true})`);
let line: string = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().startRow).translateToString()`);
let selectionPosition: { startColumn: number, startRow: number, endColumn: number, endRow: number } = await page.evaluate(`window.term.getSelectionPosition()`);
let line: string = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().start.y).translateToString()`);
let selectionPosition: { start: { x: number, y: number }, end: { x: number, y: number } } = await page.evaluate(`window.term.getSelectionPosition()`);
// We look further ahead in the line to ensure that pack was selected from package.lock
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn + 8), 'package.lock');
assert.deepEqual(line.substring(selectionPosition.start.x, selectionPosition.end.x + 8), 'package.lock');
await page.evaluate(`window.search.findNext('package.j', {incremental: true})`);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn + 3), 'package.json');
assert.deepEqual(line.substring(selectionPosition.start.x, selectionPosition.end.x + 3), 'package.json');
await page.evaluate(`window.search.findNext('package.jsonc', {incremental: true})`);
// We have to reevaluate line because it should have switched starting rows at this point
line = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().startRow).translateToString()`);
line = await page.evaluate(`window.term.buffer.active.getLine(window.term.getSelectionPosition().start.y).translateToString()`);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn), 'package.jsonc');
assert.deepEqual(line.substring(selectionPosition.start.x, selectionPosition.end.x), 'package.jsonc');
});
it('Simple Regex', async () => {
await writeSync(page, 'abc123defABCD');
Expand Down Expand Up @@ -116,10 +116,14 @@ describe('Search Tests', function (): void {
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), '𝄞');
assert.deepEqual(await page.evaluate(`window.search.findNext('𝄞')`), true);
assert.deepEqual(await page.evaluate(`window.term.getSelectionPosition()`), {
startRow: 0,
endRow: 0,
startColumn: 7,
endColumn: 8
start: {
x: 7,
y: 0
},
end: {
x: 8,
y: 0
}
});
});

Expand Down Expand Up @@ -313,69 +317,70 @@ describe('Search Tests', function (): void {
await writeSync(page, fixture);
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
let selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 53, endColumn: 30, endRow: 53 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 53 }, end: { x: 30, y: 53 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 76, endColumn: 30, endRow: 76 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 76 }, end: { x: 30, y: 76 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 96, endColumn: 30, endRow: 96 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 96 }, end: { x: 30, y: 96 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 1, startRow: 114, endColumn: 7, endRow: 114 });
assert.deepEqual(selectionPosition, { start: { x: 1, y: 114 }, end: { x: 7, y: 114 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 115, endColumn: 17, endRow: 115 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 115 }, end: { x: 17, y: 115 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 1, startRow: 126, endColumn: 7, endRow: 126 });
assert.deepEqual(selectionPosition, { start: { x: 1, y: 126 }, end: { x: 7, y: 126 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 127, endColumn: 17, endRow: 127 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 127 }, end: { x: 17, y: 127 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 1, startRow: 135, endColumn: 7, endRow: 135 });
assert.deepEqual(selectionPosition, { start: { x: 1, y: 135 }, end: { x: 7, y: 135 } });
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 136, endColumn: 17, endRow: 136 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 136 }, end: { x: 17, y: 136 } });
// Wrap around to first result
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 53, endColumn: 30, endRow: 53 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 53 }, end: { x: 30, y: 53 } });
});
it('should find all occurrences using findPrevious', async () => {

it('should y all occurrences using findPrevious', async () => {
await writeSync(page, fixture);
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
let selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 136, endColumn: 17, endRow: 136 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 136 }, end: { x: 17, y: 136 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 1, startRow: 135, endColumn: 7, endRow: 135 });
assert.deepEqual(selectionPosition, { start: { x: 1, y: 135 }, end: { x: 7, y: 135 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 127, endColumn: 17, endRow: 127 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 127 }, end: { x: 17, y: 127 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 1, startRow: 126, endColumn: 7, endRow: 126 });
assert.deepEqual(selectionPosition, { start: { x: 1, y: 126 }, end: { x: 7, y: 126 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 115, endColumn: 17, endRow: 115 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 115 }, end: { x: 17, y: 115 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 1, startRow: 114, endColumn: 7, endRow: 114 });
assert.deepEqual(selectionPosition, { start: { x: 1, y: 114 }, end: { x: 7, y: 114 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 96, endColumn: 30, endRow: 96 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 96 }, end: { x: 30, y: 96 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 76, endColumn: 30, endRow: 76 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 76 }, end: { x: 30, y: 76 } });
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 53, endColumn: 30, endRow: 53 });
assert.deepEqual(selectionPosition, { start: { x: 24, y: 53 }, end: { x: 30, y: 53 } });
// Wrap around to first result
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 136, endColumn: 17, endRow: 136 });
assert.deepEqual(selectionPosition, { start: { x: 11, y: 136 }, end: { x: 17, y: 136 } });
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions addons/xterm-addon-serialize/src/SerializeAddon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ export class SerializeAddon implements ITerminalAddon {
const selection = this._terminal?.getSelectionPosition();
if (selection !== undefined) {
return handler.serialize({
start: { x: selection.startRow, y: selection.startColumn },
end: { x: selection.endRow, y: selection.endColumn }
start: { x: selection.start.y, y: selection.start.x },
end: { x: selection.end.y, y: selection.end.x }
});
}

Expand Down
18 changes: 11 additions & 7 deletions src/browser/Terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* http://linux.die.net/man/7/urxvt
*/

import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, IViewport, ILinkifier2, CharacterJoinerHandler } from 'browser/Types';
import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler, IViewport, ILinkifier2, CharacterJoinerHandler, IBufferRange } from 'browser/Types';
import { IRenderer } from 'browser/renderer/Types';
import { CompositionHelper } from 'browser/input/CompositionHelper';
import { Viewport } from 'browser/Viewport';
Expand All @@ -33,7 +33,7 @@ import * as Browser from 'common/Platform';
import { addDisposableDomListener } from 'browser/Lifecycle';
import * as Strings from 'browser/LocalizableStrings';
import { AccessibilityManager } from './AccessibilityManager';
import { ITheme, IMarker, IDisposable, ISelectionPosition, ILinkProvider, IDecorationOptions, IDecoration } from 'xterm';
import { ITheme, IMarker, IDisposable, ILinkProvider, IDecorationOptions, IDecoration } from 'xterm';
import { DomRenderer } from 'browser/renderer/dom/DomRenderer';
import { KeyboardResultType, CoreMouseEventType, CoreMouseButton, CoreMouseAction, ITerminalOptions, ScrollSource, IColorEvent, ColorIndex, ColorRequestType } from 'common/Types';
import { evaluateKeyboardEvent } from 'common/input/Keyboard';
Expand Down Expand Up @@ -993,16 +993,20 @@ export class Terminal extends CoreTerminal implements ITerminal {
return this._selectionService ? this._selectionService.selectionText : '';
}

public getSelectionPosition(): ISelectionPosition | undefined {
public getSelectionPosition(): IBufferRange | undefined {
if (!this._selectionService || !this._selectionService.hasSelection) {
return undefined;
}

return {
startColumn: this._selectionService.selectionStart![0],
startRow: this._selectionService.selectionStart![1],
endColumn: this._selectionService.selectionEnd![0],
endRow: this._selectionService.selectionEnd![1]
start: {
x: this._selectionService.selectionStart![0],
y: this._selectionService.selectionStart![1]
},
end: {
x: this._selectionService.selectionEnd![0],
y: this._selectionService.selectionEnd![1]
}
};
}

Expand Down
Loading

0 comments on commit 09df783

Please sign in to comment.