@jupyterlab/codemirror 4.0.0-alpha.1 → 4.0.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/codemirror-ipython.d.ts +1 -2
- package/lib/codemirror-ipython.js +7 -25
- package/lib/codemirror-ipython.js.map +1 -1
- package/lib/codemirror-ipythongfm.d.ts +10 -3
- package/lib/codemirror-ipythongfm.js +60 -30
- package/lib/codemirror-ipythongfm.js.map +1 -1
- package/lib/editor.d.ts +51 -206
- package/lib/editor.js +385 -625
- package/lib/editor.js.map +1 -1
- package/lib/editorconfiguration.d.ts +149 -0
- package/lib/editorconfiguration.js +286 -0
- package/lib/editorconfiguration.js.map +1 -0
- package/lib/editortheme.d.ts +41 -0
- package/lib/editortheme.js +167 -0
- package/lib/editortheme.js.map +1 -0
- package/lib/factory.js +22 -19
- package/lib/factory.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/mimetype.js +9 -3
- package/lib/mimetype.js.map +1 -1
- package/lib/mode.d.ts +61 -54
- package/lib/mode.js +1472 -105
- package/lib/mode.js.map +1 -1
- package/lib/searchprovider.d.ts +181 -0
- package/lib/searchprovider.js +648 -0
- package/lib/searchprovider.js.map +1 -0
- package/lib/syntaxstatus.js +9 -3
- package/lib/syntaxstatus.js.map +1 -1
- package/package.json +47 -30
- package/style/base.css +14 -154
- package/style/index.css +2 -4
- package/style/index.js +2 -4
- package/lib/tokens.d.ts +0 -18
- package/lib/tokens.js +0 -9
- package/lib/tokens.js.map +0 -1
- package/typings/codemirror/codemirror.d.ts +0 -227
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
/*
|
|
4
|
+
Parts of the implementation of the search in this file were derived from
|
|
5
|
+
CodeMirror's search at:
|
|
6
|
+
https://github.com/codemirror/CodeMirror/blob/c2676685866c571a1c9c82cb25018cc08b4d42b2/addon/search/search.js
|
|
7
|
+
which is licensed with the following license:
|
|
8
|
+
|
|
9
|
+
MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in
|
|
21
|
+
all copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
29
|
+
THE SOFTWARE.
|
|
30
|
+
*/
|
|
31
|
+
import { TextSearchEngine } from '@jupyterlab/documentsearch';
|
|
32
|
+
import { JSONExt } from '@lumino/coreutils';
|
|
33
|
+
import { Signal } from '@lumino/signaling';
|
|
34
|
+
import { RegExpCursor } from '@codemirror/search';
|
|
35
|
+
import { Compartment, StateEffect, StateField } from '@codemirror/state';
|
|
36
|
+
import { Decoration, EditorView } from '@codemirror/view';
|
|
37
|
+
/**
|
|
38
|
+
* CodeMirror search provider for file editor
|
|
39
|
+
*/
|
|
40
|
+
export class CodeMirrorSearchProvider {
|
|
41
|
+
constructor(editor) {
|
|
42
|
+
/**
|
|
43
|
+
* Set to true if the widget under search is read-only, false
|
|
44
|
+
* if it is editable. Will be used to determine whether to show
|
|
45
|
+
* the replace option.
|
|
46
|
+
*/
|
|
47
|
+
this.isReadOnly = false;
|
|
48
|
+
this._matchState = {};
|
|
49
|
+
this._changed = new Signal(this);
|
|
50
|
+
this._disposed = false;
|
|
51
|
+
this.editor = editor;
|
|
52
|
+
this._highlightEffect = StateEffect.define({
|
|
53
|
+
map: (value, mapping) => ({
|
|
54
|
+
matches: value.matches.map(v => ({
|
|
55
|
+
text: v.text,
|
|
56
|
+
position: mapping.mapPos(v.position)
|
|
57
|
+
}))
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
this._highlightMark = Decoration.mark({ class: 'cm-searching' });
|
|
61
|
+
this._highlightField = StateField.define({
|
|
62
|
+
create: () => {
|
|
63
|
+
return Decoration.none;
|
|
64
|
+
},
|
|
65
|
+
update: (highlights, transaction) => {
|
|
66
|
+
highlights = highlights.map(transaction.changes);
|
|
67
|
+
for (let ef of transaction.effects) {
|
|
68
|
+
if (ef.is(this._highlightEffect)) {
|
|
69
|
+
const e = ef;
|
|
70
|
+
if (e.value.matches.length) {
|
|
71
|
+
highlights = highlights.update({
|
|
72
|
+
add: e.value.matches.map(m => this._highlightMark.range(m.position, m.position + m.text.length))
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
highlights = Decoration.none;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return highlights;
|
|
81
|
+
},
|
|
82
|
+
provide: f => EditorView.decorations.from(f)
|
|
83
|
+
});
|
|
84
|
+
this._listener = new Compartment();
|
|
85
|
+
this.editor.injectExtension(this._listener.of([]));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Whether the search provider is disposed or not.
|
|
89
|
+
*/
|
|
90
|
+
get isDisposed() {
|
|
91
|
+
return this._disposed;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Dispose the search provider
|
|
95
|
+
*/
|
|
96
|
+
dispose() {
|
|
97
|
+
if (this._disposed) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this._disposed = true;
|
|
101
|
+
Signal.clearData(this);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Initialize the search using a CodeMirrorEditor object.
|
|
105
|
+
*
|
|
106
|
+
* @param query the search regular expression
|
|
107
|
+
*/
|
|
108
|
+
async startQuery(query) {
|
|
109
|
+
if (!this.editor) {
|
|
110
|
+
return Promise.resolve();
|
|
111
|
+
}
|
|
112
|
+
return this._startQuery(query);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Refresh the search highlight overlay
|
|
116
|
+
*/
|
|
117
|
+
refreshOverlay() {
|
|
118
|
+
this._refreshOverlay();
|
|
119
|
+
}
|
|
120
|
+
async _startQuery(query, refreshOverlay = true) {
|
|
121
|
+
// no point in removing overlay in the middle of the search
|
|
122
|
+
await this.endQuery(false);
|
|
123
|
+
this._query = query;
|
|
124
|
+
this.editor.editor.dispatch({
|
|
125
|
+
effects: this._listener.reconfigure(EditorView.updateListener.of((v) => {
|
|
126
|
+
if (v.docChanged) {
|
|
127
|
+
this._onDocChanged(v);
|
|
128
|
+
}
|
|
129
|
+
}))
|
|
130
|
+
});
|
|
131
|
+
await this._setInitialMatches(query);
|
|
132
|
+
if (refreshOverlay) {
|
|
133
|
+
this._refreshOverlay();
|
|
134
|
+
}
|
|
135
|
+
const matches = this._parseMatchesFromState();
|
|
136
|
+
if (matches.length === 0) {
|
|
137
|
+
return Promise.resolve();
|
|
138
|
+
}
|
|
139
|
+
const cursorMatch = this._findNext(false);
|
|
140
|
+
const match = cursorMatch &&
|
|
141
|
+
this._matchState[cursorMatch.from.line][cursorMatch.from.ch];
|
|
142
|
+
this._currentMatch = match;
|
|
143
|
+
await this._highlightCurrentMatch(cursorMatch);
|
|
144
|
+
return Promise.resolve();
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clears state of a search provider to prepare for startQuery to be called
|
|
148
|
+
* in order to start a new query or refresh an existing one.
|
|
149
|
+
*
|
|
150
|
+
* @param removeOverlay Whether to remove the search highlight overlay or not.
|
|
151
|
+
*/
|
|
152
|
+
async endQuery(removeOverlay = true) {
|
|
153
|
+
this._matchState = {};
|
|
154
|
+
this._currentMatch = null;
|
|
155
|
+
const from = this.editor.getPositionAt(this.editor.state.selection.main.from);
|
|
156
|
+
const to = this.editor.getPositionAt(this.editor.state.selection.main.to);
|
|
157
|
+
// Setting a reverse selection to allow search-as-you-type to maintain the
|
|
158
|
+
// current selected match. See comment in _findNext for more details.
|
|
159
|
+
if (from !== to) {
|
|
160
|
+
this.editor.setSelection({
|
|
161
|
+
start: to,
|
|
162
|
+
end: from
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
this.editor.editor.dispatch({
|
|
166
|
+
effects: this._listener.reconfigure([])
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Clear currently highlighted match.
|
|
171
|
+
*/
|
|
172
|
+
clearHighlight() {
|
|
173
|
+
this._currentMatch = null;
|
|
174
|
+
const cursor = this.editor.getCursorPosition();
|
|
175
|
+
// Reset cursor position to remove any selection
|
|
176
|
+
this.editor.setCursorPosition(cursor);
|
|
177
|
+
return Promise.resolve();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Move the current match indicator to the next match.
|
|
181
|
+
*
|
|
182
|
+
* @param loop Whether to loop within the matches list.
|
|
183
|
+
*
|
|
184
|
+
* @returns A promise that resolves once the action has completed.
|
|
185
|
+
*/
|
|
186
|
+
async highlightNext(loop) {
|
|
187
|
+
return this._highlightCurrentMatch(this._findNext(false));
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Move the current match indicator to the previous match.
|
|
191
|
+
*
|
|
192
|
+
* @param loop Whether to loop within the matches list.
|
|
193
|
+
*
|
|
194
|
+
* @returns A promise that resolves once the action has completed.
|
|
195
|
+
*/
|
|
196
|
+
async highlightPrevious(loop) {
|
|
197
|
+
return this._highlightCurrentMatch(this._findNext(true));
|
|
198
|
+
}
|
|
199
|
+
async _highlightCurrentMatch(cursorMatch) {
|
|
200
|
+
// Highlight the current index
|
|
201
|
+
if (!cursorMatch) {
|
|
202
|
+
// Set cursor to remove any selection
|
|
203
|
+
this.editor.editor.dispatch({ selection: { anchor: 0 } });
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const match = this._matchState[cursorMatch.from.line][cursorMatch.from.ch];
|
|
207
|
+
this._currentMatch = match;
|
|
208
|
+
this.editor.editor.focus();
|
|
209
|
+
this.editor.editor.dispatch({
|
|
210
|
+
selection: {
|
|
211
|
+
anchor: match.position,
|
|
212
|
+
head: match.position + match.text.length
|
|
213
|
+
},
|
|
214
|
+
scrollIntoView: true
|
|
215
|
+
});
|
|
216
|
+
return match;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Replace the currently selected match with the provided text
|
|
220
|
+
*
|
|
221
|
+
* @param newText The replacement text
|
|
222
|
+
* @param loop Whether to loop within the matches list.
|
|
223
|
+
*
|
|
224
|
+
* @returns A promise that resolves with a boolean indicating whether a replace occurred.
|
|
225
|
+
*/
|
|
226
|
+
async replaceCurrentMatch(newText, loop) {
|
|
227
|
+
// If the current selection exactly matches the current match,
|
|
228
|
+
// replace it. Otherwise, just select the next match after the cursor.
|
|
229
|
+
let replaceOccurred = false;
|
|
230
|
+
if (this._currentMatchIsSelected()) {
|
|
231
|
+
const cursor = new RegExpCursor(this.editor.doc, this._query.source, { ignoreCase: !this._query.ignoreCase }, this.editor.state.selection.main.from).next();
|
|
232
|
+
if (cursor.done) {
|
|
233
|
+
return replaceOccurred;
|
|
234
|
+
}
|
|
235
|
+
const value = cursor.value;
|
|
236
|
+
replaceOccurred = true;
|
|
237
|
+
this.editor.editor.dispatch({
|
|
238
|
+
changes: { from: value.from, to: value.to, insert: newText }
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
await this.highlightNext();
|
|
242
|
+
return replaceOccurred;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Replace all matches in the notebook with the provided text
|
|
246
|
+
*
|
|
247
|
+
* @param newText The replacement text
|
|
248
|
+
*
|
|
249
|
+
* @returns A promise that resolves with a boolean indicating whether a replace occurred.
|
|
250
|
+
*/
|
|
251
|
+
async replaceAllMatches(newText) {
|
|
252
|
+
let replaceOccurred = false;
|
|
253
|
+
return new Promise((resolve, _) => {
|
|
254
|
+
let cursor = new RegExpCursor(this.editor.doc, this._query.source, {
|
|
255
|
+
ignoreCase: !this._query.ignoreCase
|
|
256
|
+
}).next();
|
|
257
|
+
let changeSpec = [];
|
|
258
|
+
while (!cursor.done) {
|
|
259
|
+
replaceOccurred = true;
|
|
260
|
+
changeSpec.push({
|
|
261
|
+
from: cursor.value.from,
|
|
262
|
+
to: cursor.value.to,
|
|
263
|
+
insert: newText
|
|
264
|
+
});
|
|
265
|
+
cursor = cursor.next();
|
|
266
|
+
}
|
|
267
|
+
this.editor.editor.dispatch({ changes: changeSpec });
|
|
268
|
+
this._matchState = {};
|
|
269
|
+
this._currentMatch = null;
|
|
270
|
+
resolve(replaceOccurred);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The list of matches
|
|
275
|
+
*/
|
|
276
|
+
get matches() {
|
|
277
|
+
return this._parseMatchesFromState();
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* The number of matches.
|
|
281
|
+
*/
|
|
282
|
+
get matchesCount() {
|
|
283
|
+
let size = 0;
|
|
284
|
+
for (const line in this._matchState) {
|
|
285
|
+
size += Object.keys(this._matchState[line]).length;
|
|
286
|
+
}
|
|
287
|
+
return size;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* The current match
|
|
291
|
+
*/
|
|
292
|
+
get currentMatch() {
|
|
293
|
+
return this._currentMatch;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Signal indicating that something in the search has changed, so the UI should update
|
|
297
|
+
*/
|
|
298
|
+
get stateChanged() {
|
|
299
|
+
return this._changed;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* The current index of the selected match.
|
|
303
|
+
*/
|
|
304
|
+
get currentMatchIndex() {
|
|
305
|
+
if (!this._currentMatch) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
// TODO make it more efficient
|
|
309
|
+
return this.matches.indexOf(this._currentMatch);
|
|
310
|
+
}
|
|
311
|
+
_onDocChanged(update) {
|
|
312
|
+
// TODO: CM6 migration
|
|
313
|
+
if (update.changes.length) {
|
|
314
|
+
this._setInitialMatches(this._query)
|
|
315
|
+
.then(() => {
|
|
316
|
+
this._changed.emit(undefined);
|
|
317
|
+
})
|
|
318
|
+
.catch(reason => {
|
|
319
|
+
console.error(`Fail to reapply search on CodeMirror document change:\n${reason}`);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
_refreshOverlay() {
|
|
324
|
+
let effects = [
|
|
325
|
+
this._highlightEffect.of({ matches: this.matches })
|
|
326
|
+
];
|
|
327
|
+
if (!this.editor.state.field(this._highlightField, false)) {
|
|
328
|
+
effects.push(StateEffect.appendConfig.of([this._highlightField]));
|
|
329
|
+
}
|
|
330
|
+
this.editor.editor.dispatch({ effects });
|
|
331
|
+
this._changed.emit(undefined);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Do a full search on the entire document.
|
|
335
|
+
*
|
|
336
|
+
* This manually constructs the initial match state across the whole
|
|
337
|
+
* document. This must be done manually because the codemirror overlay
|
|
338
|
+
* is lazy-loaded, so it will only tokenize lines that are in or near
|
|
339
|
+
* the viewport. This is sufficient for efficiently maintaining the
|
|
340
|
+
* state when changes are made to the document, as changes occur in or
|
|
341
|
+
* near the viewport, but to scan the whole document, a manual search
|
|
342
|
+
* across the entire content is required.
|
|
343
|
+
*
|
|
344
|
+
* @param query The search term
|
|
345
|
+
*/
|
|
346
|
+
async _setInitialMatches(query) {
|
|
347
|
+
this._matchState = {};
|
|
348
|
+
const content = this.editor.doc.toString();
|
|
349
|
+
const matches = await TextSearchEngine.search(query, content);
|
|
350
|
+
matches.forEach(match => {
|
|
351
|
+
const { line, ch } = this._getPosition(match.position);
|
|
352
|
+
if (!this._matchState[line]) {
|
|
353
|
+
this._matchState[line] = {};
|
|
354
|
+
}
|
|
355
|
+
this._matchState[line][ch] = match;
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
_findNext(reverse) {
|
|
359
|
+
const caseSensitive = this._query.ignoreCase;
|
|
360
|
+
const state = this.editor.state;
|
|
361
|
+
// In order to support search-as-you-type, we needed a way to allow the first
|
|
362
|
+
// match to be selected when a search is started, but prevent the selected
|
|
363
|
+
// search to move for each new keypress. To do this, when a search is ended,
|
|
364
|
+
// the cursor is reversed, putting the head at the 'from' position. When a new
|
|
365
|
+
// search is started, the cursor we want is at the 'from' position, so that the same
|
|
366
|
+
// match is selected when the next key is entered (if it is still a match).
|
|
367
|
+
//
|
|
368
|
+
// When toggling through a search normally, the cursor is always set in the forward
|
|
369
|
+
// direction, so head is always at the 'to' position. That way, if reverse = false,
|
|
370
|
+
// the search proceeds from the 'to' position during normal toggling. If reverse = true,
|
|
371
|
+
// the search always proceeds from the 'anchor' position, which is at the 'from'.
|
|
372
|
+
const lastPosition = reverse
|
|
373
|
+
? state.selection.main.anchor
|
|
374
|
+
: state.selection.main.head;
|
|
375
|
+
let cursor = new RegExpCursor(this.editor.doc, this._query.source, { ignoreCase: !caseSensitive }, lastPosition).next();
|
|
376
|
+
if (cursor.done) {
|
|
377
|
+
const startOrEnd = reverse ? this.editor.doc.length : 0;
|
|
378
|
+
cursor = new RegExpCursor(this.editor.doc, this._query.source, { ignoreCase: !caseSensitive }, startOrEnd).next();
|
|
379
|
+
if (cursor.done) {
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
from: this._getPosition(cursor.value.from),
|
|
385
|
+
to: this._getPosition(cursor.value.to)
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
// TODO: remove this when Position API are removed and we work with
|
|
389
|
+
// offsets only. Contrary to the functions in CodeMirrorEditor,
|
|
390
|
+
// these functions work with CM6 position (i.e. line number starting at 1).
|
|
391
|
+
_getPosition(offset) {
|
|
392
|
+
const line = this.editor.doc.lineAt(offset);
|
|
393
|
+
return { line: line.number, ch: offset - line.from };
|
|
394
|
+
}
|
|
395
|
+
_parseMatchesFromState() {
|
|
396
|
+
// Flatten state map
|
|
397
|
+
const matches = new Array();
|
|
398
|
+
for (const lineKey in this._matchState) {
|
|
399
|
+
const lineMatches = this._matchState[lineKey];
|
|
400
|
+
for (const posKey in lineMatches) {
|
|
401
|
+
matches.push(lineMatches[posKey]);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return matches;
|
|
405
|
+
}
|
|
406
|
+
_currentMatchIsSelected() {
|
|
407
|
+
if (!this._currentMatch) {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
const currentSelection = this.editor.getSelection();
|
|
411
|
+
const currentSelectionLength = currentSelection.end.column - currentSelection.start.column;
|
|
412
|
+
const selectionIsOneLine = currentSelection.start.line === currentSelection.end.line;
|
|
413
|
+
return (selectionIsOneLine &&
|
|
414
|
+
this._currentMatch.text.length === currentSelectionLength &&
|
|
415
|
+
this._currentMatch.position ===
|
|
416
|
+
this.editor.doc.line(currentSelection.start.line).from +
|
|
417
|
+
currentSelection.start.column);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Helper class to highlight texts in a code mirror editor.
|
|
422
|
+
*
|
|
423
|
+
* Highlighted texts (aka `matches`) must be provided through
|
|
424
|
+
* the `matches` attributes.
|
|
425
|
+
*/
|
|
426
|
+
export class CodeMirrorSearchHighlighter {
|
|
427
|
+
/**
|
|
428
|
+
* Constructor
|
|
429
|
+
*
|
|
430
|
+
* @param editor The CodeMirror editor
|
|
431
|
+
*/
|
|
432
|
+
constructor(editor) {
|
|
433
|
+
this._cm = editor;
|
|
434
|
+
this._matches = new Array();
|
|
435
|
+
this._currentIndex = null;
|
|
436
|
+
this._highlightEffect = StateEffect.define({
|
|
437
|
+
map: (value, mapping) => ({
|
|
438
|
+
matches: value.matches.map(v => ({
|
|
439
|
+
text: v.text,
|
|
440
|
+
position: mapping.mapPos(v.position)
|
|
441
|
+
}))
|
|
442
|
+
})
|
|
443
|
+
});
|
|
444
|
+
this._highlightMark = Decoration.mark({ class: 'cm-searching' });
|
|
445
|
+
this._highlightField = StateField.define({
|
|
446
|
+
create: () => {
|
|
447
|
+
return Decoration.none;
|
|
448
|
+
},
|
|
449
|
+
update: (highlights, transaction) => {
|
|
450
|
+
highlights = highlights.map(transaction.changes);
|
|
451
|
+
for (let ef of transaction.effects) {
|
|
452
|
+
if (ef.is(this._highlightEffect)) {
|
|
453
|
+
const e = ef;
|
|
454
|
+
if (e.value.matches.length) {
|
|
455
|
+
highlights = highlights.update({
|
|
456
|
+
add: e.value.matches.map(m => this._highlightMark.range(m.position, m.position + m.text.length))
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
highlights = Decoration.none;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return highlights;
|
|
465
|
+
},
|
|
466
|
+
provide: f => EditorView.decorations.from(f)
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* The current index of the selected match.
|
|
471
|
+
*/
|
|
472
|
+
get currentIndex() {
|
|
473
|
+
return this._currentIndex;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* The list of matches
|
|
477
|
+
*/
|
|
478
|
+
get matches() {
|
|
479
|
+
return this._matches;
|
|
480
|
+
}
|
|
481
|
+
set matches(v) {
|
|
482
|
+
if (!JSONExt.deepEqual(this._matches, v)) {
|
|
483
|
+
this._matches = v;
|
|
484
|
+
}
|
|
485
|
+
this._refresh();
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Clear all highlighted matches
|
|
489
|
+
*/
|
|
490
|
+
clearHighlight() {
|
|
491
|
+
this._currentIndex = null;
|
|
492
|
+
this._highlightCurrentMatch();
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Clear the highlighted matches.
|
|
496
|
+
*/
|
|
497
|
+
endQuery() {
|
|
498
|
+
this._currentIndex = null;
|
|
499
|
+
this._matches = [];
|
|
500
|
+
this._cm.editor.dispatch({
|
|
501
|
+
effects: this._highlightEffect.of({ matches: [] })
|
|
502
|
+
});
|
|
503
|
+
const selection = this._cm.state.selection.main;
|
|
504
|
+
const from = selection.from;
|
|
505
|
+
const to = selection.to;
|
|
506
|
+
// Setting a reverse selection to allow search-as-you-type to maintain the
|
|
507
|
+
// current selected match. See comment in _findNext for more details.
|
|
508
|
+
if (from !== to) {
|
|
509
|
+
this._cm.editor.dispatch({ selection: { anchor: to, head: from } });
|
|
510
|
+
}
|
|
511
|
+
return Promise.resolve();
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Highlight the next match
|
|
515
|
+
*
|
|
516
|
+
* @returns The next match if available
|
|
517
|
+
*/
|
|
518
|
+
highlightNext() {
|
|
519
|
+
this._currentIndex = this._findNext(false);
|
|
520
|
+
this._highlightCurrentMatch();
|
|
521
|
+
return Promise.resolve(this._currentIndex !== null
|
|
522
|
+
? this._matches[this._currentIndex]
|
|
523
|
+
: undefined);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Highlight the previous match
|
|
527
|
+
*
|
|
528
|
+
* @returns The previous match if available
|
|
529
|
+
*/
|
|
530
|
+
highlightPrevious() {
|
|
531
|
+
this._currentIndex = this._findNext(true);
|
|
532
|
+
this._highlightCurrentMatch();
|
|
533
|
+
return Promise.resolve(this._currentIndex !== null
|
|
534
|
+
? this._matches[this._currentIndex]
|
|
535
|
+
: undefined);
|
|
536
|
+
}
|
|
537
|
+
_highlightCurrentMatch() {
|
|
538
|
+
// Highlight the current index
|
|
539
|
+
if (this._currentIndex !== null) {
|
|
540
|
+
const match = this.matches[this._currentIndex];
|
|
541
|
+
this._cm.editor.focus();
|
|
542
|
+
this._cm.editor.dispatch({
|
|
543
|
+
selection: {
|
|
544
|
+
anchor: match.position,
|
|
545
|
+
head: match.position + match.text.length
|
|
546
|
+
},
|
|
547
|
+
scrollIntoView: true
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
// Set cursor to remove any selection
|
|
552
|
+
this._cm.editor.dispatch({ selection: { anchor: 0 } });
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
_refresh() {
|
|
556
|
+
let effects = [
|
|
557
|
+
this._highlightEffect.of({ matches: this.matches })
|
|
558
|
+
];
|
|
559
|
+
if (!this._cm.state.field(this._highlightField, false)) {
|
|
560
|
+
effects.push(StateEffect.appendConfig.of([this._highlightField]));
|
|
561
|
+
}
|
|
562
|
+
this._cm.editor.dispatch({ effects });
|
|
563
|
+
}
|
|
564
|
+
_findNext(reverse) {
|
|
565
|
+
if (this._matches.length === 0) {
|
|
566
|
+
// No-op
|
|
567
|
+
return null;
|
|
568
|
+
}
|
|
569
|
+
// In order to support search-as-you-type, we needed a way to allow the first
|
|
570
|
+
// match to be selected when a search is started, but prevent the selected
|
|
571
|
+
// search to move for each new keypress. To do this, when a search is ended,
|
|
572
|
+
// the cursor is reversed, putting the head at the 'from' position. When a new
|
|
573
|
+
// search is started, the cursor we want is at the 'from' position, so that the same
|
|
574
|
+
// match is selected when the next key is entered (if it is still a match).
|
|
575
|
+
//
|
|
576
|
+
// When toggling through a search normally, the cursor is always set in the forward
|
|
577
|
+
// direction, so head is always at the 'to' position. That way, if reverse = false,
|
|
578
|
+
// the search proceeds from the 'to' position during normal toggling. If reverse = true,
|
|
579
|
+
// the search always proceeds from the 'anchor' position, which is at the 'from'.
|
|
580
|
+
const cursor = this._cm.state.selection.main;
|
|
581
|
+
let lastPosition = reverse ? cursor.anchor : cursor.head;
|
|
582
|
+
if (lastPosition === 0 && reverse && this.currentIndex === null) {
|
|
583
|
+
// The default position is (0, 0) but we want to start from the end in that case
|
|
584
|
+
lastPosition = this._cm.doc.length;
|
|
585
|
+
}
|
|
586
|
+
const position = lastPosition;
|
|
587
|
+
let found = Utils.findNext(this._matches, position, 0, this._matches.length - 1);
|
|
588
|
+
if (found === null) {
|
|
589
|
+
// Don't loop
|
|
590
|
+
return reverse ? this._matches.length - 1 : null;
|
|
591
|
+
}
|
|
592
|
+
if (reverse) {
|
|
593
|
+
found -= 1;
|
|
594
|
+
if (found < 0) {
|
|
595
|
+
// Don't loop
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return found;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Helpers namespace
|
|
604
|
+
*/
|
|
605
|
+
var Utils;
|
|
606
|
+
(function (Utils) {
|
|
607
|
+
/**
|
|
608
|
+
* Find the closest match at `position` just after it.
|
|
609
|
+
*
|
|
610
|
+
* #### Notes
|
|
611
|
+
* Search is done using a binary search algorithm
|
|
612
|
+
*
|
|
613
|
+
* @param matches List of matches
|
|
614
|
+
* @param position Searched position
|
|
615
|
+
* @param lowerBound Lower range index
|
|
616
|
+
* @param higherBound High range index
|
|
617
|
+
* @returns The next match or null if none exists
|
|
618
|
+
*/
|
|
619
|
+
function findNext(matches, position, lowerBound = 0, higherBound = Infinity) {
|
|
620
|
+
higherBound = Math.min(matches.length - 1, higherBound);
|
|
621
|
+
while (lowerBound <= higherBound) {
|
|
622
|
+
let middle = Math.floor(0.5 * (lowerBound + higherBound));
|
|
623
|
+
const currentPosition = matches[middle].position;
|
|
624
|
+
if (currentPosition < position) {
|
|
625
|
+
lowerBound = middle + 1;
|
|
626
|
+
if (lowerBound < matches.length &&
|
|
627
|
+
matches[lowerBound].position > position) {
|
|
628
|
+
return lowerBound;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
else if (currentPosition > position) {
|
|
632
|
+
higherBound = middle - 1;
|
|
633
|
+
if (higherBound > 0 && matches[higherBound].position < position) {
|
|
634
|
+
return middle;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
return middle;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
// Next could be the first item
|
|
642
|
+
const first = lowerBound > 0 ? lowerBound - 1 : 0;
|
|
643
|
+
const match = matches[first];
|
|
644
|
+
return match.position >= position ? first : null;
|
|
645
|
+
}
|
|
646
|
+
Utils.findNext = findNext;
|
|
647
|
+
})(Utils || (Utils = {}));
|
|
648
|
+
//# sourceMappingURL=searchprovider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchprovider.js","sourceRoot":"","sources":["../src/searchprovider.ts"],"names":[],"mappings":"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"}
|