groove-dev 0.27.72 → 0.27.74

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.
Files changed (140) hide show
  1. package/CLAUDE.md +7 -0
  2. package/node_modules/@groove-dev/cli/package.json +1 -1
  3. package/node_modules/@groove-dev/daemon/package.json +1 -1
  4. package/node_modules/@groove-dev/daemon/src/api.js +10 -7
  5. package/node_modules/@groove-dev/daemon/src/providers/claude-code.js +2 -1
  6. package/node_modules/@groove-dev/daemon/src/providers/codex.js +3 -1
  7. package/node_modules/@groove-dev/daemon/src/providers/gemini.js +2 -1
  8. package/node_modules/@groove-dev/daemon/src/providers/index.js +21 -8
  9. package/node_modules/@groove-dev/gui/dist/assets/{index-CHSXqfwy.js → index-DFP3r2yE.js} +167 -167
  10. package/node_modules/@groove-dev/gui/dist/assets/index-QR7lyguO.css +1 -0
  11. package/node_modules/@groove-dev/gui/dist/index.html +2 -2
  12. package/node_modules/@groove-dev/gui/package.json +1 -1
  13. package/node_modules/@groove-dev/gui/src/components/editor/editor-tabs.jsx +5 -5
  14. package/node_modules/@groove-dev/gui/src/components/settings/ProviderSetupWizard.jsx +7 -2
  15. package/node_modules/@groove-dev/gui/src/stores/groove.js +41 -52
  16. package/node_modules/@groove-dev/gui/src/views/editor.jsx +2 -9
  17. package/node_modules/@groove-dev/gui/src/views/settings.jsx +79 -9
  18. package/package.json +1 -1
  19. package/packages/cli/package.json +1 -1
  20. package/packages/daemon/package.json +1 -1
  21. package/packages/daemon/src/api.js +10 -7
  22. package/packages/daemon/src/providers/claude-code.js +2 -1
  23. package/packages/daemon/src/providers/codex.js +3 -1
  24. package/packages/daemon/src/providers/gemini.js +2 -1
  25. package/packages/daemon/src/providers/index.js +21 -8
  26. package/packages/gui/dist/assets/{index-CHSXqfwy.js → index-DFP3r2yE.js} +167 -167
  27. package/packages/gui/dist/assets/index-QR7lyguO.css +1 -0
  28. package/packages/gui/dist/index.html +2 -2
  29. package/packages/gui/package.json +1 -1
  30. package/packages/gui/src/components/editor/editor-tabs.jsx +5 -5
  31. package/packages/gui/src/components/settings/ProviderSetupWizard.jsx +7 -2
  32. package/packages/gui/src/stores/groove.js +41 -52
  33. package/packages/gui/src/views/editor.jsx +2 -9
  34. package/packages/gui/src/views/settings.jsx +79 -9
  35. package/node_modules/@groove-dev/gui/dist/assets/index-74E3YTkT.css +0 -1
  36. package/packages/gui/dist/assets/index-74E3YTkT.css +0 -1
  37. package/packages/gui/node_modules/.vite/deps/@codemirror_autocomplete.js +0 -68
  38. package/packages/gui/node_modules/.vite/deps/@codemirror_autocomplete.js.map +0 -7
  39. package/packages/gui/node_modules/.vite/deps/@codemirror_commands.js +0 -1420
  40. package/packages/gui/node_modules/.vite/deps/@codemirror_commands.js.map +0 -7
  41. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-css.js +0 -17
  42. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-css.js.map +0 -7
  43. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-html.js +0 -22
  44. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-html.js.map +0 -7
  45. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-javascript.js +0 -34
  46. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-javascript.js.map +0 -7
  47. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-json.js +0 -101
  48. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-json.js.map +0 -7
  49. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-markdown.js +0 -2534
  50. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-markdown.js.map +0 -7
  51. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-python.js +0 -789
  52. package/packages/gui/node_modules/.vite/deps/@codemirror_lang-python.js.map +0 -7
  53. package/packages/gui/node_modules/.vite/deps/@codemirror_language.js +0 -115
  54. package/packages/gui/node_modules/.vite/deps/@codemirror_language.js.map +0 -7
  55. package/packages/gui/node_modules/.vite/deps/@codemirror_search.js +0 -1136
  56. package/packages/gui/node_modules/.vite/deps/@codemirror_search.js.map +0 -7
  57. package/packages/gui/node_modules/.vite/deps/@codemirror_state.js +0 -63
  58. package/packages/gui/node_modules/.vite/deps/@codemirror_state.js.map +0 -7
  59. package/packages/gui/node_modules/.vite/deps/@codemirror_theme-one-dark.js +0 -179
  60. package/packages/gui/node_modules/.vite/deps/@codemirror_theme-one-dark.js.map +0 -7
  61. package/packages/gui/node_modules/.vite/deps/@codemirror_view.js +0 -104
  62. package/packages/gui/node_modules/.vite/deps/@codemirror_view.js.map +0 -7
  63. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-context-menu.js +0 -1202
  64. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-context-menu.js.map +0 -7
  65. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-dialog.js +0 -365
  66. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-dialog.js.map +0 -7
  67. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-scroll-area.js +0 -757
  68. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-scroll-area.js.map +0 -7
  69. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-tabs.js +0 -219
  70. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-tabs.js.map +0 -7
  71. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-tooltip.js +0 -562
  72. package/packages/gui/node_modules/.vite/deps/@radix-ui_react-tooltip.js.map +0 -7
  73. package/packages/gui/node_modules/.vite/deps/@xterm_addon-fit.js +0 -46
  74. package/packages/gui/node_modules/.vite/deps/@xterm_addon-fit.js.map +0 -7
  75. package/packages/gui/node_modules/.vite/deps/@xterm_addon-web-links.js +0 -121
  76. package/packages/gui/node_modules/.vite/deps/@xterm_addon-web-links.js.map +0 -7
  77. package/packages/gui/node_modules/.vite/deps/@xterm_xterm.js +0 -9237
  78. package/packages/gui/node_modules/.vite/deps/@xterm_xterm.js.map +0 -7
  79. package/packages/gui/node_modules/.vite/deps/@xyflow_react.js +0 -9934
  80. package/packages/gui/node_modules/.vite/deps/@xyflow_react.js.map +0 -7
  81. package/packages/gui/node_modules/.vite/deps/_metadata.json +0 -259
  82. package/packages/gui/node_modules/.vite/deps/chunk-3EE34IFC.js +0 -5169
  83. package/packages/gui/node_modules/.vite/deps/chunk-3EE34IFC.js.map +0 -7
  84. package/packages/gui/node_modules/.vite/deps/chunk-3IB5EUP7.js +0 -2000
  85. package/packages/gui/node_modules/.vite/deps/chunk-3IB5EUP7.js.map +0 -7
  86. package/packages/gui/node_modules/.vite/deps/chunk-44CLUOQE.js +0 -1776
  87. package/packages/gui/node_modules/.vite/deps/chunk-44CLUOQE.js.map +0 -7
  88. package/packages/gui/node_modules/.vite/deps/chunk-4JHIKDUF.js +0 -435
  89. package/packages/gui/node_modules/.vite/deps/chunk-4JHIKDUF.js.map +0 -7
  90. package/packages/gui/node_modules/.vite/deps/chunk-ACEP5X2F.js +0 -292
  91. package/packages/gui/node_modules/.vite/deps/chunk-ACEP5X2F.js.map +0 -7
  92. package/packages/gui/node_modules/.vite/deps/chunk-CDLO3JFW.js +0 -1004
  93. package/packages/gui/node_modules/.vite/deps/chunk-CDLO3JFW.js.map +0 -7
  94. package/packages/gui/node_modules/.vite/deps/chunk-FOR2E6IR.js +0 -105
  95. package/packages/gui/node_modules/.vite/deps/chunk-FOR2E6IR.js.map +0 -7
  96. package/packages/gui/node_modules/.vite/deps/chunk-HPXOV7QR.js +0 -23
  97. package/packages/gui/node_modules/.vite/deps/chunk-HPXOV7QR.js.map +0 -7
  98. package/packages/gui/node_modules/.vite/deps/chunk-HVFOBSCQ.js +0 -1062
  99. package/packages/gui/node_modules/.vite/deps/chunk-HVFOBSCQ.js.map +0 -7
  100. package/packages/gui/node_modules/.vite/deps/chunk-PGL3TTJA.js +0 -1115
  101. package/packages/gui/node_modules/.vite/deps/chunk-PGL3TTJA.js.map +0 -7
  102. package/packages/gui/node_modules/.vite/deps/chunk-PGMATLPZ.js +0 -2294
  103. package/packages/gui/node_modules/.vite/deps/chunk-PGMATLPZ.js.map +0 -7
  104. package/packages/gui/node_modules/.vite/deps/chunk-PR4QN5HX.js +0 -42
  105. package/packages/gui/node_modules/.vite/deps/chunk-PR4QN5HX.js.map +0 -7
  106. package/packages/gui/node_modules/.vite/deps/chunk-QX3PPTYO.js +0 -315
  107. package/packages/gui/node_modules/.vite/deps/chunk-QX3PPTYO.js.map +0 -7
  108. package/packages/gui/node_modules/.vite/deps/chunk-RE2FU7ZU.js +0 -10985
  109. package/packages/gui/node_modules/.vite/deps/chunk-RE2FU7ZU.js.map +0 -7
  110. package/packages/gui/node_modules/.vite/deps/chunk-SPKVQGZX.js +0 -701
  111. package/packages/gui/node_modules/.vite/deps/chunk-SPKVQGZX.js.map +0 -7
  112. package/packages/gui/node_modules/.vite/deps/chunk-YAD7VOVN.js +0 -280
  113. package/packages/gui/node_modules/.vite/deps/chunk-YAD7VOVN.js.map +0 -7
  114. package/packages/gui/node_modules/.vite/deps/chunk-YEUURE4V.js +0 -264
  115. package/packages/gui/node_modules/.vite/deps/chunk-YEUURE4V.js.map +0 -7
  116. package/packages/gui/node_modules/.vite/deps/chunk-YYJMNVCJ.js +0 -3459
  117. package/packages/gui/node_modules/.vite/deps/chunk-YYJMNVCJ.js.map +0 -7
  118. package/packages/gui/node_modules/.vite/deps/chunk-Z5NIFSCT.js +0 -1106
  119. package/packages/gui/node_modules/.vite/deps/chunk-Z5NIFSCT.js.map +0 -7
  120. package/packages/gui/node_modules/.vite/deps/clsx.js +0 -22
  121. package/packages/gui/node_modules/.vite/deps/clsx.js.map +0 -7
  122. package/packages/gui/node_modules/.vite/deps/framer-motion.js +0 -12732
  123. package/packages/gui/node_modules/.vite/deps/framer-motion.js.map +0 -7
  124. package/packages/gui/node_modules/.vite/deps/lucide-react.js +0 -29653
  125. package/packages/gui/node_modules/.vite/deps/lucide-react.js.map +0 -7
  126. package/packages/gui/node_modules/.vite/deps/package.json +0 -3
  127. package/packages/gui/node_modules/.vite/deps/react-dom.js +0 -6
  128. package/packages/gui/node_modules/.vite/deps/react-dom.js.map +0 -7
  129. package/packages/gui/node_modules/.vite/deps/react-dom_client.js +0 -20217
  130. package/packages/gui/node_modules/.vite/deps/react-dom_client.js.map +0 -7
  131. package/packages/gui/node_modules/.vite/deps/react.js +0 -5
  132. package/packages/gui/node_modules/.vite/deps/react.js.map +0 -7
  133. package/packages/gui/node_modules/.vite/deps/react_jsx-dev-runtime.js +0 -278
  134. package/packages/gui/node_modules/.vite/deps/react_jsx-dev-runtime.js.map +0 -7
  135. package/packages/gui/node_modules/.vite/deps/react_jsx-runtime.js +0 -6
  136. package/packages/gui/node_modules/.vite/deps/react_jsx-runtime.js.map +0 -7
  137. package/packages/gui/node_modules/.vite/deps/tailwind-merge.js +0 -3263
  138. package/packages/gui/node_modules/.vite/deps/tailwind-merge.js.map +0 -7
  139. package/packages/gui/node_modules/.vite/deps/zustand.js +0 -56
  140. package/packages/gui/node_modules/.vite/deps/zustand.js.map +0 -7
@@ -1,1136 +0,0 @@
1
- import {
2
- Decoration,
3
- EditorView,
4
- ViewPlugin,
5
- crelt,
6
- getPanel,
7
- runScopeHandlers,
8
- showDialog,
9
- showPanel
10
- } from "./chunk-RE2FU7ZU.js";
11
- import {
12
- CharCategory,
13
- EditorSelection,
14
- EditorState,
15
- Facet,
16
- Prec,
17
- RangeSetBuilder,
18
- StateEffect,
19
- StateField,
20
- codePointAt,
21
- codePointSize,
22
- combineConfig,
23
- findClusterBreak,
24
- fromCodePoint
25
- } from "./chunk-YYJMNVCJ.js";
26
- import "./chunk-PR4QN5HX.js";
27
-
28
- // ../../node_modules/@codemirror/search/dist/index.js
29
- var basicNormalize = typeof String.prototype.normalize == "function" ? (x) => x.normalize("NFKD") : (x) => x;
30
- var SearchCursor = class {
31
- /**
32
- Create a text cursor. The query is the search string, `from` to
33
- `to` provides the region to search.
34
-
35
- When `normalize` is given, it will be called, on both the query
36
- string and the content it is matched against, before comparing.
37
- You can, for example, create a case-insensitive search by
38
- passing `s => s.toLowerCase()`.
39
-
40
- Text is always normalized with
41
- [`.normalize("NFKD")`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize)
42
- (when supported).
43
- */
44
- constructor(text, query, from = 0, to = text.length, normalize, test) {
45
- this.test = test;
46
- this.value = { from: 0, to: 0 };
47
- this.done = false;
48
- this.matches = [];
49
- this.buffer = "";
50
- this.bufferPos = 0;
51
- this.iter = text.iterRange(from, to);
52
- this.bufferStart = from;
53
- this.normalize = normalize ? (x) => normalize(basicNormalize(x)) : basicNormalize;
54
- this.query = this.normalize(query);
55
- }
56
- peek() {
57
- if (this.bufferPos == this.buffer.length) {
58
- this.bufferStart += this.buffer.length;
59
- this.iter.next();
60
- if (this.iter.done)
61
- return -1;
62
- this.bufferPos = 0;
63
- this.buffer = this.iter.value;
64
- }
65
- return codePointAt(this.buffer, this.bufferPos);
66
- }
67
- /**
68
- Look for the next match. Updates the iterator's
69
- [`value`](https://codemirror.net/6/docs/ref/#search.SearchCursor.value) and
70
- [`done`](https://codemirror.net/6/docs/ref/#search.SearchCursor.done) properties. Should be called
71
- at least once before using the cursor.
72
- */
73
- next() {
74
- while (this.matches.length)
75
- this.matches.pop();
76
- return this.nextOverlapping();
77
- }
78
- /**
79
- The `next` method will ignore matches that partially overlap a
80
- previous match. This method behaves like `next`, but includes
81
- such matches.
82
- */
83
- nextOverlapping() {
84
- for (; ; ) {
85
- let next = this.peek();
86
- if (next < 0) {
87
- this.done = true;
88
- return this;
89
- }
90
- let str = fromCodePoint(next), start = this.bufferStart + this.bufferPos;
91
- this.bufferPos += codePointSize(next);
92
- let norm = this.normalize(str);
93
- if (norm.length)
94
- for (let i = 0, pos = start; ; i++) {
95
- let code = norm.charCodeAt(i);
96
- let match = this.match(code, pos, this.bufferPos + this.bufferStart);
97
- if (i == norm.length - 1) {
98
- if (match) {
99
- this.value = match;
100
- return this;
101
- }
102
- break;
103
- }
104
- if (pos == start && i < str.length && str.charCodeAt(i) == code)
105
- pos++;
106
- }
107
- }
108
- }
109
- match(code, pos, end) {
110
- let match = null;
111
- for (let i = 0; i < this.matches.length; i += 2) {
112
- let index = this.matches[i], keep = false;
113
- if (this.query.charCodeAt(index) == code) {
114
- if (index == this.query.length - 1) {
115
- match = { from: this.matches[i + 1], to: end };
116
- } else {
117
- this.matches[i]++;
118
- keep = true;
119
- }
120
- }
121
- if (!keep) {
122
- this.matches.splice(i, 2);
123
- i -= 2;
124
- }
125
- }
126
- if (this.query.charCodeAt(0) == code) {
127
- if (this.query.length == 1)
128
- match = { from: pos, to: end };
129
- else
130
- this.matches.push(1, pos);
131
- }
132
- if (match && this.test && !this.test(match.from, match.to, this.buffer, this.bufferStart))
133
- match = null;
134
- return match;
135
- }
136
- };
137
- if (typeof Symbol != "undefined")
138
- SearchCursor.prototype[Symbol.iterator] = function() {
139
- return this;
140
- };
141
- var empty = { from: -1, to: -1, match: /.*/.exec("") };
142
- var baseFlags = "gm" + (/x/.unicode == null ? "" : "u");
143
- var RegExpCursor = class {
144
- /**
145
- Create a cursor that will search the given range in the given
146
- document. `query` should be the raw pattern (as you'd pass it to
147
- `new RegExp`).
148
- */
149
- constructor(text, query, options, from = 0, to = text.length) {
150
- this.text = text;
151
- this.to = to;
152
- this.curLine = "";
153
- this.done = false;
154
- this.value = empty;
155
- if (/\\[sWDnr]|\n|\r|\[\^/.test(query))
156
- return new MultilineRegExpCursor(text, query, options, from, to);
157
- this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
158
- this.test = options === null || options === void 0 ? void 0 : options.test;
159
- this.iter = text.iter();
160
- let startLine = text.lineAt(from);
161
- this.curLineStart = startLine.from;
162
- this.matchPos = toCharEnd(text, from);
163
- this.getLine(this.curLineStart);
164
- }
165
- getLine(skip) {
166
- this.iter.next(skip);
167
- if (this.iter.lineBreak) {
168
- this.curLine = "";
169
- } else {
170
- this.curLine = this.iter.value;
171
- if (this.curLineStart + this.curLine.length > this.to)
172
- this.curLine = this.curLine.slice(0, this.to - this.curLineStart);
173
- this.iter.next();
174
- }
175
- }
176
- nextLine() {
177
- this.curLineStart = this.curLineStart + this.curLine.length + 1;
178
- if (this.curLineStart > this.to)
179
- this.curLine = "";
180
- else
181
- this.getLine(0);
182
- }
183
- /**
184
- Move to the next match, if there is one.
185
- */
186
- next() {
187
- for (let off = this.matchPos - this.curLineStart; ; ) {
188
- this.re.lastIndex = off;
189
- let match = this.matchPos <= this.to && this.re.exec(this.curLine);
190
- if (match) {
191
- let from = this.curLineStart + match.index, to = from + match[0].length;
192
- this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0));
193
- if (from == this.curLineStart + this.curLine.length)
194
- this.nextLine();
195
- if ((from < to || from > this.value.to) && (!this.test || this.test(from, to, match))) {
196
- this.value = { from, to, match };
197
- return this;
198
- }
199
- off = this.matchPos - this.curLineStart;
200
- } else if (this.curLineStart + this.curLine.length < this.to) {
201
- this.nextLine();
202
- off = 0;
203
- } else {
204
- this.done = true;
205
- return this;
206
- }
207
- }
208
- }
209
- };
210
- var flattened = /* @__PURE__ */ new WeakMap();
211
- var FlattenedDoc = class _FlattenedDoc {
212
- constructor(from, text) {
213
- this.from = from;
214
- this.text = text;
215
- }
216
- get to() {
217
- return this.from + this.text.length;
218
- }
219
- static get(doc, from, to) {
220
- let cached = flattened.get(doc);
221
- if (!cached || cached.from >= to || cached.to <= from) {
222
- let flat = new _FlattenedDoc(from, doc.sliceString(from, to));
223
- flattened.set(doc, flat);
224
- return flat;
225
- }
226
- if (cached.from == from && cached.to == to)
227
- return cached;
228
- let { text, from: cachedFrom } = cached;
229
- if (cachedFrom > from) {
230
- text = doc.sliceString(from, cachedFrom) + text;
231
- cachedFrom = from;
232
- }
233
- if (cached.to < to)
234
- text += doc.sliceString(cached.to, to);
235
- flattened.set(doc, new _FlattenedDoc(cachedFrom, text));
236
- return new _FlattenedDoc(from, text.slice(from - cachedFrom, to - cachedFrom));
237
- }
238
- };
239
- var MultilineRegExpCursor = class {
240
- constructor(text, query, options, from, to) {
241
- this.text = text;
242
- this.to = to;
243
- this.done = false;
244
- this.value = empty;
245
- this.matchPos = toCharEnd(text, from);
246
- this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
247
- this.test = options === null || options === void 0 ? void 0 : options.test;
248
- this.flat = FlattenedDoc.get(text, from, this.chunkEnd(
249
- from + 5e3
250
- /* Chunk.Base */
251
- ));
252
- }
253
- chunkEnd(pos) {
254
- return pos >= this.to ? this.to : this.text.lineAt(pos).to;
255
- }
256
- next() {
257
- for (; ; ) {
258
- let off = this.re.lastIndex = this.matchPos - this.flat.from;
259
- let match = this.re.exec(this.flat.text);
260
- if (match && !match[0] && match.index == off) {
261
- this.re.lastIndex = off + 1;
262
- match = this.re.exec(this.flat.text);
263
- }
264
- if (match) {
265
- let from = this.flat.from + match.index, to = from + match[0].length;
266
- if ((this.flat.to >= this.to || match.index + match[0].length <= this.flat.text.length - 10) && (!this.test || this.test(from, to, match))) {
267
- this.value = { from, to, match };
268
- this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0));
269
- return this;
270
- }
271
- }
272
- if (this.flat.to == this.to) {
273
- this.done = true;
274
- return this;
275
- }
276
- this.flat = FlattenedDoc.get(this.text, this.flat.from, this.chunkEnd(this.flat.from + this.flat.text.length * 2));
277
- }
278
- }
279
- };
280
- if (typeof Symbol != "undefined") {
281
- RegExpCursor.prototype[Symbol.iterator] = MultilineRegExpCursor.prototype[Symbol.iterator] = function() {
282
- return this;
283
- };
284
- }
285
- function validRegExp(source) {
286
- try {
287
- new RegExp(source, baseFlags);
288
- return true;
289
- } catch (_a) {
290
- return false;
291
- }
292
- }
293
- function toCharEnd(text, pos) {
294
- if (pos >= text.length)
295
- return pos;
296
- let line = text.lineAt(pos), next;
297
- while (pos < line.to && (next = line.text.charCodeAt(pos - line.from)) >= 56320 && next < 57344)
298
- pos++;
299
- return pos;
300
- }
301
- var gotoLine = (view) => {
302
- let { state } = view;
303
- let line = String(state.doc.lineAt(view.state.selection.main.head).number);
304
- let { close, result } = showDialog(view, {
305
- label: state.phrase("Go to line"),
306
- input: { type: "text", name: "line", value: line },
307
- focus: true,
308
- submitLabel: state.phrase("go")
309
- });
310
- result.then((form) => {
311
- let match = form && /^([+-])?(\d+)?(:\d+)?(%)?$/.exec(form.elements["line"].value);
312
- if (!match) {
313
- view.dispatch({ effects: close });
314
- return;
315
- }
316
- let startLine = state.doc.lineAt(state.selection.main.head);
317
- let [, sign, ln, cl, percent] = match;
318
- let col = cl ? +cl.slice(1) : 0;
319
- let line2 = ln ? +ln : startLine.number;
320
- if (ln && percent) {
321
- let pc = line2 / 100;
322
- if (sign)
323
- pc = pc * (sign == "-" ? -1 : 1) + startLine.number / state.doc.lines;
324
- line2 = Math.round(state.doc.lines * pc);
325
- } else if (ln && sign) {
326
- line2 = line2 * (sign == "-" ? -1 : 1) + startLine.number;
327
- }
328
- let docLine = state.doc.line(Math.max(1, Math.min(state.doc.lines, line2)));
329
- let selection = EditorSelection.cursor(docLine.from + Math.max(0, Math.min(col, docLine.length)));
330
- view.dispatch({
331
- effects: [close, EditorView.scrollIntoView(selection.from, { y: "center" })],
332
- selection
333
- });
334
- });
335
- return true;
336
- };
337
- var defaultHighlightOptions = {
338
- highlightWordAroundCursor: false,
339
- minSelectionLength: 1,
340
- maxMatches: 100,
341
- wholeWords: false
342
- };
343
- var highlightConfig = Facet.define({
344
- combine(options) {
345
- return combineConfig(options, defaultHighlightOptions, {
346
- highlightWordAroundCursor: (a, b) => a || b,
347
- minSelectionLength: Math.min,
348
- maxMatches: Math.min
349
- });
350
- }
351
- });
352
- function highlightSelectionMatches(options) {
353
- let ext = [defaultTheme, matchHighlighter];
354
- if (options)
355
- ext.push(highlightConfig.of(options));
356
- return ext;
357
- }
358
- var matchDeco = Decoration.mark({ class: "cm-selectionMatch" });
359
- var mainMatchDeco = Decoration.mark({ class: "cm-selectionMatch cm-selectionMatch-main" });
360
- function insideWordBoundaries(check, state, from, to) {
361
- return (from == 0 || check(state.sliceDoc(from - 1, from)) != CharCategory.Word) && (to == state.doc.length || check(state.sliceDoc(to, to + 1)) != CharCategory.Word);
362
- }
363
- function insideWord(check, state, from, to) {
364
- return check(state.sliceDoc(from, from + 1)) == CharCategory.Word && check(state.sliceDoc(to - 1, to)) == CharCategory.Word;
365
- }
366
- var matchHighlighter = ViewPlugin.fromClass(class {
367
- constructor(view) {
368
- this.decorations = this.getDeco(view);
369
- }
370
- update(update) {
371
- if (update.selectionSet || update.docChanged || update.viewportChanged)
372
- this.decorations = this.getDeco(update.view);
373
- }
374
- getDeco(view) {
375
- let conf = view.state.facet(highlightConfig);
376
- let { state } = view, sel = state.selection;
377
- if (sel.ranges.length > 1)
378
- return Decoration.none;
379
- let range = sel.main, query, check = null;
380
- if (range.empty) {
381
- if (!conf.highlightWordAroundCursor)
382
- return Decoration.none;
383
- let word = state.wordAt(range.head);
384
- if (!word)
385
- return Decoration.none;
386
- check = state.charCategorizer(range.head);
387
- query = state.sliceDoc(word.from, word.to);
388
- } else {
389
- let len = range.to - range.from;
390
- if (len < conf.minSelectionLength || len > 200)
391
- return Decoration.none;
392
- if (conf.wholeWords) {
393
- query = state.sliceDoc(range.from, range.to);
394
- check = state.charCategorizer(range.head);
395
- if (!(insideWordBoundaries(check, state, range.from, range.to) && insideWord(check, state, range.from, range.to)))
396
- return Decoration.none;
397
- } else {
398
- query = state.sliceDoc(range.from, range.to);
399
- if (!query)
400
- return Decoration.none;
401
- }
402
- }
403
- let deco = [];
404
- for (let part of view.visibleRanges) {
405
- let cursor = new SearchCursor(state.doc, query, part.from, part.to);
406
- while (!cursor.next().done) {
407
- let { from, to } = cursor.value;
408
- if (!check || insideWordBoundaries(check, state, from, to)) {
409
- if (range.empty && from <= range.from && to >= range.to)
410
- deco.push(mainMatchDeco.range(from, to));
411
- else if (from >= range.to || to <= range.from)
412
- deco.push(matchDeco.range(from, to));
413
- if (deco.length > conf.maxMatches)
414
- return Decoration.none;
415
- }
416
- }
417
- }
418
- return Decoration.set(deco);
419
- }
420
- }, {
421
- decorations: (v) => v.decorations
422
- });
423
- var defaultTheme = EditorView.baseTheme({
424
- ".cm-selectionMatch": { backgroundColor: "#99ff7780" },
425
- ".cm-searchMatch .cm-selectionMatch": { backgroundColor: "transparent" }
426
- });
427
- var selectWord = ({ state, dispatch }) => {
428
- let { selection } = state;
429
- let newSel = EditorSelection.create(selection.ranges.map((range) => state.wordAt(range.head) || EditorSelection.cursor(range.head)), selection.mainIndex);
430
- if (newSel.eq(selection))
431
- return false;
432
- dispatch(state.update({ selection: newSel }));
433
- return true;
434
- };
435
- function findNextOccurrence(state, query) {
436
- let { main, ranges } = state.selection;
437
- let word = state.wordAt(main.head), fullWord = word && word.from == main.from && word.to == main.to;
438
- for (let cycled = false, cursor = new SearchCursor(state.doc, query, ranges[ranges.length - 1].to); ; ) {
439
- cursor.next();
440
- if (cursor.done) {
441
- if (cycled)
442
- return null;
443
- cursor = new SearchCursor(state.doc, query, 0, Math.max(0, ranges[ranges.length - 1].from - 1));
444
- cycled = true;
445
- } else {
446
- if (cycled && ranges.some((r) => r.from == cursor.value.from))
447
- continue;
448
- if (fullWord) {
449
- let word2 = state.wordAt(cursor.value.from);
450
- if (!word2 || word2.from != cursor.value.from || word2.to != cursor.value.to)
451
- continue;
452
- }
453
- return cursor.value;
454
- }
455
- }
456
- }
457
- var selectNextOccurrence = ({ state, dispatch }) => {
458
- let { ranges } = state.selection;
459
- if (ranges.some((sel) => sel.from === sel.to))
460
- return selectWord({ state, dispatch });
461
- let searchedText = state.sliceDoc(ranges[0].from, ranges[0].to);
462
- if (state.selection.ranges.some((r) => state.sliceDoc(r.from, r.to) != searchedText))
463
- return false;
464
- let range = findNextOccurrence(state, searchedText);
465
- if (!range)
466
- return false;
467
- dispatch(state.update({
468
- selection: state.selection.addRange(EditorSelection.range(range.from, range.to), false),
469
- effects: EditorView.scrollIntoView(range.to)
470
- }));
471
- return true;
472
- };
473
- var searchConfigFacet = Facet.define({
474
- combine(configs) {
475
- return combineConfig(configs, {
476
- top: false,
477
- caseSensitive: false,
478
- literal: false,
479
- regexp: false,
480
- wholeWord: false,
481
- createPanel: (view) => new SearchPanel(view),
482
- scrollToMatch: (range) => EditorView.scrollIntoView(range)
483
- });
484
- }
485
- });
486
- function search(config) {
487
- return config ? [searchConfigFacet.of(config), searchExtensions] : searchExtensions;
488
- }
489
- var SearchQuery = class {
490
- /**
491
- Create a query object.
492
- */
493
- constructor(config) {
494
- this.search = config.search;
495
- this.caseSensitive = !!config.caseSensitive;
496
- this.literal = !!config.literal;
497
- this.regexp = !!config.regexp;
498
- this.replace = config.replace || "";
499
- this.valid = !!this.search && (!this.regexp || validRegExp(this.search));
500
- this.unquoted = this.unquote(this.search);
501
- this.wholeWord = !!config.wholeWord;
502
- this.test = config.test;
503
- }
504
- /**
505
- @internal
506
- */
507
- unquote(text) {
508
- return this.literal ? text : text.replace(/\\([nrt\\])/g, (_, ch) => ch == "n" ? "\n" : ch == "r" ? "\r" : ch == "t" ? " " : "\\");
509
- }
510
- /**
511
- Compare this query to another query.
512
- */
513
- eq(other) {
514
- return this.search == other.search && this.replace == other.replace && this.caseSensitive == other.caseSensitive && this.regexp == other.regexp && this.wholeWord == other.wholeWord && this.test == other.test;
515
- }
516
- /**
517
- @internal
518
- */
519
- create() {
520
- return this.regexp ? new RegExpQuery(this) : new StringQuery(this);
521
- }
522
- /**
523
- Get a search cursor for this query, searching through the given
524
- range in the given state.
525
- */
526
- getCursor(state, from = 0, to) {
527
- let st = state.doc ? state : EditorState.create({ doc: state });
528
- if (to == null)
529
- to = st.doc.length;
530
- return this.regexp ? regexpCursor(this, st, from, to) : stringCursor(this, st, from, to);
531
- }
532
- };
533
- var QueryType = class {
534
- constructor(spec) {
535
- this.spec = spec;
536
- }
537
- };
538
- function wrapStringTest(test, state, inner) {
539
- return (from, to, buffer, bufferPos) => {
540
- if (inner && !inner(from, to, buffer, bufferPos))
541
- return false;
542
- let match = from >= bufferPos && to <= bufferPos + buffer.length ? buffer.slice(from - bufferPos, to - bufferPos) : state.doc.sliceString(from, to);
543
- return test(match, state, from, to);
544
- };
545
- }
546
- function stringCursor(spec, state, from, to) {
547
- let test;
548
- if (spec.wholeWord)
549
- test = stringWordTest(state.doc, state.charCategorizer(state.selection.main.head));
550
- if (spec.test)
551
- test = wrapStringTest(spec.test, state, test);
552
- return new SearchCursor(state.doc, spec.unquoted, from, to, spec.caseSensitive ? void 0 : (x) => x.toLowerCase(), test);
553
- }
554
- function stringWordTest(doc, categorizer) {
555
- return (from, to, buf, bufPos) => {
556
- if (bufPos > from || bufPos + buf.length < to) {
557
- bufPos = Math.max(0, from - 2);
558
- buf = doc.sliceString(bufPos, Math.min(doc.length, to + 2));
559
- }
560
- return (categorizer(charBefore(buf, from - bufPos)) != CharCategory.Word || categorizer(charAfter(buf, from - bufPos)) != CharCategory.Word) && (categorizer(charAfter(buf, to - bufPos)) != CharCategory.Word || categorizer(charBefore(buf, to - bufPos)) != CharCategory.Word);
561
- };
562
- }
563
- var StringQuery = class extends QueryType {
564
- constructor(spec) {
565
- super(spec);
566
- }
567
- nextMatch(state, curFrom, curTo) {
568
- let cursor = stringCursor(this.spec, state, curTo, state.doc.length).nextOverlapping();
569
- if (cursor.done) {
570
- let end = Math.min(state.doc.length, curFrom + this.spec.unquoted.length);
571
- cursor = stringCursor(this.spec, state, 0, end).nextOverlapping();
572
- }
573
- return cursor.done || cursor.value.from == curFrom && cursor.value.to == curTo ? null : cursor.value;
574
- }
575
- // Searching in reverse is, rather than implementing an inverted search
576
- // cursor, done by scanning chunk after chunk forward.
577
- prevMatchInRange(state, from, to) {
578
- for (let pos = to; ; ) {
579
- let start = Math.max(from, pos - 1e4 - this.spec.unquoted.length);
580
- let cursor = stringCursor(this.spec, state, start, pos), range = null;
581
- while (!cursor.nextOverlapping().done)
582
- range = cursor.value;
583
- if (range)
584
- return range;
585
- if (start == from)
586
- return null;
587
- pos -= 1e4;
588
- }
589
- }
590
- prevMatch(state, curFrom, curTo) {
591
- let found = this.prevMatchInRange(state, 0, curFrom);
592
- if (!found)
593
- found = this.prevMatchInRange(state, Math.max(0, curTo - this.spec.unquoted.length), state.doc.length);
594
- return found && (found.from != curFrom || found.to != curTo) ? found : null;
595
- }
596
- getReplacement(_result) {
597
- return this.spec.unquote(this.spec.replace);
598
- }
599
- matchAll(state, limit) {
600
- let cursor = stringCursor(this.spec, state, 0, state.doc.length), ranges = [];
601
- while (!cursor.next().done) {
602
- if (ranges.length >= limit)
603
- return null;
604
- ranges.push(cursor.value);
605
- }
606
- return ranges;
607
- }
608
- highlight(state, from, to, add) {
609
- let cursor = stringCursor(this.spec, state, Math.max(0, from - this.spec.unquoted.length), Math.min(to + this.spec.unquoted.length, state.doc.length));
610
- while (!cursor.next().done)
611
- add(cursor.value.from, cursor.value.to);
612
- }
613
- };
614
- function wrapRegexpTest(test, state, inner) {
615
- return (from, to, match) => {
616
- return (!inner || inner(from, to, match)) && test(match[0], state, from, to);
617
- };
618
- }
619
- function regexpCursor(spec, state, from, to) {
620
- let test;
621
- if (spec.wholeWord)
622
- test = regexpWordTest(state.charCategorizer(state.selection.main.head));
623
- if (spec.test)
624
- test = wrapRegexpTest(spec.test, state, test);
625
- return new RegExpCursor(state.doc, spec.search, { ignoreCase: !spec.caseSensitive, test }, from, to);
626
- }
627
- function charBefore(str, index) {
628
- return str.slice(findClusterBreak(str, index, false), index);
629
- }
630
- function charAfter(str, index) {
631
- return str.slice(index, findClusterBreak(str, index));
632
- }
633
- function regexpWordTest(categorizer) {
634
- return (_from, _to, match) => !match[0].length || (categorizer(charBefore(match.input, match.index)) != CharCategory.Word || categorizer(charAfter(match.input, match.index)) != CharCategory.Word) && (categorizer(charAfter(match.input, match.index + match[0].length)) != CharCategory.Word || categorizer(charBefore(match.input, match.index + match[0].length)) != CharCategory.Word);
635
- }
636
- var RegExpQuery = class extends QueryType {
637
- nextMatch(state, curFrom, curTo) {
638
- let cursor = regexpCursor(this.spec, state, curTo, state.doc.length).next();
639
- if (cursor.done)
640
- cursor = regexpCursor(this.spec, state, 0, curFrom).next();
641
- return cursor.done ? null : cursor.value;
642
- }
643
- prevMatchInRange(state, from, to) {
644
- for (let size = 1; ; size++) {
645
- let start = Math.max(
646
- from,
647
- to - size * 1e4
648
- /* FindPrev.ChunkSize */
649
- );
650
- let cursor = regexpCursor(this.spec, state, start, to), range = null;
651
- while (!cursor.next().done)
652
- range = cursor.value;
653
- if (range && (start == from || range.from > start + 10))
654
- return range;
655
- if (start == from)
656
- return null;
657
- }
658
- }
659
- prevMatch(state, curFrom, curTo) {
660
- return this.prevMatchInRange(state, 0, curFrom) || this.prevMatchInRange(state, curTo, state.doc.length);
661
- }
662
- getReplacement(result) {
663
- return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g, (m, i) => {
664
- if (i == "&")
665
- return result.match[0];
666
- if (i == "$")
667
- return "$";
668
- for (let l = i.length; l > 0; l--) {
669
- let n = +i.slice(0, l);
670
- if (n > 0 && n < result.match.length)
671
- return result.match[n] + i.slice(l);
672
- }
673
- return m;
674
- });
675
- }
676
- matchAll(state, limit) {
677
- let cursor = regexpCursor(this.spec, state, 0, state.doc.length), ranges = [];
678
- while (!cursor.next().done) {
679
- if (ranges.length >= limit)
680
- return null;
681
- ranges.push(cursor.value);
682
- }
683
- return ranges;
684
- }
685
- highlight(state, from, to, add) {
686
- let cursor = regexpCursor(this.spec, state, Math.max(
687
- 0,
688
- from - 250
689
- /* RegExp.HighlightMargin */
690
- ), Math.min(to + 250, state.doc.length));
691
- while (!cursor.next().done)
692
- add(cursor.value.from, cursor.value.to);
693
- }
694
- };
695
- var setSearchQuery = StateEffect.define();
696
- var togglePanel = StateEffect.define();
697
- var searchState = StateField.define({
698
- create(state) {
699
- return new SearchState(defaultQuery(state).create(), null);
700
- },
701
- update(value, tr) {
702
- for (let effect of tr.effects) {
703
- if (effect.is(setSearchQuery))
704
- value = new SearchState(effect.value.create(), value.panel);
705
- else if (effect.is(togglePanel))
706
- value = new SearchState(value.query, effect.value ? createSearchPanel : null);
707
- }
708
- return value;
709
- },
710
- provide: (f) => showPanel.from(f, (val) => val.panel)
711
- });
712
- function getSearchQuery(state) {
713
- let curState = state.field(searchState, false);
714
- return curState ? curState.query.spec : defaultQuery(state);
715
- }
716
- function searchPanelOpen(state) {
717
- var _a;
718
- return ((_a = state.field(searchState, false)) === null || _a === void 0 ? void 0 : _a.panel) != null;
719
- }
720
- var SearchState = class {
721
- constructor(query, panel) {
722
- this.query = query;
723
- this.panel = panel;
724
- }
725
- };
726
- var matchMark = Decoration.mark({ class: "cm-searchMatch" });
727
- var selectedMatchMark = Decoration.mark({ class: "cm-searchMatch cm-searchMatch-selected" });
728
- var searchHighlighter = ViewPlugin.fromClass(class {
729
- constructor(view) {
730
- this.view = view;
731
- this.decorations = this.highlight(view.state.field(searchState));
732
- }
733
- update(update) {
734
- let state = update.state.field(searchState);
735
- if (state != update.startState.field(searchState) || update.docChanged || update.selectionSet || update.viewportChanged)
736
- this.decorations = this.highlight(state);
737
- }
738
- highlight({ query, panel }) {
739
- if (!panel || !query.spec.valid)
740
- return Decoration.none;
741
- let { view } = this;
742
- let builder = new RangeSetBuilder();
743
- for (let i = 0, ranges = view.visibleRanges, l = ranges.length; i < l; i++) {
744
- let { from, to } = ranges[i];
745
- while (i < l - 1 && to > ranges[i + 1].from - 2 * 250)
746
- to = ranges[++i].to;
747
- query.highlight(view.state, from, to, (from2, to2) => {
748
- let selected = view.state.selection.ranges.some((r) => r.from == from2 && r.to == to2);
749
- builder.add(from2, to2, selected ? selectedMatchMark : matchMark);
750
- });
751
- }
752
- return builder.finish();
753
- }
754
- }, {
755
- decorations: (v) => v.decorations
756
- });
757
- function searchCommand(f) {
758
- return (view) => {
759
- let state = view.state.field(searchState, false);
760
- return state && state.query.spec.valid ? f(view, state) : openSearchPanel(view);
761
- };
762
- }
763
- var findNext = searchCommand((view, { query }) => {
764
- let { to } = view.state.selection.main;
765
- let next = query.nextMatch(view.state, to, to);
766
- if (!next)
767
- return false;
768
- let selection = EditorSelection.single(next.from, next.to);
769
- let config = view.state.facet(searchConfigFacet);
770
- view.dispatch({
771
- selection,
772
- effects: [announceMatch(view, next), config.scrollToMatch(selection.main, view)],
773
- userEvent: "select.search"
774
- });
775
- selectSearchInput(view);
776
- return true;
777
- });
778
- var findPrevious = searchCommand((view, { query }) => {
779
- let { state } = view, { from } = state.selection.main;
780
- let prev = query.prevMatch(state, from, from);
781
- if (!prev)
782
- return false;
783
- let selection = EditorSelection.single(prev.from, prev.to);
784
- let config = view.state.facet(searchConfigFacet);
785
- view.dispatch({
786
- selection,
787
- effects: [announceMatch(view, prev), config.scrollToMatch(selection.main, view)],
788
- userEvent: "select.search"
789
- });
790
- selectSearchInput(view);
791
- return true;
792
- });
793
- var selectMatches = searchCommand((view, { query }) => {
794
- let ranges = query.matchAll(view.state, 1e3);
795
- if (!ranges || !ranges.length)
796
- return false;
797
- view.dispatch({
798
- selection: EditorSelection.create(ranges.map((r) => EditorSelection.range(r.from, r.to))),
799
- userEvent: "select.search.matches"
800
- });
801
- return true;
802
- });
803
- var selectSelectionMatches = ({ state, dispatch }) => {
804
- let sel = state.selection;
805
- if (sel.ranges.length > 1 || sel.main.empty)
806
- return false;
807
- let { from, to } = sel.main;
808
- let ranges = [], main = 0;
809
- for (let cur = new SearchCursor(state.doc, state.sliceDoc(from, to)); !cur.next().done; ) {
810
- if (ranges.length > 1e3)
811
- return false;
812
- if (cur.value.from == from)
813
- main = ranges.length;
814
- ranges.push(EditorSelection.range(cur.value.from, cur.value.to));
815
- }
816
- dispatch(state.update({
817
- selection: EditorSelection.create(ranges, main),
818
- userEvent: "select.search.matches"
819
- }));
820
- return true;
821
- };
822
- var replaceNext = searchCommand((view, { query }) => {
823
- let { state } = view, { from, to } = state.selection.main;
824
- if (state.readOnly)
825
- return false;
826
- let match = query.nextMatch(state, from, from);
827
- if (!match)
828
- return false;
829
- let next = match;
830
- let changes = [], selection, replacement;
831
- let effects = [];
832
- if (next.from == from && next.to == to) {
833
- replacement = state.toText(query.getReplacement(next));
834
- changes.push({ from: next.from, to: next.to, insert: replacement });
835
- next = query.nextMatch(state, next.from, next.to);
836
- effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
837
- }
838
- let changeSet = view.state.changes(changes);
839
- if (next) {
840
- selection = EditorSelection.single(next.from, next.to).map(changeSet);
841
- effects.push(announceMatch(view, next));
842
- effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main, view));
843
- }
844
- view.dispatch({
845
- changes: changeSet,
846
- selection,
847
- effects,
848
- userEvent: "input.replace"
849
- });
850
- return true;
851
- });
852
- var replaceAll = searchCommand((view, { query }) => {
853
- if (view.state.readOnly)
854
- return false;
855
- let changes = query.matchAll(view.state, 1e9).map((match) => {
856
- let { from, to } = match;
857
- return { from, to, insert: query.getReplacement(match) };
858
- });
859
- if (!changes.length)
860
- return false;
861
- let announceText = view.state.phrase("replaced $ matches", changes.length) + ".";
862
- view.dispatch({
863
- changes,
864
- effects: EditorView.announce.of(announceText),
865
- userEvent: "input.replace.all"
866
- });
867
- return true;
868
- });
869
- function createSearchPanel(view) {
870
- return view.state.facet(searchConfigFacet).createPanel(view);
871
- }
872
- function defaultQuery(state, fallback) {
873
- var _a, _b, _c, _d, _e;
874
- let sel = state.selection.main;
875
- let selText = sel.empty || sel.to > sel.from + 100 ? "" : state.sliceDoc(sel.from, sel.to);
876
- if (fallback && !selText)
877
- return fallback;
878
- let config = state.facet(searchConfigFacet);
879
- return new SearchQuery({
880
- search: ((_a = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _a !== void 0 ? _a : config.literal) ? selText : selText.replace(/\n/g, "\\n"),
881
- caseSensitive: (_b = fallback === null || fallback === void 0 ? void 0 : fallback.caseSensitive) !== null && _b !== void 0 ? _b : config.caseSensitive,
882
- literal: (_c = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _c !== void 0 ? _c : config.literal,
883
- regexp: (_d = fallback === null || fallback === void 0 ? void 0 : fallback.regexp) !== null && _d !== void 0 ? _d : config.regexp,
884
- wholeWord: (_e = fallback === null || fallback === void 0 ? void 0 : fallback.wholeWord) !== null && _e !== void 0 ? _e : config.wholeWord
885
- });
886
- }
887
- function getSearchInput(view) {
888
- let panel = getPanel(view, createSearchPanel);
889
- return panel && panel.dom.querySelector("[main-field]");
890
- }
891
- function selectSearchInput(view) {
892
- let input = getSearchInput(view);
893
- if (input && input == view.root.activeElement)
894
- input.select();
895
- }
896
- var openSearchPanel = (view) => {
897
- let state = view.state.field(searchState, false);
898
- if (state && state.panel) {
899
- let searchInput = getSearchInput(view);
900
- if (searchInput && searchInput != view.root.activeElement) {
901
- let query = defaultQuery(view.state, state.query.spec);
902
- if (query.valid)
903
- view.dispatch({ effects: setSearchQuery.of(query) });
904
- searchInput.focus();
905
- searchInput.select();
906
- }
907
- } else {
908
- view.dispatch({ effects: [
909
- togglePanel.of(true),
910
- state ? setSearchQuery.of(defaultQuery(view.state, state.query.spec)) : StateEffect.appendConfig.of(searchExtensions)
911
- ] });
912
- }
913
- return true;
914
- };
915
- var closeSearchPanel = (view) => {
916
- let state = view.state.field(searchState, false);
917
- if (!state || !state.panel)
918
- return false;
919
- let panel = getPanel(view, createSearchPanel);
920
- if (panel && panel.dom.contains(view.root.activeElement))
921
- view.focus();
922
- view.dispatch({ effects: togglePanel.of(false) });
923
- return true;
924
- };
925
- var searchKeymap = [
926
- { key: "Mod-f", run: openSearchPanel, scope: "editor search-panel" },
927
- { key: "F3", run: findNext, shift: findPrevious, scope: "editor search-panel", preventDefault: true },
928
- { key: "Mod-g", run: findNext, shift: findPrevious, scope: "editor search-panel", preventDefault: true },
929
- { key: "Escape", run: closeSearchPanel, scope: "editor search-panel" },
930
- { key: "Mod-Shift-l", run: selectSelectionMatches },
931
- { key: "Mod-Alt-g", run: gotoLine },
932
- { key: "Mod-d", run: selectNextOccurrence, preventDefault: true }
933
- ];
934
- var SearchPanel = class {
935
- constructor(view) {
936
- this.view = view;
937
- let query = this.query = view.state.field(searchState).query.spec;
938
- this.commit = this.commit.bind(this);
939
- this.searchField = crelt("input", {
940
- value: query.search,
941
- placeholder: phrase(view, "Find"),
942
- "aria-label": phrase(view, "Find"),
943
- class: "cm-textfield",
944
- name: "search",
945
- form: "",
946
- "main-field": "true",
947
- onchange: this.commit,
948
- onkeyup: this.commit
949
- });
950
- this.replaceField = crelt("input", {
951
- value: query.replace,
952
- placeholder: phrase(view, "Replace"),
953
- "aria-label": phrase(view, "Replace"),
954
- class: "cm-textfield",
955
- name: "replace",
956
- form: "",
957
- onchange: this.commit,
958
- onkeyup: this.commit
959
- });
960
- this.caseField = crelt("input", {
961
- type: "checkbox",
962
- name: "case",
963
- form: "",
964
- checked: query.caseSensitive,
965
- onchange: this.commit
966
- });
967
- this.reField = crelt("input", {
968
- type: "checkbox",
969
- name: "re",
970
- form: "",
971
- checked: query.regexp,
972
- onchange: this.commit
973
- });
974
- this.wordField = crelt("input", {
975
- type: "checkbox",
976
- name: "word",
977
- form: "",
978
- checked: query.wholeWord,
979
- onchange: this.commit
980
- });
981
- function button(name, onclick, content) {
982
- return crelt("button", { class: "cm-button", name, onclick, type: "button" }, content);
983
- }
984
- this.dom = crelt("div", { onkeydown: (e) => this.keydown(e), class: "cm-search" }, [
985
- this.searchField,
986
- button("next", () => findNext(view), [phrase(view, "next")]),
987
- button("prev", () => findPrevious(view), [phrase(view, "previous")]),
988
- button("select", () => selectMatches(view), [phrase(view, "all")]),
989
- crelt("label", null, [this.caseField, phrase(view, "match case")]),
990
- crelt("label", null, [this.reField, phrase(view, "regexp")]),
991
- crelt("label", null, [this.wordField, phrase(view, "by word")]),
992
- ...view.state.readOnly ? [] : [
993
- crelt("br"),
994
- this.replaceField,
995
- button("replace", () => replaceNext(view), [phrase(view, "replace")]),
996
- button("replaceAll", () => replaceAll(view), [phrase(view, "replace all")])
997
- ],
998
- crelt("button", {
999
- name: "close",
1000
- onclick: () => closeSearchPanel(view),
1001
- "aria-label": phrase(view, "close"),
1002
- type: "button"
1003
- }, ["×"])
1004
- ]);
1005
- }
1006
- commit() {
1007
- let query = new SearchQuery({
1008
- search: this.searchField.value,
1009
- caseSensitive: this.caseField.checked,
1010
- regexp: this.reField.checked,
1011
- wholeWord: this.wordField.checked,
1012
- replace: this.replaceField.value
1013
- });
1014
- if (!query.eq(this.query)) {
1015
- this.query = query;
1016
- this.view.dispatch({ effects: setSearchQuery.of(query) });
1017
- }
1018
- }
1019
- keydown(e) {
1020
- if (runScopeHandlers(this.view, e, "search-panel")) {
1021
- e.preventDefault();
1022
- } else if (e.keyCode == 13 && e.target == this.searchField) {
1023
- e.preventDefault();
1024
- (e.shiftKey ? findPrevious : findNext)(this.view);
1025
- } else if (e.keyCode == 13 && e.target == this.replaceField) {
1026
- e.preventDefault();
1027
- replaceNext(this.view);
1028
- }
1029
- }
1030
- update(update) {
1031
- for (let tr of update.transactions)
1032
- for (let effect of tr.effects) {
1033
- if (effect.is(setSearchQuery) && !effect.value.eq(this.query))
1034
- this.setQuery(effect.value);
1035
- }
1036
- }
1037
- setQuery(query) {
1038
- this.query = query;
1039
- this.searchField.value = query.search;
1040
- this.replaceField.value = query.replace;
1041
- this.caseField.checked = query.caseSensitive;
1042
- this.reField.checked = query.regexp;
1043
- this.wordField.checked = query.wholeWord;
1044
- }
1045
- mount() {
1046
- this.searchField.select();
1047
- }
1048
- get pos() {
1049
- return 80;
1050
- }
1051
- get top() {
1052
- return this.view.state.facet(searchConfigFacet).top;
1053
- }
1054
- };
1055
- function phrase(view, phrase2) {
1056
- return view.state.phrase(phrase2);
1057
- }
1058
- var AnnounceMargin = 30;
1059
- var Break = /[\s\.,:;?!]/;
1060
- function announceMatch(view, { from, to }) {
1061
- let line = view.state.doc.lineAt(from), lineEnd = view.state.doc.lineAt(to).to;
1062
- let start = Math.max(line.from, from - AnnounceMargin), end = Math.min(lineEnd, to + AnnounceMargin);
1063
- let text = view.state.sliceDoc(start, end);
1064
- if (start != line.from) {
1065
- for (let i = 0; i < AnnounceMargin; i++)
1066
- if (!Break.test(text[i + 1]) && Break.test(text[i])) {
1067
- text = text.slice(i);
1068
- break;
1069
- }
1070
- }
1071
- if (end != lineEnd) {
1072
- for (let i = text.length - 1; i > text.length - AnnounceMargin; i--)
1073
- if (!Break.test(text[i - 1]) && Break.test(text[i])) {
1074
- text = text.slice(0, i);
1075
- break;
1076
- }
1077
- }
1078
- return EditorView.announce.of(`${view.state.phrase("current match")}. ${text} ${view.state.phrase("on line")} ${line.number}.`);
1079
- }
1080
- var baseTheme = EditorView.baseTheme({
1081
- ".cm-panel.cm-search": {
1082
- padding: "2px 6px 4px",
1083
- position: "relative",
1084
- "& [name=close]": {
1085
- position: "absolute",
1086
- top: "0",
1087
- right: "4px",
1088
- backgroundColor: "inherit",
1089
- border: "none",
1090
- font: "inherit",
1091
- padding: 0,
1092
- margin: 0
1093
- },
1094
- "& input, & button, & label": {
1095
- margin: ".2em .6em .2em 0"
1096
- },
1097
- "& input[type=checkbox]": {
1098
- marginRight: ".2em"
1099
- },
1100
- "& label": {
1101
- fontSize: "80%",
1102
- whiteSpace: "pre"
1103
- }
1104
- },
1105
- "&light .cm-searchMatch": { backgroundColor: "#ffff0054" },
1106
- "&dark .cm-searchMatch": { backgroundColor: "#00ffff8a" },
1107
- "&light .cm-searchMatch-selected": { backgroundColor: "#ff6a0054" },
1108
- "&dark .cm-searchMatch-selected": { backgroundColor: "#ff00ff8a" }
1109
- });
1110
- var searchExtensions = [
1111
- searchState,
1112
- Prec.low(searchHighlighter),
1113
- baseTheme
1114
- ];
1115
- export {
1116
- RegExpCursor,
1117
- SearchCursor,
1118
- SearchQuery,
1119
- closeSearchPanel,
1120
- findNext,
1121
- findPrevious,
1122
- getSearchQuery,
1123
- gotoLine,
1124
- highlightSelectionMatches,
1125
- openSearchPanel,
1126
- replaceAll,
1127
- replaceNext,
1128
- search,
1129
- searchKeymap,
1130
- searchPanelOpen,
1131
- selectMatches,
1132
- selectNextOccurrence,
1133
- selectSelectionMatches,
1134
- setSearchQuery
1135
- };
1136
- //# sourceMappingURL=@codemirror_search.js.map