uiwjs / uiwjs/react-codemirror

Hide multiple lines

Open
#684 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.3k
Forks
161
PR merge metrics
No merged PRs in 30d

Description

Hi 👋

I'm trying to build something like the GitHub code search

Example

image

For now I'm able to highlight words based on start and end index:

image

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?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue provides no repository file or test entry point; begin with the supplied TypeScript foldLinesPlugin and its CodeMirror decoration logic. Done means showing only matched lines while preserving their original line numbers, with the behavior verified in the editor.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.