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