refactor(code/find): reimplement find next

This commit is contained in:
Elian Doran 2025-05-12 21:21:46 +03:00
parent 2fbff5328b
commit 22d9091315
No known key found for this signature in database
3 changed files with 37 additions and 49 deletions

View File

@ -42,29 +42,11 @@ export default class FindInCode {
async findNext(direction: number, currentFound: number, nextFound: number) {
const codeEditor = await this.getCodeEditor();
if (!codeEditor || !this.findResult) {
if (!codeEditor) {
return;
}
const doc = codeEditor.doc;
//
// Dehighlight current, highlight & scrollIntoView next
//
let marker = this.findResult[currentFound];
let pos = marker.find();
marker.clear();
marker = doc.markText(pos.from, pos.to, { className: FIND_RESULT_CSS_CLASSNAME });
this.findResult[currentFound] = marker;
marker = this.findResult[nextFound];
pos = marker.find();
marker.clear();
marker = doc.markText(pos.from, pos.to, { className: FIND_RESULT_SELECTED_CSS_CLASSNAME });
this.findResult[nextFound] = marker;
codeEditor.scrollIntoView(pos.from);
codeEditor.findNext(direction, currentFound, nextFound);
}
async findBoxClosed(totalFound: number, currentFound: number) {

View File

@ -33,11 +33,34 @@ export class SearchHighlighter {
regexp: regex,
decoration: searchMatchDecoration,
});
this.updateSearchData(this.view);
this.scrollToMatchNearestSelection();
this.#updateSearchData(this.view);
this.#scrollToMatchNearestSelection();
}
updateSearchData(view: EditorView) {
scrollToMatch(matchIndex: number) {
if (this.parsedMatches.length <= matchIndex) {
return;
}
const match = this.parsedMatches[matchIndex];
this.currentFound = matchIndex + 1;
this.view.dispatch({
effects: EditorView.scrollIntoView(match.from, { y: "center" }),
scrollIntoView: true
});
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.#updateSearchData(update.view);
}
}
destroy() {
// Do nothing.
}
#updateSearchData(view: EditorView) {
if (!this.matcher) {
return;
}
@ -56,26 +79,7 @@ export class SearchHighlighter {
this.totalFound = this.parsedMatches.length;
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.updateSearchData(update.view);
}
}
scrollToMatch(matchIndex: number) {
if (this.parsedMatches.length <= matchIndex) {
return;
}
const match = this.parsedMatches[matchIndex];
this.currentFound = matchIndex + 1;
this.view.dispatch({
effects: EditorView.scrollIntoView(match.from, { y: "center" }),
scrollIntoView: true
});
}
scrollToMatchNearestSelection() {
#scrollToMatchNearestSelection() {
const cursorPos = this.view.state.selection.main.head;
let index = 0;
for (const match of this.parsedMatches) {
@ -88,10 +92,6 @@ export class SearchHighlighter {
}
}
destroy() {
// Do nothing.
}
static deco = (v: SearchHighlighter) => v.matches;
}

View File

@ -1,5 +1,5 @@
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
import { EditorView, highlightActiveLine, keymap, lineNumbers, placeholder, ViewUpdate, type EditorViewConfig } from "@codemirror/view";
import { EditorView, highlightActiveLine, keymap, lineNumbers, placeholder, ViewPlugin, ViewUpdate, type EditorViewConfig } from "@codemirror/view";
import { defaultHighlightStyle, StreamLanguage, syntaxHighlighting, indentUnit, bracketMatching, foldGutter } from "@codemirror/language";
import { Compartment, EditorSelection, EditorState, type Extension } from "@codemirror/state";
import { highlightSelectionMatches } from "@codemirror/search";
@ -7,7 +7,7 @@ import { vim } from "@replit/codemirror-vim";
import byMimeType from "./syntax_highlighting.js";
import smartIndentWithTab from "./extensions/custom_tab.js";
import type { ThemeDefinition } from "./color_themes.js";
import { createSearchHighlighter, searchMatchHighlightTheme } from "./find_replace.js";
import { createSearchHighlighter, SearchHighlighter, searchMatchHighlightTheme } from "./find_replace.js";
export { default as ColorThemes, type ThemeDefinition, getThemeById } from "./color_themes.js";
@ -31,6 +31,7 @@ export default class CodeMirror extends EditorView {
private themeCompartment: Compartment;
private lineWrappingCompartment: Compartment;
private searchHighlightCompartment: Compartment;
private searchPlugin?: SearchHighlighter | null;
constructor(config: EditorConfig) {
const languageCompartment = new Compartment();
@ -181,6 +182,7 @@ export default class CodeMirror extends EditorView {
await new Promise(requestAnimationFrame);
const instance = this.plugin(plugin);
instance?.searchFor(searchTerm, matchCase, wholeWord);
this.searchPlugin = instance;
return {
totalFound: instance?.totalFound ?? 0,
@ -188,6 +190,10 @@ export default class CodeMirror extends EditorView {
}
}
async findNext(direction: number, currentFound: number, nextFound: number) {
this.searchPlugin?.scrollToMatch(nextFound);
}
async setMimeType(mime: string) {
let newExtension: Extension[] = [];