diff --git a/package.json b/package.json index bfa3f1c5c5f..dcdc37af79c 100644 --- a/package.json +++ b/package.json @@ -677,6 +677,11 @@ "description": "Regex matches for JumpToAnywhere motion.", "default": "\\b[A-Za-z0-9]|[A-Za-z0-9]\\b|_.|#.|[a-z][A-Z]" }, + "vim.easymotionOnlyVisibleRange": { + "type": "boolean", + "description": "Only use markers in visible range (ignores folded content).", + "default": false + }, "vim.replaceWithRegister": { "type": "boolean", "markdownDescription": "Enable the [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister) plugin for Vim.", diff --git a/src/actions/plugins/easymotion/easymotion.cmd.ts b/src/actions/plugins/easymotion/easymotion.cmd.ts index 4da98a799a5..301216b7f2e 100644 --- a/src/actions/plugins/easymotion/easymotion.cmd.ts +++ b/src/actions/plugins/easymotion/easymotion.cmd.ts @@ -115,13 +115,14 @@ function getMatchesForString( position, new RegExp(' {1,}', 'g'), options, + vimState.editor, ); default: // Search all occurences of the character pressed // If the input is not a letter, treating it as regex can cause issues if (!/[a-zA-Z]/.test(searchString)) { - return vimState.easyMotion.sortedSearch(vimState.document, position, searchString, options); + return vimState.easyMotion.sortedSearch(vimState.document, position, searchString, options, vimState.editor); } const ignorecase = @@ -132,6 +133,7 @@ function getMatchesForString( position, new RegExp(searchString, regexFlags), options, + vimState.editor, ); } } @@ -269,7 +271,7 @@ export abstract class EasyMotionWordMoveCommandBase extends BaseEasyMotionComman const regex = this._options.jumpToAnywhere ? new RegExp(configuration.easymotionJumpToAnywhereRegex, 'g') : new RegExp('\\w{1,}', 'g'); - return vimState.easyMotion.sortedSearch(vimState.document, position, regex, options); + return vimState.easyMotion.sortedSearch(vimState.document, position, regex, options, vimState.editor); } } @@ -300,6 +302,7 @@ export abstract class EasyMotionLineMoveCommandBase extends BaseEasyMotionComman position, new RegExp('^.', 'gm'), options, + vimState.editor, ); for (const match of matches) { match.position = TextEditor.getFirstNonWhitespaceCharOnLine( diff --git a/src/actions/plugins/easymotion/easymotion.ts b/src/actions/plugins/easymotion/easymotion.ts index d1e3e403c15..dac7a7738a6 100644 --- a/src/actions/plugins/easymotion/easymotion.ts +++ b/src/actions/plugins/easymotion/easymotion.ts @@ -112,6 +112,22 @@ export class EasyMotion implements IEasyMotion { return markers.filter((marker) => marker.name.startsWith(nail)); } + /** + * Check if a position is within the visible ranges of the editor + */ + private isPositionVisible(position: Position, editor: vscode.TextEditor): boolean { + if (!configuration.easymotionOnlyVisibleRange) { + return true; + } + + for (const range of editor.visibleRanges) { + if (range.contains(position)) { + return true; + } + } + return false; + } + /** * Search and sort using the index of a match compared to the index of position (usually the cursor) */ @@ -120,6 +136,7 @@ export class EasyMotion implements IEasyMotion { position: Position, search: string | RegExp = '', options: SearchOptions = {}, + editor?: vscode.TextEditor, ): Match[] { const regex = typeof search === 'string' @@ -163,10 +180,14 @@ export class EasyMotion implements IEasyMotion { // Matches on the cursor position should be ignored if (pos.isEqual(position)) { result = regex.exec(line); - } else { + } else if (!editor || this.isPositionVisible(pos, editor)) { + // Only add matches that are in visible range (if option is enabled) prevMatch = new Match(pos, result[0], matches.length); matches.push(prevMatch); result = regex.exec(line); + } else { + // Skip this match if it's not visible + result = regex.exec(line); } } } diff --git a/src/actions/plugins/easymotion/types.ts b/src/actions/plugins/easymotion/types.ts index b9918dd1a38..6ef78801016 100644 --- a/src/actions/plugins/easymotion/types.ts +++ b/src/actions/plugins/easymotion/types.ts @@ -82,6 +82,7 @@ export interface IEasyMotion { position: Position, search?: string | RegExp, options?: SearchOptions, + editor?: vscode.TextEditor, ): Match[]; updateDecorations(editor: vscode.TextEditor): void; clearMarkers(): void; diff --git a/src/configuration/configuration.ts b/src/configuration/configuration.ts index 0f0f53ac158..f92b11ba5a6 100644 --- a/src/configuration/configuration.ts +++ b/src/configuration/configuration.ts @@ -277,6 +277,7 @@ class Configuration implements IConfiguration { easymotionMarkerFontWeight = 'bold'; easymotionKeys = 'hklyuiopnm,qwertzxcvbasdgjf;'; easymotionJumpToAnywhereRegex = '\\b[A-Za-z0-9]|[A-Za-z0-9]\\b|_.|#.|[a-z][A-Z]'; + easymotionOnlyVisibleRange = false; targets: ITargetsConfiguration = { enable: false,