-
-
Notifications
You must be signed in to change notification settings - Fork 155
Open
Description
Hi 👋
I'm trying to build something like the GitHub code search
For now I'm able to highlight words based on start and end index:
Code
const getDecorations = (
highlights: Array<{ start: number; end: number }> = []
) => {
const decorations = highlights.map(({ start, end }) =>
Decoration.mark({
attributes: { style: "background-color: #dadb1699" },
}).range(start, end)
);
return Decoration.set(decorations);
};
export const highlightPlugin = (
highlights: Array<{ start: number; end: number }>
) =>
ViewPlugin.fromClass(
class {
decorations: DecorationSet;
constructor() {
this.decorations = getDecorations(highlights);
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.decorations = getDecorations();
}
}
},
{
decorations: (v) => v.decorations,
}
);
const pointIsInRanges = (point: number, start: number, end: number) => point >= start && point <= end
export const foldLinesPlugin = (
rangesToKeep: { start: number; end: number }[]
): ViewPlugin<{ decorations: DecorationSet }> => {
return ViewPlugin.fromClass(
class {
decorations: DecorationSet;
constructor(view: EditorView) {
this.decorations = this.foldLines(view);
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.decorations = this.foldLines(update.view);
}
}
foldLines(view: EditorView): DecorationSet {
const builder = new RangeSetBuilder<Decoration>();
const lines = view.state.doc.lines;
for (let i = 1; i <= lines; i++) {
const line = view.state.doc.line(i);
let found = false;
for (const range of rangesToKeep) {
if (
pointIsInRanges(range.start, line.from, line.to) ||
pointIsInRanges(range.end, line.from, line.to)
) {
found = true;
break;
}
}
if (!found) {
builder.add(
line.from,
line.to,
Decoration.replace({ widget: new FoldWidget() })
);
}
}
return builder.finish();
}
},
{
decorations: (v) => v.decorations,
}
);
};
class FoldWidget extends WidgetType {
toDOM() {
const span = document.createElement("span");
span.style.display = "none";
return span;
}
}How can I just show only the match result without all other lines and how can I keep the only the original line number?
Metadata
Metadata
Assignees
Labels
No labels

