Cache search decorations when possible

This actually saves a *lot* of work on simple keystrokes like `hjkl` when you've got a lot of search results highlighted.
This commit is contained in:
Jason Fields 2022-06-27 18:48:57 -04:00
parent bd9ee5d270
commit 47aa61ceab
2 changed files with 26 additions and 9 deletions

View File

@ -17,7 +17,7 @@ import { PairMatcher } from './../common/matching/matcher';
import { laterOf } from './../common/motion/position';
import { Cursor } from '../common/motion/cursor';
import { RecordedState } from './../state/recordedState';
import { IBaseAction } from "../actions/types";
import { IBaseAction } from '../actions/types';
import { Register, RegisterMode } from './../register/register';
import { Remappers } from '../configuration/remapper';
import { StatusBar } from '../statusBar';
@ -46,6 +46,7 @@ import { Position, Uri } from 'vscode';
import { RemapState } from '../state/remapState';
import * as process from 'process';
import { EasyMotion } from '../actions/plugins/easymotion/easymotion';
import { SearchState } from '../state/searchState';
interface IModeHandlerMap {
get(editorId: Uri): ModeHandler | undefined;
@ -63,6 +64,10 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {
public focusChanged = false;
private searchDecorationCacheKey:
| { searchState: SearchState; documentVersion: number }
| undefined;
private readonly disposables: vscode.Disposable[] = [];
private readonly handlerMap: IModeHandlerMap;
private readonly remappers: Remappers;
@ -1156,6 +1161,9 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {
}
public updateSearchHighlights(showHighlights: boolean) {
const cacheKey = this.searchDecorationCacheKey;
this.searchDecorationCacheKey = undefined;
let decorations: SearchDecorations | undefined;
if (showHighlights) {
if (
@ -1163,11 +1171,24 @@ export class ModeHandler implements vscode.Disposable, IModeHandler {
this.vimState.modeData.mode === Mode.SearchInProgressMode
) {
decorations = this.vimState.modeData.commandLine.getDecorations(this.vimState);
} else {
} else if (globalState.searchState) {
if (
cacheKey &&
cacheKey.searchState === globalState.searchState &&
cacheKey.documentVersion === this.vimState.document.version
) {
// The decorations are fine as-is, don't waste time re-calculating
this.searchDecorationCacheKey = cacheKey;
return;
}
// If there are no decorations from the command line, get decorations for previous SearchState
decorations = getDecorationsForSearchMatchRanges(
globalState.searchState?.getMatchRanges(this.vimState)
globalState.searchState.getMatchRanges(this.vimState)
);
this.searchDecorationCacheKey = {
searchState: globalState.searchState,
documentVersion: this.vimState.document.version,
};
}
}

View File

@ -24,7 +24,7 @@ export type SearchDecorations = {
* character.
*/
export function ensureVisible(range: Range): DecorationOptions {
return range.start.isLineEnd() && (range.isEmpty || range.end.isLineBeginning())
return (range.isEmpty || range.end.isLineBeginning()) && range.start.isLineEnd()
? {
// range is at EOL, possibly containing EOL char(s).
range: range.with(undefined, range.start),
@ -61,13 +61,9 @@ export function formatDecorationText(
* @returns search decorations for the given ranges, taking into account the current match
*/
export function getDecorationsForSearchMatchRanges(
ranges: Range[] | undefined,
ranges: Range[],
currentMatchIndex?: number
): SearchDecorations {
if (ranges === undefined) {
return {};
}
const searchHighlight: DecorationOptions[] = [];
const searchMatch: DecorationOptions[] = [];