repl-sdk 1.0.0 → 1.0.1

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 (272) hide show
  1. package/dist/apl-fqmucPXA.js +141 -0
  2. package/dist/apl-fqmucPXA.js.map +1 -0
  3. package/dist/asciiarmor-DucZyvP0.js +57 -0
  4. package/dist/asciiarmor-DucZyvP0.js.map +1 -0
  5. package/dist/asn1-BnOEsgAm.js +145 -0
  6. package/dist/asn1-BnOEsgAm.js.map +1 -0
  7. package/dist/assets/{tar-worker-kdkltuRC.js → tar-worker-CxTcoQcr.js} +1 -6
  8. package/dist/assets/{tar-worker-kdkltuRC.js.map → tar-worker-CxTcoQcr.js.map} +1 -1
  9. package/dist/asterisk-QAlztEwS.js +346 -0
  10. package/dist/asterisk-QAlztEwS.js.map +1 -0
  11. package/dist/brainfuck-DZVCuF_t.js +54 -0
  12. package/dist/brainfuck-DZVCuF_t.js.map +1 -0
  13. package/dist/clike-CTYGlS6x.js +800 -0
  14. package/dist/clike-CTYGlS6x.js.map +1 -0
  15. package/dist/clojure-BhXMqnxz.js +850 -0
  16. package/dist/clojure-BhXMqnxz.js.map +1 -0
  17. package/dist/cmake-BGaNd9E7.js +72 -0
  18. package/dist/cmake-BGaNd9E7.js.map +1 -0
  19. package/dist/cobol-4yqQntpt.js +121 -0
  20. package/dist/cobol-4yqQntpt.js.map +1 -0
  21. package/dist/codemirror-De3S70Np.js +2912 -0
  22. package/dist/codemirror-De3S70Np.js.map +1 -0
  23. package/dist/coffeescript-D2dXvhEc.js +309 -0
  24. package/dist/coffeescript-D2dXvhEc.js.map +1 -0
  25. package/dist/commonlisp-CF_VNHQR.js +131 -0
  26. package/dist/commonlisp-CF_VNHQR.js.map +1 -0
  27. package/dist/crystal-DyuLTqLs.js +399 -0
  28. package/dist/crystal-DyuLTqLs.js.map +1 -0
  29. package/dist/css-DkSyTW67.js +1773 -0
  30. package/dist/css-DkSyTW67.js.map +1 -0
  31. package/dist/cypher-Dlu_3r4V.js +122 -0
  32. package/dist/cypher-Dlu_3r4V.js.map +1 -0
  33. package/dist/d-UURgV0Ux.js +180 -0
  34. package/dist/d-UURgV0Ux.js.map +1 -0
  35. package/dist/diff-B_Bi2Crb.js +26 -0
  36. package/dist/diff-B_Bi2Crb.js.map +1 -0
  37. package/dist/dockerfile-Bvk733Ga.js +202 -0
  38. package/dist/dockerfile-Bvk733Ga.js.map +1 -0
  39. package/dist/dtd-Dy74G54E.js +115 -0
  40. package/dist/dtd-Dy74G54E.js.map +1 -0
  41. package/dist/dylan-TSb-Nfix.js +315 -0
  42. package/dist/dylan-TSb-Nfix.js.map +1 -0
  43. package/dist/ebnf-4fKAGW3a.js +141 -0
  44. package/dist/ebnf-4fKAGW3a.js.map +1 -0
  45. package/dist/ecl-B59qGGVg.js +179 -0
  46. package/dist/ecl-B59qGGVg.js.map +1 -0
  47. package/dist/eiffel-Dze7nlu3.js +135 -0
  48. package/dist/eiffel-Dze7nlu3.js.map +1 -0
  49. package/dist/elm-DG7jkhNZ.js +177 -0
  50. package/dist/elm-DG7jkhNZ.js.map +1 -0
  51. package/dist/erlang-BO6gOnGA.js +675 -0
  52. package/dist/erlang-BO6gOnGA.js.map +1 -0
  53. package/dist/factor-CMxFHDqz.js +66 -0
  54. package/dist/factor-CMxFHDqz.js.map +1 -0
  55. package/dist/fcl-CDDUNjTj.js +142 -0
  56. package/dist/fcl-CDDUNjTj.js.map +1 -0
  57. package/dist/forth-B9D2JCeE.js +117 -0
  58. package/dist/forth-B9D2JCeE.js.map +1 -0
  59. package/dist/fortran-CAG2BFbe.js +468 -0
  60. package/dist/fortran-CAG2BFbe.js.map +1 -0
  61. package/dist/gas-0Aw8zDr5.js +294 -0
  62. package/dist/gas-0Aw8zDr5.js.map +1 -0
  63. package/dist/gherkin-DhZlEZiy.js +116 -0
  64. package/dist/gherkin-DhZlEZiy.js.map +1 -0
  65. package/dist/{gjs-CzFzkEFv.js → gjs-DfguZDLq.js} +4 -4
  66. package/dist/gjs-DfguZDLq.js.map +1 -0
  67. package/dist/{gmd-D9OXs2v3.js → gmd-Yas-Oo8k.js} +3 -6
  68. package/dist/gmd-Yas-Oo8k.js.map +1 -0
  69. package/dist/groovy-CpwJiBl7.js +224 -0
  70. package/dist/groovy-CpwJiBl7.js.map +1 -0
  71. package/dist/haskell-ySd-OUo8.js +460 -0
  72. package/dist/haskell-ySd-OUo8.js.map +1 -0
  73. package/dist/haxe-7MlzfeYV.js +515 -0
  74. package/dist/haxe-7MlzfeYV.js.map +1 -0
  75. package/dist/{hbs-CuhWjffM.js → hbs-CxcmWxSJ.js} +2 -2
  76. package/dist/{hbs-CuhWjffM.js.map → hbs-CxcmWxSJ.js.map} +1 -1
  77. package/dist/http-BqypyemW.js +80 -0
  78. package/dist/http-BqypyemW.js.map +1 -0
  79. package/dist/idl-4HIGJlDI.js +986 -0
  80. package/dist/idl-4HIGJlDI.js.map +1 -0
  81. package/dist/index-B3Meoznj.js +118 -0
  82. package/dist/index-B3Meoznj.js.map +1 -0
  83. package/dist/index-BQyfDUUx.js +692 -0
  84. package/dist/index-BQyfDUUx.js.map +1 -0
  85. package/dist/index-BRDroAD8.js +305 -0
  86. package/dist/index-BRDroAD8.js.map +1 -0
  87. package/dist/index-BRMAzRyM.js +179 -0
  88. package/dist/index-BRMAzRyM.js.map +1 -0
  89. package/dist/index-Bb8uYQgv.js +927 -0
  90. package/dist/index-Bb8uYQgv.js.map +1 -0
  91. package/dist/index-BlOjO66K.js +17618 -0
  92. package/dist/index-BlOjO66K.js.map +1 -0
  93. package/dist/index-BoGWnSNL.js +706 -0
  94. package/dist/index-BoGWnSNL.js.map +1 -0
  95. package/dist/index-BsRrEiOu.js +98 -0
  96. package/dist/index-BsRrEiOu.js.map +1 -0
  97. package/dist/index-C2sFZMth.js +391 -0
  98. package/dist/index-C2sFZMth.js.map +1 -0
  99. package/dist/index-C7xwOjmS.js +291 -0
  100. package/dist/index-C7xwOjmS.js.map +1 -0
  101. package/dist/index-CA3lFUx6.js +315 -0
  102. package/dist/index-CA3lFUx6.js.map +1 -0
  103. package/dist/index-CB-pPTIf.js +98 -0
  104. package/dist/index-CB-pPTIf.js.map +1 -0
  105. package/dist/index-CCa6x1FE.js +386 -0
  106. package/dist/index-CCa6x1FE.js.map +1 -0
  107. package/dist/index-CD4DINI1.js +158 -0
  108. package/dist/index-CD4DINI1.js.map +1 -0
  109. package/dist/index-CE0B_fcG.js +328 -0
  110. package/dist/index-CE0B_fcG.js.map +1 -0
  111. package/dist/{index-CUWCqMoD.js → index-CVGAEPMV.js} +33 -27
  112. package/dist/index-CVGAEPMV.js.map +1 -0
  113. package/dist/index-CmaT2afn.js +332 -0
  114. package/dist/index-CmaT2afn.js.map +1 -0
  115. package/dist/index-D8sUxXp5.js +83 -0
  116. package/dist/index-D8sUxXp5.js.map +1 -0
  117. package/dist/index-DIz8Vpn-.js +737 -0
  118. package/dist/index-DIz8Vpn-.js.map +1 -0
  119. package/dist/index-DNP1xT-S.js +408 -0
  120. package/dist/index-DNP1xT-S.js.map +1 -0
  121. package/dist/index-DOAqdvnQ.js +862 -0
  122. package/dist/index-DOAqdvnQ.js.map +1 -0
  123. package/dist/index-DVUMFbgi.js +152 -0
  124. package/dist/index-DVUMFbgi.js.map +1 -0
  125. package/dist/index-VeTBKRVd.js +83 -0
  126. package/dist/index-VeTBKRVd.js.map +1 -0
  127. package/dist/index-dXZeR7Bx.js +1767 -0
  128. package/dist/index-dXZeR7Bx.js.map +1 -0
  129. package/dist/index-gtqbIb6T.js +62 -0
  130. package/dist/index-gtqbIb6T.js.map +1 -0
  131. package/dist/index-pN_pUAQ7.js +2426 -0
  132. package/dist/index-pN_pUAQ7.js.map +1 -0
  133. package/dist/index-wasu5VX0.js +1150 -0
  134. package/dist/index-wasu5VX0.js.map +1 -0
  135. package/dist/javascript-Bt8B7yTi.js +993 -0
  136. package/dist/javascript-Bt8B7yTi.js.map +1 -0
  137. package/dist/julia-Bs6JJhYG.js +408 -0
  138. package/dist/julia-Bs6JJhYG.js.map +1 -0
  139. package/dist/livescript-DmzgM3Yt.js +297 -0
  140. package/dist/livescript-DmzgM3Yt.js.map +1 -0
  141. package/dist/lua-8cJgIlqe.js +257 -0
  142. package/dist/lua-8cJgIlqe.js.map +1 -0
  143. package/dist/mathematica-DNLOL9PQ.js +111 -0
  144. package/dist/mathematica-DNLOL9PQ.js.map +1 -0
  145. package/dist/mbox-Ga7d4MMN.js +118 -0
  146. package/dist/mbox-Ga7d4MMN.js.map +1 -0
  147. package/dist/mirc-Dma3B8rS.js +108 -0
  148. package/dist/mirc-Dma3B8rS.js.map +1 -0
  149. package/dist/mllike-DHn7xckP.js +335 -0
  150. package/dist/mllike-DHn7xckP.js.map +1 -0
  151. package/dist/modelica-0d55jYY0.js +148 -0
  152. package/dist/modelica-0d55jYY0.js.map +1 -0
  153. package/dist/mscgen-DdqZYINH.js +136 -0
  154. package/dist/mscgen-DdqZYINH.js.map +1 -0
  155. package/dist/mumps-Btr8VblO.js +94 -0
  156. package/dist/mumps-Btr8VblO.js.map +1 -0
  157. package/dist/nginx-DTDtBDVN.js +142 -0
  158. package/dist/nginx-DTDtBDVN.js.map +1 -0
  159. package/dist/nsis-3zG7tgur.js +63 -0
  160. package/dist/nsis-3zG7tgur.js.map +1 -0
  161. package/dist/ntriples-CvgOYMpL.js +154 -0
  162. package/dist/ntriples-CvgOYMpL.js.map +1 -0
  163. package/dist/octave-DYBj3-tl.js +201 -0
  164. package/dist/octave-DYBj3-tl.js.map +1 -0
  165. package/dist/oz-R_e8WMIi.js +232 -0
  166. package/dist/oz-R_e8WMIi.js.map +1 -0
  167. package/dist/parse-CAqQaKsh.js +21685 -0
  168. package/dist/parse-CAqQaKsh.js.map +1 -0
  169. package/dist/pascal-GD8iposT.js +106 -0
  170. package/dist/pascal-GD8iposT.js.map +1 -0
  171. package/dist/perl-DL9mHpoi.js +1106 -0
  172. package/dist/perl-DL9mHpoi.js.map +1 -0
  173. package/dist/pig-C_4T4YIV.js +102 -0
  174. package/dist/pig-C_4T4YIV.js.map +1 -0
  175. package/dist/powershell-B0suO7Vd.js +329 -0
  176. package/dist/powershell-B0suO7Vd.js.map +1 -0
  177. package/dist/properties-BR-vP1aU.js +59 -0
  178. package/dist/properties-BR-vP1aU.js.map +1 -0
  179. package/dist/protobuf-BxgpyhoW.js +78 -0
  180. package/dist/protobuf-BxgpyhoW.js.map +1 -0
  181. package/dist/pug-vHnWR0UE.js +406 -0
  182. package/dist/pug-vHnWR0UE.js.map +1 -0
  183. package/dist/puppet-Bdao66PW.js +138 -0
  184. package/dist/puppet-Bdao66PW.js.map +1 -0
  185. package/dist/python-BFGRmuZ9.js +427 -0
  186. package/dist/python-BFGRmuZ9.js.map +1 -0
  187. package/dist/q-CrbCVq4a.js +132 -0
  188. package/dist/q-CrbCVq4a.js.map +1 -0
  189. package/dist/r-V7nswm59.js +171 -0
  190. package/dist/r-V7nswm59.js.map +1 -0
  191. package/dist/repl-sdk.js +7 -0
  192. package/dist/repl-sdk.js.map +1 -0
  193. package/dist/rpm-C-DLY-If.js +110 -0
  194. package/dist/rpm-C-DLY-If.js.map +1 -0
  195. package/dist/ruby-JDKLJNK0.js +331 -0
  196. package/dist/ruby-JDKLJNK0.js.map +1 -0
  197. package/dist/sas-D2UG-yhZ.js +208 -0
  198. package/dist/sas-D2UG-yhZ.js.map +1 -0
  199. package/dist/scheme-BKzrkGJD.js +223 -0
  200. package/dist/scheme-BKzrkGJD.js.map +1 -0
  201. package/dist/shell-BlsXDxCn.js +223 -0
  202. package/dist/shell-BlsXDxCn.js.map +1 -0
  203. package/dist/sieve-CjwBwOY5.js +136 -0
  204. package/dist/sieve-CjwBwOY5.js.map +1 -0
  205. package/dist/simple-mode-DMneyfDu.js +131 -0
  206. package/dist/simple-mode-DMneyfDu.js.map +1 -0
  207. package/dist/smalltalk-BOIGQuhN.js +122 -0
  208. package/dist/smalltalk-BOIGQuhN.js.map +1 -0
  209. package/dist/solr-CwD7U71z.js +70 -0
  210. package/dist/solr-CwD7U71z.js.map +1 -0
  211. package/dist/sparql-DYskk2vE.js +250 -0
  212. package/dist/sparql-DYskk2vE.js.map +1 -0
  213. package/dist/spreadsheet-Bgtt3oLP.js +88 -0
  214. package/dist/spreadsheet-Bgtt3oLP.js.map +1 -0
  215. package/dist/sql-Cei9CMfk.js +343 -0
  216. package/dist/sql-Cei9CMfk.js.map +1 -0
  217. package/dist/stex-C1nZSzAw.js +231 -0
  218. package/dist/stex-C1nZSzAw.js.map +1 -0
  219. package/dist/stylus-BkS-boTH.js +566 -0
  220. package/dist/stylus-BkS-boTH.js.map +1 -0
  221. package/dist/swift-FRZi1uvB.js +292 -0
  222. package/dist/swift-FRZi1uvB.js.map +1 -0
  223. package/dist/tcl-CUcaCdmq.js +115 -0
  224. package/dist/tcl-CUcaCdmq.js.map +1 -0
  225. package/dist/textile-BnFpjsrl.js +415 -0
  226. package/dist/textile-BnFpjsrl.js.map +1 -0
  227. package/dist/tiddlywiki-CjprD-Qp.js +219 -0
  228. package/dist/tiddlywiki-CjprD-Qp.js.map +1 -0
  229. package/dist/tiki-DK9DOeWn.js +269 -0
  230. package/dist/tiki-DK9DOeWn.js.map +1 -0
  231. package/dist/toml-BOuWGMcf.js +77 -0
  232. package/dist/toml-BOuWGMcf.js.map +1 -0
  233. package/dist/troff-E1bJ0PPL.js +62 -0
  234. package/dist/troff-E1bJ0PPL.js.map +1 -0
  235. package/dist/ttcn-cfg-Dc39-fIP.js +134 -0
  236. package/dist/ttcn-cfg-Dc39-fIP.js.map +1 -0
  237. package/dist/ttcn-tKd4HLu4.js +193 -0
  238. package/dist/ttcn-tKd4HLu4.js.map +1 -0
  239. package/dist/turtle-Dq7-1WAf.js +125 -0
  240. package/dist/turtle-Dq7-1WAf.js.map +1 -0
  241. package/dist/vb-Dp90gtsv.js +197 -0
  242. package/dist/vb-Dp90gtsv.js.map +1 -0
  243. package/dist/vbscript-Bfn8O8I7.js +479 -0
  244. package/dist/vbscript-Bfn8O8I7.js.map +1 -0
  245. package/dist/velocity-BwIZK1TH.js +150 -0
  246. package/dist/velocity-BwIZK1TH.js.map +1 -0
  247. package/dist/verilog-CnT9bMk0.js +430 -0
  248. package/dist/verilog-CnT9bMk0.js.map +1 -0
  249. package/dist/vhdl-DCkMIyT9.js +159 -0
  250. package/dist/vhdl-DCkMIyT9.js.map +1 -0
  251. package/dist/webidl-BTLTThCm.js +205 -0
  252. package/dist/webidl-BTLTThCm.js.map +1 -0
  253. package/dist/xquery-BrBUuxMR.js +526 -0
  254. package/dist/xquery-BrBUuxMR.js.map +1 -0
  255. package/dist/yacas-b5lAVEIl.js +131 -0
  256. package/dist/yacas-b5lAVEIl.js.map +1 -0
  257. package/dist/z80-ClgwfNdB.js +93 -0
  258. package/dist/z80-ClgwfNdB.js.map +1 -0
  259. package/package.json +10 -11
  260. package/src/compilers/ember/gjs.js +2 -2
  261. package/src/compilers/ember/gmd.js +1 -1
  262. package/src/compilers/markdown.js +1 -1
  263. package/src/compilers/react.js +15 -3
  264. package/dist/codemirror-D4aIVflZ.js +0 -110
  265. package/dist/codemirror-D4aIVflZ.js.map +0 -1
  266. package/dist/gjs-CzFzkEFv.js.map +0 -1
  267. package/dist/gmd-D9OXs2v3.js.map +0 -1
  268. package/dist/index-CUWCqMoD.js.map +0 -1
  269. package/dist/index.js +0 -7
  270. package/dist/index.js.map +0 -1
  271. package/dist/parse-aBKk9rfS.js +0 -328
  272. package/dist/parse-aBKk9rfS.js.map +0 -1
@@ -0,0 +1,2912 @@
1
+ import { c as closeBrackets, a as autocompletion, b as closeBracketsKeymap, d as completionKeymap } from "./index-pN_pUAQ7.js";
2
+ import { S as StateField, F as Facet, E as EditorView, a as EditorSelection, I as IndentContext, g as getIndentation, c as countColumn, i as indentString, T as Text, A as Annotation, b as Transaction, d as combineConfig, f as findClusterBreak, s as syntaxTree, e as StateEffect, C as ChangeSet, h as ChangeDesc, D as Direction, m as matchBrackets, j as getIndentUnit, k as indentUnit, V as ViewPlugin, P as Prec, l as getPanel, n as Decoration, o as showPanel, p as codePointAt, q as codePointSize, r as fromCodePoint, t as CharCategory, u as EditorState, R as RangeSetBuilder, v as runScopeHandlers, w as hoverTooltip, W as WidgetType, x as lineNumbers, y as highlightActiveLineGutter, z as highlightSpecialChars, B as foldGutter, G as drawSelection, H as dropCursor, J as indentOnInput, K as syntaxHighlighting, L as bracketMatching, M as rectangularSelection, N as crosshairCursor, O as highlightActiveLine, Q as keymap, U as foldKeymap, X as defaultHighlightStyle, Y as Compartment } from "./index-BlOjO66K.js";
3
+ import { NodeProp } from "@lezer/common";
4
+ import { markdownKeymap } from "./index-C2sFZMth.js";
5
+ import { foldByIndent } from "./index-DOAqdvnQ.js";
6
+ function crelt() {
7
+ var elt = arguments[0];
8
+ if (typeof elt == "string") elt = document.createElement(elt);
9
+ var i = 1, next = arguments[1];
10
+ if (next && typeof next == "object" && next.nodeType == null && !Array.isArray(next)) {
11
+ for (var name in next) if (Object.prototype.hasOwnProperty.call(next, name)) {
12
+ var value = next[name];
13
+ if (typeof value == "string") elt.setAttribute(name, value);
14
+ else if (value != null) elt[name] = value;
15
+ }
16
+ i++;
17
+ }
18
+ for (; i < arguments.length; i++) add(elt, arguments[i]);
19
+ return elt;
20
+ }
21
+ function add(elt, child) {
22
+ if (typeof child == "string") {
23
+ elt.appendChild(document.createTextNode(child));
24
+ } else if (child == null) ;
25
+ else if (child.nodeType != null) {
26
+ elt.appendChild(child);
27
+ } else if (Array.isArray(child)) {
28
+ for (var i = 0; i < child.length; i++) add(elt, child[i]);
29
+ } else {
30
+ throw new RangeError("Unsupported child node: " + child);
31
+ }
32
+ }
33
+ const toggleComment = (target) => {
34
+ let { state } = target, line = state.doc.lineAt(state.selection.main.from), config = getConfig(target.state, line.from);
35
+ return config.line ? toggleLineComment(target) : config.block ? toggleBlockCommentByLine(target) : false;
36
+ };
37
+ function command(f, option) {
38
+ return ({ state, dispatch }) => {
39
+ if (state.readOnly)
40
+ return false;
41
+ let tr = f(option, state);
42
+ if (!tr)
43
+ return false;
44
+ dispatch(state.update(tr));
45
+ return true;
46
+ };
47
+ }
48
+ const toggleLineComment = /* @__PURE__ */ command(
49
+ changeLineComment,
50
+ 0
51
+ /* CommentOption.Toggle */
52
+ );
53
+ const toggleBlockComment = /* @__PURE__ */ command(
54
+ changeBlockComment,
55
+ 0
56
+ /* CommentOption.Toggle */
57
+ );
58
+ const toggleBlockCommentByLine = /* @__PURE__ */ command(
59
+ (o, s) => changeBlockComment(o, s, selectedLineRanges(s)),
60
+ 0
61
+ /* CommentOption.Toggle */
62
+ );
63
+ function getConfig(state, pos) {
64
+ let data = state.languageDataAt("commentTokens", pos, 1);
65
+ return data.length ? data[0] : {};
66
+ }
67
+ const SearchMargin = 50;
68
+ function findBlockComment(state, { open, close }, from, to) {
69
+ let textBefore = state.sliceDoc(from - SearchMargin, from);
70
+ let textAfter = state.sliceDoc(to, to + SearchMargin);
71
+ let spaceBefore = /\s*$/.exec(textBefore)[0].length, spaceAfter = /^\s*/.exec(textAfter)[0].length;
72
+ let beforeOff = textBefore.length - spaceBefore;
73
+ if (textBefore.slice(beforeOff - open.length, beforeOff) == open && textAfter.slice(spaceAfter, spaceAfter + close.length) == close) {
74
+ return {
75
+ open: { pos: from - spaceBefore, margin: spaceBefore && 1 },
76
+ close: { pos: to + spaceAfter, margin: spaceAfter && 1 }
77
+ };
78
+ }
79
+ let startText, endText;
80
+ if (to - from <= 2 * SearchMargin) {
81
+ startText = endText = state.sliceDoc(from, to);
82
+ } else {
83
+ startText = state.sliceDoc(from, from + SearchMargin);
84
+ endText = state.sliceDoc(to - SearchMargin, to);
85
+ }
86
+ let startSpace = /^\s*/.exec(startText)[0].length, endSpace = /\s*$/.exec(endText)[0].length;
87
+ let endOff = endText.length - endSpace - close.length;
88
+ if (startText.slice(startSpace, startSpace + open.length) == open && endText.slice(endOff, endOff + close.length) == close) {
89
+ return {
90
+ open: {
91
+ pos: from + startSpace + open.length,
92
+ margin: /\s/.test(startText.charAt(startSpace + open.length)) ? 1 : 0
93
+ },
94
+ close: {
95
+ pos: to - endSpace - close.length,
96
+ margin: /\s/.test(endText.charAt(endOff - 1)) ? 1 : 0
97
+ }
98
+ };
99
+ }
100
+ return null;
101
+ }
102
+ function selectedLineRanges(state) {
103
+ let ranges = [];
104
+ for (let r of state.selection.ranges) {
105
+ let fromLine = state.doc.lineAt(r.from);
106
+ let toLine = r.to <= fromLine.to ? fromLine : state.doc.lineAt(r.to);
107
+ if (toLine.from > fromLine.from && toLine.from == r.to)
108
+ toLine = r.to == fromLine.to + 1 ? fromLine : state.doc.lineAt(r.to - 1);
109
+ let last = ranges.length - 1;
110
+ if (last >= 0 && ranges[last].to > fromLine.from)
111
+ ranges[last].to = toLine.to;
112
+ else
113
+ ranges.push({ from: fromLine.from + /^\s*/.exec(fromLine.text)[0].length, to: toLine.to });
114
+ }
115
+ return ranges;
116
+ }
117
+ function changeBlockComment(option, state, ranges = state.selection.ranges) {
118
+ let tokens = ranges.map((r) => getConfig(state, r.from).block);
119
+ if (!tokens.every((c) => c))
120
+ return null;
121
+ let comments = ranges.map((r, i) => findBlockComment(state, tokens[i], r.from, r.to));
122
+ if (option != 2 && !comments.every((c) => c)) {
123
+ return { changes: state.changes(ranges.map((range, i) => {
124
+ if (comments[i])
125
+ return [];
126
+ return [{ from: range.from, insert: tokens[i].open + " " }, { from: range.to, insert: " " + tokens[i].close }];
127
+ })) };
128
+ } else if (option != 1 && comments.some((c) => c)) {
129
+ let changes = [];
130
+ for (let i = 0, comment; i < comments.length; i++)
131
+ if (comment = comments[i]) {
132
+ let token = tokens[i], { open, close } = comment;
133
+ changes.push({ from: open.pos - token.open.length, to: open.pos + open.margin }, { from: close.pos - close.margin, to: close.pos + token.close.length });
134
+ }
135
+ return { changes };
136
+ }
137
+ return null;
138
+ }
139
+ function changeLineComment(option, state, ranges = state.selection.ranges) {
140
+ let lines = [];
141
+ let prevLine = -1;
142
+ for (let { from, to } of ranges) {
143
+ let startI = lines.length, minIndent = 1e9;
144
+ let token = getConfig(state, from).line;
145
+ if (!token)
146
+ continue;
147
+ for (let pos = from; pos <= to; ) {
148
+ let line = state.doc.lineAt(pos);
149
+ if (line.from > prevLine && (from == to || to > line.from)) {
150
+ prevLine = line.from;
151
+ let indent = /^\s*/.exec(line.text)[0].length;
152
+ let empty2 = indent == line.length;
153
+ let comment = line.text.slice(indent, indent + token.length) == token ? indent : -1;
154
+ if (indent < line.text.length && indent < minIndent)
155
+ minIndent = indent;
156
+ lines.push({ line, comment, token, indent, empty: empty2, single: false });
157
+ }
158
+ pos = line.to + 1;
159
+ }
160
+ if (minIndent < 1e9) {
161
+ for (let i = startI; i < lines.length; i++)
162
+ if (lines[i].indent < lines[i].line.text.length)
163
+ lines[i].indent = minIndent;
164
+ }
165
+ if (lines.length == startI + 1)
166
+ lines[startI].single = true;
167
+ }
168
+ if (option != 2 && lines.some((l) => l.comment < 0 && (!l.empty || l.single))) {
169
+ let changes = [];
170
+ for (let { line, token, indent, empty: empty2, single } of lines)
171
+ if (single || !empty2)
172
+ changes.push({ from: line.from + indent, insert: token + " " });
173
+ let changeSet = state.changes(changes);
174
+ return { changes: changeSet, selection: state.selection.map(changeSet, 1) };
175
+ } else if (option != 1 && lines.some((l) => l.comment >= 0)) {
176
+ let changes = [];
177
+ for (let { line, comment, token } of lines)
178
+ if (comment >= 0) {
179
+ let from = line.from + comment, to = from + token.length;
180
+ if (line.text[to - line.from] == " ")
181
+ to++;
182
+ changes.push({ from, to });
183
+ }
184
+ return { changes };
185
+ }
186
+ return null;
187
+ }
188
+ const fromHistory = /* @__PURE__ */ Annotation.define();
189
+ const isolateHistory = /* @__PURE__ */ Annotation.define();
190
+ const invertedEffects = /* @__PURE__ */ Facet.define();
191
+ const historyConfig = /* @__PURE__ */ Facet.define({
192
+ combine(configs) {
193
+ return combineConfig(configs, {
194
+ minDepth: 100,
195
+ newGroupDelay: 500,
196
+ joinToEvent: (_t, isAdjacent2) => isAdjacent2
197
+ }, {
198
+ minDepth: Math.max,
199
+ newGroupDelay: Math.min,
200
+ joinToEvent: (a, b) => (tr, adj) => a(tr, adj) || b(tr, adj)
201
+ });
202
+ }
203
+ });
204
+ const historyField_ = /* @__PURE__ */ StateField.define({
205
+ create() {
206
+ return HistoryState.empty;
207
+ },
208
+ update(state, tr) {
209
+ let config = tr.state.facet(historyConfig);
210
+ let fromHist = tr.annotation(fromHistory);
211
+ if (fromHist) {
212
+ let item = HistEvent.fromTransaction(tr, fromHist.selection), from = fromHist.side;
213
+ let other = from == 0 ? state.undone : state.done;
214
+ if (item)
215
+ other = updateBranch(other, other.length, config.minDepth, item);
216
+ else
217
+ other = addSelection(other, tr.startState.selection);
218
+ return new HistoryState(from == 0 ? fromHist.rest : other, from == 0 ? other : fromHist.rest);
219
+ }
220
+ let isolate = tr.annotation(isolateHistory);
221
+ if (isolate == "full" || isolate == "before")
222
+ state = state.isolate();
223
+ if (tr.annotation(Transaction.addToHistory) === false)
224
+ return !tr.changes.empty ? state.addMapping(tr.changes.desc) : state;
225
+ let event = HistEvent.fromTransaction(tr);
226
+ let time = tr.annotation(Transaction.time), userEvent = tr.annotation(Transaction.userEvent);
227
+ if (event)
228
+ state = state.addChanges(event, time, userEvent, config, tr);
229
+ else if (tr.selection)
230
+ state = state.addSelection(tr.startState.selection, time, userEvent, config.newGroupDelay);
231
+ if (isolate == "full" || isolate == "after")
232
+ state = state.isolate();
233
+ return state;
234
+ },
235
+ toJSON(value) {
236
+ return { done: value.done.map((e) => e.toJSON()), undone: value.undone.map((e) => e.toJSON()) };
237
+ },
238
+ fromJSON(json) {
239
+ return new HistoryState(json.done.map(HistEvent.fromJSON), json.undone.map(HistEvent.fromJSON));
240
+ }
241
+ });
242
+ function history(config = {}) {
243
+ return [
244
+ historyField_,
245
+ historyConfig.of(config),
246
+ EditorView.domEventHandlers({
247
+ beforeinput(e, view) {
248
+ let command2 = e.inputType == "historyUndo" ? undo : e.inputType == "historyRedo" ? redo : null;
249
+ if (!command2)
250
+ return false;
251
+ e.preventDefault();
252
+ return command2(view);
253
+ }
254
+ })
255
+ ];
256
+ }
257
+ function cmd(side, selection) {
258
+ return function({ state, dispatch }) {
259
+ if (!selection && state.readOnly)
260
+ return false;
261
+ let historyState = state.field(historyField_, false);
262
+ if (!historyState)
263
+ return false;
264
+ let tr = historyState.pop(side, state, selection);
265
+ if (!tr)
266
+ return false;
267
+ dispatch(tr);
268
+ return true;
269
+ };
270
+ }
271
+ const undo = /* @__PURE__ */ cmd(0, false);
272
+ const redo = /* @__PURE__ */ cmd(1, false);
273
+ const undoSelection = /* @__PURE__ */ cmd(0, true);
274
+ const redoSelection = /* @__PURE__ */ cmd(1, true);
275
+ class HistEvent {
276
+ constructor(changes, effects, mapped, startSelection, selectionsAfter) {
277
+ this.changes = changes;
278
+ this.effects = effects;
279
+ this.mapped = mapped;
280
+ this.startSelection = startSelection;
281
+ this.selectionsAfter = selectionsAfter;
282
+ }
283
+ setSelAfter(after) {
284
+ return new HistEvent(this.changes, this.effects, this.mapped, this.startSelection, after);
285
+ }
286
+ toJSON() {
287
+ var _a, _b, _c;
288
+ return {
289
+ changes: (_a = this.changes) === null || _a === void 0 ? void 0 : _a.toJSON(),
290
+ mapped: (_b = this.mapped) === null || _b === void 0 ? void 0 : _b.toJSON(),
291
+ startSelection: (_c = this.startSelection) === null || _c === void 0 ? void 0 : _c.toJSON(),
292
+ selectionsAfter: this.selectionsAfter.map((s) => s.toJSON())
293
+ };
294
+ }
295
+ static fromJSON(json) {
296
+ return new HistEvent(json.changes && ChangeSet.fromJSON(json.changes), [], json.mapped && ChangeDesc.fromJSON(json.mapped), json.startSelection && EditorSelection.fromJSON(json.startSelection), json.selectionsAfter.map(EditorSelection.fromJSON));
297
+ }
298
+ // This does not check `addToHistory` and such, it assumes the
299
+ // transaction needs to be converted to an item. Returns null when
300
+ // there are no changes or effects in the transaction.
301
+ static fromTransaction(tr, selection) {
302
+ let effects = none;
303
+ for (let invert of tr.startState.facet(invertedEffects)) {
304
+ let result = invert(tr);
305
+ if (result.length)
306
+ effects = effects.concat(result);
307
+ }
308
+ if (!effects.length && tr.changes.empty)
309
+ return null;
310
+ return new HistEvent(tr.changes.invert(tr.startState.doc), effects, void 0, selection || tr.startState.selection, none);
311
+ }
312
+ static selection(selections) {
313
+ return new HistEvent(void 0, none, void 0, void 0, selections);
314
+ }
315
+ }
316
+ function updateBranch(branch, to, maxLen, newEvent) {
317
+ let start = to + 1 > maxLen + 20 ? to - maxLen - 1 : 0;
318
+ let newBranch = branch.slice(start, to);
319
+ newBranch.push(newEvent);
320
+ return newBranch;
321
+ }
322
+ function isAdjacent(a, b) {
323
+ let ranges = [], isAdjacent2 = false;
324
+ a.iterChangedRanges((f, t) => ranges.push(f, t));
325
+ b.iterChangedRanges((_f, _t, f, t) => {
326
+ for (let i = 0; i < ranges.length; ) {
327
+ let from = ranges[i++], to = ranges[i++];
328
+ if (t >= from && f <= to)
329
+ isAdjacent2 = true;
330
+ }
331
+ });
332
+ return isAdjacent2;
333
+ }
334
+ function eqSelectionShape(a, b) {
335
+ return a.ranges.length == b.ranges.length && a.ranges.filter((r, i) => r.empty != b.ranges[i].empty).length === 0;
336
+ }
337
+ function conc(a, b) {
338
+ return !a.length ? b : !b.length ? a : a.concat(b);
339
+ }
340
+ const none = [];
341
+ const MaxSelectionsPerEvent = 200;
342
+ function addSelection(branch, selection) {
343
+ if (!branch.length) {
344
+ return [HistEvent.selection([selection])];
345
+ } else {
346
+ let lastEvent = branch[branch.length - 1];
347
+ let sels = lastEvent.selectionsAfter.slice(Math.max(0, lastEvent.selectionsAfter.length - MaxSelectionsPerEvent));
348
+ if (sels.length && sels[sels.length - 1].eq(selection))
349
+ return branch;
350
+ sels.push(selection);
351
+ return updateBranch(branch, branch.length - 1, 1e9, lastEvent.setSelAfter(sels));
352
+ }
353
+ }
354
+ function popSelection(branch) {
355
+ let last = branch[branch.length - 1];
356
+ let newBranch = branch.slice();
357
+ newBranch[branch.length - 1] = last.setSelAfter(last.selectionsAfter.slice(0, last.selectionsAfter.length - 1));
358
+ return newBranch;
359
+ }
360
+ function addMappingToBranch(branch, mapping) {
361
+ if (!branch.length)
362
+ return branch;
363
+ let length = branch.length, selections = none;
364
+ while (length) {
365
+ let event = mapEvent(branch[length - 1], mapping, selections);
366
+ if (event.changes && !event.changes.empty || event.effects.length) {
367
+ let result = branch.slice(0, length);
368
+ result[length - 1] = event;
369
+ return result;
370
+ } else {
371
+ mapping = event.mapped;
372
+ length--;
373
+ selections = event.selectionsAfter;
374
+ }
375
+ }
376
+ return selections.length ? [HistEvent.selection(selections)] : none;
377
+ }
378
+ function mapEvent(event, mapping, extraSelections) {
379
+ let selections = conc(event.selectionsAfter.length ? event.selectionsAfter.map((s) => s.map(mapping)) : none, extraSelections);
380
+ if (!event.changes)
381
+ return HistEvent.selection(selections);
382
+ let mappedChanges = event.changes.map(mapping), before = mapping.mapDesc(event.changes, true);
383
+ let fullMapping = event.mapped ? event.mapped.composeDesc(before) : before;
384
+ return new HistEvent(mappedChanges, StateEffect.mapEffects(event.effects, mapping), fullMapping, event.startSelection.map(before), selections);
385
+ }
386
+ const joinableUserEvent = /^(input\.type|delete)($|\.)/;
387
+ class HistoryState {
388
+ constructor(done, undone, prevTime = 0, prevUserEvent = void 0) {
389
+ this.done = done;
390
+ this.undone = undone;
391
+ this.prevTime = prevTime;
392
+ this.prevUserEvent = prevUserEvent;
393
+ }
394
+ isolate() {
395
+ return this.prevTime ? new HistoryState(this.done, this.undone) : this;
396
+ }
397
+ addChanges(event, time, userEvent, config, tr) {
398
+ let done = this.done, lastEvent = done[done.length - 1];
399
+ if (lastEvent && lastEvent.changes && !lastEvent.changes.empty && event.changes && (!userEvent || joinableUserEvent.test(userEvent)) && (!lastEvent.selectionsAfter.length && time - this.prevTime < config.newGroupDelay && config.joinToEvent(tr, isAdjacent(lastEvent.changes, event.changes)) || // For compose (but not compose.start) events, always join with previous event
400
+ userEvent == "input.type.compose")) {
401
+ done = updateBranch(done, done.length - 1, config.minDepth, new HistEvent(event.changes.compose(lastEvent.changes), conc(StateEffect.mapEffects(event.effects, lastEvent.changes), lastEvent.effects), lastEvent.mapped, lastEvent.startSelection, none));
402
+ } else {
403
+ done = updateBranch(done, done.length, config.minDepth, event);
404
+ }
405
+ return new HistoryState(done, none, time, userEvent);
406
+ }
407
+ addSelection(selection, time, userEvent, newGroupDelay) {
408
+ let last = this.done.length ? this.done[this.done.length - 1].selectionsAfter : none;
409
+ if (last.length > 0 && time - this.prevTime < newGroupDelay && userEvent == this.prevUserEvent && userEvent && /^select($|\.)/.test(userEvent) && eqSelectionShape(last[last.length - 1], selection))
410
+ return this;
411
+ return new HistoryState(addSelection(this.done, selection), this.undone, time, userEvent);
412
+ }
413
+ addMapping(mapping) {
414
+ return new HistoryState(addMappingToBranch(this.done, mapping), addMappingToBranch(this.undone, mapping), this.prevTime, this.prevUserEvent);
415
+ }
416
+ pop(side, state, onlySelection) {
417
+ let branch = side == 0 ? this.done : this.undone;
418
+ if (branch.length == 0)
419
+ return null;
420
+ let event = branch[branch.length - 1], selection = event.selectionsAfter[0] || state.selection;
421
+ if (onlySelection && event.selectionsAfter.length) {
422
+ return state.update({
423
+ selection: event.selectionsAfter[event.selectionsAfter.length - 1],
424
+ annotations: fromHistory.of({ side, rest: popSelection(branch), selection }),
425
+ userEvent: side == 0 ? "select.undo" : "select.redo",
426
+ scrollIntoView: true
427
+ });
428
+ } else if (!event.changes) {
429
+ return null;
430
+ } else {
431
+ let rest = branch.length == 1 ? none : branch.slice(0, branch.length - 1);
432
+ if (event.mapped)
433
+ rest = addMappingToBranch(rest, event.mapped);
434
+ return state.update({
435
+ changes: event.changes,
436
+ selection: event.startSelection,
437
+ effects: event.effects,
438
+ annotations: fromHistory.of({ side, rest, selection }),
439
+ filter: false,
440
+ userEvent: side == 0 ? "undo" : "redo",
441
+ scrollIntoView: true
442
+ });
443
+ }
444
+ }
445
+ }
446
+ HistoryState.empty = /* @__PURE__ */ new HistoryState(none, none);
447
+ const historyKeymap = [
448
+ { key: "Mod-z", run: undo, preventDefault: true },
449
+ { key: "Mod-y", mac: "Mod-Shift-z", run: redo, preventDefault: true },
450
+ { linux: "Ctrl-Shift-z", run: redo, preventDefault: true },
451
+ { key: "Mod-u", run: undoSelection, preventDefault: true },
452
+ { key: "Alt-u", mac: "Mod-Shift-u", run: redoSelection, preventDefault: true }
453
+ ];
454
+ function updateSel(sel, by) {
455
+ return EditorSelection.create(sel.ranges.map(by), sel.mainIndex);
456
+ }
457
+ function setSel(state, selection) {
458
+ return state.update({ selection, scrollIntoView: true, userEvent: "select" });
459
+ }
460
+ function moveSel({ state, dispatch }, how) {
461
+ let selection = updateSel(state.selection, how);
462
+ if (selection.eq(state.selection, true))
463
+ return false;
464
+ dispatch(setSel(state, selection));
465
+ return true;
466
+ }
467
+ function rangeEnd(range, forward) {
468
+ return EditorSelection.cursor(forward ? range.to : range.from);
469
+ }
470
+ function cursorByChar(view, forward) {
471
+ return moveSel(view, (range) => range.empty ? view.moveByChar(range, forward) : rangeEnd(range, forward));
472
+ }
473
+ function ltrAtCursor(view) {
474
+ return view.textDirectionAt(view.state.selection.main.head) == Direction.LTR;
475
+ }
476
+ const cursorCharLeft = (view) => cursorByChar(view, !ltrAtCursor(view));
477
+ const cursorCharRight = (view) => cursorByChar(view, ltrAtCursor(view));
478
+ function cursorByGroup(view, forward) {
479
+ return moveSel(view, (range) => range.empty ? view.moveByGroup(range, forward) : rangeEnd(range, forward));
480
+ }
481
+ const cursorGroupLeft = (view) => cursorByGroup(view, !ltrAtCursor(view));
482
+ const cursorGroupRight = (view) => cursorByGroup(view, ltrAtCursor(view));
483
+ function interestingNode(state, node, bracketProp) {
484
+ if (node.type.prop(bracketProp))
485
+ return true;
486
+ let len = node.to - node.from;
487
+ return len && (len > 2 || /[^\s,.;:]/.test(state.sliceDoc(node.from, node.to))) || node.firstChild;
488
+ }
489
+ function moveBySyntax(state, start, forward) {
490
+ let pos = syntaxTree(state).resolveInner(start.head);
491
+ let bracketProp = forward ? NodeProp.closedBy : NodeProp.openedBy;
492
+ for (let at = start.head; ; ) {
493
+ let next = forward ? pos.childAfter(at) : pos.childBefore(at);
494
+ if (!next)
495
+ break;
496
+ if (interestingNode(state, next, bracketProp))
497
+ pos = next;
498
+ else
499
+ at = forward ? next.to : next.from;
500
+ }
501
+ let bracket = pos.type.prop(bracketProp), match, newPos;
502
+ if (bracket && (match = forward ? matchBrackets(state, pos.from, 1) : matchBrackets(state, pos.to, -1)) && match.matched)
503
+ newPos = forward ? match.end.to : match.end.from;
504
+ else
505
+ newPos = forward ? pos.to : pos.from;
506
+ return EditorSelection.cursor(newPos, forward ? -1 : 1);
507
+ }
508
+ const cursorSyntaxLeft = (view) => moveSel(view, (range) => moveBySyntax(view.state, range, !ltrAtCursor(view)));
509
+ const cursorSyntaxRight = (view) => moveSel(view, (range) => moveBySyntax(view.state, range, ltrAtCursor(view)));
510
+ function cursorByLine(view, forward) {
511
+ return moveSel(view, (range) => {
512
+ if (!range.empty)
513
+ return rangeEnd(range, forward);
514
+ let moved = view.moveVertically(range, forward);
515
+ return moved.head != range.head ? moved : view.moveToLineBoundary(range, forward);
516
+ });
517
+ }
518
+ const cursorLineUp = (view) => cursorByLine(view, false);
519
+ const cursorLineDown = (view) => cursorByLine(view, true);
520
+ function pageInfo(view) {
521
+ let selfScroll = view.scrollDOM.clientHeight < view.scrollDOM.scrollHeight - 2;
522
+ let marginTop = 0, marginBottom = 0, height;
523
+ if (selfScroll) {
524
+ for (let source of view.state.facet(EditorView.scrollMargins)) {
525
+ let margins = source(view);
526
+ if (margins === null || margins === void 0 ? void 0 : margins.top)
527
+ marginTop = Math.max(margins === null || margins === void 0 ? void 0 : margins.top, marginTop);
528
+ if (margins === null || margins === void 0 ? void 0 : margins.bottom)
529
+ marginBottom = Math.max(margins === null || margins === void 0 ? void 0 : margins.bottom, marginBottom);
530
+ }
531
+ height = view.scrollDOM.clientHeight - marginTop - marginBottom;
532
+ } else {
533
+ height = (view.dom.ownerDocument.defaultView || window).innerHeight;
534
+ }
535
+ return {
536
+ marginTop,
537
+ marginBottom,
538
+ selfScroll,
539
+ height: Math.max(view.defaultLineHeight, height - 5)
540
+ };
541
+ }
542
+ function cursorByPage(view, forward) {
543
+ let page = pageInfo(view);
544
+ let { state } = view, selection = updateSel(state.selection, (range) => {
545
+ return range.empty ? view.moveVertically(range, forward, page.height) : rangeEnd(range, forward);
546
+ });
547
+ if (selection.eq(state.selection))
548
+ return false;
549
+ let effect;
550
+ if (page.selfScroll) {
551
+ let startPos = view.coordsAtPos(state.selection.main.head);
552
+ let scrollRect = view.scrollDOM.getBoundingClientRect();
553
+ let scrollTop = scrollRect.top + page.marginTop, scrollBottom = scrollRect.bottom - page.marginBottom;
554
+ if (startPos && startPos.top > scrollTop && startPos.bottom < scrollBottom)
555
+ effect = EditorView.scrollIntoView(selection.main.head, { y: "start", yMargin: startPos.top - scrollTop });
556
+ }
557
+ view.dispatch(setSel(state, selection), { effects: effect });
558
+ return true;
559
+ }
560
+ const cursorPageUp = (view) => cursorByPage(view, false);
561
+ const cursorPageDown = (view) => cursorByPage(view, true);
562
+ function moveByLineBoundary(view, start, forward) {
563
+ let line = view.lineBlockAt(start.head), moved = view.moveToLineBoundary(start, forward);
564
+ if (moved.head == start.head && moved.head != (forward ? line.to : line.from))
565
+ moved = view.moveToLineBoundary(start, forward, false);
566
+ if (!forward && moved.head == line.from && line.length) {
567
+ let space = /^\s*/.exec(view.state.sliceDoc(line.from, Math.min(line.from + 100, line.to)))[0].length;
568
+ if (space && start.head != line.from + space)
569
+ moved = EditorSelection.cursor(line.from + space);
570
+ }
571
+ return moved;
572
+ }
573
+ const cursorLineBoundaryForward = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, true));
574
+ const cursorLineBoundaryBackward = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, false));
575
+ const cursorLineBoundaryLeft = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, !ltrAtCursor(view)));
576
+ const cursorLineBoundaryRight = (view) => moveSel(view, (range) => moveByLineBoundary(view, range, ltrAtCursor(view)));
577
+ const cursorLineStart = (view) => moveSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).from, 1));
578
+ const cursorLineEnd = (view) => moveSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).to, -1));
579
+ function toMatchingBracket(state, dispatch, extend) {
580
+ let found = false, selection = updateSel(state.selection, (range) => {
581
+ let matching = matchBrackets(state, range.head, -1) || matchBrackets(state, range.head, 1) || range.head > 0 && matchBrackets(state, range.head - 1, 1) || range.head < state.doc.length && matchBrackets(state, range.head + 1, -1);
582
+ if (!matching || !matching.end)
583
+ return range;
584
+ found = true;
585
+ let head = matching.start.from == range.head ? matching.end.to : matching.end.from;
586
+ return EditorSelection.cursor(head);
587
+ });
588
+ if (!found)
589
+ return false;
590
+ dispatch(setSel(state, selection));
591
+ return true;
592
+ }
593
+ const cursorMatchingBracket = ({ state, dispatch }) => toMatchingBracket(state, dispatch);
594
+ function extendSel(target, how) {
595
+ let selection = updateSel(target.state.selection, (range) => {
596
+ let head = how(range);
597
+ return EditorSelection.range(range.anchor, head.head, head.goalColumn, head.bidiLevel || void 0);
598
+ });
599
+ if (selection.eq(target.state.selection))
600
+ return false;
601
+ target.dispatch(setSel(target.state, selection));
602
+ return true;
603
+ }
604
+ function selectByChar(view, forward) {
605
+ return extendSel(view, (range) => view.moveByChar(range, forward));
606
+ }
607
+ const selectCharLeft = (view) => selectByChar(view, !ltrAtCursor(view));
608
+ const selectCharRight = (view) => selectByChar(view, ltrAtCursor(view));
609
+ function selectByGroup(view, forward) {
610
+ return extendSel(view, (range) => view.moveByGroup(range, forward));
611
+ }
612
+ const selectGroupLeft = (view) => selectByGroup(view, !ltrAtCursor(view));
613
+ const selectGroupRight = (view) => selectByGroup(view, ltrAtCursor(view));
614
+ const selectSyntaxLeft = (view) => extendSel(view, (range) => moveBySyntax(view.state, range, !ltrAtCursor(view)));
615
+ const selectSyntaxRight = (view) => extendSel(view, (range) => moveBySyntax(view.state, range, ltrAtCursor(view)));
616
+ function selectByLine(view, forward) {
617
+ return extendSel(view, (range) => view.moveVertically(range, forward));
618
+ }
619
+ const selectLineUp = (view) => selectByLine(view, false);
620
+ const selectLineDown = (view) => selectByLine(view, true);
621
+ function selectByPage(view, forward) {
622
+ return extendSel(view, (range) => view.moveVertically(range, forward, pageInfo(view).height));
623
+ }
624
+ const selectPageUp = (view) => selectByPage(view, false);
625
+ const selectPageDown = (view) => selectByPage(view, true);
626
+ const selectLineBoundaryForward = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, true));
627
+ const selectLineBoundaryBackward = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, false));
628
+ const selectLineBoundaryLeft = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, !ltrAtCursor(view)));
629
+ const selectLineBoundaryRight = (view) => extendSel(view, (range) => moveByLineBoundary(view, range, ltrAtCursor(view)));
630
+ const selectLineStart = (view) => extendSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).from));
631
+ const selectLineEnd = (view) => extendSel(view, (range) => EditorSelection.cursor(view.lineBlockAt(range.head).to));
632
+ const cursorDocStart = ({ state, dispatch }) => {
633
+ dispatch(setSel(state, { anchor: 0 }));
634
+ return true;
635
+ };
636
+ const cursorDocEnd = ({ state, dispatch }) => {
637
+ dispatch(setSel(state, { anchor: state.doc.length }));
638
+ return true;
639
+ };
640
+ const selectDocStart = ({ state, dispatch }) => {
641
+ dispatch(setSel(state, { anchor: state.selection.main.anchor, head: 0 }));
642
+ return true;
643
+ };
644
+ const selectDocEnd = ({ state, dispatch }) => {
645
+ dispatch(setSel(state, { anchor: state.selection.main.anchor, head: state.doc.length }));
646
+ return true;
647
+ };
648
+ const selectAll = ({ state, dispatch }) => {
649
+ dispatch(state.update({ selection: { anchor: 0, head: state.doc.length }, userEvent: "select" }));
650
+ return true;
651
+ };
652
+ const selectLine = ({ state, dispatch }) => {
653
+ let ranges = selectedLineBlocks(state).map(({ from, to }) => EditorSelection.range(from, Math.min(to + 1, state.doc.length)));
654
+ dispatch(state.update({ selection: EditorSelection.create(ranges), userEvent: "select" }));
655
+ return true;
656
+ };
657
+ const selectParentSyntax = ({ state, dispatch }) => {
658
+ let selection = updateSel(state.selection, (range) => {
659
+ let tree = syntaxTree(state), stack = tree.resolveStack(range.from, 1);
660
+ if (range.empty) {
661
+ let stackBefore = tree.resolveStack(range.from, -1);
662
+ if (stackBefore.node.from >= stack.node.from && stackBefore.node.to <= stack.node.to)
663
+ stack = stackBefore;
664
+ }
665
+ for (let cur = stack; cur; cur = cur.next) {
666
+ let { node } = cur;
667
+ if ((node.from < range.from && node.to >= range.to || node.to > range.to && node.from <= range.from) && cur.next)
668
+ return EditorSelection.range(node.to, node.from);
669
+ }
670
+ return range;
671
+ });
672
+ if (selection.eq(state.selection))
673
+ return false;
674
+ dispatch(setSel(state, selection));
675
+ return true;
676
+ };
677
+ const simplifySelection = ({ state, dispatch }) => {
678
+ let cur = state.selection, selection = null;
679
+ if (cur.ranges.length > 1)
680
+ selection = EditorSelection.create([cur.main]);
681
+ else if (!cur.main.empty)
682
+ selection = EditorSelection.create([EditorSelection.cursor(cur.main.head)]);
683
+ if (!selection)
684
+ return false;
685
+ dispatch(setSel(state, selection));
686
+ return true;
687
+ };
688
+ function deleteBy(target, by) {
689
+ if (target.state.readOnly)
690
+ return false;
691
+ let event = "delete.selection", { state } = target;
692
+ let changes = state.changeByRange((range) => {
693
+ let { from, to } = range;
694
+ if (from == to) {
695
+ let towards = by(range);
696
+ if (towards < from) {
697
+ event = "delete.backward";
698
+ towards = skipAtomic(target, towards, false);
699
+ } else if (towards > from) {
700
+ event = "delete.forward";
701
+ towards = skipAtomic(target, towards, true);
702
+ }
703
+ from = Math.min(from, towards);
704
+ to = Math.max(to, towards);
705
+ } else {
706
+ from = skipAtomic(target, from, false);
707
+ to = skipAtomic(target, to, true);
708
+ }
709
+ return from == to ? { range } : { changes: { from, to }, range: EditorSelection.cursor(from, from < range.head ? -1 : 1) };
710
+ });
711
+ if (changes.changes.empty)
712
+ return false;
713
+ target.dispatch(state.update(changes, {
714
+ scrollIntoView: true,
715
+ userEvent: event,
716
+ effects: event == "delete.selection" ? EditorView.announce.of(state.phrase("Selection deleted")) : void 0
717
+ }));
718
+ return true;
719
+ }
720
+ function skipAtomic(target, pos, forward) {
721
+ if (target instanceof EditorView)
722
+ for (let ranges of target.state.facet(EditorView.atomicRanges).map((f) => f(target)))
723
+ ranges.between(pos, pos, (from, to) => {
724
+ if (from < pos && to > pos)
725
+ pos = forward ? to : from;
726
+ });
727
+ return pos;
728
+ }
729
+ const deleteByChar = (target, forward, byIndentUnit) => deleteBy(target, (range) => {
730
+ let pos = range.from, { state } = target, line = state.doc.lineAt(pos), before, targetPos;
731
+ if (byIndentUnit && !forward && pos > line.from && pos < line.from + 200 && !/[^ \t]/.test(before = line.text.slice(0, pos - line.from))) {
732
+ if (before[before.length - 1] == " ")
733
+ return pos - 1;
734
+ let col = countColumn(before, state.tabSize), drop = col % getIndentUnit(state) || getIndentUnit(state);
735
+ for (let i = 0; i < drop && before[before.length - 1 - i] == " "; i++)
736
+ pos--;
737
+ targetPos = pos;
738
+ } else {
739
+ targetPos = findClusterBreak(line.text, pos - line.from, forward, forward) + line.from;
740
+ if (targetPos == pos && line.number != (forward ? state.doc.lines : 1))
741
+ targetPos += forward ? 1 : -1;
742
+ else if (!forward && /[\ufe00-\ufe0f]/.test(line.text.slice(targetPos - line.from, pos - line.from)))
743
+ targetPos = findClusterBreak(line.text, targetPos - line.from, false, false) + line.from;
744
+ }
745
+ return targetPos;
746
+ });
747
+ const deleteCharBackward = (view) => deleteByChar(view, false, true);
748
+ const deleteCharForward = (view) => deleteByChar(view, true, false);
749
+ const deleteByGroup = (target, forward) => deleteBy(target, (range) => {
750
+ let pos = range.head, { state } = target, line = state.doc.lineAt(pos);
751
+ let categorize = state.charCategorizer(pos);
752
+ for (let cat = null; ; ) {
753
+ if (pos == (forward ? line.to : line.from)) {
754
+ if (pos == range.head && line.number != (forward ? state.doc.lines : 1))
755
+ pos += forward ? 1 : -1;
756
+ break;
757
+ }
758
+ let next = findClusterBreak(line.text, pos - line.from, forward) + line.from;
759
+ let nextChar = line.text.slice(Math.min(pos, next) - line.from, Math.max(pos, next) - line.from);
760
+ let nextCat = categorize(nextChar);
761
+ if (cat != null && nextCat != cat)
762
+ break;
763
+ if (nextChar != " " || pos != range.head)
764
+ cat = nextCat;
765
+ pos = next;
766
+ }
767
+ return pos;
768
+ });
769
+ const deleteGroupBackward = (target) => deleteByGroup(target, false);
770
+ const deleteGroupForward = (target) => deleteByGroup(target, true);
771
+ const deleteToLineEnd = (view) => deleteBy(view, (range) => {
772
+ let lineEnd = view.lineBlockAt(range.head).to;
773
+ return range.head < lineEnd ? lineEnd : Math.min(view.state.doc.length, range.head + 1);
774
+ });
775
+ const deleteLineBoundaryBackward = (view) => deleteBy(view, (range) => {
776
+ let lineStart = view.moveToLineBoundary(range, false).head;
777
+ return range.head > lineStart ? lineStart : Math.max(0, range.head - 1);
778
+ });
779
+ const deleteLineBoundaryForward = (view) => deleteBy(view, (range) => {
780
+ let lineStart = view.moveToLineBoundary(range, true).head;
781
+ return range.head < lineStart ? lineStart : Math.min(view.state.doc.length, range.head + 1);
782
+ });
783
+ const splitLine = ({ state, dispatch }) => {
784
+ if (state.readOnly)
785
+ return false;
786
+ let changes = state.changeByRange((range) => {
787
+ return {
788
+ changes: { from: range.from, to: range.to, insert: Text.of(["", ""]) },
789
+ range: EditorSelection.cursor(range.from)
790
+ };
791
+ });
792
+ dispatch(state.update(changes, { scrollIntoView: true, userEvent: "input" }));
793
+ return true;
794
+ };
795
+ const transposeChars = ({ state, dispatch }) => {
796
+ if (state.readOnly)
797
+ return false;
798
+ let changes = state.changeByRange((range) => {
799
+ if (!range.empty || range.from == 0 || range.from == state.doc.length)
800
+ return { range };
801
+ let pos = range.from, line = state.doc.lineAt(pos);
802
+ let from = pos == line.from ? pos - 1 : findClusterBreak(line.text, pos - line.from, false) + line.from;
803
+ let to = pos == line.to ? pos + 1 : findClusterBreak(line.text, pos - line.from, true) + line.from;
804
+ return {
805
+ changes: { from, to, insert: state.doc.slice(pos, to).append(state.doc.slice(from, pos)) },
806
+ range: EditorSelection.cursor(to)
807
+ };
808
+ });
809
+ if (changes.changes.empty)
810
+ return false;
811
+ dispatch(state.update(changes, { scrollIntoView: true, userEvent: "move.character" }));
812
+ return true;
813
+ };
814
+ function selectedLineBlocks(state) {
815
+ let blocks = [], upto = -1;
816
+ for (let range of state.selection.ranges) {
817
+ let startLine = state.doc.lineAt(range.from), endLine = state.doc.lineAt(range.to);
818
+ if (!range.empty && range.to == endLine.from)
819
+ endLine = state.doc.lineAt(range.to - 1);
820
+ if (upto >= startLine.number) {
821
+ let prev = blocks[blocks.length - 1];
822
+ prev.to = endLine.to;
823
+ prev.ranges.push(range);
824
+ } else {
825
+ blocks.push({ from: startLine.from, to: endLine.to, ranges: [range] });
826
+ }
827
+ upto = endLine.number + 1;
828
+ }
829
+ return blocks;
830
+ }
831
+ function moveLine(state, dispatch, forward) {
832
+ if (state.readOnly)
833
+ return false;
834
+ let changes = [], ranges = [];
835
+ for (let block of selectedLineBlocks(state)) {
836
+ if (forward ? block.to == state.doc.length : block.from == 0)
837
+ continue;
838
+ let nextLine = state.doc.lineAt(forward ? block.to + 1 : block.from - 1);
839
+ let size = nextLine.length + 1;
840
+ if (forward) {
841
+ changes.push({ from: block.to, to: nextLine.to }, { from: block.from, insert: nextLine.text + state.lineBreak });
842
+ for (let r of block.ranges)
843
+ ranges.push(EditorSelection.range(Math.min(state.doc.length, r.anchor + size), Math.min(state.doc.length, r.head + size)));
844
+ } else {
845
+ changes.push({ from: nextLine.from, to: block.from }, { from: block.to, insert: state.lineBreak + nextLine.text });
846
+ for (let r of block.ranges)
847
+ ranges.push(EditorSelection.range(r.anchor - size, r.head - size));
848
+ }
849
+ }
850
+ if (!changes.length)
851
+ return false;
852
+ dispatch(state.update({
853
+ changes,
854
+ scrollIntoView: true,
855
+ selection: EditorSelection.create(ranges, state.selection.mainIndex),
856
+ userEvent: "move.line"
857
+ }));
858
+ return true;
859
+ }
860
+ const moveLineUp = ({ state, dispatch }) => moveLine(state, dispatch, false);
861
+ const moveLineDown = ({ state, dispatch }) => moveLine(state, dispatch, true);
862
+ function copyLine(state, dispatch, forward) {
863
+ if (state.readOnly)
864
+ return false;
865
+ let changes = [];
866
+ for (let block of selectedLineBlocks(state)) {
867
+ if (forward)
868
+ changes.push({ from: block.from, insert: state.doc.slice(block.from, block.to) + state.lineBreak });
869
+ else
870
+ changes.push({ from: block.to, insert: state.lineBreak + state.doc.slice(block.from, block.to) });
871
+ }
872
+ dispatch(state.update({ changes, scrollIntoView: true, userEvent: "input.copyline" }));
873
+ return true;
874
+ }
875
+ const copyLineUp = ({ state, dispatch }) => copyLine(state, dispatch, false);
876
+ const copyLineDown = ({ state, dispatch }) => copyLine(state, dispatch, true);
877
+ const deleteLine = (view) => {
878
+ if (view.state.readOnly)
879
+ return false;
880
+ let { state } = view, changes = state.changes(selectedLineBlocks(state).map(({ from, to }) => {
881
+ if (from > 0)
882
+ from--;
883
+ else if (to < state.doc.length)
884
+ to++;
885
+ return { from, to };
886
+ }));
887
+ let selection = updateSel(state.selection, (range) => {
888
+ let dist = void 0;
889
+ if (view.lineWrapping) {
890
+ let block = view.lineBlockAt(range.head), pos = view.coordsAtPos(range.head, range.assoc || 1);
891
+ if (pos)
892
+ dist = block.bottom + view.documentTop - pos.bottom + view.defaultLineHeight / 2;
893
+ }
894
+ return view.moveVertically(range, true, dist);
895
+ }).map(changes);
896
+ view.dispatch({ changes, selection, scrollIntoView: true, userEvent: "delete.line" });
897
+ return true;
898
+ };
899
+ function isBetweenBrackets(state, pos) {
900
+ if (/\(\)|\[\]|\{\}/.test(state.sliceDoc(pos - 1, pos + 1)))
901
+ return { from: pos, to: pos };
902
+ let context = syntaxTree(state).resolveInner(pos);
903
+ let before = context.childBefore(pos), after = context.childAfter(pos), closedBy;
904
+ if (before && after && before.to <= pos && after.from >= pos && (closedBy = before.type.prop(NodeProp.closedBy)) && closedBy.indexOf(after.name) > -1 && state.doc.lineAt(before.to).from == state.doc.lineAt(after.from).from && !/\S/.test(state.sliceDoc(before.to, after.from)))
905
+ return { from: before.to, to: after.from };
906
+ return null;
907
+ }
908
+ const insertNewlineAndIndent = /* @__PURE__ */ newlineAndIndent(false);
909
+ const insertBlankLine = /* @__PURE__ */ newlineAndIndent(true);
910
+ function newlineAndIndent(atEof) {
911
+ return ({ state, dispatch }) => {
912
+ if (state.readOnly)
913
+ return false;
914
+ let changes = state.changeByRange((range) => {
915
+ let { from, to } = range, line = state.doc.lineAt(from);
916
+ let explode = !atEof && from == to && isBetweenBrackets(state, from);
917
+ if (atEof)
918
+ from = to = (to <= line.to ? line : state.doc.lineAt(to)).to;
919
+ let cx = new IndentContext(state, { simulateBreak: from, simulateDoubleBreak: !!explode });
920
+ let indent = getIndentation(cx, from);
921
+ if (indent == null)
922
+ indent = countColumn(/^\s*/.exec(state.doc.lineAt(from).text)[0], state.tabSize);
923
+ while (to < line.to && /\s/.test(line.text[to - line.from]))
924
+ to++;
925
+ if (explode)
926
+ ({ from, to } = explode);
927
+ else if (from > line.from && from < line.from + 100 && !/\S/.test(line.text.slice(0, from)))
928
+ from = line.from;
929
+ let insert = ["", indentString(state, indent)];
930
+ if (explode)
931
+ insert.push(indentString(state, cx.lineIndent(line.from, -1)));
932
+ return {
933
+ changes: { from, to, insert: Text.of(insert) },
934
+ range: EditorSelection.cursor(from + 1 + insert[1].length)
935
+ };
936
+ });
937
+ dispatch(state.update(changes, { scrollIntoView: true, userEvent: "input" }));
938
+ return true;
939
+ };
940
+ }
941
+ function changeBySelectedLine(state, f) {
942
+ let atLine = -1;
943
+ return state.changeByRange((range) => {
944
+ let changes = [];
945
+ for (let pos = range.from; pos <= range.to; ) {
946
+ let line = state.doc.lineAt(pos);
947
+ if (line.number > atLine && (range.empty || range.to > line.from)) {
948
+ f(line, changes, range);
949
+ atLine = line.number;
950
+ }
951
+ pos = line.to + 1;
952
+ }
953
+ let changeSet = state.changes(changes);
954
+ return {
955
+ changes,
956
+ range: EditorSelection.range(changeSet.mapPos(range.anchor, 1), changeSet.mapPos(range.head, 1))
957
+ };
958
+ });
959
+ }
960
+ const indentSelection = ({ state, dispatch }) => {
961
+ if (state.readOnly)
962
+ return false;
963
+ let updated = /* @__PURE__ */ Object.create(null);
964
+ let context = new IndentContext(state, { overrideIndentation: (start) => {
965
+ let found = updated[start];
966
+ return found == null ? -1 : found;
967
+ } });
968
+ let changes = changeBySelectedLine(state, (line, changes2, range) => {
969
+ let indent = getIndentation(context, line.from);
970
+ if (indent == null)
971
+ return;
972
+ if (!/\S/.test(line.text))
973
+ indent = 0;
974
+ let cur = /^\s*/.exec(line.text)[0];
975
+ let norm = indentString(state, indent);
976
+ if (cur != norm || range.from < line.from + cur.length) {
977
+ updated[line.from] = indent;
978
+ changes2.push({ from: line.from, to: line.from + cur.length, insert: norm });
979
+ }
980
+ });
981
+ if (!changes.changes.empty)
982
+ dispatch(state.update(changes, { userEvent: "indent" }));
983
+ return true;
984
+ };
985
+ const indentMore = ({ state, dispatch }) => {
986
+ if (state.readOnly)
987
+ return false;
988
+ dispatch(state.update(changeBySelectedLine(state, (line, changes) => {
989
+ changes.push({ from: line.from, insert: state.facet(indentUnit) });
990
+ }), { userEvent: "input.indent" }));
991
+ return true;
992
+ };
993
+ const indentLess = ({ state, dispatch }) => {
994
+ if (state.readOnly)
995
+ return false;
996
+ dispatch(state.update(changeBySelectedLine(state, (line, changes) => {
997
+ let space = /^\s*/.exec(line.text)[0];
998
+ if (!space)
999
+ return;
1000
+ let col = countColumn(space, state.tabSize), keep = 0;
1001
+ let insert = indentString(state, Math.max(0, col - getIndentUnit(state)));
1002
+ while (keep < space.length && keep < insert.length && space.charCodeAt(keep) == insert.charCodeAt(keep))
1003
+ keep++;
1004
+ changes.push({ from: line.from + keep, to: line.from + space.length, insert: insert.slice(keep) });
1005
+ }), { userEvent: "delete.dedent" }));
1006
+ return true;
1007
+ };
1008
+ const toggleTabFocusMode = (view) => {
1009
+ view.setTabFocusMode();
1010
+ return true;
1011
+ };
1012
+ const emacsStyleKeymap = [
1013
+ { key: "Ctrl-b", run: cursorCharLeft, shift: selectCharLeft, preventDefault: true },
1014
+ { key: "Ctrl-f", run: cursorCharRight, shift: selectCharRight },
1015
+ { key: "Ctrl-p", run: cursorLineUp, shift: selectLineUp },
1016
+ { key: "Ctrl-n", run: cursorLineDown, shift: selectLineDown },
1017
+ { key: "Ctrl-a", run: cursorLineStart, shift: selectLineStart },
1018
+ { key: "Ctrl-e", run: cursorLineEnd, shift: selectLineEnd },
1019
+ { key: "Ctrl-d", run: deleteCharForward },
1020
+ { key: "Ctrl-h", run: deleteCharBackward },
1021
+ { key: "Ctrl-k", run: deleteToLineEnd },
1022
+ { key: "Ctrl-Alt-h", run: deleteGroupBackward },
1023
+ { key: "Ctrl-o", run: splitLine },
1024
+ { key: "Ctrl-t", run: transposeChars },
1025
+ { key: "Ctrl-v", run: cursorPageDown }
1026
+ ];
1027
+ const standardKeymap = /* @__PURE__ */ [
1028
+ { key: "ArrowLeft", run: cursorCharLeft, shift: selectCharLeft, preventDefault: true },
1029
+ { key: "Mod-ArrowLeft", mac: "Alt-ArrowLeft", run: cursorGroupLeft, shift: selectGroupLeft, preventDefault: true },
1030
+ { mac: "Cmd-ArrowLeft", run: cursorLineBoundaryLeft, shift: selectLineBoundaryLeft, preventDefault: true },
1031
+ { key: "ArrowRight", run: cursorCharRight, shift: selectCharRight, preventDefault: true },
1032
+ { key: "Mod-ArrowRight", mac: "Alt-ArrowRight", run: cursorGroupRight, shift: selectGroupRight, preventDefault: true },
1033
+ { mac: "Cmd-ArrowRight", run: cursorLineBoundaryRight, shift: selectLineBoundaryRight, preventDefault: true },
1034
+ { key: "ArrowUp", run: cursorLineUp, shift: selectLineUp, preventDefault: true },
1035
+ { mac: "Cmd-ArrowUp", run: cursorDocStart, shift: selectDocStart },
1036
+ { mac: "Ctrl-ArrowUp", run: cursorPageUp, shift: selectPageUp },
1037
+ { key: "ArrowDown", run: cursorLineDown, shift: selectLineDown, preventDefault: true },
1038
+ { mac: "Cmd-ArrowDown", run: cursorDocEnd, shift: selectDocEnd },
1039
+ { mac: "Ctrl-ArrowDown", run: cursorPageDown, shift: selectPageDown },
1040
+ { key: "PageUp", run: cursorPageUp, shift: selectPageUp },
1041
+ { key: "PageDown", run: cursorPageDown, shift: selectPageDown },
1042
+ { key: "Home", run: cursorLineBoundaryBackward, shift: selectLineBoundaryBackward, preventDefault: true },
1043
+ { key: "Mod-Home", run: cursorDocStart, shift: selectDocStart },
1044
+ { key: "End", run: cursorLineBoundaryForward, shift: selectLineBoundaryForward, preventDefault: true },
1045
+ { key: "Mod-End", run: cursorDocEnd, shift: selectDocEnd },
1046
+ { key: "Enter", run: insertNewlineAndIndent, shift: insertNewlineAndIndent },
1047
+ { key: "Mod-a", run: selectAll },
1048
+ { key: "Backspace", run: deleteCharBackward, shift: deleteCharBackward },
1049
+ { key: "Delete", run: deleteCharForward },
1050
+ { key: "Mod-Backspace", mac: "Alt-Backspace", run: deleteGroupBackward },
1051
+ { key: "Mod-Delete", mac: "Alt-Delete", run: deleteGroupForward },
1052
+ { mac: "Mod-Backspace", run: deleteLineBoundaryBackward },
1053
+ { mac: "Mod-Delete", run: deleteLineBoundaryForward }
1054
+ ].concat(/* @__PURE__ */ emacsStyleKeymap.map((b) => ({ mac: b.key, run: b.run, shift: b.shift })));
1055
+ const defaultKeymap = /* @__PURE__ */ [
1056
+ { key: "Alt-ArrowLeft", mac: "Ctrl-ArrowLeft", run: cursorSyntaxLeft, shift: selectSyntaxLeft },
1057
+ { key: "Alt-ArrowRight", mac: "Ctrl-ArrowRight", run: cursorSyntaxRight, shift: selectSyntaxRight },
1058
+ { key: "Alt-ArrowUp", run: moveLineUp },
1059
+ { key: "Shift-Alt-ArrowUp", run: copyLineUp },
1060
+ { key: "Alt-ArrowDown", run: moveLineDown },
1061
+ { key: "Shift-Alt-ArrowDown", run: copyLineDown },
1062
+ { key: "Escape", run: simplifySelection },
1063
+ { key: "Mod-Enter", run: insertBlankLine },
1064
+ { key: "Alt-l", mac: "Ctrl-l", run: selectLine },
1065
+ { key: "Mod-i", run: selectParentSyntax, preventDefault: true },
1066
+ { key: "Mod-[", run: indentLess },
1067
+ { key: "Mod-]", run: indentMore },
1068
+ { key: "Mod-Alt-\\", run: indentSelection },
1069
+ { key: "Shift-Mod-k", run: deleteLine },
1070
+ { key: "Shift-Mod-\\", run: cursorMatchingBracket },
1071
+ { key: "Mod-/", run: toggleComment },
1072
+ { key: "Alt-A", run: toggleBlockComment },
1073
+ { key: "Ctrl-m", mac: "Shift-Alt-m", run: toggleTabFocusMode }
1074
+ ].concat(standardKeymap);
1075
+ const indentWithTab = { key: "Tab", run: indentMore, shift: indentLess };
1076
+ const basicNormalize = typeof String.prototype.normalize == "function" ? (x) => x.normalize("NFKD") : (x) => x;
1077
+ class SearchCursor {
1078
+ /**
1079
+ Create a text cursor. The query is the search string, `from` to
1080
+ `to` provides the region to search.
1081
+
1082
+ When `normalize` is given, it will be called, on both the query
1083
+ string and the content it is matched against, before comparing.
1084
+ You can, for example, create a case-insensitive search by
1085
+ passing `s => s.toLowerCase()`.
1086
+
1087
+ Text is always normalized with
1088
+ [`.normalize("NFKD")`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize)
1089
+ (when supported).
1090
+ */
1091
+ constructor(text, query, from = 0, to = text.length, normalize, test) {
1092
+ this.test = test;
1093
+ this.value = { from: 0, to: 0 };
1094
+ this.done = false;
1095
+ this.matches = [];
1096
+ this.buffer = "";
1097
+ this.bufferPos = 0;
1098
+ this.iter = text.iterRange(from, to);
1099
+ this.bufferStart = from;
1100
+ this.normalize = normalize ? (x) => normalize(basicNormalize(x)) : basicNormalize;
1101
+ this.query = this.normalize(query);
1102
+ }
1103
+ peek() {
1104
+ if (this.bufferPos == this.buffer.length) {
1105
+ this.bufferStart += this.buffer.length;
1106
+ this.iter.next();
1107
+ if (this.iter.done)
1108
+ return -1;
1109
+ this.bufferPos = 0;
1110
+ this.buffer = this.iter.value;
1111
+ }
1112
+ return codePointAt(this.buffer, this.bufferPos);
1113
+ }
1114
+ /**
1115
+ Look for the next match. Updates the iterator's
1116
+ [`value`](https://codemirror.net/6/docs/ref/#search.SearchCursor.value) and
1117
+ [`done`](https://codemirror.net/6/docs/ref/#search.SearchCursor.done) properties. Should be called
1118
+ at least once before using the cursor.
1119
+ */
1120
+ next() {
1121
+ while (this.matches.length)
1122
+ this.matches.pop();
1123
+ return this.nextOverlapping();
1124
+ }
1125
+ /**
1126
+ The `next` method will ignore matches that partially overlap a
1127
+ previous match. This method behaves like `next`, but includes
1128
+ such matches.
1129
+ */
1130
+ nextOverlapping() {
1131
+ for (; ; ) {
1132
+ let next = this.peek();
1133
+ if (next < 0) {
1134
+ this.done = true;
1135
+ return this;
1136
+ }
1137
+ let str = fromCodePoint(next), start = this.bufferStart + this.bufferPos;
1138
+ this.bufferPos += codePointSize(next);
1139
+ let norm = this.normalize(str);
1140
+ if (norm.length)
1141
+ for (let i = 0, pos = start; ; i++) {
1142
+ let code = norm.charCodeAt(i);
1143
+ let match = this.match(code, pos, this.bufferPos + this.bufferStart);
1144
+ if (i == norm.length - 1) {
1145
+ if (match) {
1146
+ this.value = match;
1147
+ return this;
1148
+ }
1149
+ break;
1150
+ }
1151
+ if (pos == start && i < str.length && str.charCodeAt(i) == code)
1152
+ pos++;
1153
+ }
1154
+ }
1155
+ }
1156
+ match(code, pos, end) {
1157
+ let match = null;
1158
+ for (let i = 0; i < this.matches.length; i += 2) {
1159
+ let index = this.matches[i], keep = false;
1160
+ if (this.query.charCodeAt(index) == code) {
1161
+ if (index == this.query.length - 1) {
1162
+ match = { from: this.matches[i + 1], to: end };
1163
+ } else {
1164
+ this.matches[i]++;
1165
+ keep = true;
1166
+ }
1167
+ }
1168
+ if (!keep) {
1169
+ this.matches.splice(i, 2);
1170
+ i -= 2;
1171
+ }
1172
+ }
1173
+ if (this.query.charCodeAt(0) == code) {
1174
+ if (this.query.length == 1)
1175
+ match = { from: pos, to: end };
1176
+ else
1177
+ this.matches.push(1, pos);
1178
+ }
1179
+ if (match && this.test && !this.test(match.from, match.to, this.buffer, this.bufferStart))
1180
+ match = null;
1181
+ return match;
1182
+ }
1183
+ }
1184
+ if (typeof Symbol != "undefined")
1185
+ SearchCursor.prototype[Symbol.iterator] = function() {
1186
+ return this;
1187
+ };
1188
+ const empty = { from: -1, to: -1, match: /* @__PURE__ */ /.*/.exec("") };
1189
+ const baseFlags = "gm" + (/x/.unicode == null ? "" : "u");
1190
+ class RegExpCursor {
1191
+ /**
1192
+ Create a cursor that will search the given range in the given
1193
+ document. `query` should be the raw pattern (as you'd pass it to
1194
+ `new RegExp`).
1195
+ */
1196
+ constructor(text, query, options, from = 0, to = text.length) {
1197
+ this.text = text;
1198
+ this.to = to;
1199
+ this.curLine = "";
1200
+ this.done = false;
1201
+ this.value = empty;
1202
+ if (/\\[sWDnr]|\n|\r|\[\^/.test(query))
1203
+ return new MultilineRegExpCursor(text, query, options, from, to);
1204
+ this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
1205
+ this.test = options === null || options === void 0 ? void 0 : options.test;
1206
+ this.iter = text.iter();
1207
+ let startLine = text.lineAt(from);
1208
+ this.curLineStart = startLine.from;
1209
+ this.matchPos = toCharEnd(text, from);
1210
+ this.getLine(this.curLineStart);
1211
+ }
1212
+ getLine(skip) {
1213
+ this.iter.next(skip);
1214
+ if (this.iter.lineBreak) {
1215
+ this.curLine = "";
1216
+ } else {
1217
+ this.curLine = this.iter.value;
1218
+ if (this.curLineStart + this.curLine.length > this.to)
1219
+ this.curLine = this.curLine.slice(0, this.to - this.curLineStart);
1220
+ this.iter.next();
1221
+ }
1222
+ }
1223
+ nextLine() {
1224
+ this.curLineStart = this.curLineStart + this.curLine.length + 1;
1225
+ if (this.curLineStart > this.to)
1226
+ this.curLine = "";
1227
+ else
1228
+ this.getLine(0);
1229
+ }
1230
+ /**
1231
+ Move to the next match, if there is one.
1232
+ */
1233
+ next() {
1234
+ for (let off = this.matchPos - this.curLineStart; ; ) {
1235
+ this.re.lastIndex = off;
1236
+ let match = this.matchPos <= this.to && this.re.exec(this.curLine);
1237
+ if (match) {
1238
+ let from = this.curLineStart + match.index, to = from + match[0].length;
1239
+ this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0));
1240
+ if (from == this.curLineStart + this.curLine.length)
1241
+ this.nextLine();
1242
+ if ((from < to || from > this.value.to) && (!this.test || this.test(from, to, match))) {
1243
+ this.value = { from, to, match };
1244
+ return this;
1245
+ }
1246
+ off = this.matchPos - this.curLineStart;
1247
+ } else if (this.curLineStart + this.curLine.length < this.to) {
1248
+ this.nextLine();
1249
+ off = 0;
1250
+ } else {
1251
+ this.done = true;
1252
+ return this;
1253
+ }
1254
+ }
1255
+ }
1256
+ }
1257
+ const flattened = /* @__PURE__ */ new WeakMap();
1258
+ class FlattenedDoc {
1259
+ constructor(from, text) {
1260
+ this.from = from;
1261
+ this.text = text;
1262
+ }
1263
+ get to() {
1264
+ return this.from + this.text.length;
1265
+ }
1266
+ static get(doc, from, to) {
1267
+ let cached = flattened.get(doc);
1268
+ if (!cached || cached.from >= to || cached.to <= from) {
1269
+ let flat = new FlattenedDoc(from, doc.sliceString(from, to));
1270
+ flattened.set(doc, flat);
1271
+ return flat;
1272
+ }
1273
+ if (cached.from == from && cached.to == to)
1274
+ return cached;
1275
+ let { text, from: cachedFrom } = cached;
1276
+ if (cachedFrom > from) {
1277
+ text = doc.sliceString(from, cachedFrom) + text;
1278
+ cachedFrom = from;
1279
+ }
1280
+ if (cached.to < to)
1281
+ text += doc.sliceString(cached.to, to);
1282
+ flattened.set(doc, new FlattenedDoc(cachedFrom, text));
1283
+ return new FlattenedDoc(from, text.slice(from - cachedFrom, to - cachedFrom));
1284
+ }
1285
+ }
1286
+ class MultilineRegExpCursor {
1287
+ constructor(text, query, options, from, to) {
1288
+ this.text = text;
1289
+ this.to = to;
1290
+ this.done = false;
1291
+ this.value = empty;
1292
+ this.matchPos = toCharEnd(text, from);
1293
+ this.re = new RegExp(query, baseFlags + ((options === null || options === void 0 ? void 0 : options.ignoreCase) ? "i" : ""));
1294
+ this.test = options === null || options === void 0 ? void 0 : options.test;
1295
+ this.flat = FlattenedDoc.get(text, from, this.chunkEnd(
1296
+ from + 5e3
1297
+ /* Chunk.Base */
1298
+ ));
1299
+ }
1300
+ chunkEnd(pos) {
1301
+ return pos >= this.to ? this.to : this.text.lineAt(pos).to;
1302
+ }
1303
+ next() {
1304
+ for (; ; ) {
1305
+ let off = this.re.lastIndex = this.matchPos - this.flat.from;
1306
+ let match = this.re.exec(this.flat.text);
1307
+ if (match && !match[0] && match.index == off) {
1308
+ this.re.lastIndex = off + 1;
1309
+ match = this.re.exec(this.flat.text);
1310
+ }
1311
+ if (match) {
1312
+ let from = this.flat.from + match.index, to = from + match[0].length;
1313
+ if ((this.flat.to >= this.to || match.index + match[0].length <= this.flat.text.length - 10) && (!this.test || this.test(from, to, match))) {
1314
+ this.value = { from, to, match };
1315
+ this.matchPos = toCharEnd(this.text, to + (from == to ? 1 : 0));
1316
+ return this;
1317
+ }
1318
+ }
1319
+ if (this.flat.to == this.to) {
1320
+ this.done = true;
1321
+ return this;
1322
+ }
1323
+ this.flat = FlattenedDoc.get(this.text, this.flat.from, this.chunkEnd(this.flat.from + this.flat.text.length * 2));
1324
+ }
1325
+ }
1326
+ }
1327
+ if (typeof Symbol != "undefined") {
1328
+ RegExpCursor.prototype[Symbol.iterator] = MultilineRegExpCursor.prototype[Symbol.iterator] = function() {
1329
+ return this;
1330
+ };
1331
+ }
1332
+ function validRegExp(source) {
1333
+ try {
1334
+ new RegExp(source, baseFlags);
1335
+ return true;
1336
+ } catch (_a) {
1337
+ return false;
1338
+ }
1339
+ }
1340
+ function toCharEnd(text, pos) {
1341
+ if (pos >= text.length)
1342
+ return pos;
1343
+ let line = text.lineAt(pos), next;
1344
+ while (pos < line.to && (next = line.text.charCodeAt(pos - line.from)) >= 56320 && next < 57344)
1345
+ pos++;
1346
+ return pos;
1347
+ }
1348
+ function createLineDialog(view) {
1349
+ let line = String(view.state.doc.lineAt(view.state.selection.main.head).number);
1350
+ let input = crelt("input", { class: "cm-textfield", name: "line", value: line });
1351
+ let dom = crelt("form", {
1352
+ class: "cm-gotoLine",
1353
+ onkeydown: (event) => {
1354
+ if (event.keyCode == 27) {
1355
+ event.preventDefault();
1356
+ view.dispatch({ effects: dialogEffect.of(false) });
1357
+ view.focus();
1358
+ } else if (event.keyCode == 13) {
1359
+ event.preventDefault();
1360
+ go();
1361
+ }
1362
+ },
1363
+ onsubmit: (event) => {
1364
+ event.preventDefault();
1365
+ go();
1366
+ }
1367
+ }, crelt("label", view.state.phrase("Go to line"), ": ", input), " ", crelt("button", { class: "cm-button", type: "submit" }, view.state.phrase("go")), crelt("button", {
1368
+ name: "close",
1369
+ onclick: () => {
1370
+ view.dispatch({ effects: dialogEffect.of(false) });
1371
+ view.focus();
1372
+ },
1373
+ "aria-label": view.state.phrase("close"),
1374
+ type: "button"
1375
+ }, ["×"]));
1376
+ function go() {
1377
+ let match = /^([+-])?(\d+)?(:\d+)?(%)?$/.exec(input.value);
1378
+ if (!match)
1379
+ return;
1380
+ let { state } = view, startLine = state.doc.lineAt(state.selection.main.head);
1381
+ let [, sign, ln, cl, percent] = match;
1382
+ let col = cl ? +cl.slice(1) : 0;
1383
+ let line2 = ln ? +ln : startLine.number;
1384
+ if (ln && percent) {
1385
+ let pc = line2 / 100;
1386
+ if (sign)
1387
+ pc = pc * (sign == "-" ? -1 : 1) + startLine.number / state.doc.lines;
1388
+ line2 = Math.round(state.doc.lines * pc);
1389
+ } else if (ln && sign) {
1390
+ line2 = line2 * (sign == "-" ? -1 : 1) + startLine.number;
1391
+ }
1392
+ let docLine = state.doc.line(Math.max(1, Math.min(state.doc.lines, line2)));
1393
+ let selection = EditorSelection.cursor(docLine.from + Math.max(0, Math.min(col, docLine.length)));
1394
+ view.dispatch({
1395
+ effects: [dialogEffect.of(false), EditorView.scrollIntoView(selection.from, { y: "center" })],
1396
+ selection
1397
+ });
1398
+ view.focus();
1399
+ }
1400
+ return { dom };
1401
+ }
1402
+ const dialogEffect = /* @__PURE__ */ StateEffect.define();
1403
+ const dialogField = /* @__PURE__ */ StateField.define({
1404
+ create() {
1405
+ return true;
1406
+ },
1407
+ update(value, tr) {
1408
+ for (let e of tr.effects)
1409
+ if (e.is(dialogEffect))
1410
+ value = e.value;
1411
+ return value;
1412
+ },
1413
+ provide: (f) => showPanel.from(f, (val) => val ? createLineDialog : null)
1414
+ });
1415
+ const gotoLine = (view) => {
1416
+ let panel = getPanel(view, createLineDialog);
1417
+ if (!panel) {
1418
+ let effects = [dialogEffect.of(true)];
1419
+ if (view.state.field(dialogField, false) == null)
1420
+ effects.push(StateEffect.appendConfig.of([dialogField, baseTheme$1]));
1421
+ view.dispatch({ effects });
1422
+ panel = getPanel(view, createLineDialog);
1423
+ }
1424
+ if (panel)
1425
+ panel.dom.querySelector("input").select();
1426
+ return true;
1427
+ };
1428
+ const baseTheme$1 = /* @__PURE__ */ EditorView.baseTheme({
1429
+ ".cm-panel.cm-gotoLine": {
1430
+ padding: "2px 6px 4px",
1431
+ position: "relative",
1432
+ "& label": { fontSize: "80%" },
1433
+ "& [name=close]": {
1434
+ position: "absolute",
1435
+ top: "0",
1436
+ bottom: "0",
1437
+ right: "4px",
1438
+ backgroundColor: "inherit",
1439
+ border: "none",
1440
+ font: "inherit",
1441
+ padding: "0"
1442
+ }
1443
+ }
1444
+ });
1445
+ const defaultHighlightOptions = {
1446
+ highlightWordAroundCursor: false,
1447
+ minSelectionLength: 1,
1448
+ maxMatches: 100,
1449
+ wholeWords: false
1450
+ };
1451
+ const highlightConfig = /* @__PURE__ */ Facet.define({
1452
+ combine(options) {
1453
+ return combineConfig(options, defaultHighlightOptions, {
1454
+ highlightWordAroundCursor: (a, b) => a || b,
1455
+ minSelectionLength: Math.min,
1456
+ maxMatches: Math.min
1457
+ });
1458
+ }
1459
+ });
1460
+ function highlightSelectionMatches(options) {
1461
+ let ext = [defaultTheme, matchHighlighter];
1462
+ return ext;
1463
+ }
1464
+ const matchDeco = /* @__PURE__ */ Decoration.mark({ class: "cm-selectionMatch" });
1465
+ const mainMatchDeco = /* @__PURE__ */ Decoration.mark({ class: "cm-selectionMatch cm-selectionMatch-main" });
1466
+ function insideWordBoundaries(check, state, from, to) {
1467
+ return (from == 0 || check(state.sliceDoc(from - 1, from)) != CharCategory.Word) && (to == state.doc.length || check(state.sliceDoc(to, to + 1)) != CharCategory.Word);
1468
+ }
1469
+ function insideWord(check, state, from, to) {
1470
+ return check(state.sliceDoc(from, from + 1)) == CharCategory.Word && check(state.sliceDoc(to - 1, to)) == CharCategory.Word;
1471
+ }
1472
+ const matchHighlighter = /* @__PURE__ */ ViewPlugin.fromClass(class {
1473
+ constructor(view) {
1474
+ this.decorations = this.getDeco(view);
1475
+ }
1476
+ update(update) {
1477
+ if (update.selectionSet || update.docChanged || update.viewportChanged)
1478
+ this.decorations = this.getDeco(update.view);
1479
+ }
1480
+ getDeco(view) {
1481
+ let conf = view.state.facet(highlightConfig);
1482
+ let { state } = view, sel = state.selection;
1483
+ if (sel.ranges.length > 1)
1484
+ return Decoration.none;
1485
+ let range = sel.main, query, check = null;
1486
+ if (range.empty) {
1487
+ if (!conf.highlightWordAroundCursor)
1488
+ return Decoration.none;
1489
+ let word = state.wordAt(range.head);
1490
+ if (!word)
1491
+ return Decoration.none;
1492
+ check = state.charCategorizer(range.head);
1493
+ query = state.sliceDoc(word.from, word.to);
1494
+ } else {
1495
+ let len = range.to - range.from;
1496
+ if (len < conf.minSelectionLength || len > 200)
1497
+ return Decoration.none;
1498
+ if (conf.wholeWords) {
1499
+ query = state.sliceDoc(range.from, range.to);
1500
+ check = state.charCategorizer(range.head);
1501
+ if (!(insideWordBoundaries(check, state, range.from, range.to) && insideWord(check, state, range.from, range.to)))
1502
+ return Decoration.none;
1503
+ } else {
1504
+ query = state.sliceDoc(range.from, range.to);
1505
+ if (!query)
1506
+ return Decoration.none;
1507
+ }
1508
+ }
1509
+ let deco = [];
1510
+ for (let part of view.visibleRanges) {
1511
+ let cursor = new SearchCursor(state.doc, query, part.from, part.to);
1512
+ while (!cursor.next().done) {
1513
+ let { from, to } = cursor.value;
1514
+ if (!check || insideWordBoundaries(check, state, from, to)) {
1515
+ if (range.empty && from <= range.from && to >= range.to)
1516
+ deco.push(mainMatchDeco.range(from, to));
1517
+ else if (from >= range.to || to <= range.from)
1518
+ deco.push(matchDeco.range(from, to));
1519
+ if (deco.length > conf.maxMatches)
1520
+ return Decoration.none;
1521
+ }
1522
+ }
1523
+ }
1524
+ return Decoration.set(deco);
1525
+ }
1526
+ }, {
1527
+ decorations: (v) => v.decorations
1528
+ });
1529
+ const defaultTheme = /* @__PURE__ */ EditorView.baseTheme({
1530
+ ".cm-selectionMatch": { backgroundColor: "#99ff7780" },
1531
+ ".cm-searchMatch .cm-selectionMatch": { backgroundColor: "transparent" }
1532
+ });
1533
+ const selectWord = ({ state, dispatch }) => {
1534
+ let { selection } = state;
1535
+ let newSel = EditorSelection.create(selection.ranges.map((range) => state.wordAt(range.head) || EditorSelection.cursor(range.head)), selection.mainIndex);
1536
+ if (newSel.eq(selection))
1537
+ return false;
1538
+ dispatch(state.update({ selection: newSel }));
1539
+ return true;
1540
+ };
1541
+ function findNextOccurrence(state, query) {
1542
+ let { main, ranges } = state.selection;
1543
+ let word = state.wordAt(main.head), fullWord = word && word.from == main.from && word.to == main.to;
1544
+ for (let cycled = false, cursor = new SearchCursor(state.doc, query, ranges[ranges.length - 1].to); ; ) {
1545
+ cursor.next();
1546
+ if (cursor.done) {
1547
+ if (cycled)
1548
+ return null;
1549
+ cursor = new SearchCursor(state.doc, query, 0, Math.max(0, ranges[ranges.length - 1].from - 1));
1550
+ cycled = true;
1551
+ } else {
1552
+ if (cycled && ranges.some((r) => r.from == cursor.value.from))
1553
+ continue;
1554
+ if (fullWord) {
1555
+ let word2 = state.wordAt(cursor.value.from);
1556
+ if (!word2 || word2.from != cursor.value.from || word2.to != cursor.value.to)
1557
+ continue;
1558
+ }
1559
+ return cursor.value;
1560
+ }
1561
+ }
1562
+ }
1563
+ const selectNextOccurrence = ({ state, dispatch }) => {
1564
+ let { ranges } = state.selection;
1565
+ if (ranges.some((sel) => sel.from === sel.to))
1566
+ return selectWord({ state, dispatch });
1567
+ let searchedText = state.sliceDoc(ranges[0].from, ranges[0].to);
1568
+ if (state.selection.ranges.some((r) => state.sliceDoc(r.from, r.to) != searchedText))
1569
+ return false;
1570
+ let range = findNextOccurrence(state, searchedText);
1571
+ if (!range)
1572
+ return false;
1573
+ dispatch(state.update({
1574
+ selection: state.selection.addRange(EditorSelection.range(range.from, range.to), false),
1575
+ effects: EditorView.scrollIntoView(range.to)
1576
+ }));
1577
+ return true;
1578
+ };
1579
+ const searchConfigFacet = /* @__PURE__ */ Facet.define({
1580
+ combine(configs) {
1581
+ return combineConfig(configs, {
1582
+ top: false,
1583
+ caseSensitive: false,
1584
+ literal: false,
1585
+ regexp: false,
1586
+ wholeWord: false,
1587
+ createPanel: (view) => new SearchPanel(view),
1588
+ scrollToMatch: (range) => EditorView.scrollIntoView(range)
1589
+ });
1590
+ }
1591
+ });
1592
+ class SearchQuery {
1593
+ /**
1594
+ Create a query object.
1595
+ */
1596
+ constructor(config) {
1597
+ this.search = config.search;
1598
+ this.caseSensitive = !!config.caseSensitive;
1599
+ this.literal = !!config.literal;
1600
+ this.regexp = !!config.regexp;
1601
+ this.replace = config.replace || "";
1602
+ this.valid = !!this.search && (!this.regexp || validRegExp(this.search));
1603
+ this.unquoted = this.unquote(this.search);
1604
+ this.wholeWord = !!config.wholeWord;
1605
+ }
1606
+ /**
1607
+ @internal
1608
+ */
1609
+ unquote(text) {
1610
+ return this.literal ? text : text.replace(/\\([nrt\\])/g, (_, ch) => ch == "n" ? "\n" : ch == "r" ? "\r" : ch == "t" ? " " : "\\");
1611
+ }
1612
+ /**
1613
+ Compare this query to another query.
1614
+ */
1615
+ eq(other) {
1616
+ return this.search == other.search && this.replace == other.replace && this.caseSensitive == other.caseSensitive && this.regexp == other.regexp && this.wholeWord == other.wholeWord;
1617
+ }
1618
+ /**
1619
+ @internal
1620
+ */
1621
+ create() {
1622
+ return this.regexp ? new RegExpQuery(this) : new StringQuery(this);
1623
+ }
1624
+ /**
1625
+ Get a search cursor for this query, searching through the given
1626
+ range in the given state.
1627
+ */
1628
+ getCursor(state, from = 0, to) {
1629
+ let st = state.doc ? state : EditorState.create({ doc: state });
1630
+ if (to == null)
1631
+ to = st.doc.length;
1632
+ return this.regexp ? regexpCursor(this, st, from, to) : stringCursor(this, st, from, to);
1633
+ }
1634
+ }
1635
+ class QueryType {
1636
+ constructor(spec) {
1637
+ this.spec = spec;
1638
+ }
1639
+ }
1640
+ function stringCursor(spec, state, from, to) {
1641
+ return new SearchCursor(state.doc, spec.unquoted, from, to, spec.caseSensitive ? void 0 : (x) => x.toLowerCase(), spec.wholeWord ? stringWordTest(state.doc, state.charCategorizer(state.selection.main.head)) : void 0);
1642
+ }
1643
+ function stringWordTest(doc, categorizer) {
1644
+ return (from, to, buf, bufPos) => {
1645
+ if (bufPos > from || bufPos + buf.length < to) {
1646
+ bufPos = Math.max(0, from - 2);
1647
+ buf = doc.sliceString(bufPos, Math.min(doc.length, to + 2));
1648
+ }
1649
+ 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);
1650
+ };
1651
+ }
1652
+ class StringQuery extends QueryType {
1653
+ constructor(spec) {
1654
+ super(spec);
1655
+ }
1656
+ nextMatch(state, curFrom, curTo) {
1657
+ let cursor = stringCursor(this.spec, state, curTo, state.doc.length).nextOverlapping();
1658
+ if (cursor.done) {
1659
+ let end = Math.min(state.doc.length, curFrom + this.spec.unquoted.length);
1660
+ cursor = stringCursor(this.spec, state, 0, end).nextOverlapping();
1661
+ }
1662
+ return cursor.done || cursor.value.from == curFrom && cursor.value.to == curTo ? null : cursor.value;
1663
+ }
1664
+ // Searching in reverse is, rather than implementing an inverted search
1665
+ // cursor, done by scanning chunk after chunk forward.
1666
+ prevMatchInRange(state, from, to) {
1667
+ for (let pos = to; ; ) {
1668
+ let start = Math.max(from, pos - 1e4 - this.spec.unquoted.length);
1669
+ let cursor = stringCursor(this.spec, state, start, pos), range = null;
1670
+ while (!cursor.nextOverlapping().done)
1671
+ range = cursor.value;
1672
+ if (range)
1673
+ return range;
1674
+ if (start == from)
1675
+ return null;
1676
+ pos -= 1e4;
1677
+ }
1678
+ }
1679
+ prevMatch(state, curFrom, curTo) {
1680
+ let found = this.prevMatchInRange(state, 0, curFrom);
1681
+ if (!found)
1682
+ found = this.prevMatchInRange(state, Math.max(0, curTo - this.spec.unquoted.length), state.doc.length);
1683
+ return found && (found.from != curFrom || found.to != curTo) ? found : null;
1684
+ }
1685
+ getReplacement(_result) {
1686
+ return this.spec.unquote(this.spec.replace);
1687
+ }
1688
+ matchAll(state, limit) {
1689
+ let cursor = stringCursor(this.spec, state, 0, state.doc.length), ranges = [];
1690
+ while (!cursor.next().done) {
1691
+ if (ranges.length >= limit)
1692
+ return null;
1693
+ ranges.push(cursor.value);
1694
+ }
1695
+ return ranges;
1696
+ }
1697
+ highlight(state, from, to, add2) {
1698
+ let cursor = stringCursor(this.spec, state, Math.max(0, from - this.spec.unquoted.length), Math.min(to + this.spec.unquoted.length, state.doc.length));
1699
+ while (!cursor.next().done)
1700
+ add2(cursor.value.from, cursor.value.to);
1701
+ }
1702
+ }
1703
+ function regexpCursor(spec, state, from, to) {
1704
+ return new RegExpCursor(state.doc, spec.search, {
1705
+ ignoreCase: !spec.caseSensitive,
1706
+ test: spec.wholeWord ? regexpWordTest(state.charCategorizer(state.selection.main.head)) : void 0
1707
+ }, from, to);
1708
+ }
1709
+ function charBefore(str, index) {
1710
+ return str.slice(findClusterBreak(str, index, false), index);
1711
+ }
1712
+ function charAfter(str, index) {
1713
+ return str.slice(index, findClusterBreak(str, index));
1714
+ }
1715
+ function regexpWordTest(categorizer) {
1716
+ 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);
1717
+ }
1718
+ class RegExpQuery extends QueryType {
1719
+ nextMatch(state, curFrom, curTo) {
1720
+ let cursor = regexpCursor(this.spec, state, curTo, state.doc.length).next();
1721
+ if (cursor.done)
1722
+ cursor = regexpCursor(this.spec, state, 0, curFrom).next();
1723
+ return cursor.done ? null : cursor.value;
1724
+ }
1725
+ prevMatchInRange(state, from, to) {
1726
+ for (let size = 1; ; size++) {
1727
+ let start = Math.max(
1728
+ from,
1729
+ to - size * 1e4
1730
+ /* FindPrev.ChunkSize */
1731
+ );
1732
+ let cursor = regexpCursor(this.spec, state, start, to), range = null;
1733
+ while (!cursor.next().done)
1734
+ range = cursor.value;
1735
+ if (range && (start == from || range.from > start + 10))
1736
+ return range;
1737
+ if (start == from)
1738
+ return null;
1739
+ }
1740
+ }
1741
+ prevMatch(state, curFrom, curTo) {
1742
+ return this.prevMatchInRange(state, 0, curFrom) || this.prevMatchInRange(state, curTo, state.doc.length);
1743
+ }
1744
+ getReplacement(result) {
1745
+ return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g, (m, i) => {
1746
+ if (i == "&")
1747
+ return result.match[0];
1748
+ if (i == "$")
1749
+ return "$";
1750
+ for (let l = i.length; l > 0; l--) {
1751
+ let n = +i.slice(0, l);
1752
+ if (n > 0 && n < result.match.length)
1753
+ return result.match[n] + i.slice(l);
1754
+ }
1755
+ return m;
1756
+ });
1757
+ }
1758
+ matchAll(state, limit) {
1759
+ let cursor = regexpCursor(this.spec, state, 0, state.doc.length), ranges = [];
1760
+ while (!cursor.next().done) {
1761
+ if (ranges.length >= limit)
1762
+ return null;
1763
+ ranges.push(cursor.value);
1764
+ }
1765
+ return ranges;
1766
+ }
1767
+ highlight(state, from, to, add2) {
1768
+ let cursor = regexpCursor(this.spec, state, Math.max(
1769
+ 0,
1770
+ from - 250
1771
+ /* RegExp.HighlightMargin */
1772
+ ), Math.min(to + 250, state.doc.length));
1773
+ while (!cursor.next().done)
1774
+ add2(cursor.value.from, cursor.value.to);
1775
+ }
1776
+ }
1777
+ const setSearchQuery = /* @__PURE__ */ StateEffect.define();
1778
+ const togglePanel$1 = /* @__PURE__ */ StateEffect.define();
1779
+ const searchState = /* @__PURE__ */ StateField.define({
1780
+ create(state) {
1781
+ return new SearchState(defaultQuery(state).create(), null);
1782
+ },
1783
+ update(value, tr) {
1784
+ for (let effect of tr.effects) {
1785
+ if (effect.is(setSearchQuery))
1786
+ value = new SearchState(effect.value.create(), value.panel);
1787
+ else if (effect.is(togglePanel$1))
1788
+ value = new SearchState(value.query, effect.value ? createSearchPanel : null);
1789
+ }
1790
+ return value;
1791
+ },
1792
+ provide: (f) => showPanel.from(f, (val) => val.panel)
1793
+ });
1794
+ class SearchState {
1795
+ constructor(query, panel) {
1796
+ this.query = query;
1797
+ this.panel = panel;
1798
+ }
1799
+ }
1800
+ const matchMark = /* @__PURE__ */ Decoration.mark({ class: "cm-searchMatch" }), selectedMatchMark = /* @__PURE__ */ Decoration.mark({ class: "cm-searchMatch cm-searchMatch-selected" });
1801
+ const searchHighlighter = /* @__PURE__ */ ViewPlugin.fromClass(class {
1802
+ constructor(view) {
1803
+ this.view = view;
1804
+ this.decorations = this.highlight(view.state.field(searchState));
1805
+ }
1806
+ update(update) {
1807
+ let state = update.state.field(searchState);
1808
+ if (state != update.startState.field(searchState) || update.docChanged || update.selectionSet || update.viewportChanged)
1809
+ this.decorations = this.highlight(state);
1810
+ }
1811
+ highlight({ query, panel }) {
1812
+ if (!panel || !query.spec.valid)
1813
+ return Decoration.none;
1814
+ let { view } = this;
1815
+ let builder = new RangeSetBuilder();
1816
+ for (let i = 0, ranges = view.visibleRanges, l = ranges.length; i < l; i++) {
1817
+ let { from, to } = ranges[i];
1818
+ while (i < l - 1 && to > ranges[i + 1].from - 2 * 250)
1819
+ to = ranges[++i].to;
1820
+ query.highlight(view.state, from, to, (from2, to2) => {
1821
+ let selected = view.state.selection.ranges.some((r) => r.from == from2 && r.to == to2);
1822
+ builder.add(from2, to2, selected ? selectedMatchMark : matchMark);
1823
+ });
1824
+ }
1825
+ return builder.finish();
1826
+ }
1827
+ }, {
1828
+ decorations: (v) => v.decorations
1829
+ });
1830
+ function searchCommand(f) {
1831
+ return (view) => {
1832
+ let state = view.state.field(searchState, false);
1833
+ return state && state.query.spec.valid ? f(view, state) : openSearchPanel(view);
1834
+ };
1835
+ }
1836
+ const findNext = /* @__PURE__ */ searchCommand((view, { query }) => {
1837
+ let { to } = view.state.selection.main;
1838
+ let next = query.nextMatch(view.state, to, to);
1839
+ if (!next)
1840
+ return false;
1841
+ let selection = EditorSelection.single(next.from, next.to);
1842
+ let config = view.state.facet(searchConfigFacet);
1843
+ view.dispatch({
1844
+ selection,
1845
+ effects: [announceMatch(view, next), config.scrollToMatch(selection.main, view)],
1846
+ userEvent: "select.search"
1847
+ });
1848
+ selectSearchInput(view);
1849
+ return true;
1850
+ });
1851
+ const findPrevious = /* @__PURE__ */ searchCommand((view, { query }) => {
1852
+ let { state } = view, { from } = state.selection.main;
1853
+ let prev = query.prevMatch(state, from, from);
1854
+ if (!prev)
1855
+ return false;
1856
+ let selection = EditorSelection.single(prev.from, prev.to);
1857
+ let config = view.state.facet(searchConfigFacet);
1858
+ view.dispatch({
1859
+ selection,
1860
+ effects: [announceMatch(view, prev), config.scrollToMatch(selection.main, view)],
1861
+ userEvent: "select.search"
1862
+ });
1863
+ selectSearchInput(view);
1864
+ return true;
1865
+ });
1866
+ const selectMatches = /* @__PURE__ */ searchCommand((view, { query }) => {
1867
+ let ranges = query.matchAll(view.state, 1e3);
1868
+ if (!ranges || !ranges.length)
1869
+ return false;
1870
+ view.dispatch({
1871
+ selection: EditorSelection.create(ranges.map((r) => EditorSelection.range(r.from, r.to))),
1872
+ userEvent: "select.search.matches"
1873
+ });
1874
+ return true;
1875
+ });
1876
+ const selectSelectionMatches = ({ state, dispatch }) => {
1877
+ let sel = state.selection;
1878
+ if (sel.ranges.length > 1 || sel.main.empty)
1879
+ return false;
1880
+ let { from, to } = sel.main;
1881
+ let ranges = [], main = 0;
1882
+ for (let cur = new SearchCursor(state.doc, state.sliceDoc(from, to)); !cur.next().done; ) {
1883
+ if (ranges.length > 1e3)
1884
+ return false;
1885
+ if (cur.value.from == from)
1886
+ main = ranges.length;
1887
+ ranges.push(EditorSelection.range(cur.value.from, cur.value.to));
1888
+ }
1889
+ dispatch(state.update({
1890
+ selection: EditorSelection.create(ranges, main),
1891
+ userEvent: "select.search.matches"
1892
+ }));
1893
+ return true;
1894
+ };
1895
+ const replaceNext = /* @__PURE__ */ searchCommand((view, { query }) => {
1896
+ let { state } = view, { from, to } = state.selection.main;
1897
+ if (state.readOnly)
1898
+ return false;
1899
+ let match = query.nextMatch(state, from, from);
1900
+ if (!match)
1901
+ return false;
1902
+ let next = match;
1903
+ let changes = [], selection, replacement;
1904
+ let effects = [];
1905
+ if (next.from == from && next.to == to) {
1906
+ replacement = state.toText(query.getReplacement(next));
1907
+ changes.push({ from: next.from, to: next.to, insert: replacement });
1908
+ next = query.nextMatch(state, next.from, next.to);
1909
+ effects.push(EditorView.announce.of(state.phrase("replaced match on line $", state.doc.lineAt(from).number) + "."));
1910
+ }
1911
+ let changeSet = view.state.changes(changes);
1912
+ if (next) {
1913
+ selection = EditorSelection.single(next.from, next.to).map(changeSet);
1914
+ effects.push(announceMatch(view, next));
1915
+ effects.push(state.facet(searchConfigFacet).scrollToMatch(selection.main, view));
1916
+ }
1917
+ view.dispatch({
1918
+ changes: changeSet,
1919
+ selection,
1920
+ effects,
1921
+ userEvent: "input.replace"
1922
+ });
1923
+ return true;
1924
+ });
1925
+ const replaceAll = /* @__PURE__ */ searchCommand((view, { query }) => {
1926
+ if (view.state.readOnly)
1927
+ return false;
1928
+ let changes = query.matchAll(view.state, 1e9).map((match) => {
1929
+ let { from, to } = match;
1930
+ return { from, to, insert: query.getReplacement(match) };
1931
+ });
1932
+ if (!changes.length)
1933
+ return false;
1934
+ let announceText = view.state.phrase("replaced $ matches", changes.length) + ".";
1935
+ view.dispatch({
1936
+ changes,
1937
+ effects: EditorView.announce.of(announceText),
1938
+ userEvent: "input.replace.all"
1939
+ });
1940
+ return true;
1941
+ });
1942
+ function createSearchPanel(view) {
1943
+ return view.state.facet(searchConfigFacet).createPanel(view);
1944
+ }
1945
+ function defaultQuery(state, fallback) {
1946
+ var _a, _b, _c, _d, _e;
1947
+ let sel = state.selection.main;
1948
+ let selText = sel.empty || sel.to > sel.from + 100 ? "" : state.sliceDoc(sel.from, sel.to);
1949
+ if (fallback && !selText)
1950
+ return fallback;
1951
+ let config = state.facet(searchConfigFacet);
1952
+ return new SearchQuery({
1953
+ search: ((_a = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _a !== void 0 ? _a : config.literal) ? selText : selText.replace(/\n/g, "\\n"),
1954
+ caseSensitive: (_b = fallback === null || fallback === void 0 ? void 0 : fallback.caseSensitive) !== null && _b !== void 0 ? _b : config.caseSensitive,
1955
+ literal: (_c = fallback === null || fallback === void 0 ? void 0 : fallback.literal) !== null && _c !== void 0 ? _c : config.literal,
1956
+ regexp: (_d = fallback === null || fallback === void 0 ? void 0 : fallback.regexp) !== null && _d !== void 0 ? _d : config.regexp,
1957
+ wholeWord: (_e = fallback === null || fallback === void 0 ? void 0 : fallback.wholeWord) !== null && _e !== void 0 ? _e : config.wholeWord
1958
+ });
1959
+ }
1960
+ function getSearchInput(view) {
1961
+ let panel = getPanel(view, createSearchPanel);
1962
+ return panel && panel.dom.querySelector("[main-field]");
1963
+ }
1964
+ function selectSearchInput(view) {
1965
+ let input = getSearchInput(view);
1966
+ if (input && input == view.root.activeElement)
1967
+ input.select();
1968
+ }
1969
+ const openSearchPanel = (view) => {
1970
+ let state = view.state.field(searchState, false);
1971
+ if (state && state.panel) {
1972
+ let searchInput = getSearchInput(view);
1973
+ if (searchInput && searchInput != view.root.activeElement) {
1974
+ let query = defaultQuery(view.state, state.query.spec);
1975
+ if (query.valid)
1976
+ view.dispatch({ effects: setSearchQuery.of(query) });
1977
+ searchInput.focus();
1978
+ searchInput.select();
1979
+ }
1980
+ } else {
1981
+ view.dispatch({ effects: [
1982
+ togglePanel$1.of(true),
1983
+ state ? setSearchQuery.of(defaultQuery(view.state, state.query.spec)) : StateEffect.appendConfig.of(searchExtensions)
1984
+ ] });
1985
+ }
1986
+ return true;
1987
+ };
1988
+ const closeSearchPanel = (view) => {
1989
+ let state = view.state.field(searchState, false);
1990
+ if (!state || !state.panel)
1991
+ return false;
1992
+ let panel = getPanel(view, createSearchPanel);
1993
+ if (panel && panel.dom.contains(view.root.activeElement))
1994
+ view.focus();
1995
+ view.dispatch({ effects: togglePanel$1.of(false) });
1996
+ return true;
1997
+ };
1998
+ const searchKeymap = [
1999
+ { key: "Mod-f", run: openSearchPanel, scope: "editor search-panel" },
2000
+ { key: "F3", run: findNext, shift: findPrevious, scope: "editor search-panel", preventDefault: true },
2001
+ { key: "Mod-g", run: findNext, shift: findPrevious, scope: "editor search-panel", preventDefault: true },
2002
+ { key: "Escape", run: closeSearchPanel, scope: "editor search-panel" },
2003
+ { key: "Mod-Shift-l", run: selectSelectionMatches },
2004
+ { key: "Mod-Alt-g", run: gotoLine },
2005
+ { key: "Mod-d", run: selectNextOccurrence, preventDefault: true }
2006
+ ];
2007
+ class SearchPanel {
2008
+ constructor(view) {
2009
+ this.view = view;
2010
+ let query = this.query = view.state.field(searchState).query.spec;
2011
+ this.commit = this.commit.bind(this);
2012
+ this.searchField = crelt("input", {
2013
+ value: query.search,
2014
+ placeholder: phrase(view, "Find"),
2015
+ "aria-label": phrase(view, "Find"),
2016
+ class: "cm-textfield",
2017
+ name: "search",
2018
+ form: "",
2019
+ "main-field": "true",
2020
+ onchange: this.commit,
2021
+ onkeyup: this.commit
2022
+ });
2023
+ this.replaceField = crelt("input", {
2024
+ value: query.replace,
2025
+ placeholder: phrase(view, "Replace"),
2026
+ "aria-label": phrase(view, "Replace"),
2027
+ class: "cm-textfield",
2028
+ name: "replace",
2029
+ form: "",
2030
+ onchange: this.commit,
2031
+ onkeyup: this.commit
2032
+ });
2033
+ this.caseField = crelt("input", {
2034
+ type: "checkbox",
2035
+ name: "case",
2036
+ form: "",
2037
+ checked: query.caseSensitive,
2038
+ onchange: this.commit
2039
+ });
2040
+ this.reField = crelt("input", {
2041
+ type: "checkbox",
2042
+ name: "re",
2043
+ form: "",
2044
+ checked: query.regexp,
2045
+ onchange: this.commit
2046
+ });
2047
+ this.wordField = crelt("input", {
2048
+ type: "checkbox",
2049
+ name: "word",
2050
+ form: "",
2051
+ checked: query.wholeWord,
2052
+ onchange: this.commit
2053
+ });
2054
+ function button(name, onclick, content) {
2055
+ return crelt("button", { class: "cm-button", name, onclick, type: "button" }, content);
2056
+ }
2057
+ this.dom = crelt("div", { onkeydown: (e) => this.keydown(e), class: "cm-search" }, [
2058
+ this.searchField,
2059
+ button("next", () => findNext(view), [phrase(view, "next")]),
2060
+ button("prev", () => findPrevious(view), [phrase(view, "previous")]),
2061
+ button("select", () => selectMatches(view), [phrase(view, "all")]),
2062
+ crelt("label", null, [this.caseField, phrase(view, "match case")]),
2063
+ crelt("label", null, [this.reField, phrase(view, "regexp")]),
2064
+ crelt("label", null, [this.wordField, phrase(view, "by word")]),
2065
+ ...view.state.readOnly ? [] : [
2066
+ crelt("br"),
2067
+ this.replaceField,
2068
+ button("replace", () => replaceNext(view), [phrase(view, "replace")]),
2069
+ button("replaceAll", () => replaceAll(view), [phrase(view, "replace all")])
2070
+ ],
2071
+ crelt("button", {
2072
+ name: "close",
2073
+ onclick: () => closeSearchPanel(view),
2074
+ "aria-label": phrase(view, "close"),
2075
+ type: "button"
2076
+ }, ["×"])
2077
+ ]);
2078
+ }
2079
+ commit() {
2080
+ let query = new SearchQuery({
2081
+ search: this.searchField.value,
2082
+ caseSensitive: this.caseField.checked,
2083
+ regexp: this.reField.checked,
2084
+ wholeWord: this.wordField.checked,
2085
+ replace: this.replaceField.value
2086
+ });
2087
+ if (!query.eq(this.query)) {
2088
+ this.query = query;
2089
+ this.view.dispatch({ effects: setSearchQuery.of(query) });
2090
+ }
2091
+ }
2092
+ keydown(e) {
2093
+ if (runScopeHandlers(this.view, e, "search-panel")) {
2094
+ e.preventDefault();
2095
+ } else if (e.keyCode == 13 && e.target == this.searchField) {
2096
+ e.preventDefault();
2097
+ (e.shiftKey ? findPrevious : findNext)(this.view);
2098
+ } else if (e.keyCode == 13 && e.target == this.replaceField) {
2099
+ e.preventDefault();
2100
+ replaceNext(this.view);
2101
+ }
2102
+ }
2103
+ update(update) {
2104
+ for (let tr of update.transactions)
2105
+ for (let effect of tr.effects) {
2106
+ if (effect.is(setSearchQuery) && !effect.value.eq(this.query))
2107
+ this.setQuery(effect.value);
2108
+ }
2109
+ }
2110
+ setQuery(query) {
2111
+ this.query = query;
2112
+ this.searchField.value = query.search;
2113
+ this.replaceField.value = query.replace;
2114
+ this.caseField.checked = query.caseSensitive;
2115
+ this.reField.checked = query.regexp;
2116
+ this.wordField.checked = query.wholeWord;
2117
+ }
2118
+ mount() {
2119
+ this.searchField.select();
2120
+ }
2121
+ get pos() {
2122
+ return 80;
2123
+ }
2124
+ get top() {
2125
+ return this.view.state.facet(searchConfigFacet).top;
2126
+ }
2127
+ }
2128
+ function phrase(view, phrase2) {
2129
+ return view.state.phrase(phrase2);
2130
+ }
2131
+ const AnnounceMargin = 30;
2132
+ const Break = /[\s\.,:;?!]/;
2133
+ function announceMatch(view, { from, to }) {
2134
+ let line = view.state.doc.lineAt(from), lineEnd = view.state.doc.lineAt(to).to;
2135
+ let start = Math.max(line.from, from - AnnounceMargin), end = Math.min(lineEnd, to + AnnounceMargin);
2136
+ let text = view.state.sliceDoc(start, end);
2137
+ if (start != line.from) {
2138
+ for (let i = 0; i < AnnounceMargin; i++)
2139
+ if (!Break.test(text[i + 1]) && Break.test(text[i])) {
2140
+ text = text.slice(i);
2141
+ break;
2142
+ }
2143
+ }
2144
+ if (end != lineEnd) {
2145
+ for (let i = text.length - 1; i > text.length - AnnounceMargin; i--)
2146
+ if (!Break.test(text[i - 1]) && Break.test(text[i])) {
2147
+ text = text.slice(0, i);
2148
+ break;
2149
+ }
2150
+ }
2151
+ return EditorView.announce.of(`${view.state.phrase("current match")}. ${text} ${view.state.phrase("on line")} ${line.number}.`);
2152
+ }
2153
+ const baseTheme$2 = /* @__PURE__ */ EditorView.baseTheme({
2154
+ ".cm-panel.cm-search": {
2155
+ padding: "2px 6px 4px",
2156
+ position: "relative",
2157
+ "& [name=close]": {
2158
+ position: "absolute",
2159
+ top: "0",
2160
+ right: "4px",
2161
+ backgroundColor: "inherit",
2162
+ border: "none",
2163
+ font: "inherit",
2164
+ padding: 0,
2165
+ margin: 0
2166
+ },
2167
+ "& input, & button, & label": {
2168
+ margin: ".2em .6em .2em 0"
2169
+ },
2170
+ "& input[type=checkbox]": {
2171
+ marginRight: ".2em"
2172
+ },
2173
+ "& label": {
2174
+ fontSize: "80%",
2175
+ whiteSpace: "pre"
2176
+ }
2177
+ },
2178
+ "&light .cm-searchMatch": { backgroundColor: "#ffff0054" },
2179
+ "&dark .cm-searchMatch": { backgroundColor: "#00ffff8a" },
2180
+ "&light .cm-searchMatch-selected": { backgroundColor: "#ff6a0054" },
2181
+ "&dark .cm-searchMatch-selected": { backgroundColor: "#ff00ff8a" }
2182
+ });
2183
+ const searchExtensions = [
2184
+ searchState,
2185
+ /* @__PURE__ */ Prec.low(searchHighlighter),
2186
+ baseTheme$2
2187
+ ];
2188
+ class SelectedDiagnostic {
2189
+ constructor(from, to, diagnostic) {
2190
+ this.from = from;
2191
+ this.to = to;
2192
+ this.diagnostic = diagnostic;
2193
+ }
2194
+ }
2195
+ class LintState {
2196
+ constructor(diagnostics, panel, selected) {
2197
+ this.diagnostics = diagnostics;
2198
+ this.panel = panel;
2199
+ this.selected = selected;
2200
+ }
2201
+ static init(diagnostics, panel, state) {
2202
+ let diagnosticFilter = state.facet(lintConfig).markerFilter;
2203
+ if (diagnosticFilter)
2204
+ diagnostics = diagnosticFilter(diagnostics, state);
2205
+ let sorted = diagnostics.slice().sort((a, b) => a.from - b.from || a.to - b.to);
2206
+ let deco = new RangeSetBuilder(), active = [], pos = 0;
2207
+ let scan = state.doc.iter(), scanPos = 0, docLen = state.doc.length;
2208
+ for (let i = 0; ; ) {
2209
+ let next = i == sorted.length ? null : sorted[i];
2210
+ if (!next && !active.length)
2211
+ break;
2212
+ let from, to;
2213
+ if (active.length) {
2214
+ from = pos;
2215
+ to = active.reduce((p, d) => Math.min(p, d.to), next && next.from > from ? next.from : 1e8);
2216
+ } else {
2217
+ from = next.from;
2218
+ if (from > docLen)
2219
+ break;
2220
+ to = next.to;
2221
+ active.push(next);
2222
+ i++;
2223
+ }
2224
+ while (i < sorted.length) {
2225
+ let next2 = sorted[i];
2226
+ if (next2.from == from && (next2.to > next2.from || next2.to == from)) {
2227
+ active.push(next2);
2228
+ i++;
2229
+ to = Math.min(next2.to, to);
2230
+ } else {
2231
+ to = Math.min(next2.from, to);
2232
+ break;
2233
+ }
2234
+ }
2235
+ to = Math.min(to, docLen);
2236
+ let widget = false;
2237
+ if (active.some((d) => d.from == from && (d.to == to || to == docLen))) {
2238
+ widget = from == to;
2239
+ if (!widget && to - from < 10) {
2240
+ let behind = from - (scanPos + scan.value.length);
2241
+ if (behind > 0) {
2242
+ scan.next(behind);
2243
+ scanPos = from;
2244
+ }
2245
+ for (let check = from; ; ) {
2246
+ if (check >= to) {
2247
+ widget = true;
2248
+ break;
2249
+ }
2250
+ if (!scan.lineBreak && scanPos + scan.value.length > check)
2251
+ break;
2252
+ check = scanPos + scan.value.length;
2253
+ scanPos += scan.value.length;
2254
+ scan.next();
2255
+ }
2256
+ }
2257
+ }
2258
+ let sev = maxSeverity(active);
2259
+ if (widget) {
2260
+ deco.add(from, from, Decoration.widget({
2261
+ widget: new DiagnosticWidget(sev),
2262
+ diagnostics: active.slice()
2263
+ }));
2264
+ } else {
2265
+ let markClass = active.reduce((c, d) => d.markClass ? c + " " + d.markClass : c, "");
2266
+ deco.add(from, to, Decoration.mark({
2267
+ class: "cm-lintRange cm-lintRange-" + sev + markClass,
2268
+ diagnostics: active.slice(),
2269
+ inclusiveEnd: active.some((a) => a.to > to)
2270
+ }));
2271
+ }
2272
+ pos = to;
2273
+ if (pos == docLen)
2274
+ break;
2275
+ for (let i2 = 0; i2 < active.length; i2++)
2276
+ if (active[i2].to <= pos)
2277
+ active.splice(i2--, 1);
2278
+ }
2279
+ let set = deco.finish();
2280
+ return new LintState(set, panel, findDiagnostic(set));
2281
+ }
2282
+ }
2283
+ function findDiagnostic(diagnostics, diagnostic = null, after = 0) {
2284
+ let found = null;
2285
+ diagnostics.between(after, 1e9, (from, to, { spec }) => {
2286
+ if (diagnostic && spec.diagnostics.indexOf(diagnostic) < 0)
2287
+ return;
2288
+ if (!found)
2289
+ found = new SelectedDiagnostic(from, to, diagnostic || spec.diagnostics[0]);
2290
+ else if (spec.diagnostics.indexOf(found.diagnostic) < 0)
2291
+ return false;
2292
+ else
2293
+ found = new SelectedDiagnostic(found.from, to, found.diagnostic);
2294
+ });
2295
+ return found;
2296
+ }
2297
+ function hideTooltip(tr, tooltip) {
2298
+ let from = tooltip.pos, to = tooltip.end || from;
2299
+ let result = tr.state.facet(lintConfig).hideOn(tr, from, to);
2300
+ if (result != null)
2301
+ return result;
2302
+ let line = tr.startState.doc.lineAt(tooltip.pos);
2303
+ return !!(tr.effects.some((e) => e.is(setDiagnosticsEffect)) || tr.changes.touchesRange(line.from, Math.max(line.to, to)));
2304
+ }
2305
+ function maybeEnableLint(state, effects) {
2306
+ return state.field(lintState, false) ? effects : effects.concat(StateEffect.appendConfig.of(lintExtensions));
2307
+ }
2308
+ const setDiagnosticsEffect = /* @__PURE__ */ StateEffect.define();
2309
+ const togglePanel = /* @__PURE__ */ StateEffect.define();
2310
+ const movePanelSelection = /* @__PURE__ */ StateEffect.define();
2311
+ const lintState = /* @__PURE__ */ StateField.define({
2312
+ create() {
2313
+ return new LintState(Decoration.none, null, null);
2314
+ },
2315
+ update(value, tr) {
2316
+ if (tr.docChanged && value.diagnostics.size) {
2317
+ let mapped = value.diagnostics.map(tr.changes), selected = null, panel = value.panel;
2318
+ if (value.selected) {
2319
+ let selPos = tr.changes.mapPos(value.selected.from, 1);
2320
+ selected = findDiagnostic(mapped, value.selected.diagnostic, selPos) || findDiagnostic(mapped, null, selPos);
2321
+ }
2322
+ if (!mapped.size && panel && tr.state.facet(lintConfig).autoPanel)
2323
+ panel = null;
2324
+ value = new LintState(mapped, panel, selected);
2325
+ }
2326
+ for (let effect of tr.effects) {
2327
+ if (effect.is(setDiagnosticsEffect)) {
2328
+ let panel = !tr.state.facet(lintConfig).autoPanel ? value.panel : effect.value.length ? LintPanel.open : null;
2329
+ value = LintState.init(effect.value, panel, tr.state);
2330
+ } else if (effect.is(togglePanel)) {
2331
+ value = new LintState(value.diagnostics, effect.value ? LintPanel.open : null, value.selected);
2332
+ } else if (effect.is(movePanelSelection)) {
2333
+ value = new LintState(value.diagnostics, value.panel, effect.value);
2334
+ }
2335
+ }
2336
+ return value;
2337
+ },
2338
+ provide: (f) => [
2339
+ showPanel.from(f, (val) => val.panel),
2340
+ EditorView.decorations.from(f, (s) => s.diagnostics)
2341
+ ]
2342
+ });
2343
+ const activeMark = /* @__PURE__ */ Decoration.mark({ class: "cm-lintRange cm-lintRange-active" });
2344
+ function lintTooltip(view, pos, side) {
2345
+ let { diagnostics } = view.state.field(lintState);
2346
+ let found, start = -1, end = -1;
2347
+ diagnostics.between(pos - (side < 0 ? 1 : 0), pos + (side > 0 ? 1 : 0), (from, to, { spec }) => {
2348
+ if (pos >= from && pos <= to && (from == to || (pos > from || side > 0) && (pos < to || side < 0))) {
2349
+ found = spec.diagnostics;
2350
+ start = from;
2351
+ end = to;
2352
+ return false;
2353
+ }
2354
+ });
2355
+ let diagnosticFilter = view.state.facet(lintConfig).tooltipFilter;
2356
+ if (found && diagnosticFilter)
2357
+ found = diagnosticFilter(found, view.state);
2358
+ if (!found)
2359
+ return null;
2360
+ return {
2361
+ pos: start,
2362
+ end,
2363
+ above: view.state.doc.lineAt(start).to < end,
2364
+ create() {
2365
+ return { dom: diagnosticsTooltip(view, found) };
2366
+ }
2367
+ };
2368
+ }
2369
+ function diagnosticsTooltip(view, diagnostics) {
2370
+ return crelt("ul", { class: "cm-tooltip-lint" }, diagnostics.map((d) => renderDiagnostic(view, d, false)));
2371
+ }
2372
+ const openLintPanel = (view) => {
2373
+ let field = view.state.field(lintState, false);
2374
+ if (!field || !field.panel)
2375
+ view.dispatch({ effects: maybeEnableLint(view.state, [togglePanel.of(true)]) });
2376
+ let panel = getPanel(view, LintPanel.open);
2377
+ if (panel)
2378
+ panel.dom.querySelector(".cm-panel-lint ul").focus();
2379
+ return true;
2380
+ };
2381
+ const closeLintPanel = (view) => {
2382
+ let field = view.state.field(lintState, false);
2383
+ if (!field || !field.panel)
2384
+ return false;
2385
+ view.dispatch({ effects: togglePanel.of(false) });
2386
+ return true;
2387
+ };
2388
+ const nextDiagnostic = (view) => {
2389
+ let field = view.state.field(lintState, false);
2390
+ if (!field)
2391
+ return false;
2392
+ let sel = view.state.selection.main, next = field.diagnostics.iter(sel.to + 1);
2393
+ if (!next.value) {
2394
+ next = field.diagnostics.iter(0);
2395
+ if (!next.value || next.from == sel.from && next.to == sel.to)
2396
+ return false;
2397
+ }
2398
+ view.dispatch({ selection: { anchor: next.from, head: next.to }, scrollIntoView: true });
2399
+ return true;
2400
+ };
2401
+ const lintKeymap = [
2402
+ { key: "Mod-Shift-m", run: openLintPanel, preventDefault: true },
2403
+ { key: "F8", run: nextDiagnostic }
2404
+ ];
2405
+ const lintConfig = /* @__PURE__ */ Facet.define({
2406
+ combine(input) {
2407
+ return {
2408
+ sources: input.map((i) => i.source).filter((x) => x != null),
2409
+ ...combineConfig(input.map((i) => i.config), {
2410
+ delay: 750,
2411
+ markerFilter: null,
2412
+ tooltipFilter: null,
2413
+ needsRefresh: null,
2414
+ hideOn: () => null
2415
+ }, {
2416
+ delay: Math.max,
2417
+ markerFilter: combineFilter,
2418
+ tooltipFilter: combineFilter,
2419
+ needsRefresh: (a, b) => !a ? b : !b ? a : (u) => a(u) || b(u),
2420
+ hideOn: (a, b) => !a ? b : !b ? a : (t, x, y) => a(t, x, y) || b(t, x, y),
2421
+ autoPanel: (a, b) => a || b
2422
+ })
2423
+ };
2424
+ }
2425
+ });
2426
+ function combineFilter(a, b) {
2427
+ return !a ? b : !b ? a : (d, s) => b(a(d, s), s);
2428
+ }
2429
+ function assignKeys(actions) {
2430
+ let assigned = [];
2431
+ if (actions)
2432
+ actions: for (let { name } of actions) {
2433
+ for (let i = 0; i < name.length; i++) {
2434
+ let ch = name[i];
2435
+ if (/[a-zA-Z]/.test(ch) && !assigned.some((c) => c.toLowerCase() == ch.toLowerCase())) {
2436
+ assigned.push(ch);
2437
+ continue actions;
2438
+ }
2439
+ }
2440
+ assigned.push("");
2441
+ }
2442
+ return assigned;
2443
+ }
2444
+ function renderDiagnostic(view, diagnostic, inPanel) {
2445
+ var _a;
2446
+ let keys = inPanel ? assignKeys(diagnostic.actions) : [];
2447
+ return crelt("li", { class: "cm-diagnostic cm-diagnostic-" + diagnostic.severity }, crelt("span", { class: "cm-diagnosticText" }, diagnostic.renderMessage ? diagnostic.renderMessage(view) : diagnostic.message), (_a = diagnostic.actions) === null || _a === void 0 ? void 0 : _a.map((action, i) => {
2448
+ let fired = false, click = (e) => {
2449
+ e.preventDefault();
2450
+ if (fired)
2451
+ return;
2452
+ fired = true;
2453
+ let found = findDiagnostic(view.state.field(lintState).diagnostics, diagnostic);
2454
+ if (found)
2455
+ action.apply(view, found.from, found.to);
2456
+ };
2457
+ let { name } = action, keyIndex = keys[i] ? name.indexOf(keys[i]) : -1;
2458
+ let nameElt = keyIndex < 0 ? name : [
2459
+ name.slice(0, keyIndex),
2460
+ crelt("u", name.slice(keyIndex, keyIndex + 1)),
2461
+ name.slice(keyIndex + 1)
2462
+ ];
2463
+ let markClass = action.markClass ? " " + action.markClass : "";
2464
+ return crelt("button", {
2465
+ type: "button",
2466
+ class: "cm-diagnosticAction" + markClass,
2467
+ onclick: click,
2468
+ onmousedown: click,
2469
+ "aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`
2470
+ }, nameElt);
2471
+ }), diagnostic.source && crelt("div", { class: "cm-diagnosticSource" }, diagnostic.source));
2472
+ }
2473
+ class DiagnosticWidget extends WidgetType {
2474
+ constructor(sev) {
2475
+ super();
2476
+ this.sev = sev;
2477
+ }
2478
+ eq(other) {
2479
+ return other.sev == this.sev;
2480
+ }
2481
+ toDOM() {
2482
+ return crelt("span", { class: "cm-lintPoint cm-lintPoint-" + this.sev });
2483
+ }
2484
+ }
2485
+ class PanelItem {
2486
+ constructor(view, diagnostic) {
2487
+ this.diagnostic = diagnostic;
2488
+ this.id = "item_" + Math.floor(Math.random() * 4294967295).toString(16);
2489
+ this.dom = renderDiagnostic(view, diagnostic, true);
2490
+ this.dom.id = this.id;
2491
+ this.dom.setAttribute("role", "option");
2492
+ }
2493
+ }
2494
+ class LintPanel {
2495
+ constructor(view) {
2496
+ this.view = view;
2497
+ this.items = [];
2498
+ let onkeydown = (event) => {
2499
+ if (event.keyCode == 27) {
2500
+ closeLintPanel(this.view);
2501
+ this.view.focus();
2502
+ } else if (event.keyCode == 38 || event.keyCode == 33) {
2503
+ this.moveSelection((this.selectedIndex - 1 + this.items.length) % this.items.length);
2504
+ } else if (event.keyCode == 40 || event.keyCode == 34) {
2505
+ this.moveSelection((this.selectedIndex + 1) % this.items.length);
2506
+ } else if (event.keyCode == 36) {
2507
+ this.moveSelection(0);
2508
+ } else if (event.keyCode == 35) {
2509
+ this.moveSelection(this.items.length - 1);
2510
+ } else if (event.keyCode == 13) {
2511
+ this.view.focus();
2512
+ } else if (event.keyCode >= 65 && event.keyCode <= 90 && this.selectedIndex >= 0) {
2513
+ let { diagnostic } = this.items[this.selectedIndex], keys = assignKeys(diagnostic.actions);
2514
+ for (let i = 0; i < keys.length; i++)
2515
+ if (keys[i].toUpperCase().charCodeAt(0) == event.keyCode) {
2516
+ let found = findDiagnostic(this.view.state.field(lintState).diagnostics, diagnostic);
2517
+ if (found)
2518
+ diagnostic.actions[i].apply(view, found.from, found.to);
2519
+ }
2520
+ } else {
2521
+ return;
2522
+ }
2523
+ event.preventDefault();
2524
+ };
2525
+ let onclick = (event) => {
2526
+ for (let i = 0; i < this.items.length; i++) {
2527
+ if (this.items[i].dom.contains(event.target))
2528
+ this.moveSelection(i);
2529
+ }
2530
+ };
2531
+ this.list = crelt("ul", {
2532
+ tabIndex: 0,
2533
+ role: "listbox",
2534
+ "aria-label": this.view.state.phrase("Diagnostics"),
2535
+ onkeydown,
2536
+ onclick
2537
+ });
2538
+ this.dom = crelt("div", { class: "cm-panel-lint" }, this.list, crelt("button", {
2539
+ type: "button",
2540
+ name: "close",
2541
+ "aria-label": this.view.state.phrase("close"),
2542
+ onclick: () => closeLintPanel(this.view)
2543
+ }, "×"));
2544
+ this.update();
2545
+ }
2546
+ get selectedIndex() {
2547
+ let selected = this.view.state.field(lintState).selected;
2548
+ if (!selected)
2549
+ return -1;
2550
+ for (let i = 0; i < this.items.length; i++)
2551
+ if (this.items[i].diagnostic == selected.diagnostic)
2552
+ return i;
2553
+ return -1;
2554
+ }
2555
+ update() {
2556
+ let { diagnostics, selected } = this.view.state.field(lintState);
2557
+ let i = 0, needsSync = false, newSelectedItem = null;
2558
+ let seen = /* @__PURE__ */ new Set();
2559
+ diagnostics.between(0, this.view.state.doc.length, (_start, _end, { spec }) => {
2560
+ for (let diagnostic of spec.diagnostics) {
2561
+ if (seen.has(diagnostic))
2562
+ continue;
2563
+ seen.add(diagnostic);
2564
+ let found = -1, item;
2565
+ for (let j = i; j < this.items.length; j++)
2566
+ if (this.items[j].diagnostic == diagnostic) {
2567
+ found = j;
2568
+ break;
2569
+ }
2570
+ if (found < 0) {
2571
+ item = new PanelItem(this.view, diagnostic);
2572
+ this.items.splice(i, 0, item);
2573
+ needsSync = true;
2574
+ } else {
2575
+ item = this.items[found];
2576
+ if (found > i) {
2577
+ this.items.splice(i, found - i);
2578
+ needsSync = true;
2579
+ }
2580
+ }
2581
+ if (selected && item.diagnostic == selected.diagnostic) {
2582
+ if (!item.dom.hasAttribute("aria-selected")) {
2583
+ item.dom.setAttribute("aria-selected", "true");
2584
+ newSelectedItem = item;
2585
+ }
2586
+ } else if (item.dom.hasAttribute("aria-selected")) {
2587
+ item.dom.removeAttribute("aria-selected");
2588
+ }
2589
+ i++;
2590
+ }
2591
+ });
2592
+ while (i < this.items.length && !(this.items.length == 1 && this.items[0].diagnostic.from < 0)) {
2593
+ needsSync = true;
2594
+ this.items.pop();
2595
+ }
2596
+ if (this.items.length == 0) {
2597
+ this.items.push(new PanelItem(this.view, {
2598
+ from: -1,
2599
+ to: -1,
2600
+ severity: "info",
2601
+ message: this.view.state.phrase("No diagnostics")
2602
+ }));
2603
+ needsSync = true;
2604
+ }
2605
+ if (newSelectedItem) {
2606
+ this.list.setAttribute("aria-activedescendant", newSelectedItem.id);
2607
+ this.view.requestMeasure({
2608
+ key: this,
2609
+ read: () => ({ sel: newSelectedItem.dom.getBoundingClientRect(), panel: this.list.getBoundingClientRect() }),
2610
+ write: ({ sel, panel }) => {
2611
+ let scaleY = panel.height / this.list.offsetHeight;
2612
+ if (sel.top < panel.top)
2613
+ this.list.scrollTop -= (panel.top - sel.top) / scaleY;
2614
+ else if (sel.bottom > panel.bottom)
2615
+ this.list.scrollTop += (sel.bottom - panel.bottom) / scaleY;
2616
+ }
2617
+ });
2618
+ } else if (this.selectedIndex < 0) {
2619
+ this.list.removeAttribute("aria-activedescendant");
2620
+ }
2621
+ if (needsSync)
2622
+ this.sync();
2623
+ }
2624
+ sync() {
2625
+ let domPos = this.list.firstChild;
2626
+ function rm() {
2627
+ let prev = domPos;
2628
+ domPos = prev.nextSibling;
2629
+ prev.remove();
2630
+ }
2631
+ for (let item of this.items) {
2632
+ if (item.dom.parentNode == this.list) {
2633
+ while (domPos != item.dom)
2634
+ rm();
2635
+ domPos = item.dom.nextSibling;
2636
+ } else {
2637
+ this.list.insertBefore(item.dom, domPos);
2638
+ }
2639
+ }
2640
+ while (domPos)
2641
+ rm();
2642
+ }
2643
+ moveSelection(selectedIndex) {
2644
+ if (this.selectedIndex < 0)
2645
+ return;
2646
+ let field = this.view.state.field(lintState);
2647
+ let selection = findDiagnostic(field.diagnostics, this.items[selectedIndex].diagnostic);
2648
+ if (!selection)
2649
+ return;
2650
+ this.view.dispatch({
2651
+ selection: { anchor: selection.from, head: selection.to },
2652
+ scrollIntoView: true,
2653
+ effects: movePanelSelection.of(selection)
2654
+ });
2655
+ }
2656
+ static open(view) {
2657
+ return new LintPanel(view);
2658
+ }
2659
+ }
2660
+ function svg(content, attrs = `viewBox="0 0 40 40"`) {
2661
+ return `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" ${attrs}>${encodeURIComponent(content)}</svg>')`;
2662
+ }
2663
+ function underline(color) {
2664
+ return svg(`<path d="m0 2.5 l2 -1.5 l1 0 l2 1.5 l1 0" stroke="${color}" fill="none" stroke-width=".7"/>`, `width="6" height="3"`);
2665
+ }
2666
+ const baseTheme = /* @__PURE__ */ EditorView.baseTheme({
2667
+ ".cm-diagnostic": {
2668
+ padding: "3px 6px 3px 8px",
2669
+ marginLeft: "-1px",
2670
+ display: "block",
2671
+ whiteSpace: "pre-wrap"
2672
+ },
2673
+ ".cm-diagnostic-error": { borderLeft: "5px solid #d11" },
2674
+ ".cm-diagnostic-warning": { borderLeft: "5px solid orange" },
2675
+ ".cm-diagnostic-info": { borderLeft: "5px solid #999" },
2676
+ ".cm-diagnostic-hint": { borderLeft: "5px solid #66d" },
2677
+ ".cm-diagnosticAction": {
2678
+ font: "inherit",
2679
+ border: "none",
2680
+ padding: "2px 4px",
2681
+ backgroundColor: "#444",
2682
+ color: "white",
2683
+ borderRadius: "3px",
2684
+ marginLeft: "8px",
2685
+ cursor: "pointer"
2686
+ },
2687
+ ".cm-diagnosticSource": {
2688
+ fontSize: "70%",
2689
+ opacity: 0.7
2690
+ },
2691
+ ".cm-lintRange": {
2692
+ backgroundPosition: "left bottom",
2693
+ backgroundRepeat: "repeat-x",
2694
+ paddingBottom: "0.7px"
2695
+ },
2696
+ ".cm-lintRange-error": { backgroundImage: /* @__PURE__ */ underline("#d11") },
2697
+ ".cm-lintRange-warning": { backgroundImage: /* @__PURE__ */ underline("orange") },
2698
+ ".cm-lintRange-info": { backgroundImage: /* @__PURE__ */ underline("#999") },
2699
+ ".cm-lintRange-hint": { backgroundImage: /* @__PURE__ */ underline("#66d") },
2700
+ ".cm-lintRange-active": { backgroundColor: "#ffdd9980" },
2701
+ ".cm-tooltip-lint": {
2702
+ padding: 0,
2703
+ margin: 0
2704
+ },
2705
+ ".cm-lintPoint": {
2706
+ position: "relative",
2707
+ "&:after": {
2708
+ content: '""',
2709
+ position: "absolute",
2710
+ bottom: 0,
2711
+ left: "-2px",
2712
+ borderLeft: "3px solid transparent",
2713
+ borderRight: "3px solid transparent",
2714
+ borderBottom: "4px solid #d11"
2715
+ }
2716
+ },
2717
+ ".cm-lintPoint-warning": {
2718
+ "&:after": { borderBottomColor: "orange" }
2719
+ },
2720
+ ".cm-lintPoint-info": {
2721
+ "&:after": { borderBottomColor: "#999" }
2722
+ },
2723
+ ".cm-lintPoint-hint": {
2724
+ "&:after": { borderBottomColor: "#66d" }
2725
+ },
2726
+ ".cm-panel.cm-panel-lint": {
2727
+ position: "relative",
2728
+ "& ul": {
2729
+ maxHeight: "100px",
2730
+ overflowY: "auto",
2731
+ "& [aria-selected]": {
2732
+ backgroundColor: "#ddd",
2733
+ "& u": { textDecoration: "underline" }
2734
+ },
2735
+ "&:focus [aria-selected]": {
2736
+ background_fallback: "#bdf",
2737
+ backgroundColor: "Highlight",
2738
+ color_fallback: "white",
2739
+ color: "HighlightText"
2740
+ },
2741
+ "& u": { textDecoration: "none" },
2742
+ padding: 0,
2743
+ margin: 0
2744
+ },
2745
+ "& [name=close]": {
2746
+ position: "absolute",
2747
+ top: "0",
2748
+ right: "2px",
2749
+ background: "inherit",
2750
+ border: "none",
2751
+ font: "inherit",
2752
+ padding: 0,
2753
+ margin: 0
2754
+ }
2755
+ }
2756
+ });
2757
+ function severityWeight(sev) {
2758
+ return sev == "error" ? 4 : sev == "warning" ? 3 : sev == "info" ? 2 : 1;
2759
+ }
2760
+ function maxSeverity(diagnostics) {
2761
+ let sev = "hint", weight = 1;
2762
+ for (let d of diagnostics) {
2763
+ let w = severityWeight(d.severity);
2764
+ if (w > weight) {
2765
+ weight = w;
2766
+ sev = d.severity;
2767
+ }
2768
+ }
2769
+ return sev;
2770
+ }
2771
+ const lintExtensions = [
2772
+ lintState,
2773
+ /* @__PURE__ */ EditorView.decorations.compute([lintState], (state) => {
2774
+ let { selected, panel } = state.field(lintState);
2775
+ return !selected || !panel || selected.from == selected.to ? Decoration.none : Decoration.set([
2776
+ activeMark.range(selected.from, selected.to)
2777
+ ]);
2778
+ }),
2779
+ /* @__PURE__ */ hoverTooltip(lintTooltip, { hideOn: hideTooltip }),
2780
+ baseTheme
2781
+ ];
2782
+ const basicSetup = /* @__PURE__ */ (() => [
2783
+ lineNumbers(),
2784
+ highlightActiveLineGutter(),
2785
+ highlightSpecialChars(),
2786
+ history(),
2787
+ foldGutter(),
2788
+ drawSelection(),
2789
+ dropCursor(),
2790
+ EditorState.allowMultipleSelections.of(true),
2791
+ indentOnInput(),
2792
+ syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
2793
+ bracketMatching(),
2794
+ closeBrackets(),
2795
+ autocompletion(),
2796
+ rectangularSelection(),
2797
+ crosshairCursor(),
2798
+ highlightActiveLine(),
2799
+ highlightSelectionMatches(),
2800
+ keymap.of([
2801
+ ...closeBracketsKeymap,
2802
+ ...defaultKeymap,
2803
+ ...searchKeymap,
2804
+ ...historyKeymap,
2805
+ ...foldKeymap,
2806
+ ...completionKeymap,
2807
+ ...lintKeymap
2808
+ ])
2809
+ ])();
2810
+ async function buildCodemirror({
2811
+ element,
2812
+ text,
2813
+ format,
2814
+ extensions,
2815
+ handleUpdate,
2816
+ getLang,
2817
+ getSupport
2818
+ }) {
2819
+ const languageConf = new Compartment();
2820
+ const supportConf = new Compartment();
2821
+ const tabSize = new Compartment();
2822
+ const updateListener = EditorView.updateListener.of(({ state, docChanged }) => {
2823
+ if (docChanged) {
2824
+ handleUpdate(state.doc.toString());
2825
+ }
2826
+ });
2827
+ async function languageForFormat(format2) {
2828
+ switch (format2) {
2829
+ case "glimdown":
2830
+ case "gdm":
2831
+ case "gmd":
2832
+ return getLang("gmd");
2833
+ case "jsx":
2834
+ case "jsx|react":
2835
+ return getLang("jsx|react");
2836
+ default:
2837
+ return getLang(format2);
2838
+ }
2839
+ }
2840
+ async function supportForFormat(format2) {
2841
+ const support2 = await getSupport(format2);
2842
+ if (!support2) {
2843
+ return [];
2844
+ }
2845
+ return Array.isArray(support2) ? support2 : [support2];
2846
+ }
2847
+ const [language, support] = await Promise.all([
2848
+ languageForFormat(format),
2849
+ supportForFormat(format)
2850
+ ]);
2851
+ const editorExtensions = [
2852
+ // features
2853
+ basicSetup,
2854
+ foldByIndent(),
2855
+ // Language
2856
+ languageConf.of(language),
2857
+ supportConf.of(support),
2858
+ updateListener,
2859
+ EditorView.lineWrapping,
2860
+ keymap.of([indentWithTab, ...completionKeymap, ...markdownKeymap]),
2861
+ // TODO: lsp,
2862
+ ...extensions ?? []
2863
+ ].filter(Boolean);
2864
+ const view = new EditorView({
2865
+ parent: element,
2866
+ state: EditorState.create({
2867
+ extensions: editorExtensions
2868
+ })
2869
+ });
2870
+ const setText = async (text2, format2) => {
2871
+ const [language2, support2] = await Promise.all([
2872
+ languageForFormat(format2),
2873
+ supportForFormat(format2)
2874
+ ]);
2875
+ console.debug(`Codemirror changing to ${format2}: ${language2 ? "ok" : "not ok"}`);
2876
+ view.dispatch({
2877
+ changes: {
2878
+ from: 0,
2879
+ to: view.state.doc.length,
2880
+ insert: text2
2881
+ },
2882
+ effects: [languageConf.reconfigure(language2), supportConf.reconfigure(support2)]
2883
+ });
2884
+ };
2885
+ const setFormat = async (format2) => {
2886
+ const [language2, support2] = await Promise.all([
2887
+ languageForFormat(format2),
2888
+ supportForFormat(format2)
2889
+ ]);
2890
+ console.debug(`Codemirror changing to ${format2}: ${language2 ? "ok" : "not ok"}`);
2891
+ view.dispatch({
2892
+ effects: [languageConf.reconfigure(language2), supportConf.reconfigure(support2)]
2893
+ });
2894
+ };
2895
+ view.dispatch(
2896
+ view.state.changeByRange((range) => ({
2897
+ changes: [{ from: range.from, insert: text }],
2898
+ range: EditorSelection.range(range.from, range.to)
2899
+ }))
2900
+ );
2901
+ view.dispatch({
2902
+ effects: [
2903
+ tabSize.reconfigure(EditorState.tabSize.of(2))
2904
+ // languageConf.reconfigure(languageForFormat(format)),
2905
+ ]
2906
+ });
2907
+ return { view, setText, setFormat };
2908
+ }
2909
+ export {
2910
+ buildCodemirror
2911
+ };
2912
+ //# sourceMappingURL=codemirror-De3S70Np.js.map