Add test around viewport scrolling behavior
This commit is contained in:
@@ -99,7 +99,7 @@ export class SearchAddon extends Disposable implements ITerminalAddon, ISearchAp
|
|||||||
const nextIndex = this._resolveResultIndex(matches, term, searchOptions, direction, searchKey);
|
const nextIndex = this._resolveResultIndex(matches, term, searchOptions, direction, searchKey);
|
||||||
const activeMatch = matches[nextIndex];
|
const activeMatch = matches[nextIndex];
|
||||||
terminal.select(activeMatch.startX, activeMatch.startY, activeMatch.cellLength);
|
terminal.select(activeMatch.startX, activeMatch.startY, activeMatch.cellLength);
|
||||||
terminal.scrollToLine(activeMatch.startY);
|
this._revealResult(activeMatch);
|
||||||
this._lastResolvedNavigation = {
|
this._lastResolvedNavigation = {
|
||||||
searchKey,
|
searchKey,
|
||||||
matches,
|
matches,
|
||||||
@@ -539,6 +539,20 @@ export class SearchAddon extends Disposable implements ITerminalAddon, ISearchAp
|
|||||||
return byRow.get(selection.start.y)?.get(selection.start.x) ?? -1;
|
return byRow.get(selection.start.y)?.get(selection.start.x) ?? -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _revealResult(match: IMatch): void {
|
||||||
|
const terminal = this._terminal;
|
||||||
|
if (!terminal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const viewportTop = terminal.buffer.active.viewportY;
|
||||||
|
const viewportBottom = viewportTop + terminal.rows - 1;
|
||||||
|
if (match.startY >= viewportTop && match.endY <= viewportBottom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const middleY = Math.floor((match.startY + match.endY) / 2);
|
||||||
|
terminal.scrollToLine(Math.max(0, middleY - Math.floor(terminal.rows / 2)));
|
||||||
|
}
|
||||||
|
|
||||||
private _refreshDecorations(matches: IMatch[], decorationOptions: ISearchDecorationOptions, activeMatch: IMatch | undefined): void {
|
private _refreshDecorations(matches: IMatch[], decorationOptions: ISearchDecorationOptions, activeMatch: IMatch | undefined): void {
|
||||||
const terminal = this._terminal;
|
const terminal = this._terminal;
|
||||||
if (!terminal) {
|
if (!terminal) {
|
||||||
|
|||||||
@@ -45,6 +45,53 @@ test.describe('Search Tests', () => {
|
|||||||
deepStrictEqual(await ctx.page.evaluate(`window.search.findNext('$^1_3{}test$#')`), true);
|
deepStrictEqual(await ctx.page.evaluate(`window.search.findNext('$^1_3{}test$#')`), true);
|
||||||
deepStrictEqual(await ctx.proxy.getSelection(), '$^1_3{}test$#');
|
deepStrictEqual(await ctx.proxy.getSelection(), '$^1_3{}test$#');
|
||||||
});
|
});
|
||||||
|
test('Search should not scroll when match is already in viewport', async () => {
|
||||||
|
let dataString = '';
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
if (i === 40) {
|
||||||
|
dataString += `line ${i} needle-in-view`;
|
||||||
|
} else {
|
||||||
|
dataString += `line ${i}`;
|
||||||
|
}
|
||||||
|
dataString += '\n\r';
|
||||||
|
}
|
||||||
|
await ctx.proxy.write(dataString);
|
||||||
|
await ctx.page.evaluate('window.term.scrollToLine(35)');
|
||||||
|
strictEqual(await ctx.page.evaluate('window.term.buffer.active.viewportY'), 35);
|
||||||
|
|
||||||
|
strictEqual(await ctx.page.evaluate(`window.search.findNext('needle-in-view')`), true);
|
||||||
|
deepStrictEqual(await ctx.proxy.getSelection(), 'needle-in-view');
|
||||||
|
strictEqual(await ctx.page.evaluate('window.term.buffer.active.viewportY'), 35);
|
||||||
|
});
|
||||||
|
test('Search should center the match when it is outside the viewport', async () => {
|
||||||
|
let dataString = '';
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
if (i === 60) {
|
||||||
|
dataString += `line ${i} needle-center`;
|
||||||
|
} else {
|
||||||
|
dataString += `line ${i}`;
|
||||||
|
}
|
||||||
|
dataString += '\n\r';
|
||||||
|
}
|
||||||
|
await ctx.proxy.write(dataString);
|
||||||
|
await ctx.page.evaluate('window.term.scrollToLine(0)');
|
||||||
|
strictEqual(await ctx.page.evaluate('window.term.buffer.active.viewportY'), 0);
|
||||||
|
|
||||||
|
strictEqual(await ctx.page.evaluate(`window.search.findNext('needle-center')`), true);
|
||||||
|
deepStrictEqual(await ctx.proxy.getSelection(), 'needle-center');
|
||||||
|
deepStrictEqual(await ctx.page.evaluate(`
|
||||||
|
const viewportY = window.term.buffer.active.viewportY;
|
||||||
|
const rows = window.term.rows;
|
||||||
|
const selection = window.term.getSelectionPosition();
|
||||||
|
return {
|
||||||
|
viewportY,
|
||||||
|
expectedViewportY: selection.start.y - Math.floor(rows / 2)
|
||||||
|
};
|
||||||
|
`), {
|
||||||
|
viewportY: 48,
|
||||||
|
expectedViewportY: 48
|
||||||
|
});
|
||||||
|
});
|
||||||
test('Incremental Find Previous', async () => {
|
test('Incremental Find Previous', async () => {
|
||||||
await ctx.proxy.writeln(`package.jsonc\n`);
|
await ctx.proxy.writeln(`package.jsonc\n`);
|
||||||
await ctx.proxy.write('package.json pack package.lock');
|
await ctx.proxy.write('package.json pack package.lock');
|
||||||
|
|||||||
Reference in New Issue
Block a user