[mod] highlightWhitespace

This commit is contained in:
Andy Bunce 2025-10-20 15:21:47 +01:00
parent 55fef63678
commit be12f0200c
7 changed files with 347 additions and 338 deletions

View file

@ -2,7 +2,7 @@
import { EditorState, StateEffect, Compartment } from '@codemirror/state';
import {
lineNumbers, highlightActiveLineGutter, highlightSpecialChars,
lineNumbers, highlightActiveLineGutter, highlightWhitespace,
drawSelection, rectangularSelection, crosshairCursor, highlightActiveLine,
keymap, dropCursor, EditorView
} from '@codemirror/view';
@ -37,12 +37,14 @@ let create = (v) => {
const compartment = new Compartment();
let curOpts = {
lineWrap: true,
minimap: true
minimap: true,
highlightWhitespace: true
}
// array of extensions reflecting opts
function optExts(opts) {
let exts = []
if (opts.lineWrap) exts.push(EditorView.lineWrapping)
if (opts.highlightWhitespace) exts.push(highlightWhitespace())
if (opts.minimap) exts.push(
showMinimap.compute(['doc'], (state) => {
return {
@ -82,7 +84,6 @@ function simpleWebSocketTransport(uri) {
const baseExts = [
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter(),
lintGutter(),

226
package-lock.json generated
View file

@ -430,9 +430,9 @@
}
},
"node_modules/@codemirror/view": {
"version": "6.38.5",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.5.tgz",
"integrity": "sha512-SFVsNAgsAoou+BjRewMqN+m9jaztB9wCWN9RSRgePqUbq8UVlvJfku5zB2KVhLPgH/h0RLk38tvd4tGeAhygnw==",
"version": "6.38.6",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.6.tgz",
"integrity": "sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.5.0",
@ -492,9 +492,9 @@
}
},
"node_modules/@lezer/common": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.3.0.tgz",
"integrity": "sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ==",
"license": "MIT"
},
"node_modules/@lezer/cpp": {
@ -531,12 +531,12 @@
}
},
"node_modules/@lezer/highlight": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.2.tgz",
"integrity": "sha512-z8TQwaBXXQIvG6i2g3e9cgMwUUXu9Ib7jo2qRRggdhwKpM56Dw3PM3wmexn+EGaaOZ7az0K7sjc3/gcGW7sz7A==",
"license": "MIT",
"dependencies": {
"@lezer/common": "^1.0.0"
"@lezer/common": "^1.3.0"
}
},
"node_modules/@lezer/html": {
@ -593,9 +593,9 @@
}
},
"node_modules/@lezer/markdown": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.4.3.tgz",
"integrity": "sha512-kfw+2uMrQ/wy/+ONfrH83OkdFNM0ye5Xq96cLlaCy7h5UT9FO54DU4oRoIc0CSBh5NWmWuiIJA7NGLMJbQ+Oxg==",
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.5.1.tgz",
"integrity": "sha512-F3ZFnIfNAOy/jPSk6Q0e3bs7e9grfK/n5zerkKoc5COH6Guy3Zb0vrJwXzdck79K16goBhYBRAvhf+ksqe0cMg==",
"license": "MIT",
"dependencies": {
"@lezer/common": "^1.0.0",
@ -773,9 +773,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz",
"integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz",
"integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==",
"cpu": [
"arm"
],
@ -787,9 +787,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz",
"integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz",
"integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==",
"cpu": [
"arm64"
],
@ -801,9 +801,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz",
"integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz",
"integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==",
"cpu": [
"arm64"
],
@ -815,9 +815,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz",
"integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz",
"integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==",
"cpu": [
"x64"
],
@ -829,9 +829,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz",
"integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz",
"integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==",
"cpu": [
"arm64"
],
@ -843,9 +843,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz",
"integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz",
"integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==",
"cpu": [
"x64"
],
@ -857,9 +857,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz",
"integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz",
"integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==",
"cpu": [
"arm"
],
@ -871,9 +871,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz",
"integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz",
"integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==",
"cpu": [
"arm"
],
@ -885,9 +885,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz",
"integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz",
"integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==",
"cpu": [
"arm64"
],
@ -899,9 +899,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz",
"integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz",
"integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==",
"cpu": [
"arm64"
],
@ -913,9 +913,9 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz",
"integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz",
"integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==",
"cpu": [
"loong64"
],
@ -927,9 +927,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz",
"integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz",
"integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==",
"cpu": [
"ppc64"
],
@ -941,9 +941,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz",
"integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz",
"integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==",
"cpu": [
"riscv64"
],
@ -955,9 +955,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz",
"integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz",
"integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==",
"cpu": [
"riscv64"
],
@ -969,9 +969,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz",
"integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz",
"integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==",
"cpu": [
"s390x"
],
@ -983,9 +983,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz",
"integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz",
"integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==",
"cpu": [
"x64"
],
@ -997,9 +997,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz",
"integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz",
"integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==",
"cpu": [
"x64"
],
@ -1011,9 +1011,9 @@
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz",
"integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz",
"integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==",
"cpu": [
"arm64"
],
@ -1025,9 +1025,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz",
"integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz",
"integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==",
"cpu": [
"arm64"
],
@ -1039,9 +1039,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz",
"integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz",
"integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==",
"cpu": [
"ia32"
],
@ -1053,9 +1053,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz",
"integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz",
"integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==",
"cpu": [
"x64"
],
@ -1067,9 +1067,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz",
"integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz",
"integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==",
"cpu": [
"x64"
],
@ -1095,9 +1095,9 @@
"license": "MIT"
},
"node_modules/ace-builds": {
"version": "1.43.3",
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.3.tgz",
"integrity": "sha512-MCl9rALmXwIty/4Qboijo/yNysx1r6hBTzG+6n/TiOm5LFhZpEvEIcIITPFiEOEFDfgBOEmxu+a4f54LEFM6Sg==",
"version": "1.43.4",
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.4.tgz",
"integrity": "sha512-8hAxVfo2ImICd69BWlZwZlxe9rxDGDjuUhh+WeWgGDvfBCE+r3lkynkQvIovDz4jcMi8O7bsEaFygaDT+h9sBA==",
"license": "BSD-3-Clause"
},
"node_modules/ace-linters": {
@ -1138,9 +1138,9 @@
}
},
"node_modules/beercss": {
"version": "3.12.11",
"resolved": "https://registry.npmjs.org/beercss/-/beercss-3.12.11.tgz",
"integrity": "sha512-9NQWL3kxSOb5RPWAV5BPVs64CS72F5Z4HgxusqD07Ho4asaTJB33/SkJBMclQeUQs7hFH2CJOgGgDnIsRk2RyQ==",
"version": "3.12.12",
"resolved": "https://registry.npmjs.org/beercss/-/beercss-3.12.12.tgz",
"integrity": "sha512-xjlBAaKQljk0BI1ld9D4U6yf1lIqNrRwKJQKAXXw2BQLSTctZeBdTfPQQjffkty+QpC2PYeVxT6DtJVwqfVasw==",
"license": "MIT",
"dependencies": {
"material-dynamic-colors": "^1.1.2"
@ -1604,9 +1604,9 @@
}
},
"node_modules/rollup": {
"version": "4.52.4",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz",
"integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==",
"version": "4.52.5",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz",
"integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1620,28 +1620,28 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.52.4",
"@rollup/rollup-android-arm64": "4.52.4",
"@rollup/rollup-darwin-arm64": "4.52.4",
"@rollup/rollup-darwin-x64": "4.52.4",
"@rollup/rollup-freebsd-arm64": "4.52.4",
"@rollup/rollup-freebsd-x64": "4.52.4",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.4",
"@rollup/rollup-linux-arm-musleabihf": "4.52.4",
"@rollup/rollup-linux-arm64-gnu": "4.52.4",
"@rollup/rollup-linux-arm64-musl": "4.52.4",
"@rollup/rollup-linux-loong64-gnu": "4.52.4",
"@rollup/rollup-linux-ppc64-gnu": "4.52.4",
"@rollup/rollup-linux-riscv64-gnu": "4.52.4",
"@rollup/rollup-linux-riscv64-musl": "4.52.4",
"@rollup/rollup-linux-s390x-gnu": "4.52.4",
"@rollup/rollup-linux-x64-gnu": "4.52.4",
"@rollup/rollup-linux-x64-musl": "4.52.4",
"@rollup/rollup-openharmony-arm64": "4.52.4",
"@rollup/rollup-win32-arm64-msvc": "4.52.4",
"@rollup/rollup-win32-ia32-msvc": "4.52.4",
"@rollup/rollup-win32-x64-gnu": "4.52.4",
"@rollup/rollup-win32-x64-msvc": "4.52.4",
"@rollup/rollup-android-arm-eabi": "4.52.5",
"@rollup/rollup-android-arm64": "4.52.5",
"@rollup/rollup-darwin-arm64": "4.52.5",
"@rollup/rollup-darwin-x64": "4.52.5",
"@rollup/rollup-freebsd-arm64": "4.52.5",
"@rollup/rollup-freebsd-x64": "4.52.5",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.5",
"@rollup/rollup-linux-arm-musleabihf": "4.52.5",
"@rollup/rollup-linux-arm64-gnu": "4.52.5",
"@rollup/rollup-linux-arm64-musl": "4.52.5",
"@rollup/rollup-linux-loong64-gnu": "4.52.5",
"@rollup/rollup-linux-ppc64-gnu": "4.52.5",
"@rollup/rollup-linux-riscv64-gnu": "4.52.5",
"@rollup/rollup-linux-riscv64-musl": "4.52.5",
"@rollup/rollup-linux-s390x-gnu": "4.52.5",
"@rollup/rollup-linux-x64-gnu": "4.52.5",
"@rollup/rollup-linux-x64-musl": "4.52.5",
"@rollup/rollup-openharmony-arm64": "4.52.5",
"@rollup/rollup-win32-arm64-msvc": "4.52.5",
"@rollup/rollup-win32-ia32-msvc": "4.52.5",
"@rollup/rollup-win32-x64-gnu": "4.52.5",
"@rollup/rollup-win32-x64-msvc": "4.52.5",
"fsevents": "~2.3.2"
}
},
@ -1696,9 +1696,9 @@
}
},
"node_modules/style-mod": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz",
"integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==",
"license": "MIT"
},
"node_modules/supports-preserve-symlinks-flag": {

View file

@ -76,3 +76,6 @@ function app:dev() {
cm:htmx2("dev/home.htm", map{})
};
declare function app:logs() {
(admin:logs()=>foot()=>admin:logs())[@type eq 'LSP']
};

View file

@ -210,6 +210,10 @@
<input name="wrapLines" type="checkbox" class="form-check-input" id="lineWrap">
<label class="form-check-label" for="lineWrap">Wrap lines</label>
</div>
<div class="mb-3 form-check">
<input name="highlightWhitespace" type="checkbox" class="form-check-input" id="highlightWhitespace">
<label class="form-check-label" for="highlightWhitespace">highlight Whitespace</label>
</div>
<div class="mb-3 form-check">
<input name="minimap" type="checkbox" class="form-check-input" id="minimap">
<label class="form-check-label" for="minimap">Show minimap</label>

View file

@ -4281,6 +4281,35 @@ var lsp = (function (exports) {
}
}
let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
const ie_edge = /*@__PURE__*//Edge\/(\d+)/.exec(nav.userAgent);
const ie_upto10 = /*@__PURE__*//MSIE \d/.test(nav.userAgent);
const ie_11up = /*@__PURE__*//Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
const ie = !!(ie_upto10 || ie_11up || ie_edge);
const gecko = !ie && /*@__PURE__*//gecko\/(\d+)/i.test(nav.userAgent);
const chrome = !ie && /*@__PURE__*//Chrome\/(\d+)/.exec(nav.userAgent);
const webkit = "webkitFontSmoothing" in doc.documentElement.style;
const safari = !ie && /*@__PURE__*//Apple Computer/.test(nav.vendor);
const ios = safari && (/*@__PURE__*//Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
var browser = {
mac: ios || /*@__PURE__*//Mac/.test(nav.platform),
windows: /*@__PURE__*//Win/.test(nav.platform),
linux: /*@__PURE__*//Linux|X11/.test(nav.platform),
ie,
ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
gecko,
gecko_version: gecko ? +(/*@__PURE__*//Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
chrome: !!chrome,
chrome_version: chrome ? +chrome[1] : 0,
ios,
android: /*@__PURE__*//Android\b/.test(nav.userAgent),
webkit_version: webkit ? +(/*@__PURE__*//\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
safari,
safari_version: safari ? +(/*@__PURE__*//\bVersion\/(\d+(\.\d+)?)/.exec(nav.userAgent) || [0, 0])[1] : 0,
tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
};
function getSelection(root) {
let target;
// Browsers differ on whether shadow roots have a getSelection
@ -4531,6 +4560,9 @@ var lsp = (function (exports) {
}
}
let preventScrollSupported = null;
// Safari 26 breaks preventScroll support
if (browser.safari && browser.safari_version >= 26)
preventScrollSupported = false;
// Feature-detects support for .focus({preventScroll: true}), and uses
// a fallback kludge when not supported.
function focusPreventScroll(dom) {
@ -5000,34 +5032,6 @@ var lsp = (function (exports) {
replaceRange(parent, fromI, fromOff, toI, toOff, insert, 0, openStart, openEnd);
}
let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
const ie_edge = /*@__PURE__*//Edge\/(\d+)/.exec(nav.userAgent);
const ie_upto10 = /*@__PURE__*//MSIE \d/.test(nav.userAgent);
const ie_11up = /*@__PURE__*//Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
const ie = !!(ie_upto10 || ie_11up || ie_edge);
const gecko = !ie && /*@__PURE__*//gecko\/(\d+)/i.test(nav.userAgent);
const chrome = !ie && /*@__PURE__*//Chrome\/(\d+)/.exec(nav.userAgent);
const webkit = "webkitFontSmoothing" in doc.documentElement.style;
const safari = !ie && /*@__PURE__*//Apple Computer/.test(nav.vendor);
const ios = safari && (/*@__PURE__*//Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
var browser = {
mac: ios || /*@__PURE__*//Mac/.test(nav.platform),
windows: /*@__PURE__*//Win/.test(nav.platform),
linux: /*@__PURE__*//Linux|X11/.test(nav.platform),
ie,
ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
gecko,
gecko_version: gecko ? +(/*@__PURE__*//Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
chrome: !!chrome,
chrome_version: chrome ? +chrome[1] : 0,
ios,
android: /*@__PURE__*//Android\b/.test(nav.userAgent),
safari,
webkit_version: webkit ? +(/*@__PURE__*//\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
};
const MaxJoinLen = 256;
class TextView extends ContentView {
constructor(text) {
@ -8131,9 +8135,10 @@ var lsp = (function (exports) {
if (next == end)
break;
let view = ContentView.get(cur), nextView = ContentView.get(next);
if (view && nextView ? view.breakAfter :
if ((view && nextView ? view.breakAfter :
(view ? view.breakAfter : isBlockElement(cur)) ||
(isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen))
(isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen)) &&
!isEmptyToEnd(next, end))
this.lineBreak();
cur = next;
}
@ -8212,6 +8217,25 @@ var lsp = (function (exports) {
node = node.parentNode;
}
}
function isEmptyToEnd(node, end) {
let widgets;
for (;; node = node.nextSibling) {
if (node == end || !node)
break;
let view = ContentView.get(node);
if (!((view === null || view === void 0 ? void 0 : view.isWidget) || node.cmIgnore))
return false;
if (view)
(widgets || (widgets = [])).push(view);
}
if (widgets)
for (let w of widgets) {
let override = w.overrideDOMText;
if (override === null || override === void 0 ? void 0 : override.length)
return false;
}
return true;
}
class DOMPoint {
constructor(node, offset) {
this.node = node;
@ -8653,7 +8677,7 @@ var lsp = (function (exports) {
return dispatchKey(this.view.contentDOM, key.key, key.keyCode, key instanceof KeyboardEvent ? key : undefined);
}
ignoreDuringComposition(event) {
if (!/^key/.test(event.type))
if (!/^key/.test(event.type) || event.synthetic)
return false;
if (this.composing > 0)
return true;
@ -11557,20 +11581,23 @@ var lsp = (function (exports) {
let from = this.toEditorPos(e.updateRangeStart), to = this.toEditorPos(e.updateRangeEnd);
if (view.inputState.composing >= 0 && !this.composing)
this.composing = { contextBase: e.updateRangeStart, editorBase: from, drifted: false };
let change = { from, to, insert: Text.of(e.text.split("\n")) };
let deletes = to - from > e.text.length;
// If the window doesn't include the anchor, assume changes
// adjacent to a side go up to the anchor.
if (change.from == this.from && anchor < this.from)
change.from = anchor;
else if (change.to == this.to && anchor > this.to)
change.to = anchor;
if (from == this.from && anchor < this.from)
from = anchor;
else if (to == this.to && anchor > this.to)
to = anchor;
let diff = findDiff(view.state.sliceDoc(from, to), e.text, (deletes ? main.from : main.to) - from, deletes ? "end" : null);
// Edit contexts sometimes fire empty changes
if (change.from == change.to && !change.insert.length) {
if (!diff) {
let newSel = EditorSelection.single(this.toEditorPos(e.selectionStart), this.toEditorPos(e.selectionEnd));
if (!newSel.main.eq(main))
view.dispatch({ selection: newSel, userEvent: "select" });
return;
}
let change = { from: diff.from + from, to: diff.toA + from,
insert: Text.of(e.text.slice(diff.from, diff.toB).split("\n")) };
if ((browser.mac || browser.android) && change.from == head - 1 &&
/^\. ?$/.test(e.text) && view.contentDOM.getAttribute("autocorrect") == "off")
change = { from, to, insert: Text.of([e.text.replace(".", " ")]) };
@ -11585,6 +11612,10 @@ var lsp = (function (exports) {
this.revertPending(view.state);
this.setSelection(view.state);
}
// Work around missed compositionend events. See https://discuss.codemirror.net/t/a/9514
if (change.from < change.to && !change.insert.length && view.inputState.composing >= 0 &&
!/[\\p{Alphabetic}\\p{Number}_]/.test(context.text.slice(Math.max(0, e.updateRangeStart - 1), Math.min(context.text.length, e.updateRangeStart + 1))))
this.handlers.compositionend(e);
};
this.handlers.characterboundsupdate = e => {
let rects = [], prev = null;
@ -11600,10 +11631,11 @@ var lsp = (function (exports) {
let deco = [];
for (let format of e.getTextFormats()) {
let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
if (lineStyle != "None" && thickness != "None") {
if (!/none/i.test(lineStyle) && !/none/i.test(thickness)) {
let from = this.toEditorPos(format.rangeStart), to = this.toEditorPos(format.rangeEnd);
if (from < to) {
let style = `text-decoration: underline ${lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${thickness == "Thin" ? 1 : 2}px`;
// These values changed from capitalized custom strings to lower-case CSS keywords in 2025
let style = `text-decoration: underline ${/^[a-z]/.test(lineStyle) ? lineStyle + " " : lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${/thin/i.test(thickness) ? 1 : 2}px`;
deco.push(Decoration.mark({ attributes: { style } }).range(from, to));
}
}
@ -13370,7 +13402,7 @@ var lsp = (function (exports) {
old = next;
}
this.drawn = markers;
if (browser.ios) // Issue #1600
if (browser.safari && browser.safari_version >= 26) // Issue #1600, 1627
this.dom.style.display = this.dom.firstChild ? "" : "none";
}
}
@ -13709,156 +13741,6 @@ var lsp = (function (exports) {
}
}
const UnicodeRegexpSupport = /x/.unicode != null ? "gu" : "g";
const Specials = /*@__PURE__*/new RegExp("[\u0000-\u0008\u000a-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\u2066\u2067\u2069\ufeff\ufff9-\ufffc]", UnicodeRegexpSupport);
const Names = {
0: "null",
7: "bell",
8: "backspace",
10: "newline",
11: "vertical tab",
13: "carriage return",
27: "escape",
8203: "zero width space",
8204: "zero width non-joiner",
8205: "zero width joiner",
8206: "left-to-right mark",
8207: "right-to-left mark",
8232: "line separator",
8237: "left-to-right override",
8238: "right-to-left override",
8294: "left-to-right isolate",
8295: "right-to-left isolate",
8297: "pop directional isolate",
8233: "paragraph separator",
65279: "zero width no-break space",
65532: "object replacement"
};
let _supportsTabSize = null;
function supportsTabSize() {
var _a;
if (_supportsTabSize == null && typeof document != "undefined" && document.body) {
let styles = document.body.style;
_supportsTabSize = ((_a = styles.tabSize) !== null && _a !== void 0 ? _a : styles.MozTabSize) != null;
}
return _supportsTabSize || false;
}
const specialCharConfig = /*@__PURE__*/Facet.define({
combine(configs) {
let config = combineConfig(configs, {
render: null,
specialChars: Specials,
addSpecialChars: null
});
if (config.replaceTabs = !supportsTabSize())
config.specialChars = new RegExp("\t|" + config.specialChars.source, UnicodeRegexpSupport);
if (config.addSpecialChars)
config.specialChars = new RegExp(config.specialChars.source + "|" + config.addSpecialChars.source, UnicodeRegexpSupport);
return config;
}
});
/**
Returns an extension that installs highlighting of special
characters.
*/
function highlightSpecialChars(
/**
Configuration options.
*/
config = {}) {
return [specialCharConfig.of(config), specialCharPlugin()];
}
let _plugin = null;
function specialCharPlugin() {
return _plugin || (_plugin = ViewPlugin.fromClass(class {
constructor(view) {
this.view = view;
this.decorations = Decoration.none;
this.decorationCache = Object.create(null);
this.decorator = this.makeDecorator(view.state.facet(specialCharConfig));
this.decorations = this.decorator.createDeco(view);
}
makeDecorator(conf) {
return new MatchDecorator({
regexp: conf.specialChars,
decoration: (m, view, pos) => {
let { doc } = view.state;
let code = codePointAt(m[0], 0);
if (code == 9) {
let line = doc.lineAt(pos);
let size = view.state.tabSize, col = countColumn(line.text, size, pos - line.from);
return Decoration.replace({
widget: new TabWidget((size - (col % size)) * this.view.defaultCharacterWidth / this.view.scaleX)
});
}
return this.decorationCache[code] ||
(this.decorationCache[code] = Decoration.replace({ widget: new SpecialCharWidget(conf, code) }));
},
boundary: conf.replaceTabs ? undefined : /[^]/
});
}
update(update) {
let conf = update.state.facet(specialCharConfig);
if (update.startState.facet(specialCharConfig) != conf) {
this.decorator = this.makeDecorator(conf);
this.decorations = this.decorator.createDeco(update.view);
}
else {
this.decorations = this.decorator.updateDeco(update, this.decorations);
}
}
}, {
decorations: v => v.decorations
}));
}
const DefaultPlaceholder = "\u2022";
// Assigns placeholder characters from the Control Pictures block to
// ASCII control characters
function placeholder$1(code) {
if (code >= 32)
return DefaultPlaceholder;
if (code == 10)
return "\u2424";
return String.fromCharCode(9216 + code);
}
class SpecialCharWidget extends WidgetType {
constructor(options, code) {
super();
this.options = options;
this.code = code;
}
eq(other) { return other.code == this.code; }
toDOM(view) {
let ph = placeholder$1(this.code);
let desc = view.state.phrase("Control character") + " " + (Names[this.code] || "0x" + this.code.toString(16));
let custom = this.options.render && this.options.render(this.code, desc, ph);
if (custom)
return custom;
let span = document.createElement("span");
span.textContent = ph;
span.title = desc;
span.setAttribute("aria-label", desc);
span.className = "cm-specialChar";
return span;
}
ignoreEvent() { return false; }
}
class TabWidget extends WidgetType {
constructor(width) {
super();
this.width = width;
}
eq(other) { return other.width == this.width; }
toDOM() {
let span = document.createElement("span");
span.textContent = "\t";
span.className = "cm-tab";
span.style.width = this.width + "px";
return span;
}
ignoreEvent() { return false; }
}
/**
Mark lines that have a cursor on them with the `"cm-activeLine"`
DOM class.
@ -15526,6 +15408,33 @@ var lsp = (function (exports) {
return activeLineGutterHighlighter;
}
function matcher(decorator) {
return ViewPlugin.define(view => ({
decorations: decorator.createDeco(view),
update(u) {
this.decorations = decorator.updateDeco(u, this.decorations);
},
}), {
decorations: v => v.decorations
});
}
const tabDeco = /*@__PURE__*/Decoration.mark({ class: "cm-highlightTab" });
const spaceDeco = /*@__PURE__*/Decoration.mark({ class: "cm-highlightSpace" });
const whitespaceHighlighter = /*@__PURE__*/matcher(/*@__PURE__*/new MatchDecorator({
regexp: /\t| /g,
decoration: match => match[0] == "\t" ? tabDeco : spaceDeco,
boundary: /\S/,
}));
/**
Returns an extension that highlights whitespace, adding a
`cm-highlightSpace` class to stretches of spaces, and a
`cm-highlightTab` class to individual tab characters. By default,
the former are shown as faint dots, and the latter as arrows.
*/
function highlightWhitespace() {
return whitespaceHighlighter;
}
const basicNormalize = typeof String.prototype.normalize == "function"
? x => x.normalize("NFKD") : x => x;
/**
@ -17040,22 +16949,36 @@ var lsp = (function (exports) {
}
const lintConfig = /*@__PURE__*/Facet.define({
combine(input) {
return Object.assign({ sources: input.map(i => i.source).filter(x => x != null) }, combineConfig(input.map(i => i.config), {
delay: 750,
markerFilter: null,
tooltipFilter: null,
needsRefresh: null,
hideOn: () => null,
}, {
needsRefresh: (a, b) => !a ? b : !b ? a : u => a(u) || b(u)
}));
return {
sources: input.map(i => i.source).filter(x => x != null),
...combineConfig(input.map(i => i.config), {
delay: 750,
markerFilter: null,
tooltipFilter: null,
needsRefresh: null,
hideOn: () => null,
}, {
delay: Math.max,
markerFilter: combineFilter,
tooltipFilter: combineFilter,
needsRefresh: (a, b) => !a ? b : !b ? a : u => a(u) || b(u),
hideOn: (a, b) => !a ? b : !b ? a : (t, x, y) => a(t, x, y) || b(t, x, y),
autoPanel: (a, b) => a || b
})
};
}
});
function combineFilter(a, b) {
return !a ? b : !b ? a : (d, s) => b(a(d, s), s);
}
/**
Given a diagnostic source, this function returns an extension that
enables linting with that source. It will be called whenever the
editor is idle (after its content changed). If `null` is given as
source, this only configures the lint extension.
editor is idle (after its content changed).
Note that settings given here will apply to all linters active in
the editor. If `null` is given as source, this only configures the
lint extension.
*/
function linter(source, config = {}) {
return [
@ -17096,9 +17019,10 @@ var lsp = (function (exports) {
let nameElt = keyIndex < 0 ? name : [name.slice(0, keyIndex),
crelt("u", name.slice(keyIndex, keyIndex + 1)),
name.slice(keyIndex + 1)];
let markClass = action.markClass ? " " + action.markClass : "";
return crelt("button", {
type: "button",
class: "cm-diagnosticAction",
class: "cm-diagnosticAction" + markClass,
onclick: click,
onmousedown: click,
"aria-label": ` Action: ${name}${keyIndex < 0 ? "" : ` (access key "${keys[i]})"`}.`
@ -17521,7 +17445,7 @@ var lsp = (function (exports) {
create() { return null; },
update(tooltip, tr) {
if (tooltip && tr.docChanged)
tooltip = hideTooltip(tr, tooltip) ? null : Object.assign(Object.assign({}, tooltip), { pos: tr.changes.mapPos(tooltip.pos) });
tooltip = hideTooltip(tr, tooltip) ? null : { ...tooltip, pos: tr.changes.mapPos(tooltip.pos) };
return tr.effects.reduce((t, e) => e.is(setLintGutterTooltip) ? e.value : t, tooltip);
},
provide: field => showTooltip.from(field)
@ -17631,6 +17555,7 @@ var lsp = (function (exports) {
this.deserialize = config.deserialize || (() => {
throw new Error("This node type doesn't define a deserialize function");
});
this.combine = config.combine || null;
}
/**
This is meant to be used with
@ -17895,7 +17820,10 @@ var lsp = (function (exports) {
if (add) {
if (!newProps)
newProps = Object.assign({}, type.props);
newProps[add[0].id] = add[1];
let value = add[1], prop = add[0];
if (prop.combine && prop.id in newProps)
value = prop.combine(newProps[prop.id], value);
newProps[prop.id] = value;
}
}
newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
@ -18878,7 +18806,7 @@ var lsp = (function (exports) {
function takeNode(parentStart, minPos, children, positions, inRepeat, depth) {
let { id, start, end, size } = cursor;
let lookAheadAtStart = lookAhead, contextAtStart = contextHash;
while (size < 0) {
if (size < 0) {
cursor.next();
if (size == -1 /* SpecialRecord.Reuse */) {
let node = reused[id];
@ -19469,7 +19397,7 @@ var lsp = (function (exports) {
For example:
```javascript
parser.withProps(
parser.configure({props: [
styleTags({
// Style Number and BigNumber nodes
"Number BigNumber": tags.number,
@ -19484,7 +19412,7 @@ var lsp = (function (exports) {
// Style the node named "/" as punctuation
'"/"': tags.punctuation
})
)
]})
```
*/
function styleTags(spec) {
@ -19526,7 +19454,28 @@ var lsp = (function (exports) {
}
return ruleNodeProp.add(byName);
}
const ruleNodeProp = new NodeProp();
const ruleNodeProp = new NodeProp({
combine(a, b) {
let cur, root, take;
while (a || b) {
if (!a || a.depth > b.depth) {
take = b;
b = b.next;
}
else {
take = a;
a = a.next;
}
let copy = new Rule(take.tags, take.mode, take.context);
if (cur)
cur.next = copy;
else
root = copy;
cur = copy;
}
return root;
}
});
class Rule {
constructor(tags, mode, context, next) {
this.tags = tags;
@ -23321,6 +23270,41 @@ var lsp = (function (exports) {
dispatch(setSel(state, selection));
return true;
};
function addCursorVertically(view, forward) {
let { state } = view, sel = state.selection, ranges = state.selection.ranges.slice();
for (let range of state.selection.ranges) {
let line = state.doc.lineAt(range.head);
if (forward ? line.to < view.state.doc.length : line.from > 0)
for (let cur = range;;) {
let next = view.moveVertically(cur, forward);
if (next.head < line.from || next.head > line.to) {
if (!ranges.some(r => r.head == next.head))
ranges.push(next);
break;
}
else if (next.head == cur.head) {
break;
}
else {
cur = next;
}
}
}
if (ranges.length == sel.ranges.length)
return false;
view.dispatch(setSel(state, EditorSelection.create(ranges, ranges.length - 1)));
return true;
}
/**
Expand the selection by adding a cursor above the heads of
currently selected ranges.
*/
const addCursorAbove = view => addCursorVertically(view, false);
/**
Expand the selection by adding a cursor below the heads of
currently selected ranges.
*/
const addCursorBelow = view => addCursorVertically(view, true);
/**
Simplify the current selection. When multiple ranges are selected,
reduce it to its main range. Otherwise, if the selection is
@ -23830,12 +23814,12 @@ var lsp = (function (exports) {
{ key: "Mod-End", run: cursorDocEnd, shift: selectDocEnd },
{ key: "Enter", run: insertNewlineAndIndent, shift: insertNewlineAndIndent },
{ key: "Mod-a", run: selectAll },
{ key: "Backspace", run: deleteCharBackward, shift: deleteCharBackward },
{ key: "Delete", run: deleteCharForward },
{ key: "Mod-Backspace", mac: "Alt-Backspace", run: deleteGroupBackward },
{ key: "Mod-Delete", mac: "Alt-Delete", run: deleteGroupForward },
{ mac: "Mod-Backspace", run: deleteLineBoundaryBackward },
{ mac: "Mod-Delete", run: deleteLineBoundaryForward }
{ key: "Backspace", run: deleteCharBackward, shift: deleteCharBackward, preventDefault: true },
{ key: "Delete", run: deleteCharForward, preventDefault: true },
{ key: "Mod-Backspace", mac: "Alt-Backspace", run: deleteGroupBackward, preventDefault: true },
{ key: "Mod-Delete", mac: "Alt-Delete", run: deleteGroupForward, preventDefault: true },
{ mac: "Mod-Backspace", run: deleteLineBoundaryBackward, preventDefault: true },
{ mac: "Mod-Delete", run: deleteLineBoundaryForward, preventDefault: true }
].concat(/*@__PURE__*/emacsStyleKeymap.map(b => ({ mac: b.key, run: b.run, shift: b.shift })));
/**
The default keymap. Includes all bindings from
@ -23847,6 +23831,8 @@ var lsp = (function (exports) {
- Alt-ArrowDown: [`moveLineDown`](https://codemirror.net/6/docs/ref/#commands.moveLineDown)
- Shift-Alt-ArrowUp: [`copyLineUp`](https://codemirror.net/6/docs/ref/#commands.copyLineUp)
- Shift-Alt-ArrowDown: [`copyLineDown`](https://codemirror.net/6/docs/ref/#commands.copyLineDown)
- Ctrl-Alt-ArrowUp (Cmd-Alt-ArrowUp on macOS): [`addCursorAbove`](https://codemirror.net/6/docs/ref/#commands.addCursorAbove).
- Ctrl-Alt-ArrowDown (Cmd-Alt-ArrowDown on macOS): [`addCursorBelow`](https://codemirror.net/6/docs/ref/#commands.addCursorBelow).
- Escape: [`simplifySelection`](https://codemirror.net/6/docs/ref/#commands.simplifySelection)
- Ctrl-Enter (Cmd-Enter on macOS): [`insertBlankLine`](https://codemirror.net/6/docs/ref/#commands.insertBlankLine)
- Alt-l (Ctrl-l on macOS): [`selectLine`](https://codemirror.net/6/docs/ref/#commands.selectLine)
@ -23867,6 +23853,8 @@ var lsp = (function (exports) {
{ key: "Shift-Alt-ArrowUp", run: copyLineUp },
{ key: "Alt-ArrowDown", run: moveLineDown },
{ key: "Shift-Alt-ArrowDown", run: copyLineDown },
{ key: "Mod-Alt-ArrowUp", run: addCursorAbove },
{ key: "Mod-Alt-ArrowDown", run: addCursorBelow },
{ key: "Escape", run: simplifySelection },
{ key: "Mod-Enter", run: insertBlankLine },
{ key: "Alt-l", mac: "Ctrl-l", run: selectLine },
@ -24608,7 +24596,7 @@ var lsp = (function (exports) {
}
function sortOptions(active, state) {
let options = [];
let sections = null;
let sections = null, dynamicSectionScore = null;
let addOption = (option) => {
options.push(option);
let { section } = option.completion;
@ -24635,13 +24623,24 @@ var lsp = (function (exports) {
for (let option of a.result.options)
if (match = matcher.match(option.label)) {
let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
let score = match.score + (option.boost || 0);
addOption(new Option(option, a.source, matched, score));
if (typeof option.section == "object" && option.section.rank === "dynamic") {
let { name } = option.section;
if (!dynamicSectionScore)
dynamicSectionScore = Object.create(null);
dynamicSectionScore[name] = Math.max(score, dynamicSectionScore[name] || -1e9);
}
}
}
}
if (sections) {
let sectionOrder = Object.create(null), pos = 0;
let cmp = (a, b) => { var _a, _b; return ((_a = a.rank) !== null && _a !== void 0 ? _a : 1e9) - ((_b = b.rank) !== null && _b !== void 0 ? _b : 1e9) || (a.name < b.name ? -1 : 1); };
let cmp = (a, b) => {
return (a.rank === "dynamic" && b.rank === "dynamic" ? dynamicSectionScore[b.name] - dynamicSectionScore[a.name] : 0) ||
(typeof a.rank == "number" ? a.rank : 1e9) - (typeof b.rank == "number" ? b.rank : 1e9) ||
(a.name < b.name ? -1 : 1);
};
for (let s of sections.sort(cmp)) {
pos -= 1e5;
sectionOrder[s.name] = pos;
@ -31308,12 +31307,14 @@ ${text}</tr>
const compartment = new Compartment();
let curOpts = {
lineWrap: true,
minimap: true
minimap: true,
highlightWhitespace: true
};
// array of extensions reflecting opts
function optExts(opts) {
let exts = [];
if (opts.lineWrap) exts.push(EditorView.lineWrapping);
if (opts.highlightWhitespace) exts.push(highlightWhitespace());
if (opts.minimap) exts.push(
showMinimap.compute(['doc'], (state) => {
return {
@ -31352,7 +31353,6 @@ ${text}</tr>
const baseExts = [
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter(),
lintGutter(),

File diff suppressed because one or more lines are too long

View file

@ -139,8 +139,9 @@ function updateSettings(event) {
console.log("COPTS", lsp.curOpts);
const opts = {
lineWrap: $("lineWrap").checked,
minimap: $("minimap").checked
lineWrap: $("lineWrap").checked,
highlightWhitespace: $("highlightWhitespace").checked,
minimap: $("minimap").checked
}
console.log(opts)
lsp.updateCompartment(opts);