@kky42/pievo-server 2.3.0 → 2.4.2

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 (199) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/MachinesModal-CSbnrUER.js +1 -0
  3. package/.output/public/assets/SignIn-0Tjqs-Ma.js +1 -0
  4. package/.output/public/assets/actionUi-DpwGIGpw.js +1 -0
  5. package/.output/public/assets/app-CaZpuwOS.css +2 -0
  6. package/.output/public/assets/index-CaS_SmDq.js +10 -0
  7. package/.output/public/assets/invite._token-Btg_0aLp.js +1 -0
  8. package/.output/public/assets/invite._token-KMD2JAgE.js +1 -0
  9. package/.output/public/assets/lifecycleUi-C7dwHtbw.js +1 -0
  10. package/.output/public/assets/loops._loopId-D5usF3DO.js +67 -0
  11. package/.output/public/assets/loops._loopId_.runs._runId-DRCgXaCq.js +3 -0
  12. package/.output/public/assets/preload-helper-DsxECZIS.js +5 -0
  13. package/.output/public/assets/routes-CtFgwdgW.js +1 -0
  14. package/.output/public/assets/routes-LDbnnQ3f.js +1 -0
  15. package/.output/public/assets/t._teamId-D41xcbsF.js +1 -0
  16. package/.output/public/assets/t._teamId-DUena1pV.js +1 -0
  17. package/.output/public/assets/ui-Do4gqMyP.js +1 -0
  18. package/.output/server/_libs/@base-ui/react+[...].mjs +4130 -4130
  19. package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
  20. package/.output/server/_libs/drizzle-orm+postgres.mjs +28 -1
  21. package/.output/server/_ssr/DashboardView-C2LdV6J0.mjs +914 -0
  22. package/.output/server/_ssr/{notifyFns-DuPR1zd7.mjs → MachinesModal-BjkcVjjx.mjs} +55 -35
  23. package/.output/server/_ssr/{SignIn-RmpWm9uy.mjs → SignIn-DEGrvJvb.mjs} +10 -24
  24. package/.output/server/_ssr/SocialLinks-Cm4H8pUJ.mjs +1044 -0
  25. package/.output/server/_ssr/{actionUi-BN55TNYE.mjs → actionUi-DJBWuNwr.mjs} +3 -3
  26. package/.output/server/_ssr/{artifactFiles-BCaIIrrT.mjs → artifactFiles-DtpRidFZ.mjs} +7 -8
  27. package/.output/server/_ssr/{artifactKind-BW0isV8L.mjs → artifactKind-FBYbgSuf.mjs} +27 -2
  28. package/.output/server/_ssr/artifacts-BR3jj0NC.mjs +2 -0
  29. package/.output/server/_ssr/{auth-30Z4lV1w.mjs → auth-C0zoZCGe.mjs} +16 -19
  30. package/.output/server/_ssr/boot-CdOO4xOo.mjs +2 -0
  31. package/.output/server/_ssr/{boot-3BNKujyp.mjs → boot-sNlIkoLe.mjs} +1331 -3927
  32. package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-_7tfuNRi.mjs → bun-sqlite-dialect-BW9W1_Ps-DmlZWqO7.mjs} +2 -2
  33. package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-ucDUbeBk.mjs → d1-sqlite-dialect-BLC8LXE6-CCNzqZwZ.mjs} +2 -2
  34. package/.output/server/_ssr/db-CwLD-5w1.mjs +2 -0
  35. package/.output/server/_ssr/{dist-Cd6nlLlO.mjs → dist-B3SxDOpW.mjs} +2 -2
  36. package/.output/server/_ssr/{factory-CWWwV7XZ.mjs → factory-Dv3Zopis.mjs} +2 -2
  37. package/.output/server/_ssr/invite._token-CJ6-H-s3.mjs +20 -0
  38. package/.output/server/_ssr/{invite._token-SdWXemIc.mjs → invite._token-dLKDJKVs.mjs} +9 -17
  39. package/.output/server/_ssr/{invite._token-BKlz0R2f.mjs → invite._token-l1SjouDz.mjs} +6 -15
  40. package/.output/server/_ssr/{kysely-adapter-C8iS51DB.mjs → kysely-adapter-nL7WKSgw.mjs} +1 -1
  41. package/.output/server/_ssr/{lifecycleUi-DgBQAYzp.mjs → lifecycleUi-Dad3hvhm.mjs} +11 -11
  42. package/.output/server/_ssr/logger-B8m8F1Qu.mjs +2 -0
  43. package/.output/server/_ssr/loopApi-BKyFB4KM.mjs +342 -0
  44. package/.output/server/_ssr/{adapters-BoLkOf1T.mjs → loopProjection-B8a829ij.mjs} +25 -55
  45. package/.output/server/_ssr/loops._loopId-DS16Phmq.mjs +1271 -0
  46. package/.output/server/_ssr/{loops._loopId_.runs._runId-PUGBrD5q.mjs → loops._loopId_.runs._runId-BEJI6iK5.mjs} +23 -74
  47. package/.output/server/_ssr/{loops._loopId_.runs._runId-Ymy4lwee.mjs → loops._loopId_.runs._runId-CduETLqH.mjs} +4 -5
  48. package/.output/server/_ssr/{machineFns-BZ9puxDt.mjs → machineFns-ByMsgG12.mjs} +3 -5
  49. package/.output/server/_ssr/{node-sqlite-dialect-D_3JmkMo.mjs → node-sqlite-dialect-CjNineno.mjs} +2 -2
  50. package/.output/server/_ssr/router-CXyrnvx-.mjs +565 -0
  51. package/.output/server/_ssr/{routes-ClZEdsnB.mjs → routes-BulNEUEE.mjs} +6 -10
  52. package/.output/server/_ssr/{routes-ComqHvCL.mjs → routes-DD94baie.mjs} +3 -3
  53. package/.output/server/_ssr/{routes-D5jJJ-30.mjs → routes-Wjexi35W.mjs} +6 -6
  54. package/.output/server/_ssr/runDiff-Ba8Lg1vg.mjs +2 -0
  55. package/.output/server/_ssr/ssr.mjs +60 -100
  56. package/.output/server/_ssr/store-Cujtg2QE.mjs +2 -0
  57. package/.output/server/_ssr/{t._teamId-BgHV_KFP.mjs → t._teamId-1CreIlPV.mjs} +7 -11
  58. package/.output/server/_ssr/{t._teamId-DDERNgfn.mjs → t._teamId-Bd6-zZsy.mjs} +4 -4
  59. package/.output/server/_ssr/{t._teamId-DRJvKHZn.mjs → t._teamId-COuMKQ4r.mjs} +7 -7
  60. package/.output/server/_ssr/{teamFns-Bp81UO-x.mjs → teamFns-H438WnZC.mjs} +12 -30
  61. package/.output/server/_ssr/{teamFns-bm82twd5.mjs → teamFns-j2JKjorZ.mjs} +2 -2
  62. package/.output/server/_ssr/tokens-DgG_Syq3.mjs +2 -0
  63. package/.output/server/_ssr/{ui-Ww2tTM2u.mjs → ui-D5KWstlb.mjs} +26 -48
  64. package/.output/server/{_tanstack-start-manifest_v-DwKENYCN.mjs → _tanstack-start-manifest_v-3H7yBKLz.mjs} +25 -35
  65. package/{drizzle/0000_round_marauders.sql → .output/server/drizzle/0000_baseline.sql} +102 -44
  66. package/.output/server/drizzle/meta/_journal.json +3 -115
  67. package/.output/server/index.mjs +83 -132
  68. package/{.output/server/drizzle/0000_round_marauders.sql → drizzle/0000_baseline.sql} +102 -44
  69. package/drizzle/meta/_journal.json +3 -115
  70. package/package.json +2 -11
  71. package/scripts/pievo-server.mjs +3 -1
  72. package/scripts/server-cli-lib.mjs +23 -16
  73. package/.output/public/assets/CodeField-dOzyFQNH.js +0 -34
  74. package/.output/public/assets/LoopView-DjVHUyrR.js +0 -59
  75. package/.output/public/assets/Modal-CCRvx959.js +0 -1
  76. package/.output/public/assets/SignIn-Qxw5zDFq.js +0 -1
  77. package/.output/public/assets/actionUi-CXxhzYe2.js +0 -1
  78. package/.output/public/assets/app-D1cij_NJ.css +0 -2
  79. package/.output/public/assets/artifactView-Cd5wWPil.js +0 -66
  80. package/.output/public/assets/index-BRN_CQ8U.js +0 -12
  81. package/.output/public/assets/invite._token-BIxr8DlP.js +0 -1
  82. package/.output/public/assets/invite._token-j2BTCeG1.js +0 -1
  83. package/.output/public/assets/jsx-runtime-BseJUIpC.js +0 -1
  84. package/.output/public/assets/lifecycleUi-Qy_8beQK.js +0 -1
  85. package/.output/public/assets/loopApi-CT1mMhlb.js +0 -3
  86. package/.output/public/assets/loops._loopId-BRBQzioy.js +0 -4
  87. package/.output/public/assets/loops._loopId_.runs._runId-CMnOJkem.js +0 -3
  88. package/.output/public/assets/notifyFns-DYD4EKaG.js +0 -1
  89. package/.output/public/assets/preload-helper-DFkkpP6W.js +0 -3
  90. package/.output/public/assets/routes-3nuEJGdo.js +0 -1
  91. package/.output/public/assets/routes-DORLim-C.js +0 -1
  92. package/.output/public/assets/t._teamId-F5f4K8kd.js +0 -1
  93. package/.output/public/assets/t._teamId-XfE_S1Fo.js +0 -1
  94. package/.output/public/assets/ui-Dhsx6SW0.js +0 -1
  95. package/.output/public/assets/useRouter-DsjH8G0p.js +0 -1
  96. package/.output/server/_libs/@codemirror/autocomplete+[...].mjs +0 -19713
  97. package/.output/server/_libs/@codemirror/lang-css+[...].mjs +0 -2636
  98. package/.output/server/_libs/@codemirror/lang-html+[...].mjs +0 -2247
  99. package/.output/server/_libs/@codemirror/lang-json+[...].mjs +0 -79
  100. package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +0 -1736
  101. package/.output/server/_libs/@uiw/codemirror-extensions-basic-setup+[...].mjs +0 -76
  102. package/.output/server/_libs/babel__runtime.mjs +0 -30
  103. package/.output/server/_libs/clsx.mjs +0 -16
  104. package/.output/server/_libs/codemirror__commands.mjs +0 -1725
  105. package/.output/server/_libs/codemirror__lint.mjs +0 -565
  106. package/.output/server/_libs/codemirror__search.mjs +0 -1138
  107. package/.output/server/_libs/codemirror__theme-one-dark.mjs +0 -161
  108. package/.output/server/_libs/d3-array.mjs +0 -231
  109. package/.output/server/_libs/d3-color.mjs +0 -330
  110. package/.output/server/_libs/d3-format.mjs +0 -252
  111. package/.output/server/_libs/d3-interpolate.mjs +0 -163
  112. package/.output/server/_libs/d3-path.mjs +0 -77
  113. package/.output/server/_libs/d3-scale+[...].mjs +0 -1907
  114. package/.output/server/_libs/d3-shape.mjs +0 -818
  115. package/.output/server/_libs/decimal.js-light.mjs +0 -884
  116. package/.output/server/_libs/dom-serializer+[...].mjs +0 -708
  117. package/.output/server/_libs/domhandler.mjs +0 -461
  118. package/.output/server/_libs/domutils.mjs +0 -868
  119. package/.output/server/_libs/es-toolkit.mjs +0 -1737
  120. package/.output/server/_libs/eventemitter3.mjs +0 -236
  121. package/.output/server/_libs/html-dom-parser+htmlparser2.mjs +0 -1560
  122. package/.output/server/_libs/html-react-parser+[...].mjs +0 -1360
  123. package/.output/server/_libs/react-is.mjs +0 -48
  124. package/.output/server/_libs/react-redux+[...].mjs +0 -205
  125. package/.output/server/_libs/recharts+victory-vendor.mjs +0 -17303
  126. package/.output/server/_libs/uiw__codemirror-themes.mjs +0 -32
  127. package/.output/server/_libs/uiw__react-codemirror.mjs +0 -354
  128. package/.output/server/_ssr/CodeField-B7oOmmwH.mjs +0 -143
  129. package/.output/server/_ssr/DashboardView-BF7PciP7.mjs +0 -2736
  130. package/.output/server/_ssr/LoopPlaybook-DC7QVvPY.mjs +0 -2105
  131. package/.output/server/_ssr/LoopView-DwSrm9Ja.mjs +0 -1300
  132. package/.output/server/_ssr/Modal-MaCG52Pv.mjs +0 -49
  133. package/.output/server/_ssr/artifactView-iuPsp5aa.mjs +0 -304
  134. package/.output/server/_ssr/artifacts-jQ-bfdhI.mjs +0 -2
  135. package/.output/server/_ssr/boot-CsEFT53K.mjs +0 -2
  136. package/.output/server/_ssr/db-CXownd1H.mjs +0 -2
  137. package/.output/server/_ssr/invite._token-CWl6kipD.mjs +0 -28
  138. package/.output/server/_ssr/logger-Gy-47z3k.mjs +0 -2
  139. package/.output/server/_ssr/loopApi-8_KgBapr.mjs +0 -109
  140. package/.output/server/_ssr/loopApi-ABi9SgWS.mjs +0 -564
  141. package/.output/server/_ssr/loops._loopId-SON_t43g.mjs +0 -30
  142. package/.output/server/_ssr/loops._loopId-p1KWsvMM.mjs +0 -1477
  143. package/.output/server/_ssr/notifyFns-BUCePuF3.mjs +0 -118
  144. package/.output/server/_ssr/router-Czxvra6l.mjs +0 -685
  145. package/.output/server/_ssr/runDiff--qLtU4FI.mjs +0 -2
  146. package/.output/server/_ssr/store-40eVzW1S.mjs +0 -2
  147. package/.output/server/_ssr/tokens-CbfoRC_s.mjs +0 -2
  148. package/.output/server/drizzle/0001_naive_silver_fox.sql +0 -25
  149. package/.output/server/drizzle/0002_funny_sage.sql +0 -12
  150. package/.output/server/drizzle/0003_optimal_slapstick.sql +0 -102
  151. package/.output/server/drizzle/0004_remove_grok_agent.sql +0 -5
  152. package/.output/server/drizzle/0005_heavy_gauntlet.sql +0 -8
  153. package/.output/server/drizzle/0006_tranquil_sharon_carter.sql +0 -1
  154. package/.output/server/drizzle/0007_faulty_starbolt.sql +0 -30
  155. package/.output/server/drizzle/0008_durable_lifecycle_evidence.sql +0 -15
  156. package/.output/server/drizzle/0009_ordinary_electro.sql +0 -1
  157. package/.output/server/drizzle/0010_workable_rage.sql +0 -14
  158. package/.output/server/drizzle/0011_steep_marvel_zombies.sql +0 -3
  159. package/.output/server/drizzle/0012_blocked_run_status.sql +0 -12
  160. package/.output/server/drizzle/0013_drop_run_outcome.sql +0 -2
  161. package/.output/server/drizzle/0014_luxuriant_scrambler.sql +0 -5
  162. package/.output/server/drizzle/0015_run_history_foundation.sql +0 -43
  163. package/.output/server/drizzle/0016_plural_machine_runs.sql +0 -4
  164. package/.output/server/drizzle/meta/0000_snapshot.json +0 -1333
  165. package/.output/server/drizzle/meta/0001_snapshot.json +0 -1498
  166. package/.output/server/drizzle/meta/0002_snapshot.json +0 -1576
  167. package/.output/server/drizzle/meta/0003_snapshot.json +0 -1666
  168. package/.output/server/drizzle/meta/0005_snapshot.json +0 -1666
  169. package/.output/server/drizzle/meta/0006_snapshot.json +0 -1672
  170. package/.output/server/drizzle/meta/0007_snapshot.json +0 -1787
  171. package/.output/server/drizzle/meta/0009_snapshot.json +0 -1793
  172. package/.output/server/drizzle/meta/0010_snapshot.json +0 -1891
  173. package/.output/server/drizzle/meta/0011_snapshot.json +0 -1872
  174. package/drizzle/0001_naive_silver_fox.sql +0 -25
  175. package/drizzle/0002_funny_sage.sql +0 -12
  176. package/drizzle/0003_optimal_slapstick.sql +0 -102
  177. package/drizzle/0004_remove_grok_agent.sql +0 -5
  178. package/drizzle/0005_heavy_gauntlet.sql +0 -8
  179. package/drizzle/0006_tranquil_sharon_carter.sql +0 -1
  180. package/drizzle/0007_faulty_starbolt.sql +0 -30
  181. package/drizzle/0008_durable_lifecycle_evidence.sql +0 -15
  182. package/drizzle/0009_ordinary_electro.sql +0 -1
  183. package/drizzle/0010_workable_rage.sql +0 -14
  184. package/drizzle/0011_steep_marvel_zombies.sql +0 -3
  185. package/drizzle/0012_blocked_run_status.sql +0 -12
  186. package/drizzle/0013_drop_run_outcome.sql +0 -2
  187. package/drizzle/0014_luxuriant_scrambler.sql +0 -5
  188. package/drizzle/0015_run_history_foundation.sql +0 -43
  189. package/drizzle/0016_plural_machine_runs.sql +0 -4
  190. package/drizzle/meta/0000_snapshot.json +0 -1333
  191. package/drizzle/meta/0001_snapshot.json +0 -1498
  192. package/drizzle/meta/0002_snapshot.json +0 -1576
  193. package/drizzle/meta/0003_snapshot.json +0 -1666
  194. package/drizzle/meta/0005_snapshot.json +0 -1666
  195. package/drizzle/meta/0006_snapshot.json +0 -1672
  196. package/drizzle/meta/0007_snapshot.json +0 -1787
  197. package/drizzle/meta/0009_snapshot.json +0 -1793
  198. package/drizzle/meta/0010_snapshot.json +0 -1891
  199. package/drizzle/meta/0011_snapshot.json +0 -1872
@@ -1,1138 +0,0 @@
1
- import { $ as getPanel, At as fromCodePoint, Dt as combineConfig, Et as codePointSize, K as EditorView, St as StateField, Tt as codePointAt, W as Decoration, _t as EditorState, bt as RangeSetBuilder, ct as runScopeHandlers, dt as crelt, gt as EditorSelection, ht as CharCategory, kt as findClusterBreak, lt as showDialog, q as ViewPlugin, ut as showPanel, vt as Facet, xt as StateEffect, yt as Prec } from "./@codemirror/autocomplete+[...].mjs";
2
- //#region ../../node_modules/.pnpm/@codemirror+search@6.7.1/node_modules/@codemirror/search/dist/index.js
3
- var basicNormalize = typeof String.prototype.normalize == "function" ? (x) => x.normalize("NFKD") : (x) => x;
4
- /**
5
- A search cursor provides an iterator over text matches in a
6
- document.
7
- */
8
- var SearchCursor = class {
9
- /**
10
- Create a text cursor. The query is the search string, `from` to
11
- `to` provides the region to search.
12
-
13
- When `normalize` is given, it will be called, on both the query
14
- string and the content it is matched against, before comparing.
15
- You can, for example, create a case-insensitive search by
16
- passing `s => s.toLowerCase()`.
17
-
18
- Text is always normalized with
19
- [`.normalize("NFKD")`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize)
20
- (when supported).
21
- */
22
- constructor(text, query, from = 0, to = text.length, normalize, test) {
23
- this.test = test;
24
- /**
25
- The current match (only holds a meaningful value after
26
- [`next`](https://codemirror.net/6/docs/ref/#search.SearchCursor.next) has been called and when
27
- `done` is false).
28
-
29
- The `precise` flag will be set to false if the match starts or
30
- ends _inside_ a character that, when normalized, expands to
31
- multiple characters. It indicates that the `from`-`to` range
32
- covers content that isn't part of the actual match.
33
- */
34
- this.value = {
35
- from: 0,
36
- to: 0,
37
- precise: false
38
- };
39
- /**
40
- Whether the end of the iterated region has been reached.
41
- */
42
- this.done = false;
43
- this.matches = [];
44
- this.buffer = "";
45
- this.bufferPos = 0;
46
- this.iter = text.iterRange(from, to);
47
- this.bufferStart = from;
48
- this.normalize = normalize ? (x) => normalize(basicNormalize(x)) : basicNormalize;
49
- this.query = this.normalize(query);
50
- }
51
- peek() {
52
- if (this.bufferPos == this.buffer.length) {
53
- this.bufferStart += this.buffer.length;
54
- this.iter.next();
55
- if (this.iter.done) return -1;
56
- this.bufferPos = 0;
57
- this.buffer = this.iter.value;
58
- }
59
- return codePointAt(this.buffer, this.bufferPos);
60
- }
61
- /**
62
- Look for the next match. Updates the iterator's
63
- [`value`](https://codemirror.net/6/docs/ref/#search.SearchCursor.value) and
64
- [`done`](https://codemirror.net/6/docs/ref/#search.SearchCursor.done) properties. Should be called
65
- at least once before using the cursor.
66
- */
67
- next() {
68
- while (this.matches.length) this.matches.pop();
69
- return this.nextOverlapping();
70
- }
71
- /**
72
- The `next` method will ignore matches that partially overlap a
73
- previous match. This method behaves like `next`, but includes
74
- such matches.
75
- */
76
- nextOverlapping() {
77
- for (;;) {
78
- let next = this.peek();
79
- if (next < 0) {
80
- this.done = true;
81
- return this;
82
- }
83
- let str = fromCodePoint(next), start = this.bufferStart + this.bufferPos;
84
- this.bufferPos += codePointSize(next);
85
- let norm = this.normalize(str);
86
- if (norm.length) for (let i = 0, pos = start, posPrecise = true;; i++) {
87
- let code = norm.charCodeAt(i);
88
- let match = this.match(code, pos, posPrecise, this.bufferPos + this.bufferStart, i == norm.length - 1);
89
- if (match) {
90
- this.value = match;
91
- return this;
92
- }
93
- if (i == norm.length - 1) break;
94
- if (posPrecise && i < str.length && str.charCodeAt(i) == code) pos++;
95
- else posPrecise = false;
96
- }
97
- }
98
- }
99
- match(code, pos, posPrecise, end, endPrecise) {
100
- let match = null;
101
- for (let i = 0; i < this.matches.length;) {
102
- let partial = this.matches[i], keep = false;
103
- if (this.query.charCodeAt(partial.index) == code) if (partial.index == this.query.length - 1) match = {
104
- from: partial.from,
105
- to: end,
106
- precise: endPrecise && partial.precise
107
- };
108
- else {
109
- partial.index++;
110
- keep = true;
111
- }
112
- if (keep) i++;
113
- else this.matches.splice(i, 1);
114
- }
115
- if (this.query.charCodeAt(0) == code) if (this.query.length == 1) match = {
116
- from: pos,
117
- to: end,
118
- precise: posPrecise && endPrecise
119
- };
120
- else this.matches.push({
121
- from: pos,
122
- index: 1,
123
- precise: posPrecise
124
- });
125
- if (match && this.test && !this.test(match.from, match.to, this.buffer, this.bufferStart)) match = null;
126
- return match;
127
- }
128
- };
129
- if (typeof Symbol != "undefined") SearchCursor.prototype[Symbol.iterator] = function() {
130
- return this;
131
- };
132
- var empty = {
133
- from: -1,
134
- to: -1,
135
- match: /*@__PURE__*/ /.*/.exec(""),
136
- precise: true
137
- };
138
- var baseFlags = "gm" + (/x/.unicode == null ? "" : "u");
139
- /**
140
- This class is similar to [`SearchCursor`](https://codemirror.net/6/docs/ref/#search.SearchCursor)
141
- but searches for a regular expression pattern instead of a plain
142
- string.
143
- */
144
- var RegExpCursor = class {
145
- /**
146
- Create a cursor that will search the given range in the given
147
- document. `query` should be the raw pattern (as you'd pass it to
148
- `new RegExp`).
149
- */
150
- constructor(text, query, options, from = 0, to = text.length) {
151
- this.text = text;
152
- this.to = to;
153
- this.curLine = "";
154
- /**
155
- Set to `true` when the cursor has reached the end of the search
156
- range.
157
- */
158
- this.done = false;
159
- /**
160
- Will contain an object with the extent of the match and the
161
- match object when [`next`](https://codemirror.net/6/docs/ref/#search.RegExpCursor.next)
162
- sucessfully finds a match. The `precise` flag is always true for
163
- this type of cursor, and only there to make sure this cursor is
164
- a subtype of `SearchCursor`.
165
- */
166
- this.value = empty;
167
- if (/\\[sWDnr]|\n|\r|\[\^/.test(query)) return new MultilineRegExpCursor(text, query, options, from, to);
168
- this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
169
- this.test = options === null || options === void 0 ? void 0 : options.test;
170
- this.iter = text.iter();
171
- let startLine = text.lineAt(from);
172
- this.curLineStart = startLine.from;
173
- this.matchPos = toCharEnd(text, from);
174
- this.getLine(this.curLineStart);
175
- }
176
- getLine(skip) {
177
- this.iter.next(skip);
178
- if (this.iter.lineBreak) this.curLine = "";
179
- else {
180
- this.curLine = this.iter.value;
181
- if (this.curLineStart + this.curLine.length > this.to) this.curLine = this.curLine.slice(0, this.to - this.curLineStart);
182
- this.iter.next();
183
- }
184
- }
185
- nextLine() {
186
- this.curLineStart = this.curLineStart + this.curLine.length + 1;
187
- if (this.curLineStart > this.to) this.curLine = "";
188
- else this.getLine(0);
189
- }
190
- /**
191
- Move to the next match, if there is one.
192
- */
193
- next() {
194
- for (let off = this.matchPos - this.curLineStart;;) {
195
- this.re.lastIndex = off;
196
- let match = this.matchPos <= this.to && this.re.exec(this.curLine);
197
- if (match) {
198
- let from = this.curLineStart + match.index, to = from + match[0].length;
199
- this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0));
200
- if (from == this.curLineStart + this.curLine.length) this.nextLine();
201
- if ((from < to || from > this.value.to) && (!this.test || this.test(from, to, match))) {
202
- this.value = {
203
- from,
204
- to,
205
- precise: true,
206
- match
207
- };
208
- return this;
209
- }
210
- off = this.matchPos - this.curLineStart;
211
- } else if (this.curLineStart + this.curLine.length < this.to) {
212
- this.nextLine();
213
- off = 0;
214
- } else {
215
- this.done = true;
216
- return this;
217
- }
218
- }
219
- }
220
- };
221
- var flattened = /*@__PURE__*/ new WeakMap();
222
- var FlattenedDoc = class FlattenedDoc {
223
- constructor(from, text) {
224
- this.from = from;
225
- this.text = text;
226
- }
227
- get to() {
228
- return this.from + this.text.length;
229
- }
230
- static get(doc, from, to) {
231
- let cached = flattened.get(doc);
232
- if (!cached || cached.from >= to || cached.to <= from) {
233
- let flat = new FlattenedDoc(from, doc.sliceString(from, to));
234
- flattened.set(doc, flat);
235
- return flat;
236
- }
237
- if (cached.from == from && cached.to == to) return cached;
238
- let { text, from: cachedFrom } = cached;
239
- if (cachedFrom > from) {
240
- text = doc.sliceString(from, cachedFrom) + text;
241
- cachedFrom = from;
242
- }
243
- if (cached.to < to) text += doc.sliceString(cached.to, to);
244
- flattened.set(doc, new FlattenedDoc(cachedFrom, text));
245
- return new FlattenedDoc(from, text.slice(from - cachedFrom, to - cachedFrom));
246
- }
247
- };
248
- var MultilineRegExpCursor = class {
249
- constructor(text, query, options, from, to) {
250
- this.text = text;
251
- this.to = to;
252
- this.done = false;
253
- this.value = empty;
254
- this.matchPos = toCharEnd(text, from);
255
- this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
256
- this.test = options === null || options === void 0 ? void 0 : options.test;
257
- this.flat = FlattenedDoc.get(text, from, this.chunkEnd(from + 5e3));
258
- }
259
- chunkEnd(pos) {
260
- return pos >= this.to ? this.to : this.text.lineAt(pos).to;
261
- }
262
- next() {
263
- for (;;) {
264
- let off = this.re.lastIndex = this.matchPos - this.flat.from;
265
- let match = this.re.exec(this.flat.text);
266
- if (match && !match[0] && match.index == off) {
267
- this.re.lastIndex = off + 1;
268
- match = this.re.exec(this.flat.text);
269
- }
270
- if (match) {
271
- let from = this.flat.from + match.index, to = from + match[0].length;
272
- if ((this.flat.to >= this.to || match.index + match[0].length <= this.flat.text.length - 10) && (!this.test || this.test(from, to, match))) {
273
- this.value = {
274
- from,
275
- to,
276
- precise: true,
277
- match
278
- };
279
- this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0));
280
- return this;
281
- }
282
- }
283
- if (this.flat.to == this.to) {
284
- this.done = true;
285
- return this;
286
- }
287
- this.flat = FlattenedDoc.get(this.text, this.flat.from, this.chunkEnd(this.flat.from + this.flat.text.length * 2));
288
- }
289
- }
290
- };
291
- if (typeof Symbol != "undefined") RegExpCursor.prototype[Symbol.iterator] = MultilineRegExpCursor.prototype[Symbol.iterator] = function() {
292
- return this;
293
- };
294
- function validRegExp(source) {
295
- try {
296
- new RegExp(source, baseFlags);
297
- return true;
298
- } catch (_a) {
299
- return false;
300
- }
301
- }
302
- function toCharEnd(text, pos) {
303
- if (pos >= text.length) return pos;
304
- let line = text.lineAt(pos), next;
305
- while (pos < line.to && (next = line.text.charCodeAt(pos - line.from)) >= 56320 && next < 57344) pos++;
306
- return pos;
307
- }
308
- /**
309
- Command that shows a dialog asking the user for a line number, and
310
- when a valid position is provided, moves the cursor to that line.
311
-
312
- Supports line numbers, relative line offsets prefixed with `+` or
313
- `-`, document percentages suffixed with `%`, and an optional
314
- column position by adding `:` and a second number after the line
315
- number.
316
- */
317
- var gotoLine = (view) => {
318
- let { state } = view;
319
- let line = String(state.doc.lineAt(view.state.selection.main.head).number);
320
- let { close, result } = showDialog(view, {
321
- label: state.phrase("Go to line"),
322
- input: {
323
- type: "text",
324
- name: "line",
325
- value: line
326
- },
327
- focus: true,
328
- submitLabel: state.phrase("go")
329
- });
330
- result.then((form) => {
331
- let match = form && /^([+-])?(\d+)?(:\d+)?(%)?$/.exec(form.elements["line"].value);
332
- if (!match) {
333
- view.dispatch({ effects: close });
334
- return;
335
- }
336
- let startLine = state.doc.lineAt(state.selection.main.head);
337
- let [, sign, ln, cl, percent] = match;
338
- let col = cl ? +cl.slice(1) : 0;
339
- let line = ln ? +ln : startLine.number;
340
- if (ln && percent) {
341
- let pc = line / 100;
342
- if (sign) pc = pc * (sign == "-" ? -1 : 1) + startLine.number / state.doc.lines;
343
- line = Math.round(state.doc.lines * pc);
344
- } else if (ln && sign) line = line * (sign == "-" ? -1 : 1) + startLine.number;
345
- let docLine = state.doc.line(Math.max(1, Math.min(state.doc.lines, line)));
346
- let selection = EditorSelection.cursor(docLine.from + Math.max(0, Math.min(col, docLine.length)));
347
- view.dispatch({
348
- effects: [close, EditorView.scrollIntoView(selection.from, { y: "center" })],
349
- selection
350
- });
351
- });
352
- return true;
353
- };
354
- var defaultHighlightOptions = {
355
- highlightWordAroundCursor: false,
356
- minSelectionLength: 1,
357
- maxMatches: 100,
358
- wholeWords: false
359
- };
360
- var highlightConfig = /*@__PURE__*/ Facet.define({ combine(options) {
361
- return combineConfig(options, defaultHighlightOptions, {
362
- highlightWordAroundCursor: (a, b) => a || b,
363
- minSelectionLength: Math.min,
364
- maxMatches: Math.min
365
- });
366
- } });
367
- /**
368
- This extension highlights text that matches the selection. It uses
369
- the `"cm-selectionMatch"` class for the highlighting. When
370
- `highlightWordAroundCursor` is enabled, the word at the cursor
371
- itself will be highlighted with `"cm-selectionMatch-main"`.
372
- */
373
- function highlightSelectionMatches(options) {
374
- let ext = [defaultTheme, matchHighlighter];
375
- if (options) ext.push(highlightConfig.of(options));
376
- return ext;
377
- }
378
- var matchDeco = /*@__PURE__*/ Decoration.mark({ class: "cm-selectionMatch" });
379
- var mainMatchDeco = /*@__PURE__*/ Decoration.mark({ class: "cm-selectionMatch cm-selectionMatch-main" });
380
- function insideWordBoundaries(check, state, from, to) {
381
- return (from == 0 || check(state.sliceDoc(from - 1, from)) != CharCategory.Word) && (to == state.doc.length || check(state.sliceDoc(to, to + 1)) != CharCategory.Word);
382
- }
383
- function insideWord(check, state, from, to) {
384
- return check(state.sliceDoc(from, from + 1)) == CharCategory.Word && check(state.sliceDoc(to - 1, to)) == CharCategory.Word;
385
- }
386
- var matchHighlighter = /*@__PURE__*/ ViewPlugin.fromClass(class {
387
- constructor(view) {
388
- this.decorations = this.getDeco(view);
389
- }
390
- update(update) {
391
- if (update.selectionSet || update.docChanged || update.viewportChanged) this.decorations = this.getDeco(update.view);
392
- }
393
- getDeco(view) {
394
- let conf = view.state.facet(highlightConfig);
395
- let { state } = view, sel = state.selection;
396
- if (sel.ranges.length > 1) return Decoration.none;
397
- let range = sel.main, query, check = null;
398
- if (range.empty) {
399
- if (!conf.highlightWordAroundCursor) return Decoration.none;
400
- let word = state.wordAt(range.head);
401
- if (!word) return Decoration.none;
402
- check = state.charCategorizer(range.head);
403
- query = state.sliceDoc(word.from, word.to);
404
- } else {
405
- let len = range.to - range.from;
406
- if (len < conf.minSelectionLength || len > 200) return Decoration.none;
407
- if (conf.wholeWords) {
408
- query = state.sliceDoc(range.from, range.to);
409
- check = state.charCategorizer(range.head);
410
- if (!(insideWordBoundaries(check, state, range.from, range.to) && insideWord(check, state, range.from, range.to))) return Decoration.none;
411
- } else {
412
- query = state.sliceDoc(range.from, range.to);
413
- if (!query) return Decoration.none;
414
- }
415
- }
416
- let deco = [];
417
- for (let part of view.visibleRanges) {
418
- let cursor = new SearchCursor(state.doc, query, part.from, part.to);
419
- while (!cursor.next().done) {
420
- let { from, to } = cursor.value;
421
- if (!check || insideWordBoundaries(check, state, from, to)) {
422
- if (range.empty && from <= range.from && to >= range.to) deco.push(mainMatchDeco.range(from, to));
423
- else if (from >= range.to || to <= range.from) deco.push(matchDeco.range(from, to));
424
- if (deco.length > conf.maxMatches) return Decoration.none;
425
- }
426
- }
427
- }
428
- return Decoration.set(deco);
429
- }
430
- }, { decorations: (v) => v.decorations });
431
- var defaultTheme = /*@__PURE__*/ EditorView.baseTheme({
432
- ".cm-selectionMatch": { backgroundColor: "#99ff7780" },
433
- ".cm-searchMatch .cm-selectionMatch": { backgroundColor: "transparent" }
434
- });
435
- var selectWord = ({ state, dispatch }) => {
436
- let { selection } = state;
437
- let newSel = EditorSelection.create(selection.ranges.map((range) => state.wordAt(range.head) || EditorSelection.cursor(range.head)), selection.mainIndex);
438
- if (newSel.eq(selection)) return false;
439
- dispatch(state.update({ selection: newSel }));
440
- return true;
441
- };
442
- function findNextOccurrence(state, query) {
443
- let { main, ranges } = state.selection;
444
- let word = state.wordAt(main.head), fullWord = word && word.from == main.from && word.to == main.to;
445
- for (let cycled = false, cursor = new SearchCursor(state.doc, query, ranges[ranges.length - 1].to);;) {
446
- cursor.next();
447
- if (cursor.done) {
448
- if (cycled) return null;
449
- cursor = new SearchCursor(state.doc, query, 0, Math.max(0, ranges[ranges.length - 1].from - 1));
450
- cycled = true;
451
- } else {
452
- if (cycled && ranges.some((r) => r.from == cursor.value.from)) continue;
453
- if (fullWord) {
454
- let word = state.wordAt(cursor.value.from);
455
- if (!word || word.from != cursor.value.from || word.to != cursor.value.to) continue;
456
- }
457
- return cursor.value;
458
- }
459
- }
460
- }
461
- /**
462
- Select next occurrence of the current selection. Expand selection
463
- to the surrounding word when the selection is empty.
464
- */
465
- var selectNextOccurrence = ({ state, dispatch }) => {
466
- let { ranges } = state.selection;
467
- if (ranges.some((sel) => sel.from === sel.to)) return selectWord({
468
- state,
469
- dispatch
470
- });
471
- let searchedText = state.sliceDoc(ranges[0].from, ranges[0].to);
472
- if (state.selection.ranges.some((r) => state.sliceDoc(r.from, r.to) != searchedText)) return false;
473
- let range = findNextOccurrence(state, searchedText);
474
- if (!range) return false;
475
- dispatch(state.update({
476
- selection: state.selection.addRange(EditorSelection.range(range.from, range.to), false),
477
- effects: EditorView.scrollIntoView(range.to)
478
- }));
479
- return true;
480
- };
481
- var searchConfigFacet = /*@__PURE__*/ Facet.define({ combine(configs) {
482
- return combineConfig(configs, {
483
- top: false,
484
- caseSensitive: false,
485
- literal: false,
486
- regexp: false,
487
- wholeWord: false,
488
- createPanel: (view) => new SearchPanel(view),
489
- scrollToMatch: (range) => EditorView.scrollIntoView(range)
490
- });
491
- } });
492
- /**
493
- A search query. Part of the editor's search state.
494
- */
495
- var SearchQuery = class {
496
- /**
497
- Create a query object.
498
- */
499
- constructor(config) {
500
- this.search = config.search;
501
- this.caseSensitive = !!config.caseSensitive;
502
- this.literal = !!config.literal;
503
- this.regexp = !!config.regexp;
504
- this.replace = config.replace || "";
505
- this.valid = !!this.search && (!this.regexp || validRegExp(this.search));
506
- this.unquoted = this.unquote(this.search);
507
- this.wholeWord = !!config.wholeWord;
508
- this.test = config.test;
509
- }
510
- /**
511
- @internal
512
- */
513
- unquote(text) {
514
- return this.literal ? text : text.replace(/\\([nrt\\])/g, (_, ch) => ch == "n" ? "\n" : ch == "r" ? "\r" : ch == "t" ? " " : "\\");
515
- }
516
- /**
517
- Compare this query to another query.
518
- */
519
- eq(other) {
520
- 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;
521
- }
522
- /**
523
- @internal
524
- */
525
- create() {
526
- return this.regexp ? new RegExpQuery(this) : new StringQuery(this);
527
- }
528
- /**
529
- Get a search cursor for this query, searching through the given
530
- range in the given state.
531
- */
532
- getCursor(state, from = 0, to) {
533
- let st = state.doc ? state : EditorState.create({ doc: state });
534
- if (to == null) to = st.doc.length;
535
- return this.regexp ? regexpCursor(this, st, from, to) : stringCursor(this, st, from, to);
536
- }
537
- };
538
- var QueryType = class {
539
- constructor(spec) {
540
- this.spec = spec;
541
- }
542
- };
543
- function wrapStringTest(test, state, inner) {
544
- return (from, to, buffer, bufferPos) => {
545
- if (inner && !inner(from, to, buffer, bufferPos)) return false;
546
- return test(from >= bufferPos && to <= bufferPos + buffer.length ? buffer.slice(from - bufferPos, to - bufferPos) : state.doc.sliceString(from, to), state, from, to);
547
- };
548
- }
549
- function stringCursor(spec, state, from, to) {
550
- let test;
551
- if (spec.wholeWord) test = stringWordTest(state.doc, state.charCategorizer(state.selection.main.head));
552
- if (spec.test) test = wrapStringTest(spec.test, state, test);
553
- return new SearchCursor(state.doc, spec.unquoted, from, to, spec.caseSensitive ? void 0 : (x) => x.toLowerCase(), test);
554
- }
555
- function stringWordTest(doc, categorizer) {
556
- return (from, to, buf, bufPos) => {
557
- if (bufPos > from || bufPos + buf.length < to) {
558
- bufPos = Math.max(0, from - 2);
559
- buf = doc.sliceString(bufPos, Math.min(doc.length, to + 2));
560
- }
561
- 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);
562
- };
563
- }
564
- var StringQuery = class extends QueryType {
565
- constructor(spec) {
566
- super(spec);
567
- }
568
- nextMatch(state, curFrom, curTo) {
569
- let cursor = stringCursor(this.spec, state, curTo, state.doc.length).nextOverlapping();
570
- if (cursor.done) {
571
- let end = Math.min(state.doc.length, curFrom + this.spec.unquoted.length);
572
- cursor = stringCursor(this.spec, state, 0, end).nextOverlapping();
573
- }
574
- return cursor.done || cursor.value.from == curFrom && cursor.value.to == curTo ? null : cursor.value;
575
- }
576
- prevMatchInRange(state, from, to) {
577
- for (let pos = to;;) {
578
- let start = Math.max(from, pos - 1e4 - this.spec.unquoted.length);
579
- let cursor = stringCursor(this.spec, state, start, pos), range = null;
580
- while (!cursor.nextOverlapping().done) range = cursor.value;
581
- if (range) return range;
582
- if (start == from) return null;
583
- pos -= 1e4;
584
- }
585
- }
586
- prevMatch(state, curFrom, curTo) {
587
- let found = this.prevMatchInRange(state, 0, curFrom);
588
- if (!found) found = this.prevMatchInRange(state, Math.max(0, curTo - this.spec.unquoted.length), state.doc.length);
589
- return found && (found.from != curFrom || found.to != curTo) ? found : null;
590
- }
591
- getReplacement(_result) {
592
- return this.spec.unquote(this.spec.replace);
593
- }
594
- matchAll(state, limit) {
595
- let cursor = stringCursor(this.spec, state, 0, state.doc.length), ranges = [];
596
- while (!cursor.next().done) {
597
- if (ranges.length >= limit) return null;
598
- ranges.push(cursor.value);
599
- }
600
- return ranges;
601
- }
602
- highlight(state, from, to, add) {
603
- let cursor = stringCursor(this.spec, state, Math.max(0, from - this.spec.unquoted.length), Math.min(to + this.spec.unquoted.length, state.doc.length));
604
- while (!cursor.next().done) add(cursor.value.from, cursor.value.to);
605
- }
606
- };
607
- function wrapRegexpTest(test, state, inner) {
608
- return (from, to, match) => {
609
- return (!inner || inner(from, to, match)) && test(match[0], state, from, to);
610
- };
611
- }
612
- function regexpCursor(spec, state, from, to) {
613
- let test;
614
- if (spec.wholeWord) test = regexpWordTest(state.charCategorizer(state.selection.main.head));
615
- if (spec.test) test = wrapRegexpTest(spec.test, state, test);
616
- return new RegExpCursor(state.doc, spec.search, {
617
- ignoreCase: !spec.caseSensitive,
618
- test
619
- }, from, to);
620
- }
621
- function charBefore(str, index) {
622
- return str.slice(findClusterBreak(str, index, false), index);
623
- }
624
- function charAfter(str, index) {
625
- return str.slice(index, findClusterBreak(str, index));
626
- }
627
- function regexpWordTest(categorizer) {
628
- 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);
629
- }
630
- var RegExpQuery = class extends QueryType {
631
- nextMatch(state, curFrom, curTo) {
632
- let cursor = regexpCursor(this.spec, state, curTo, state.doc.length).next();
633
- if (cursor.done) cursor = regexpCursor(this.spec, state, 0, curFrom).next();
634
- return cursor.done ? null : cursor.value;
635
- }
636
- prevMatchInRange(state, from, to) {
637
- for (let size = 1;; size++) {
638
- let start = Math.max(from, to - size * 1e4);
639
- let cursor = regexpCursor(this.spec, state, start, to), range = null;
640
- while (!cursor.next().done) range = cursor.value;
641
- if (range && (start == from || range.from > start + 10)) return range;
642
- if (start == from) return null;
643
- }
644
- }
645
- prevMatch(state, curFrom, curTo) {
646
- return this.prevMatchInRange(state, 0, curFrom) || this.prevMatchInRange(state, curTo, state.doc.length);
647
- }
648
- getReplacement(result) {
649
- return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g, (m, i) => {
650
- if (i == "&") return result.match[0];
651
- if (i == "$") return "$";
652
- for (let l = i.length; l > 0; l--) {
653
- let n = +i.slice(0, l);
654
- if (n > 0 && n < result.match.length) return result.match[n] + i.slice(l);
655
- }
656
- return m;
657
- });
658
- }
659
- matchAll(state, limit) {
660
- let cursor = regexpCursor(this.spec, state, 0, state.doc.length), ranges = [];
661
- while (!cursor.next().done) {
662
- if (ranges.length >= limit) return null;
663
- ranges.push(cursor.value);
664
- }
665
- return ranges;
666
- }
667
- highlight(state, from, to, add) {
668
- let cursor = regexpCursor(this.spec, state, Math.max(0, from - 250), Math.min(to + 250, state.doc.length));
669
- while (!cursor.next().done) add(cursor.value.from, cursor.value.to);
670
- }
671
- };
672
- /**
673
- A state effect that updates the current search query. Note that
674
- this only has an effect if the search state has been initialized
675
- (by including [`search`](https://codemirror.net/6/docs/ref/#search.search) in your configuration or
676
- by running [`openSearchPanel`](https://codemirror.net/6/docs/ref/#search.openSearchPanel) at least
677
- once).
678
- */
679
- var setSearchQuery = /*@__PURE__*/ StateEffect.define();
680
- var togglePanel = /*@__PURE__*/ StateEffect.define();
681
- var searchState = /*@__PURE__*/ StateField.define({
682
- create(state) {
683
- return new SearchState(defaultQuery(state).create(), null);
684
- },
685
- update(value, tr) {
686
- for (let effect of tr.effects) if (effect.is(setSearchQuery)) value = new SearchState(effect.value.create(), value.panel);
687
- else if (effect.is(togglePanel)) value = new SearchState(value.query, effect.value ? createSearchPanel : null);
688
- return value;
689
- },
690
- provide: (f) => showPanel.from(f, (val) => val.panel)
691
- });
692
- var SearchState = class {
693
- constructor(query, panel) {
694
- this.query = query;
695
- this.panel = panel;
696
- }
697
- };
698
- var matchMark = /*@__PURE__*/ Decoration.mark({ class: "cm-searchMatch" }), selectedMatchMark = /*@__PURE__*/ Decoration.mark({ class: "cm-searchMatch cm-searchMatch-selected" });
699
- var searchHighlighter = /*@__PURE__*/ ViewPlugin.fromClass(class {
700
- constructor(view) {
701
- this.view = view;
702
- this.decorations = this.highlight(view.state.field(searchState));
703
- }
704
- update(update) {
705
- let state = update.state.field(searchState);
706
- if (state != update.startState.field(searchState) || update.docChanged || update.selectionSet || update.viewportChanged) this.decorations = this.highlight(state);
707
- }
708
- highlight({ query, panel }) {
709
- if (!panel || !query.spec.valid) return Decoration.none;
710
- let { view } = this;
711
- let builder = new RangeSetBuilder();
712
- for (let i = 0, ranges = view.visibleRanges, l = ranges.length; i < l; i++) {
713
- let { from, to } = ranges[i];
714
- while (i < l - 1 && to > ranges[i + 1].from - 500) to = ranges[++i].to;
715
- query.highlight(view.state, from, to, (from, to) => {
716
- let selected = view.state.selection.ranges.some((r) => r.from == from && r.to == to);
717
- builder.add(from, to, selected ? selectedMatchMark : matchMark);
718
- });
719
- }
720
- return builder.finish();
721
- }
722
- }, { decorations: (v) => v.decorations });
723
- function searchCommand(f) {
724
- return (view) => {
725
- let state = view.state.field(searchState, false);
726
- return state && state.query.spec.valid ? f(view, state) : openSearchPanel(view);
727
- };
728
- }
729
- /**
730
- Open the search panel if it isn't already open, and move the
731
- selection to the first match after the current main selection.
732
- Will wrap around to the start of the document when it reaches the
733
- end.
734
- */
735
- var findNext = /*@__PURE__*/ searchCommand((view, { query }) => {
736
- let { to } = view.state.selection.main;
737
- let next = query.nextMatch(view.state, to, to);
738
- if (!next) return false;
739
- let selection = EditorSelection.single(next.from, next.to);
740
- let config = view.state.facet(searchConfigFacet);
741
- view.dispatch({
742
- selection,
743
- effects: [announceMatch(view, next), config.scrollToMatch(selection.main, view)],
744
- userEvent: "select.search"
745
- });
746
- selectSearchInput(view);
747
- return true;
748
- });
749
- /**
750
- Move the selection to the previous instance of the search query,
751
- before the current main selection. Will wrap past the start
752
- of the document to start searching at the end again.
753
- */
754
- var findPrevious = /*@__PURE__*/ searchCommand((view, { query }) => {
755
- let { state } = view, { from } = state.selection.main;
756
- let prev = query.prevMatch(state, from, from);
757
- if (!prev) return false;
758
- let selection = EditorSelection.single(prev.from, prev.to);
759
- let config = view.state.facet(searchConfigFacet);
760
- view.dispatch({
761
- selection,
762
- effects: [announceMatch(view, prev), config.scrollToMatch(selection.main, view)],
763
- userEvent: "select.search"
764
- });
765
- selectSearchInput(view);
766
- return true;
767
- });
768
- /**
769
- Select all instances of the search query.
770
- */
771
- var selectMatches = /*@__PURE__*/ searchCommand((view, { query }) => {
772
- let ranges = query.matchAll(view.state, 1e3);
773
- if (!ranges || !ranges.length) return false;
774
- view.dispatch({
775
- selection: EditorSelection.create(ranges.map((r) => EditorSelection.range(r.from, r.to))),
776
- userEvent: "select.search.matches"
777
- });
778
- return true;
779
- });
780
- /**
781
- Select all instances of the currently selected text.
782
- */
783
- var selectSelectionMatches = ({ state, dispatch }) => {
784
- let sel = state.selection;
785
- if (sel.ranges.length > 1 || sel.main.empty) return false;
786
- let { from, to } = sel.main;
787
- let ranges = [], main = 0;
788
- for (let cur = new SearchCursor(state.doc, state.sliceDoc(from, to)); !cur.next().done;) {
789
- if (ranges.length > 1e3) return false;
790
- if (cur.value.from == from) main = ranges.length;
791
- ranges.push(EditorSelection.range(cur.value.from, cur.value.to));
792
- }
793
- dispatch(state.update({
794
- selection: EditorSelection.create(ranges, main),
795
- userEvent: "select.search.matches"
796
- }));
797
- return true;
798
- };
799
- /**
800
- Replace the current match of the search query.
801
- */
802
- var replaceNext = /*@__PURE__*/ searchCommand((view, { query }) => {
803
- let { state } = view, { from, to } = state.selection.main;
804
- if (state.readOnly) return false;
805
- let match = query.nextMatch(state, from, from);
806
- if (!match) return false;
807
- let next = match;
808
- let changes = [], selection, replacement;
809
- let effects = [];
810
- if (!next.precise) next = query.nextMatch(state, next.from, next.to);
811
- else if (next.from == from && next.to == to) {
812
- replacement = state.toText(query.getReplacement(next));
813
- changes.push({
814
- from: next.from,
815
- to: next.to,
816
- insert: replacement
817
- });
818
- next = query.nextMatch(state, next.from, next.to);
819
- effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
820
- }
821
- let changeSet = view.state.changes(changes);
822
- if (next) {
823
- selection = EditorSelection.single(next.from, next.to).map(changeSet);
824
- effects.push(announceMatch(view, next));
825
- effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main, view));
826
- }
827
- view.dispatch({
828
- changes: changeSet,
829
- selection,
830
- effects,
831
- userEvent: "input.replace"
832
- });
833
- return true;
834
- });
835
- /**
836
- Replace all instances of the search query with the given
837
- replacement.
838
- */
839
- var replaceAll = /*@__PURE__*/ searchCommand((view, { query }) => {
840
- if (view.state.readOnly) return false;
841
- let changes = [];
842
- for (let match of query.matchAll(view.state, 1e9)) {
843
- let { from, to, precise } = match;
844
- if (precise) changes.push({
845
- from,
846
- to,
847
- insert: query.getReplacement(match)
848
- });
849
- }
850
- if (!changes.length) return false;
851
- let announceText = view.state.phrase("replaced $ matches", changes.length) + ".";
852
- view.dispatch({
853
- changes,
854
- effects: EditorView.announce.of(announceText),
855
- userEvent: "input.replace.all"
856
- });
857
- return true;
858
- });
859
- function createSearchPanel(view) {
860
- return view.state.facet(searchConfigFacet).createPanel(view);
861
- }
862
- function defaultQuery(state, fallback) {
863
- var _a, _b, _c, _d, _e;
864
- let sel = state.selection.main;
865
- let selText = sel.empty || sel.to > sel.from + 100 ? "" : state.sliceDoc(sel.from, sel.to);
866
- if (fallback && !selText) return fallback;
867
- let config = state.facet(searchConfigFacet);
868
- return new SearchQuery({
869
- search: ((_a = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _a !== void 0 ? _a : config.literal) ? selText : selText.replace(/\n/g, "\\n"),
870
- caseSensitive: (_b = fallback === null || fallback === void 0 ? void 0 : fallback.caseSensitive) !== null && _b !== void 0 ? _b : config.caseSensitive,
871
- literal: (_c = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _c !== void 0 ? _c : config.literal,
872
- regexp: (_d = fallback === null || fallback === void 0 ? void 0 : fallback.regexp) !== null && _d !== void 0 ? _d : config.regexp,
873
- wholeWord: (_e = fallback === null || fallback === void 0 ? void 0 : fallback.wholeWord) !== null && _e !== void 0 ? _e : config.wholeWord
874
- });
875
- }
876
- function getSearchInput(view) {
877
- let panel = getPanel(view, createSearchPanel);
878
- return panel && panel.dom.querySelector("[main-field]");
879
- }
880
- function selectSearchInput(view) {
881
- let input = getSearchInput(view);
882
- if (input && input == view.root.activeElement) input.select();
883
- }
884
- /**
885
- Make sure the search panel is open and focused.
886
- */
887
- var openSearchPanel = (view) => {
888
- let state = view.state.field(searchState, false);
889
- if (state && state.panel) {
890
- let searchInput = getSearchInput(view);
891
- if (searchInput && searchInput != view.root.activeElement) {
892
- let query = defaultQuery(view.state, state.query.spec);
893
- if (query.valid) view.dispatch({ effects: setSearchQuery.of(query) });
894
- searchInput.focus();
895
- searchInput.select();
896
- }
897
- } else view.dispatch({ effects: [togglePanel.of(true), state ? setSearchQuery.of(defaultQuery(view.state, state.query.spec)) : StateEffect.appendConfig.of(searchExtensions)] });
898
- return true;
899
- };
900
- /**
901
- Close the search panel.
902
- */
903
- var closeSearchPanel = (view) => {
904
- let state = view.state.field(searchState, false);
905
- if (!state || !state.panel) return false;
906
- let panel = getPanel(view, createSearchPanel);
907
- if (panel && panel.dom.contains(view.root.activeElement)) view.focus();
908
- view.dispatch({ effects: togglePanel.of(false) });
909
- return true;
910
- };
911
- /**
912
- Default search-related key bindings.
913
-
914
- - Mod-f: [`openSearchPanel`](https://codemirror.net/6/docs/ref/#search.openSearchPanel)
915
- - F3, Mod-g: [`findNext`](https://codemirror.net/6/docs/ref/#search.findNext)
916
- - Shift-F3, Shift-Mod-g: [`findPrevious`](https://codemirror.net/6/docs/ref/#search.findPrevious)
917
- - Mod-Alt-g: [`gotoLine`](https://codemirror.net/6/docs/ref/#search.gotoLine)
918
- - Mod-d: [`selectNextOccurrence`](https://codemirror.net/6/docs/ref/#search.selectNextOccurrence)
919
- */
920
- var searchKeymap = [
921
- {
922
- key: "Mod-f",
923
- run: openSearchPanel,
924
- scope: "editor search-panel"
925
- },
926
- {
927
- key: "F3",
928
- run: findNext,
929
- shift: findPrevious,
930
- scope: "editor search-panel",
931
- preventDefault: true
932
- },
933
- {
934
- key: "Mod-g",
935
- run: findNext,
936
- shift: findPrevious,
937
- scope: "editor search-panel",
938
- preventDefault: true
939
- },
940
- {
941
- key: "Escape",
942
- run: closeSearchPanel,
943
- scope: "editor search-panel"
944
- },
945
- {
946
- key: "Mod-Shift-l",
947
- run: selectSelectionMatches
948
- },
949
- {
950
- key: "Mod-Alt-g",
951
- run: gotoLine
952
- },
953
- {
954
- key: "Mod-d",
955
- run: selectNextOccurrence,
956
- preventDefault: true
957
- }
958
- ];
959
- var SearchPanel = class {
960
- constructor(view) {
961
- this.view = view;
962
- let query = this.query = view.state.field(searchState).query.spec;
963
- this.commit = this.commit.bind(this);
964
- this.searchField = crelt("input", {
965
- value: query.search,
966
- placeholder: phrase(view, "Find"),
967
- "aria-label": phrase(view, "Find"),
968
- class: "cm-textfield",
969
- name: "search",
970
- form: "",
971
- "main-field": "true",
972
- onchange: this.commit,
973
- onkeyup: this.commit
974
- });
975
- this.replaceField = crelt("input", {
976
- value: query.replace,
977
- placeholder: phrase(view, "Replace"),
978
- "aria-label": phrase(view, "Replace"),
979
- class: "cm-textfield",
980
- name: "replace",
981
- form: "",
982
- onchange: this.commit,
983
- onkeyup: this.commit
984
- });
985
- this.caseField = crelt("input", {
986
- type: "checkbox",
987
- name: "case",
988
- form: "",
989
- checked: query.caseSensitive,
990
- onchange: this.commit
991
- });
992
- this.reField = crelt("input", {
993
- type: "checkbox",
994
- name: "re",
995
- form: "",
996
- checked: query.regexp,
997
- onchange: this.commit
998
- });
999
- this.wordField = crelt("input", {
1000
- type: "checkbox",
1001
- name: "word",
1002
- form: "",
1003
- checked: query.wholeWord,
1004
- onchange: this.commit
1005
- });
1006
- function button(name, onclick, content) {
1007
- return crelt("button", {
1008
- class: "cm-button",
1009
- name,
1010
- onclick,
1011
- type: "button"
1012
- }, content);
1013
- }
1014
- this.dom = crelt("div", {
1015
- onkeydown: (e) => this.keydown(e),
1016
- class: "cm-search"
1017
- }, [
1018
- this.searchField,
1019
- button("next", () => findNext(view), [phrase(view, "next")]),
1020
- button("prev", () => findPrevious(view), [phrase(view, "previous")]),
1021
- button("select", () => selectMatches(view), [phrase(view, "all")]),
1022
- crelt("label", null, [this.caseField, phrase(view, "match case")]),
1023
- crelt("label", null, [this.reField, phrase(view, "regexp")]),
1024
- crelt("label", null, [this.wordField, phrase(view, "by word")]),
1025
- ...view.state.readOnly ? [] : [
1026
- crelt("br"),
1027
- this.replaceField,
1028
- button("replace", () => replaceNext(view), [phrase(view, "replace")]),
1029
- button("replaceAll", () => replaceAll(view), [phrase(view, "replace all")])
1030
- ],
1031
- crelt("button", {
1032
- name: "close",
1033
- onclick: () => closeSearchPanel(view),
1034
- "aria-label": phrase(view, "close"),
1035
- type: "button"
1036
- }, ["×"])
1037
- ]);
1038
- }
1039
- commit() {
1040
- let query = new SearchQuery({
1041
- search: this.searchField.value,
1042
- caseSensitive: this.caseField.checked,
1043
- regexp: this.reField.checked,
1044
- wholeWord: this.wordField.checked,
1045
- replace: this.replaceField.value
1046
- });
1047
- if (!query.eq(this.query)) {
1048
- this.query = query;
1049
- this.view.dispatch({ effects: setSearchQuery.of(query) });
1050
- }
1051
- }
1052
- keydown(e) {
1053
- if (runScopeHandlers(this.view, e, "search-panel")) e.preventDefault();
1054
- else if (e.keyCode == 13 && e.target == this.searchField) {
1055
- e.preventDefault();
1056
- (e.shiftKey ? findPrevious : findNext)(this.view);
1057
- } else if (e.keyCode == 13 && e.target == this.replaceField) {
1058
- e.preventDefault();
1059
- replaceNext(this.view);
1060
- }
1061
- }
1062
- update(update) {
1063
- for (let tr of update.transactions) for (let effect of tr.effects) if (effect.is(setSearchQuery) && !effect.value.eq(this.query)) this.setQuery(effect.value);
1064
- }
1065
- setQuery(query) {
1066
- this.query = query;
1067
- this.searchField.value = query.search;
1068
- this.replaceField.value = query.replace;
1069
- this.caseField.checked = query.caseSensitive;
1070
- this.reField.checked = query.regexp;
1071
- this.wordField.checked = query.wholeWord;
1072
- }
1073
- mount() {
1074
- this.searchField.select();
1075
- }
1076
- get pos() {
1077
- return 80;
1078
- }
1079
- get top() {
1080
- return this.view.state.facet(searchConfigFacet).top;
1081
- }
1082
- };
1083
- function phrase(view, phrase) {
1084
- return view.state.phrase(phrase);
1085
- }
1086
- var AnnounceMargin = 30;
1087
- var Break = /[\s\.,:;?!]/;
1088
- function announceMatch(view, { from, to }) {
1089
- let line = view.state.doc.lineAt(from), lineEnd = view.state.doc.lineAt(to).to;
1090
- let start = Math.max(line.from, from - AnnounceMargin), end = Math.min(lineEnd, to + AnnounceMargin);
1091
- let text = view.state.sliceDoc(start, end);
1092
- if (start != line.from) {
1093
- for (let i = 0; i < AnnounceMargin; i++) if (!Break.test(text[i + 1]) && Break.test(text[i])) {
1094
- text = text.slice(i);
1095
- break;
1096
- }
1097
- }
1098
- if (end != lineEnd) {
1099
- for (let i = text.length - 1; i > text.length - AnnounceMargin; i--) if (!Break.test(text[i - 1]) && Break.test(text[i])) {
1100
- text = text.slice(0, i);
1101
- break;
1102
- }
1103
- }
1104
- return EditorView.announce.of(`${view.state.phrase("current match")}. ${text} ${view.state.phrase("on line")} ${line.number}.`);
1105
- }
1106
- var baseTheme = /*@__PURE__*/ EditorView.baseTheme({
1107
- ".cm-panel.cm-search": {
1108
- padding: "2px 6px 4px",
1109
- position: "relative",
1110
- "& [name=close]": {
1111
- position: "absolute",
1112
- top: "0",
1113
- right: "4px",
1114
- backgroundColor: "inherit",
1115
- border: "none",
1116
- font: "inherit",
1117
- padding: 0,
1118
- margin: 0
1119
- },
1120
- "& input, & button, & label": { margin: ".2em .6em .2em 0" },
1121
- "& input[type=checkbox]": { marginRight: ".2em" },
1122
- "& label": {
1123
- fontSize: "80%",
1124
- whiteSpace: "pre"
1125
- }
1126
- },
1127
- "&light .cm-searchMatch": { backgroundColor: "#ffff0054" },
1128
- "&dark .cm-searchMatch": { backgroundColor: "#00ffff8a" },
1129
- "&light .cm-searchMatch-selected": { backgroundColor: "#ff6a0054" },
1130
- "&dark .cm-searchMatch-selected": { backgroundColor: "#ff00ff8a" }
1131
- });
1132
- var searchExtensions = [
1133
- searchState,
1134
- /*@__PURE__*/ Prec.low(searchHighlighter),
1135
- baseTheme
1136
- ];
1137
- //#endregion
1138
- export { searchKeymap as n, highlightSelectionMatches as t };