diff --git a/src/vs/editor/contrib/find/common/findController.ts b/src/vs/editor/contrib/find/common/findController.ts index ee36a31d605fda841e45293c872b8c43a0d46279..dca8998c28bf0584f7efc4ee4e82f2e4d08b86d9 100644 --- a/src/vs/editor/contrib/find/common/findController.ts +++ b/src/vs/editor/contrib/find/common/findController.ts @@ -220,6 +220,15 @@ export class CommonFindController extends Disposable implements editorCommon.IEd } return false; } + + public selectAllMatches(): boolean { + if (this._model) { + this._model.selectAllMatches(); + this._editor.focus(); + return true; + } + return false; + } } export class StartFindAction extends EditorAction { @@ -726,3 +735,6 @@ registerFindCommand(FIND_IDS.ReplaceOneAction, x => x.replace(), { registerFindCommand(FIND_IDS.ReplaceAllAction, x => x.replaceAll(), { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter }); +registerFindCommand(FIND_IDS.SelectAllMatchesAction, x => x.selectAllMatches(), { + primary: KeyMod.Alt | KeyCode.Enter +}); diff --git a/src/vs/editor/contrib/find/common/findModel.ts b/src/vs/editor/contrib/find/common/findModel.ts index a1689596841b08f0627262472e912558df457708..520a4a2d6fa9dc8196398b6b497e8bcc41370617 100644 --- a/src/vs/editor/contrib/find/common/findModel.ts +++ b/src/vs/editor/contrib/find/common/findModel.ts @@ -14,6 +14,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import {FindDecorations} from './findDecorations'; import {FindReplaceState, FindReplaceStateChangedEvent} from './findState'; import {ReplaceAllCommand} from './replaceAllCommand'; +import {Selection} from 'vs/editor/common/core/selection'; export const FIND_IDS = { StartFindAction: 'actions.find', @@ -29,7 +30,8 @@ export const FIND_IDS = { ToggleWholeWordCommand: 'toggleFindWholeWord', ToggleRegexCommand: 'toggleFindRegex', ReplaceOneAction: 'editor.action.replaceOne', - ReplaceAllAction: 'editor.action.replaceAll' + ReplaceAllAction: 'editor.action.replaceAll', + SelectAllMatchesAction: 'editor.action.selectAllMatches' }; export const MATCHES_LIMIT = 999; @@ -354,6 +356,19 @@ export class FindModelBoundToEditorModel { this.research(false); } + public selectAllMatches(): void { + if (!this._hasMatches()) { + return; + } + + let findScope = this._decorations.getFindScope(); + + // Get all the ranges (even more than the highlighted ones) + let ranges = this._findMatches(findScope, Number.MAX_VALUE); + + this._editor.setSelections(ranges.map(r => new Selection(r.startLineNumber, r.startColumn, r.endLineNumber, r.endColumn))); + } + private _executeEditorCommand(source:string, command:editorCommon.ICommand): void { try { this._ignoreModelContentChanged = true; diff --git a/src/vs/editor/contrib/find/test/common/findModel.test.ts b/src/vs/editor/contrib/find/test/common/findModel.test.ts index 93e947a9f75db94c1e3728585fef686b3b722ae3..0411a09189e69e121252e4d17ee5e0069eb156bd 100644 --- a/src/vs/editor/contrib/find/test/common/findModel.test.ts +++ b/src/vs/editor/contrib/find/test/common/findModel.test.ts @@ -7,6 +7,7 @@ import * as assert from 'assert'; import {Cursor} from 'vs/editor/common/controller/cursor'; import {Position} from 'vs/editor/common/core/position'; +import {Selection} from 'vs/editor/common/core/selection'; import {Range} from 'vs/editor/common/core/range'; import {Handler, ICommonCodeEditor, IRange} from 'vs/editor/common/editorCommon'; import {FindModelBoundToEditorModel, parseReplaceString} from 'vs/editor/contrib/find/common/findModel'; @@ -1395,6 +1396,48 @@ suite('FindModel', () => { findState.dispose(); }); + findTest('selectAllMatches', (editor, cursor) => { + let findState = new FindReplaceState(); + findState.change({ searchString: 'hello', replaceString: 'hi', wholeWord: true }, false); + let findModel = new FindModelBoundToEditorModel(editor, findState); + + assertFindState( + editor, + [1, 1, 1, 1], + null, + [ + [6, 14, 6, 19], + [6, 27, 6, 32], + [7, 14, 7, 19], + [8, 14, 8, 19] + ] + ); + + findModel.selectAllMatches(); + + assert.deepEqual(editor.getSelections().map(s => s.toString()), [ + new Selection(6, 14, 6, 19), + new Selection(6, 27, 6, 32), + new Selection(7, 14, 7, 19), + new Selection(8, 14, 8, 19) + ].map(s => s.toString())); + + assertFindState( + editor, + [6, 14, 6, 19], + null, + [ + [6, 14, 6, 19], + [6, 27, 6, 32], + [7, 14, 7, 19], + [8, 14, 8, 19] + ] + ); + + findModel.dispose(); + findState.dispose(); + }); + findTest('issue #1914: NPE when there is only one find match', (editor, cursor) => { let findState = new FindReplaceState(); findState.change({ searchString: 'cool.h' }, false);