Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent search result from being deselected if it is the only result #2491

Merged
merged 9 commits into from Oct 22, 2019
10 changes: 9 additions & 1 deletion addons/xterm-addon-search/src/SearchAddon.api.ts
Expand Up @@ -15,7 +15,7 @@ const width = 800;
const height = 600;

describe('Search Tests', function (): void {
this.timeout(200000);
this.timeout(20000);

before(async function (): Promise<any> {
browser = await puppeteer.launch({
Expand Down Expand Up @@ -98,6 +98,14 @@ describe('Search Tests', function (): void {
await page.evaluate(`window.search.findNext('[A-Z]+', {regex: true, caseSensitive: true})`);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), 'ABCD');
});

it('Search for single result twice should not unselect it', async () => {
await writeSync('abc def');
assert.deepEqual(await page.evaluate(`window.search.findNext('abc')`), true);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), 'abc');
assert.deepEqual(await page.evaluate(`window.search.findNext('abc')`), true);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), 'abc');
});
});

async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
Expand Down
17 changes: 12 additions & 5 deletions addons/xterm-addon-search/src/SearchAddon.ts
Expand Up @@ -3,7 +3,7 @@
* @license MIT
*/

import { Terminal, IDisposable, ITerminalAddon } from 'xterm';
import { Terminal, IDisposable, ITerminalAddon, ISelectionPosition } from 'xterm';

export interface ISearchOptions {
regex?: boolean;
Expand Down Expand Up @@ -59,12 +59,12 @@ export class SearchAddon implements ITerminalAddon {

let startCol = 0;
let startRow = 0;

let currentSelection: ISelectionPosition | 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
const currentSelection = this._terminal.getSelectionPosition()!;
currentSelection = this._terminal.getSelectionPosition()!;
startRow = incremental ? currentSelection.startRow : currentSelection.endRow;
startCol = incremental ? currentSelection.startColumn : currentSelection.endColumn;
}
Expand Down Expand Up @@ -97,6 +97,9 @@ export class SearchAddon implements ITerminalAddon {
}
}

// If there is only one result, return true.
if (!result && currentSelection) return true;

// Set selection and scroll if a result was found
return this._selectResult(result);
}
Expand All @@ -121,10 +124,11 @@ export class SearchAddon implements ITerminalAddon {
const isReverseSearch = true;
let startRow = this._terminal.buffer.baseY + this._terminal.rows;
let startCol = this._terminal.cols;
let result: ISearchResult | undefined = undefined;
let result: ISearchResult | undefined;
const incremental = searchOptions ? searchOptions.incremental : false;
let currentSelection: ISelectionPosition | undefined;
if (this._terminal.hasSelection()) {
const currentSelection = this._terminal.getSelectionPosition()!;
currentSelection = this._terminal.getSelectionPosition()!;
// Start from selection start if there is a selection
startRow = currentSelection.startRow;
startCol = currentSelection.startColumn;
Expand Down Expand Up @@ -161,6 +165,9 @@ export class SearchAddon implements ITerminalAddon {
}
}

// If there is only one result, return true.
if (!result && currentSelection) return true;

// Set selection and scroll if a result was found
return this._selectResult(result);
}
Expand Down