Path: blob/master/src/packages/frontend/editors/slate/search/find-matches.ts
1698 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { Editor, Node, Path, Point, Range, Transforms } from "slate";6import { rangeAll, rangeToEnd, rangeFromStart } from "../slate-util";78/* Find locations of all positions in the editor that match the search string. */910// TODO: findMatches will be used for "replace all" functionality, but isn't used now.11export function findMatches(12editor: Editor,13decorate: (x: [Node, Path]) => any[]14): any[] {15const matches: any[] = [];16for (const [node, path] of Editor.nodes(editor, {17at: rangeAll(editor),18})) {19for (const match of decorate([node, path])) {20matches.push(match);21}22}23return matches;24}2526function selectMatch(27editor: Editor,28decorate,29options,30above: boolean31): boolean {32let cursor;33if (editor.selection == null) {34cursor = undefined;35} else {36const edges = Range.edges(editor.selection);37cursor = above ? edges[0] : edges[1];38}39for (const [node, path] of Editor.nodes(editor, options)) {40const dc = decorate([node, path]);41if (options.reverse) {42dc.reverse();43}44for (const match of dc) {45if (46cursor == null ||47(!above && Point.equals(cursor, match.anchor)) ||48(above && Point.isBefore(match.anchor, cursor)) ||49(!above && Point.isAfter(match.anchor, cursor))50) {51Transforms.setSelection(editor, {52anchor: match.anchor,53focus: match.focus,54});55return true;56}57}58}59return false;60}6162export function selectNextMatch(editor: Editor, decorate) : boolean {63{64const { anchor, focus } = rangeToEnd(editor);65const at = { focus, anchor: { path: anchor.path, offset: 0 } };66if (selectMatch(editor, decorate, { at }, false)) return true;67}68{69const at = rangeFromStart(editor);70if (selectMatch(editor, decorate, { at }, true)) return true;71}72return false;73}7475export function selectPreviousMatch(editor: Editor, decorate) : boolean {76{77const { anchor, focus } = rangeFromStart(editor);78const n = Editor.next(editor, { at: focus.path });79const at = { anchor, focus: n != null ? n[1] : focus };80if (selectMatch(editor, decorate, { at, reverse: true }, true)) return true;81}82{83const at = rangeToEnd(editor);84if (selectMatch(editor, decorate, { at, reverse: true }, false)) return true;85}86return false;87}888990