mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
refactor(code/find): remove inner class
This commit is contained in:
parent
e5417827f4
commit
8a35e390f2
@ -1,5 +1,5 @@
|
|||||||
import { EditorView, Decoration, MatchDecorator, ViewPlugin, ViewUpdate } from "@codemirror/view";
|
import { EditorView, Decoration, MatchDecorator, ViewPlugin, ViewUpdate } from "@codemirror/view";
|
||||||
import { StateEffect, Compartment, EditorSelection, RangeSet } from "@codemirror/state";
|
import { RangeSet, RangeSetBuilder } from "@codemirror/state";
|
||||||
|
|
||||||
const searchMatchDecoration = Decoration.mark({ class: "cm-searchMatch" });
|
const searchMatchDecoration = Decoration.mark({ class: "cm-searchMatch" });
|
||||||
|
|
||||||
@ -8,33 +8,40 @@ interface Match {
|
|||||||
to: number;
|
to: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSearchHighlighter(view: EditorView, searchTerm: string, matchCase: boolean, wholeWord: boolean) {
|
export class SearchHighlighter {
|
||||||
// Escape the search term for use in RegExp
|
matches: RangeSet<Decoration>;
|
||||||
const escapedTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
||||||
const wordBoundary = wholeWord ? "\\b" : "";
|
|
||||||
const flags = matchCase ? "g" : "gi";
|
|
||||||
const regex = new RegExp(`${wordBoundary}${escapedTerm}${wordBoundary}`, flags);
|
|
||||||
|
|
||||||
const matcher = new MatchDecorator({
|
|
||||||
regexp: regex,
|
|
||||||
decoration: searchMatchDecoration,
|
|
||||||
});
|
|
||||||
|
|
||||||
return ViewPlugin.fromClass(class SearchHighlighter {
|
|
||||||
matches!: RangeSet<Decoration>;
|
|
||||||
currentFound: number;
|
currentFound: number;
|
||||||
totalFound: number;
|
totalFound: number;
|
||||||
|
matcher?: MatchDecorator;
|
||||||
private parsedMatches: Match[];
|
private parsedMatches: Match[];
|
||||||
|
|
||||||
constructor(public view: EditorView) {
|
constructor(public view: EditorView) {
|
||||||
this.parsedMatches = [];
|
this.parsedMatches = [];
|
||||||
this.currentFound = 0;
|
this.currentFound = 0;
|
||||||
this.totalFound = 0;
|
this.totalFound = 0;
|
||||||
this.updateSearchData(view);
|
this.matches = (new RangeSetBuilder<Decoration>()).finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
searchFor(searchTerm: string, matchCase: boolean, wholeWord: boolean) {
|
||||||
|
// Escape the search term for use in RegExp
|
||||||
|
const escapedTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
const wordBoundary = wholeWord ? "\\b" : "";
|
||||||
|
const flags = matchCase ? "g" : "gi";
|
||||||
|
const regex = new RegExp(`${wordBoundary}${escapedTerm}${wordBoundary}`, flags);
|
||||||
|
|
||||||
|
this.matcher = new MatchDecorator({
|
||||||
|
regexp: regex,
|
||||||
|
decoration: searchMatchDecoration,
|
||||||
|
});
|
||||||
|
this.updateSearchData(this.view);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSearchData(view: EditorView) {
|
updateSearchData(view: EditorView) {
|
||||||
const matches = matcher.createDeco(view);
|
if (!this.matcher) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matches = this.matcher.createDeco(view);
|
||||||
const cursor = matches.iter();
|
const cursor = matches.iter();
|
||||||
while (cursor.value) {
|
while (cursor.value) {
|
||||||
this.parsedMatches.push({
|
this.parsedMatches.push({
|
||||||
@ -85,13 +92,15 @@ export function createSearchHighlighter(view: EditorView, searchTerm: string, ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
static deco = (v: SearchHighlighter) => v.matches;
|
static deco = (v: SearchHighlighter) => v.matches;
|
||||||
}, {
|
}
|
||||||
|
|
||||||
|
export function createSearchHighlighter() {
|
||||||
|
return ViewPlugin.fromClass(SearchHighlighter, {
|
||||||
decorations: v => v.matches,
|
decorations: v => v.matches,
|
||||||
provide: (plugin) => plugin
|
provide: (plugin) => plugin
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const searchMatchHighlightTheme = EditorView.baseTheme({
|
export const searchMatchHighlightTheme = EditorView.baseTheme({
|
||||||
".cm-searchMatch": {
|
".cm-searchMatch": {
|
||||||
backgroundColor: "rgba(255, 255, 0, 0.4)",
|
backgroundColor: "rgba(255, 255, 0, 0.4)",
|
||||||
|
@ -172,7 +172,7 @@ export default class CodeMirror extends EditorView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async performFind(searchTerm: string, matchCase: boolean, wholeWord: boolean) {
|
async performFind(searchTerm: string, matchCase: boolean, wholeWord: boolean) {
|
||||||
const plugin = createSearchHighlighter(this, searchTerm, matchCase, wholeWord);
|
const plugin = createSearchHighlighter();
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
effects: this.searchHighlightCompartment.reconfigure(plugin)
|
effects: this.searchHighlightCompartment.reconfigure(plugin)
|
||||||
});
|
});
|
||||||
@ -180,6 +180,7 @@ export default class CodeMirror extends EditorView {
|
|||||||
// Wait for the plugin to activate in the next render cycle
|
// Wait for the plugin to activate in the next render cycle
|
||||||
await new Promise(requestAnimationFrame);
|
await new Promise(requestAnimationFrame);
|
||||||
const instance = this.plugin(plugin);
|
const instance = this.plugin(plugin);
|
||||||
|
instance?.searchFor(searchTerm, matchCase, wholeWord);
|
||||||
if (instance) {
|
if (instance) {
|
||||||
instance.scrollToMatchNearestSelection();
|
instance.scrollToMatchNearestSelection();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user