on master help sign in
.envrc+1
since splitsnapshots
unifiedsplit
@@ -1,5 +1,6 @@
1watch_file shell.nix
1watch_file shell.nix
2watch_file flake.lock
2watch_file flake.lock
3+watch_file rust-toolchain.toml
3
4
4# try to use flakes, if it fails use normal nix (ie. shell.nix)
5# try to use flakes, if it fails use normal nix (ie. shell.nix)
5use flake || use nix
6use flake || use nix
.github/ISSUE_TEMPLATE/bug_report.yaml+10
@@ -55,6 +55,16 @@ body:
55 placeholder: wezterm 20220101-133340-7edc5b5a
55 placeholder: wezterm 20220101-133340-7edc5b5a
56 validations:
56 validations:
57 required: true
57 required: true
58+ - type: input
59+ id: installation-method
60+ attributes:
61+ label: Installation Method
62+ description: >
63+ How you installed Helix - from a package manager like Homebrew or the
64+ AUR, built from source, downloaded a binary from the releases page, etc.
65+ placeholder: "source / brew / nixpkgs / flake / releases page"
66+ validations:
67+ required: true
58 - type: input
68 - type: input
59 id: helix-version
69 id: helix-version
60 attributes:
70 attributes:
.github/workflows/build.yml+11−3
@@ -22,6 +22,8 @@ jobs:
22 override: true
22 override: true
23
23
24 - uses: Swatinem/rust-cache@v2
24 - uses: Swatinem/rust-cache@v2
25+ with:
26+ shared-key: "build"
25
27
26 - name: Run cargo check
28 - name: Run cargo check
27 run: cargo check
29 run: cargo check
@@ -37,9 +39,11 @@ jobs:
37 uses: actions/checkout@v4
39 uses: actions/checkout@v4
38
40
39 - name: Install stable toolchain
41 - name: Install stable toolchain
40− uses: dtolnay/rust-toolchain@1.65
42+ uses: dtolnay/rust-toolchain@1.70
41
43
42 - uses: Swatinem/rust-cache@v2
44 - uses: Swatinem/rust-cache@v2
45+ with:
46+ shared-key: "build"
43
47
44 - name: Cache test tree-sitter grammar
48 - name: Cache test tree-sitter grammar
45 uses: actions/cache@v3
49 uses: actions/cache@v3
@@ -66,11 +70,13 @@ jobs:
66 uses: actions/checkout@v4
70 uses: actions/checkout@v4
67
71
68 - name: Install stable toolchain
72 - name: Install stable toolchain
69− uses: dtolnay/rust-toolchain@1.65
73+ uses: dtolnay/rust-toolchain@1.70
70 with:
74 with:
71 components: rustfmt, clippy
75 components: rustfmt, clippy
72
76
73 - uses: Swatinem/rust-cache@v2
77 - uses: Swatinem/rust-cache@v2
78+ with:
79+ shared-key: "build"
74
80
75 - name: Run cargo fmt
81 - name: Run cargo fmt
76 run: cargo fmt --all --check
82 run: cargo fmt --all --check
@@ -91,9 +97,11 @@ jobs:
91 uses: actions/checkout@v4
97 uses: actions/checkout@v4
92
98
93 - name: Install stable toolchain
99 - name: Install stable toolchain
94− uses: dtolnay/rust-toolchain@1.65
100+ uses: dtolnay/rust-toolchain@1.70
95
101
96 - uses: Swatinem/rust-cache@v2
102 - uses: Swatinem/rust-cache@v2
103+ with:
104+ shared-key: "build"
97
105
98 - name: Validate queries
106 - name: Validate queries
99 run: cargo xtask query-check
107 run: cargo xtask query-check
.github/workflows/cachix.yml+2−2
@@ -14,10 +14,10 @@ jobs:
14 uses: actions/checkout@v4
14 uses: actions/checkout@v4
15
15
16 - name: Install nix
16 - name: Install nix
17− uses: cachix/install-nix-action@v23
17+ uses: cachix/install-nix-action@v24
18
18
19 - name: Authenticate with Cachix
19 - name: Authenticate with Cachix
20− uses: cachix/cachix-action@v12
20+ uses: cachix/cachix-action@v13
21 with:
21 with:
22 name: helix
22 name: helix
23 authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
23 authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
.github/workflows/gh-pages.yml+4−4
@@ -26,16 +26,16 @@ jobs:
26 OUTDIR=$(basename ${{ github.ref }})
26 OUTDIR=$(basename ${{ github.ref }})
27 echo "OUTDIR=$OUTDIR" >> $GITHUB_ENV
27 echo "OUTDIR=$OUTDIR" >> $GITHUB_ENV
28
28
29− - name: Deploy
29+ - name: Deploy stable
30 uses: peaceiris/actions-gh-pages@v3
30 uses: peaceiris/actions-gh-pages@v3
31+ if: startswith(github.ref, 'refs/tags/')
31 with:
32 with:
32 github_token: ${{ secrets.GITHUB_TOKEN }}
33 github_token: ${{ secrets.GITHUB_TOKEN }}
33 publish_dir: ./book/book
34 publish_dir: ./book/book
34− destination_dir: ./${{ env.OUTDIR }}
35
35
36− - name: Deploy stable
36+ - name: Deploy
37 uses: peaceiris/actions-gh-pages@v3
37 uses: peaceiris/actions-gh-pages@v3
38− if: startswith(github.ref, 'refs/tags/')
39 with:
38 with:
40 github_token: ${{ secrets.GITHUB_TOKEN }}
39 github_token: ${{ secrets.GITHUB_TOKEN }}
41 publish_dir: ./book/book
40 publish_dir: ./book/book
41+ destination_dir: ./${{ env.OUTDIR }}
.github/workflows/release.yml+10−10
@@ -36,7 +36,7 @@ jobs:
36 - name: Bundle grammars
36 - name: Bundle grammars
37 run: tar cJf grammars.tar.xz -C runtime/grammars/sources .
37 run: tar cJf grammars.tar.xz -C runtime/grammars/sources .
38
38
39− - uses: actions/upload-artifact@v3
39+ - uses: actions/upload-artifact@v4
40 with:
40 with:
41 name: grammars
41 name: grammars
42 path: grammars.tar.xz
42 path: grammars.tar.xz
@@ -70,11 +70,11 @@ jobs:
70 rust: stable
70 rust: stable
71 target: aarch64-unknown-linux-gnu
71 target: aarch64-unknown-linux-gnu
72 cross: true
72 cross: true
73− - build: riscv64-linux
73+ # - build: riscv64-linux
74− os: ubuntu-latest
74+ # os: ubuntu-latest
75− rust: stable
75+ # rust: stable
76− target: riscv64gc-unknown-linux-gnu
76+ # target: riscv64gc-unknown-linux-gnu
77− cross: true
77+ # cross: true
78 - build: x86_64-macos
78 - build: x86_64-macos
79 os: macos-latest
79 os: macos-latest
80 rust: stable
80 rust: stable
@@ -106,7 +106,7 @@ jobs:
106 uses: actions/checkout@v4
106 uses: actions/checkout@v4
107
107
108 - name: Download grammars
108 - name: Download grammars
109− uses: actions/download-artifact@v3
109+ uses: actions/download-artifact@v4
110
110
111 - name: Move grammars under runtime
111 - name: Move grammars under runtime
112 if: "!startsWith(matrix.os, 'windows')"
112 if: "!startsWith(matrix.os, 'windows')"
@@ -220,7 +220,7 @@ jobs:
220 fi
220 fi
221 cp -r runtime dist
221 cp -r runtime dist
222
222
223− - uses: actions/upload-artifact@v3
223+ - uses: actions/upload-artifact@v4
224 with:
224 with:
225 name: bins-${{ matrix.build }}
225 name: bins-${{ matrix.build }}
226 path: dist
226 path: dist
@@ -233,7 +233,7 @@ jobs:
233 - name: Checkout sources
233 - name: Checkout sources
234 uses: actions/checkout@v4
234 uses: actions/checkout@v4
235
235
236− - uses: actions/download-artifact@v3
236+ - uses: actions/download-artifact@v4
237
237
238 - name: Build archive
238 - name: Build archive
239 shell: bash
239 shell: bash
@@ -288,7 +288,7 @@ jobs:
288 overwrite: true
288 overwrite: true
289
289
290 - name: Upload binaries as artifact
290 - name: Upload binaries as artifact
291− uses: actions/upload-artifact@v3
291+ uses: actions/upload-artifact@v4
292 if: env.preview == 'true'
292 if: env.preview == 'true'
293 with:
293 with:
294 name: release
294 name: release
CHANGELOG.md+260
@@ -1,3 +1,263 @@
1+# 23.10 (2023-10-24)
2+
3+A big shout out to all the contributors! We had 118 contributors in this release.
4+
5+Breaking changes:
6+
7+- Support multiple language servers per language ([#2507](https://github.com/helix-editor/helix/pull/2507))
8+ - This is a breaking change to language configuration
9+
10+Features:
11+
12+- Support multiple language servers per language ([#2507](https://github.com/helix-editor/helix/pull/2507), [#7082](https://github.com/helix-editor/helix/pull/7082), [#7286](https://github.com/helix-editor/helix/pull/7286), [#8374](https://github.com/helix-editor/helix/pull/8374))
13+- Add a statusline element for the selected register ([#7222](https://github.com/helix-editor/helix/pull/7222))
14+- Add `%`, `#`, `.`, `*` and `+` special registers ([#6985](https://github.com/helix-editor/helix/pull/6985))
15+- Add initial support for LSP DidChangeWatchedFiles notifications ([#7665](https://github.com/helix-editor/helix/pull/7665))
16+- Search buffer contents in `global_search` ([#5652](https://github.com/helix-editor/helix/pull/5652))
17+- Add a "smart tab" command that intelligently jumps the cursor on tab ([#4443](https://github.com/helix-editor/helix/pull/4443))
18+- Add a statusline element for whether a file is read-only ([#7222](https://github.com/helix-editor/helix/pull/7222), [#7875](https://github.com/helix-editor/helix/pull/7875))
19+- Syntax highlight regex prompts ([#7738](https://github.com/helix-editor/helix/pull/7738))
20+- Allow defining alignment in indent queries ([#5355](https://github.com/helix-editor/helix/pull/5355))
21+- Show visual feedback in `surround_replace` ([#7588](https://github.com/helix-editor/helix/pull/7588))
22+- Switch to Nucleo for fuzzy matching ([#7814](https://github.com/helix-editor/helix/pull/7814), [#8148](https://github.com/helix-editor/helix/pull/8148), [#8192](https://github.com/helix-editor/helix/pull/8192), [#8194](https://github.com/helix-editor/helix/pull/8194))
23+- Insert a trailing newline on write ([#8157](https://github.com/helix-editor/helix/pull/8157))
24+- Add a `-w`/`--working-dir` CLI flag for specifying a working directory on startup ([#8223](https://github.com/helix-editor/helix/pull/8223), [#8498](https://github.com/helix-editor/helix/pull/8498), [#8520](https://github.com/helix-editor/helix/pull/8520))
25+- Accept a `+N` CLI argument to set the first file's line number ([#8521](https://github.com/helix-editor/helix/pull/8521))
26+- Accept Helix-specific ignore files in `.helix/ignore` and `~/.config/helix/ignore` ([#8099](https://github.com/helix-editor/helix/pull/8099))
27+
28+Commands:
29+
30+- `merge_selections` (`A-minus`) - merge all selections into one selection that covers all ranges ([#7053](https://github.com/helix-editor/helix/pull/7053))
31+- `move_prev_long_word_end` and `extend_prev_long_word_end` - move/extend to the end of the previous WORD ([#6905](https://github.com/helix-editor/helix/pull/6905))
32+- `reverse_selection_contents` - swaps the values of each selection so they are reversed ([#7329](https://github.com/helix-editor/helix/pull/7329))
33+- Add `:rl` and `:rla` aliases for `:reload` and `:reload-all` ([#7158](https://github.com/helix-editor/helix/pull/7158))
34+- `yank_joined` - join the selections and yank to the selected register ([#7195](https://github.com/helix-editor/helix/pull/7195))
35+- `:write-all!` (`:wa!`) - forcibly write all buffers to disk and create any necessary subdirectories ([#7577](https://github.com/helix-editor/helix/pull/7577))
36+- `:redraw` - clear re-render the UI ([#6949](https://github.com/helix-editor/helix/pull/6949))
37+- `:tree-sitter-highlight-name` - show the theme scope name of the highlight under the cursor ([#8170](https://github.com/helix-editor/helix/pull/8170))
38+
39+Usability improvements:
40+
41+- Allow cycling option values at runtime ([#4411](https://github.com/helix-editor/helix/pull/4411), [#7240](https://github.com/helix-editor/helix/pull/7240), [#7877](https://github.com/helix-editor/helix/pull/7877))
42+- Exit gracefully on termination signals ([#7236](https://github.com/helix-editor/helix/pull/7236))
43+- Add plaintext matching fallback to tree-sitter pair matching ([#4288](https://github.com/helix-editor/helix/pull/4288))
44+- Persist register selection in pending keymaps ([0e08349](https://github.com/helix-editor/helix/commit/0e08349))
45+- Propagate the count and register to command palette commands ([b394997](https://github.com/helix-editor/helix/commit/b394997))
46+- Auto indent on `insert_at_line_start` ([#5837](https://github.com/helix-editor/helix/pull/5837))
47+- Add a config option to control whether LSP completions are automatically inserted on preview ([#7189](https://github.com/helix-editor/helix/pull/7189))
48+- Add a config option for default line endings ([#5621](https://github.com/helix-editor/helix/pull/5621), [#7357](https://github.com/helix-editor/helix/pull/7357))
49+- Allow ANSI colors in themes ([#5119](https://github.com/helix-editor/helix/pull/5119))
50+- Match pairs that don't form a standalone tree-sitter node ([#7242](https://github.com/helix-editor/helix/pull/7242))
51+- Allow indent sizes of up to 16 columns ([#7429](https://github.com/helix-editor/helix/pull/7429))
52+- Improve performance of mapping positions through changes ([#7408](https://github.com/helix-editor/helix/pull/7408), [8d39a81](https://github.com/helix-editor/helix/commit/8d39a81), [#7471](https://github.com/helix-editor/helix/pull/7471))
53+- Mark buffers created from stdin as modified ([#7431](https://github.com/helix-editor/helix/pull/7431))
54+- Forcibly shut down uninitialized language servers ([#7449](https://github.com/helix-editor/helix/pull/7449))
55+- Add filename completer for shell prompts ([#7569](https://github.com/helix-editor/helix/pull/7569))
56+- Allow binding F13-F24 ([#7672](https://github.com/helix-editor/helix/pull/7672))
57+- Resolve LSP code actions ([#7677](https://github.com/helix-editor/helix/pull/7677), [#8421](https://github.com/helix-editor/helix/pull/8421))
58+- Save an undo checkpoint before accepting completions ([#7747](https://github.com/helix-editor/helix/pull/7747))
59+- Include gitignored files in debugger completions ([#7936](https://github.com/helix-editor/helix/pull/7936))
60+- Make editor remember the last search register ([#5244](https://github.com/helix-editor/helix/pull/5244))
61+- Open directories with `goto_file` ([#7909](https://github.com/helix-editor/helix/pull/7909))
62+- Use relative path to open buffer in `goto_file` (`gf`) ([#7965](https://github.com/helix-editor/helix/pull/7965))
63+- Support `default` color in themes ([#8083](https://github.com/helix-editor/helix/pull/8083), [#8114](https://github.com/helix-editor/helix/pull/8114))
64+- Toggle between relative and absolute line numbers when the terminal loses focus ([#7955](https://github.com/helix-editor/helix/pull/7955))
65+- Lower default idle-timeout to 250ms ([060e73a](https://github.com/helix-editor/helix/commit/060e73a))
66+- Allow theming diff gutters separately from other diff colors ([#8343](https://github.com/helix-editor/helix/pull/8343))
67+- Style bold/italic/strikethrough in markdown doc popups ([#8385](https://github.com/helix-editor/helix/pull/8385))
68+- Maintain the cursor position and view when splitting with `:hsplit`/`:vsplit` ([#8109](https://github.com/helix-editor/helix/pull/8109))
69+- Accept `-` in macros outside of `<`/`>` ([#8475](https://github.com/helix-editor/helix/pull/8475))
70+- Show all language servers for each language in `--health` ([#7315](https://github.com/helix-editor/helix/pull/7315))
71+- Don't break on hyphens in `:reflow` ([#8569](https://github.com/helix-editor/helix/pull/8569))
72+
73+Fixes:
74+
75+- Update diagnostics correctly on language server exit ([#7111](https://github.com/helix-editor/helix/pull/7111))
76+- Fix off-by-one in `select_references_to_symbol_under_cursor` ([#7132](https://github.com/helix-editor/helix/pull/7132))
77+- Extend selection with repeat-last-motion only if the original motion extended the selection ([#7159](https://github.com/helix-editor/helix/pull/7159))
78+- Fix undefined behavior in the diff gutter ([#7227](https://github.com/helix-editor/helix/pull/7227))
79+- Check that tab width is non-zero ([#7178](https://github.com/helix-editor/helix/pull/7178))
80+- Fix styles being overwritten in table rows with multiple cells ([#7281](https://github.com/helix-editor/helix/pull/7281))
81+- Add file for `--log` CLI arg in help text ([#7307](https://github.com/helix-editor/helix/pull/7307))
82+- Fix underflow when repeating a completion that has a negative shift position ([#7322](https://github.com/helix-editor/helix/pull/7322))
83+- Prefer longer matches in `select_next_sibling` and `select_prev_sibling` ([#7332](https://github.com/helix-editor/helix/pull/7332))
84+- Preview scratch buffers in the jumplist picker ([#7331](https://github.com/helix-editor/helix/pull/7331))
85+- Fix chunking by bytes in tree-sitter parsing ([#7417](https://github.com/helix-editor/helix/pull/7417))
86+- Discard LSP publishDiagnostic from uninitialized servers ([#7467](https://github.com/helix-editor/helix/pull/7467))
87+- Use negotiated position encoding for LSP workspace edits ([#7469](https://github.com/helix-editor/helix/pull/7469))
88+- Fix error message for unknown gutter types in config ([#7534](https://github.com/helix-editor/helix/pull/7534))
89+- Fix `:log-open` when `--log` CLI arg is specified ([#7573](https://github.com/helix-editor/helix/pull/7573), [#7585](https://github.com/helix-editor/helix/pull/7585))
90+- Fix debouncing of LSP messages to fix the last message sticking around ([#7538](https://github.com/helix-editor/helix/pull/7538), [#8023](https://github.com/helix-editor/helix/pull/8023))
91+- Fix crash when the current working directory is deleted ([#7185](https://github.com/helix-editor/helix/pull/7185))
92+- Fix piping to Helix on macOS ([#5468](https://github.com/helix-editor/helix/pull/5468))
93+- Fix crash when parsing overlapping injections ([#7621](https://github.com/helix-editor/helix/pull/7621))
94+- Clear the statusline when the prompt is visible ([#7646](https://github.com/helix-editor/helix/pull/7646))
95+- Fix range formatting error message typo ([#7823](https://github.com/helix-editor/helix/pull/7823))
96+- Skip rendering gutters when gutter width exceeds view width ([#7821](https://github.com/helix-editor/helix/pull/7821))
97+- Center the picker preview using visual lines ([#7837](https://github.com/helix-editor/helix/pull/7837))
98+- Align view correctly for background buffers opened with `A-ret` ([#7691](https://github.com/helix-editor/helix/pull/7691))
99+- Fix cursor resetting to block when quitting via a keybind ([#7931](https://github.com/helix-editor/helix/pull/7931))
100+- Remove path completions for the `:new` command ([#8010](https://github.com/helix-editor/helix/pull/8010))
101+- Use binary path resolved by `which` for formatter commands ([#8064](https://github.com/helix-editor/helix/pull/8064))
102+- Handle crossterm's `hidden` modifier ([#8120](https://github.com/helix-editor/helix/pull/8120))
103+- Clear completion when switching between windows with the mouse ([#8118](https://github.com/helix-editor/helix/pull/8118))
104+- Eagerly remove the last picker (`<space>'`) when the picker has many items ([#8127](https://github.com/helix-editor/helix/pull/8127))
105+- Fix find commands for buffers with non-LF line-endings ([#8111](https://github.com/helix-editor/helix/pull/8111))
106+- Detect the tmux clipboard provider on macOS ([#8182](https://github.com/helix-editor/helix/pull/8182))
107+- Fix syntax highlighting in dynamic picker preview pane ([#8206](https://github.com/helix-editor/helix/pull/8206))
108+- Recognize HTML code tags with attributes as code in markdown previews ([#8397](https://github.com/helix-editor/helix/pull/8397))
109+- Fix multicursor snippet placeholder directions ([#8423](https://github.com/helix-editor/helix/pull/8423))
110+- Only show diagnostic highlights when diagnostics are enabled for a language server ([#8551](https://github.com/helix-editor/helix/pull/8551))
111+
112+Themes:
113+
114+- Improve the selection color in `ferra` ([#7138](https://github.com/helix-editor/helix/pull/7138))
115+- Add `variable.other.member` theming to `spacebones_light` ([#7125](https://github.com/helix-editor/helix/pull/7125))
116+- Update `autumn` and theme the soft-wrap indicator ([#7229](https://github.com/helix-editor/helix/pull/7229))
117+- Add `gruvbox_dark_soft` ([#7139](https://github.com/helix-editor/helix/pull/7139))
118+- Add `merionette` ([#7186](https://github.com/helix-editor/helix/pull/7186))
119+- Add `zed_onedark` and `zed_onelight` ([#7250](https://github.com/helix-editor/helix/pull/7250))
120+- Use light-gray for `onedarker` inlay hint theming ([#7433](https://github.com/helix-editor/helix/pull/7433))
121+- Update the Nord theme to follow the style guidelines ([#7490](https://github.com/helix-editor/helix/pull/7490))
122+- Tune `dark_plus` inlay hint colors ([#7611](https://github.com/helix-editor/helix/pull/7611))
123+- Add `naysayer` ([#7570](https://github.com/helix-editor/helix/pull/7570))
124+- Add `kaolin-dark`, `kaolin-light` and `kaolin-valley-dark` ([#7151](https://github.com/helix-editor/helix/pull/7151))
125+- Fix selection highlighting in gruvbox variants ([#7717](https://github.com/helix-editor/helix/pull/7717))
126+- Add soft-wrap indicator to `gruvbox` ([#7736](https://github.com/helix-editor/helix/pull/7736))
127+- Add missing palette definitions in `everforest_dark` ([#7739](https://github.com/helix-editor/helix/pull/7739))
128+- Increase diagnostics clarity in `pop-dark` ([#7702](https://github.com/helix-editor/helix/pull/7702))
129+- Add `vim_dark_high_contrast` ([#7785](https://github.com/helix-editor/helix/pull/7785))
130+- Add `new_moon` ([#7834](https://github.com/helix-editor/helix/pull/7834))
131+- Add `yellowed` ([#7849](https://github.com/helix-editor/helix/pull/7849))
132+- Improve comment readability for `autumn` ([#7939](https://github.com/helix-editor/helix/pull/7939))
133+- Distinguish active bufferline buffer in `monokai` ([#7983](https://github.com/helix-editor/helix/pull/7983))
134+- Update ruler colors in `nord` ([#7995](https://github.com/helix-editor/helix/pull/7995))
135+- Update Catppuccin themes ([#8102](https://github.com/helix-editor/helix/pull/8102))
136+- Add text focus scope and diagnostics undercurls for `nord` ([#8165](https://github.com/helix-editor/helix/pull/8165))
137+- Add material theme collection ([#8211](https://github.com/helix-editor/helix/pull/8211))
138+- Improve indent line color in `dracula` ([#8266](https://github.com/helix-editor/helix/pull/8266))
139+- Clean up and refactor `papercolor` to use inheritance ([#8276](https://github.com/helix-editor/helix/pull/8276))
140+- Fix `zenburn` inlay hint color ([#8278](https://github.com/helix-editor/helix/pull/8278)a)
141+- Fix picker crash when previewing an invalid range ([e9d0bd7](https://github.com/helix-editor/helix/commit/e9d0bd7))
142+- Correctly center items in the picker preview ([13d4463](https://github.com/helix-editor/helix/commit/13d4463))
143+- Add `cyan_light` ([#8293](https://github.com/helix-editor/helix/pull/8293), [#8587](https://github.com/helix-editor/helix/pull/8587))
144+- Theme HTML tags in `onedark` ([#8409](https://github.com/helix-editor/helix/pull/8409))
145+- Refine `darcula` and `darcula-solid` themes ([#8412](https://github.com/helix-editor/helix/pull/8412))
146+- Improve `nord` highlights ([#8414](https://github.com/helix-editor/helix/pull/8414))
147+- Add `nord-night` ([#8549](https://github.com/helix-editor/helix/pull/8549))
148+
149+New languages:
150+
151+- Blueprint ([#7213](https://github.com/helix-editor/helix/pull/7213), [#8161](https://github.com/helix-editor/helix/pull/8161))
152+- Forth ([#7256](https://github.com/helix-editor/helix/pull/7256), [#7334](https://github.com/helix-editor/helix/pull/7334))
153+- t32 ([#7140](https://github.com/helix-editor/helix/pull/7140), [#7811](https://github.com/helix-editor/helix/pull/7811))
154+- WebC ([#7290](https://github.com/helix-editor/helix/pull/7290))
155+- Persistent DSL for Haskell ([#7261](https://github.com/helix-editor/helix/pull/7261))
156+- F# ([#7619](https://github.com/helix-editor/helix/pull/7619), [#8024](https://github.com/helix-editor/helix/pull/8024))
157+- Wren ([#7765](https://github.com/helix-editor/helix/pull/7765), [#7819](https://github.com/helix-editor/helix/pull/7819))
158+- Unison ([#7724](https://github.com/helix-editor/helix/pull/7724))
159+- Todo.txt ([#7835](https://github.com/helix-editor/helix/pull/7835))
160+- Jinja and Handlebars ([#7233](https://github.com/helix-editor/helix/pull/7233))
161+- Pod ([#7907](https://github.com/helix-editor/helix/pull/7907))
162+- Strace ([#7928](https://github.com/helix-editor/helix/pull/7928))
163+- Gemini ([#8070](https://github.com/helix-editor/helix/pull/8070))
164+- GNU Assembler (GAS) ([#8291](https://github.com/helix-editor/helix/pull/8291))
165+- JSON5 ([#8473](https://github.com/helix-editor/helix/pull/8473))
166+- TEMPL ([#8540](https://github.com/helix-editor/helix/pull/8540))
167+
168+Updated languages and queries:
169+
170+- Add one to the ruler numbers for git-commit ([#7072](https://github.com/helix-editor/helix/pull/7072))
171+- Recognize XAML files as XML ([#7083](https://github.com/helix-editor/helix/pull/7083))
172+- Recognize `Cargo.lock` as TOML ([#7095](https://github.com/helix-editor/helix/pull/7095))
173+- Use Rust grammar for Cairo ([c6d1430](https://github.com/helix-editor/helix/commit/c6d1430))
174+- Update tree-sitter-nickel ([#7059](https://github.com/helix-editor/helix/pull/7059), [#7551](https://github.com/helix-editor/helix/pull/7551))
175+- Tune auto-pair characters for Nickel ([#7059](https://github.com/helix-editor/helix/pull/7059))
176+- Recognize `Vagrantfile` as Ruby ([#7112](https://github.com/helix-editor/helix/pull/7112))
177+- Recognize hidden justfiles as Just ([#7088](https://github.com/helix-editor/helix/pull/7088))
178+- Update Java and TypeScript highlight queries ([#7145](https://github.com/helix-editor/helix/pull/7145))
179+- Recognize `.zimrc` as Bash ([#7146](https://github.com/helix-editor/helix/pull/7146))
180+- Recognize `.gir` as XML ([#7152](https://github.com/helix-editor/helix/pull/7152))
181+- Update tree-sitter-scala ([#7147](https://github.com/helix-editor/helix/pull/7147))
182+- Recognize make file-type as Makefile ([#7212](https://github.com/helix-editor/helix/pull/7212))
183+- Update tree-sitter-verilog ([#7262](https://github.com/helix-editor/helix/pull/7262))
184+- Update tree-sitter-cpp ([#7285](https://github.com/helix-editor/helix/pull/7285))
185+- Support core mode for delve debugger ([#7300](https://github.com/helix-editor/helix/pull/7300))
186+- Add Fortran comment injections ([#7305](https://github.com/helix-editor/helix/pull/7305))
187+- Switch Vue language server to `vue-language-server` ([#7312](https://github.com/helix-editor/helix/pull/7312))
188+- Update tree-sitter-sql ([#7387](https://github.com/helix-editor/helix/pull/7387), [#8464](https://github.com/helix-editor/helix/pull/8464))
189+- Replace the MATLAB tre-sitter grammar ([#7388](https://github.com/helix-editor/helix/pull/7388), [#7442](https://github.com/helix-editor/helix/pull/7442), [#7491](https://github.com/helix-editor/helix/pull/7491), [#7493](https://github.com/helix-editor/helix/pull/7493), [#7511](https://github.com/helix-editor/helix/pull/7511), [#7532](https://github.com/helix-editor/helix/pull/7532), [#8040](https://github.com/helix-editor/helix/pull/8040))
190+- Highlight TOML table headers ([#7441](https://github.com/helix-editor/helix/pull/7441))
191+- Recognize `cppm` file-type as C++ ([#7492](https://github.com/helix-editor/helix/pull/7492))
192+- Refactor ecma language queries into private and public queries ([#7207](https://github.com/helix-editor/helix/pull/7207))
193+- Update tree-sitter-dart ([#7576](https://github.com/helix-editor/helix/pull/7576))
194+- Add shebang for nushell files ([#7606](https://github.com/helix-editor/helix/pull/7606))
195+- Recognize systemd files as INI ([#7592](https://github.com/helix-editor/helix/pull/7592))
196+- Update TypeScript, TSX and Svelte grammars ([#6874](https://github.com/helix-editor/helix/pull/6874))
197+- Enable inlay hints in the Svelte language server ([#7622](https://github.com/helix-editor/helix/pull/7622))
198+- Recognize `Brewfile`s as Ruby ([#7629](https://github.com/helix-editor/helix/pull/7629))
199+- Add more file-types for R ([#7633](https://github.com/helix-editor/helix/pull/7633))
200+- Switch tree-sitter-perl to official upstream parser ([#7644](https://github.com/helix-editor/helix/pull/7644), [#7947](https://github.com/helix-editor/helix/pull/7947))
201+- Fix predicate typo in comment highlights ([#7732](https://github.com/helix-editor/helix/pull/7732))
202+- Update tree-sitter-prql ([#7771](https://github.com/helix-editor/helix/pull/7771))
203+- Recognize `.gitf` as JSON ([#7781](https://github.com/helix-editor/helix/pull/7781))
204+- Switch V language server to `v-analyzer` ([#7760](https://github.com/helix-editor/helix/pull/7760))
205+- Add protobuf language servers ([#7796](https://github.com/helix-editor/helix/pull/7796))
206+- Update tree-sitter-zig ([#7803](https://github.com/helix-editor/helix/pull/7803))
207+- Update tree-sitter-hare ([#7784](https://github.com/helix-editor/helix/pull/7784))
208+- Add Java indent queries ([#7844](https://github.com/helix-editor/helix/pull/7844))
209+- Update tree-sitter-scheme ([979933b](https://github.com/helix-editor/helix/commit/979933b))
210+- Recognize `scm` as Scheme instead of TSQ ([5707151](https://github.com/helix-editor/helix/commit/5707151))
211+- Update tree-sitter-git-commit ([#7831](https://github.com/helix-editor/helix/pull/7831))
212+- Update JavaScript, TypeScript and TSX grammars ([#7852](https://github.com/helix-editor/helix/pull/7852))
213+- Update tree-sitter-nu ([#7873](https://github.com/helix-editor/helix/pull/7873))
214+- Fix YAML indentation ([#6768](https://github.com/helix-editor/helix/pull/6768))
215+- Add `csharp-ls`, Pyright, Pylyzer and add roots for Python ([#7897](https://github.com/helix-editor/helix/pull/7897), [#8032](https://github.com/helix-editor/helix/pull/8032))
216+- Update tree-sitter-slint ([#7893](https://github.com/helix-editor/helix/pull/7893))
217+- Recognize more ZSH file-types as Bash ([#7930](https://github.com/helix-editor/helix/pull/7930))
218+- Recognize `star` extension as Starlark ([#7922](https://github.com/helix-editor/helix/pull/7922))
219+- Fix inline HTML tag highlighting in markdown ([#7960](https://github.com/helix-editor/helix/pull/7960))
220+- Update tree-sitter-robot ([#7970](https://github.com/helix-editor/helix/pull/7970))
221+- Highlight Dart 3 `sealed` and `base` keywords ([#7974](https://github.com/helix-editor/helix/pull/7974))
222+- Add configuration for `ltex-ls` to the default `languages.toml` ([#7838](https://github.com/helix-editor/helix/pull/7838))
223+- Update tree-sitter-strace ([#8087](https://github.com/helix-editor/helix/pull/8087))
224+- Update tree-sitter-gleam, enable auto-format ([#8085](https://github.com/helix-editor/helix/pull/8085))
225+- Update tree-sitter-esdl ([#8222](https://github.com/helix-editor/helix/pull/8222))
226+- Expand ignore file-types ([#8220](https://github.com/helix-editor/helix/pull/8220))
227+- Recognize feed related formats as XML ([#8232](https://github.com/helix-editor/helix/pull/8232))
228+- Improve YAML injections ([#8217](https://github.com/helix-editor/helix/pull/8217))
229+- Add shebangs for TypeScript, Julia, Java and OCaml ([95e994a](https://github.com/helix-editor/helix/commit/95e994a))
230+- Highlight abbreviations in Scheme ([ef23847](https://github.com/helix-editor/helix/commit/ef23847))
231+- Remove backtic auto-pair in OCaml ([#8260](https://github.com/helix-editor/helix/pull/8260))
232+- Recognize `flake.lock` as JSON ([#8304](https://github.com/helix-editor/helix/pull/8304))
233+- Add Python test script injection for Nix ([b4494e1](https://github.com/helix-editor/helix/commit/b4494e1))
234+- Fix Nix comment injection precedence ([37e48f4](https://github.com/helix-editor/helix/commit/37e48f4))
235+- Recognize editorconfig files as INI ([#8308](https://github.com/helix-editor/helix/pull/8308))
236+- Recognize `.babelrc` as JSON ([#8309](https://github.com/helix-editor/helix/pull/8309))
237+- Switch Purescript to its own tree-sitter parser ([#8306](https://github.com/helix-editor/helix/pull/8306), [#8338](https://github.com/helix-editor/helix/pull/8338), [#8527](https://github.com/helix-editor/helix/pull/8527))
238+- Update Unison highlights ([#8315](https://github.com/helix-editor/helix/pull/8315))
239+- Recognize `.webmanifest` as JSON ([#8342](https://github.com/helix-editor/helix/pull/8342))
240+- Recognize polkit policy files as XML ([#8369](https://github.com/helix-editor/helix/pull/8369))
241+- Recognize polkit rules files as JavaScript ([#8370](https://github.com/helix-editor/helix/pull/8370))
242+- Update Go highlight queries ([#8399](https://github.com/helix-editor/helix/pull/8399))
243+- Add shebangs for Makefiles ([#8410](https://github.com/helix-editor/helix/pull/8410))
244+- Add file-type associations from VSCode ([#8388](https://github.com/helix-editor/helix/pull/8388))
245+- Add validation to JSON/CSS language server configs ([#8433](https://github.com/helix-editor/helix/pull/8433))
246+- Add a configuration for the tailwind language server ([#8442](https://github.com/helix-editor/helix/pull/8442))
247+- Add a configuration for the ansible language server ([#7973](https://github.com/helix-editor/helix/pull/7973))
248+- Add a configuration for the GraphQL language server ([#8492](https://github.com/helix-editor/helix/pull/8492))
249+- Indent while statements in Bash ([#8528](https://github.com/helix-editor/helix/pull/8528))
250+- Update tree-sitter-haskell and queries ([#8558](https://github.com/helix-editor/helix/pull/8558))
251+
252+Packaging:
253+
254+- Add an overlay to the Nix flake ([#7078](https://github.com/helix-editor/helix/pull/7078))
255+- Check for `git` before fetching or building grammars ([#7320](https://github.com/helix-editor/helix/pull/7320))
256+- Refactor Nix flake to use Crane ([#7763](https://github.com/helix-editor/helix/pull/7763))
257+- Remove the aarch64 appimage from the release CI ([#7832](https://github.com/helix-editor/helix/pull/7832))
258+- Add desktop and icon files to Nix flake output ([#7979](https://github.com/helix-editor/helix/pull/7979))
259+- Build flake packages with the latest stable Rust ([#8133](https://github.com/helix-editor/helix/pull/8133))
260+
1# 23.05 (2023-05-18)
261# 23.05 (2023-05-18)
2
262
323.05 is a smaller release focusing on fixes. There were 88 contributors in this release. Thank you all!
26323.05 is a smaller release focusing on fixes. There were 88 contributors in this release. Thank you all!
Cargo.lock+404−595
@@ -19,30 +19,22 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19
19
20[[package]]
20[[package]]
21name = "ahash"
21name = "ahash"
22−version = "0.8.3"
22+version = "0.8.6"
23source = "registry+https://github.com/rust-lang/crates.io-index"
23source = "registry+https://github.com/rust-lang/crates.io-index"
24−checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
24+checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
25dependencies = [
25dependencies = [
26 "cfg-if",
26 "cfg-if",
27 "getrandom",
27 "getrandom",
28 "once_cell",
28 "once_cell",
29 "version_check",
29 "version_check",
30+ "zerocopy",
30]
31]
31
32
32[[package]]
33[[package]]
33name = "aho-corasick"
34name = "aho-corasick"
34−version = "0.7.20"
35+version = "1.1.2"
35−source = "registry+https://github.com/rust-lang/crates.io-index"
36−checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
37−dependencies = [
38− "memchr",
39−]
40−
41−[[package]]
42−name = "aho-corasick"
43−version = "1.0.2"
44source = "registry+https://github.com/rust-lang/crates.io-index"
36source = "registry+https://github.com/rust-lang/crates.io-index"
45−checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
37+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
46dependencies = [
38dependencies = [
47 "memchr",
39 "memchr",
48]
40]
@@ -70,9 +62,9 @@ dependencies = [
70
62
71[[package]]
63[[package]]
72name = "anyhow"
64name = "anyhow"
73−version = "1.0.75"
65+version = "1.0.76"
74source = "registry+https://github.com/rust-lang/crates.io-index"
66source = "registry+https://github.com/rust-lang/crates.io-index"
75−checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
67+checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355"
76
68
77[[package]]
69[[package]]
78name = "arc-swap"
70name = "arc-swap"
@@ -109,15 +101,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
109
101
110[[package]]
102[[package]]
111name = "bitflags"
103name = "bitflags"
112−version = "2.4.0"
104+version = "2.4.1"
113source = "registry+https://github.com/rust-lang/crates.io-index"
105source = "registry+https://github.com/rust-lang/crates.io-index"
114−checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
106+checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
115
107
116[[package]]
108[[package]]
117name = "bstr"
109name = "bstr"
118−version = "1.6.0"
110+version = "1.8.0"
119source = "registry+https://github.com/rust-lang/crates.io-index"
111source = "registry+https://github.com/rust-lang/crates.io-index"
120−checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
112+checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
121dependencies = [
113dependencies = [
122 "memchr",
114 "memchr",
123 "regex-automata",
115 "regex-automata",
@@ -139,12 +131,6 @@ version = "3.12.0"
139source = "registry+https://github.com/rust-lang/crates.io-index"
131source = "registry+https://github.com/rust-lang/crates.io-index"
140checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
132checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
141
133
142−[[package]]
143−name = "bytecount"
144−version = "0.6.3"
145−source = "registry+https://github.com/rust-lang/crates.io-index"
146−checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
147−
148[[package]]
134[[package]]
149name = "bytes"
135name = "bytes"
150version = "1.4.0"
136version = "1.4.0"
@@ -159,9 +145,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
159
145
160[[package]]
146[[package]]
161name = "cc"
147name = "cc"
162−version = "1.0.83"
148+version = "1.0.84"
163source = "registry+https://github.com/rust-lang/crates.io-index"
149source = "registry+https://github.com/rust-lang/crates.io-index"
164−checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
150+checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856"
165dependencies = [
151dependencies = [
166 "libc",
152 "libc",
167]
153]
@@ -185,9 +171,9 @@ dependencies = [
185
171
186[[package]]
172[[package]]
187name = "chrono"
173name = "chrono"
188−version = "0.4.30"
174+version = "0.4.31"
189source = "registry+https://github.com/rust-lang/crates.io-index"
175source = "registry+https://github.com/rust-lang/crates.io-index"
190−checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877"
176+checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
191dependencies = [
177dependencies = [
192 "android-tzdata",
178 "android-tzdata",
193 "iana-time-zone",
179 "iana-time-zone",
@@ -197,13 +183,11 @@ dependencies = [
197
183
198[[package]]
184[[package]]
199name = "clipboard-win"
185name = "clipboard-win"
200−version = "4.5.0"
186+version = "5.0.0"
201source = "registry+https://github.com/rust-lang/crates.io-index"
187source = "registry+https://github.com/rust-lang/crates.io-index"
202−checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362"
188+checksum = "c57002a5d9be777c1ef967e33674dac9ebd310d8893e4e3437b14d5f0f6372cc"
203dependencies = [
189dependencies = [
204 "error-code",
190 "error-code",
205− "str-buf",
206− "winapi",
207]
191]
208
192
209[[package]]
193[[package]]
@@ -301,7 +285,7 @@ version = "0.27.0"
301source = "registry+https://github.com/rust-lang/crates.io-index"
285source = "registry+https://github.com/rust-lang/crates.io-index"
302checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
286checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
303dependencies = [
287dependencies = [
304− "bitflags 2.4.0",
288+ "bitflags 2.4.1",
305 "crossterm_winapi",
289 "crossterm_winapi",
306 "filedescriptor",
290 "filedescriptor",
307 "futures-core",
291 "futures-core",
@@ -346,7 +330,7 @@ dependencies = [
346 "proc-macro2",
330 "proc-macro2",
347 "quote",
331 "quote",
348 "scratch",
332 "scratch",
349− "syn 2.0.28",
333+ "syn 2.0.38",
350]
334]
351
335
352[[package]]
336[[package]]
@@ -363,28 +347,7 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
363dependencies = [
347dependencies = [
364 "proc-macro2",
348 "proc-macro2",
365 "quote",
349 "quote",
366− "syn 2.0.28",
350+ "syn 2.0.38",
367−]
368−
369−[[package]]
370−name = "dirs"
371−version = "5.0.1"
372−source = "registry+https://github.com/rust-lang/crates.io-index"
373−checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
374−dependencies = [
375− "dirs-sys",
376−]
377−
378−[[package]]
379−name = "dirs-sys"
380−version = "0.4.1"
381−source = "registry+https://github.com/rust-lang/crates.io-index"
382−checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
383−dependencies = [
384− "libc",
385− "option-ext",
386− "redox_users",
387− "windows-sys 0.48.0",
388]
351]
389
352
390[[package]]
353[[package]]
@@ -425,34 +388,19 @@ checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
425
388
426[[package]]
389[[package]]
427name = "errno"
390name = "errno"
428−version = "0.3.1"
391+version = "0.3.8"
429−source = "registry+https://github.com/rust-lang/crates.io-index"
430−checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
431−dependencies = [
432− "errno-dragonfly",
433− "libc",
434− "windows-sys 0.48.0",
435−]
436−
437−[[package]]
438−name = "errno-dragonfly"
439−version = "0.1.2"
440source = "registry+https://github.com/rust-lang/crates.io-index"
392source = "registry+https://github.com/rust-lang/crates.io-index"
441−checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
393+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
442dependencies = [
394dependencies = [
443− "cc",
444 "libc",
395 "libc",
396+ "windows-sys 0.52.0",
445]
397]
446
398
447[[package]]
399[[package]]
448name = "error-code"
400name = "error-code"
449−version = "2.3.1"
401+version = "3.0.0"
450source = "registry+https://github.com/rust-lang/crates.io-index"
402source = "registry+https://github.com/rust-lang/crates.io-index"
451−checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
403+checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc"
452−dependencies = [
453− "libc",
454− "str-buf",
455−]
456
404
457[[package]]
405[[package]]
458name = "etcetera"
406name = "etcetera"
@@ -465,6 +413,15 @@ dependencies = [
465 "windows-sys 0.48.0",
413 "windows-sys 0.48.0",
466]
414]
467
415
416+[[package]]
417+name = "faster-hex"
418+version = "0.9.0"
419+source = "registry+https://github.com/rust-lang/crates.io-index"
420+checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183"
421+dependencies = [
422+ "serde",
423+]
424+
468[[package]]
425[[package]]
469name = "fastrand"
426name = "fastrand"
470version = "2.0.0"
427version = "2.0.0"
@@ -491,18 +448,6 @@ dependencies = [
491 "winapi",
448 "winapi",
492]
449]
493
450
494−[[package]]
495−name = "filetime"
496−version = "0.2.21"
497−source = "registry+https://github.com/rust-lang/crates.io-index"
498−checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153"
499−dependencies = [
500− "cfg-if",
501− "libc",
502− "redox_syscall 0.2.16",
503− "windows-sys 0.48.0",
504−]
505−
506[[package]]
451[[package]]
507name = "flate2"
452name = "flate2"
508version = "1.0.27"
453version = "1.0.27"
@@ -513,32 +458,26 @@ dependencies = [
513 "miniz_oxide",
458 "miniz_oxide",
514]
459]
515
460
516−[[package]]
517−name = "fnv"
518−version = "1.0.7"
519−source = "registry+https://github.com/rust-lang/crates.io-index"
520−checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
521−
522[[package]]
461[[package]]
523name = "form_urlencoded"
462name = "form_urlencoded"
524−version = "1.2.0"
463+version = "1.2.1"
525source = "registry+https://github.com/rust-lang/crates.io-index"
464source = "registry+https://github.com/rust-lang/crates.io-index"
526−checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
465+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
527dependencies = [
466dependencies = [
528 "percent-encoding",
467 "percent-encoding",
529]
468]
530
469
531[[package]]
470[[package]]
532name = "futures-core"
471name = "futures-core"
533−version = "0.3.28"
472+version = "0.3.30"
534source = "registry+https://github.com/rust-lang/crates.io-index"
473source = "registry+https://github.com/rust-lang/crates.io-index"
535−checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
474+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
536
475
537[[package]]
476[[package]]
538name = "futures-executor"
477name = "futures-executor"
539−version = "0.3.28"
478+version = "0.3.29"
540source = "registry+https://github.com/rust-lang/crates.io-index"
479source = "registry+https://github.com/rust-lang/crates.io-index"
541−checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
480+checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
542dependencies = [
481dependencies = [
543 "futures-core",
482 "futures-core",
544 "futures-task",
483 "futures-task",
@@ -547,15 +486,15 @@ dependencies = [
547
486
548[[package]]
487[[package]]
549name = "futures-task"
488name = "futures-task"
550−version = "0.3.28"
489+version = "0.3.30"
551source = "registry+https://github.com/rust-lang/crates.io-index"
490source = "registry+https://github.com/rust-lang/crates.io-index"
552−checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
491+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
553
492
554[[package]]
493[[package]]
555name = "futures-util"
494name = "futures-util"
556−version = "0.3.28"
495+version = "0.3.30"
557source = "registry+https://github.com/rust-lang/crates.io-index"
496source = "registry+https://github.com/rust-lang/crates.io-index"
558−checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
497+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
559dependencies = [
498dependencies = [
560 "futures-core",
499 "futures-core",
561 "futures-task",
500 "futures-task",
@@ -583,15 +522,13 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
583
522
584[[package]]
523[[package]]
585name = "gix"
524name = "gix"
586−version = "0.48.0"
525+version = "0.57.0"
587source = "registry+https://github.com/rust-lang/crates.io-index"
526source = "registry+https://github.com/rust-lang/crates.io-index"
588−checksum = "c1e74cea676de7f53a79f3c0365812b11f6814b81e671b8ee4abae6ca09c7881"
527+checksum = "721c7497ab24b665ed5a1eb2b3526936aa60068e61ba260651f7e77c52feec69"
589dependencies = [
528dependencies = [
590 "gix-actor",
529 "gix-actor",
591− "gix-attributes",
592 "gix-commitgraph",
530 "gix-commitgraph",
593 "gix-config",
531 "gix-config",
594− "gix-credentials",
595 "gix-date",
532 "gix-date",
596 "gix-diff",
533 "gix-diff",
597 "gix-discover",
534 "gix-discover",
@@ -600,19 +537,16 @@ dependencies = [
600 "gix-glob",
537 "gix-glob",
601 "gix-hash",
538 "gix-hash",
602 "gix-hashtable",
539 "gix-hashtable",
603− "gix-ignore",
604− "gix-index",
605 "gix-lock",
540 "gix-lock",
606− "gix-mailmap",
541+ "gix-macros",
607− "gix-negotiate",
608 "gix-object",
542 "gix-object",
609 "gix-odb",
543 "gix-odb",
610 "gix-pack",
544 "gix-pack",
611 "gix-path",
545 "gix-path",
612− "gix-prompt",
613 "gix-ref",
546 "gix-ref",
614 "gix-refspec",
547 "gix-refspec",
615 "gix-revision",
548 "gix-revision",
549+ "gix-revwalk",
616 "gix-sec",
550 "gix-sec",
617 "gix-tempfile",
551 "gix-tempfile",
618 "gix-trace",
552 "gix-trace",
@@ -620,10 +554,8 @@ dependencies = [
620 "gix-url",
554 "gix-url",
621 "gix-utils",
555 "gix-utils",
622 "gix-validate",
556 "gix-validate",
623− "gix-worktree",
624− "log",
625 "once_cell",
557 "once_cell",
626− "signal-hook",
558+ "parking_lot",
627 "smallvec",
559 "smallvec",
628 "thiserror",
560 "thiserror",
629 "unicode-normalization",
561 "unicode-normalization",
@@ -631,81 +563,46 @@ dependencies = [
631
563
632[[package]]
564[[package]]
633name = "gix-actor"
565name = "gix-actor"
634−version = "0.23.0"
566+version = "0.29.0"
635source = "registry+https://github.com/rust-lang/crates.io-index"
567source = "registry+https://github.com/rust-lang/crates.io-index"
636−checksum = "1969b77b9ee4cc1755c841987ec6f7622aaca95e952bcafb76973ae59d1b8716"
568+checksum = "886014c4865b93ce268f1d3eddd4fd3261242c3f3ee61eb36009f913016a9059"
637dependencies = [
569dependencies = [
638 "bstr",
570 "bstr",
639 "btoi",
571 "btoi",
640 "gix-date",
572 "gix-date",
641 "itoa",
573 "itoa",
642− "nom",
643− "thiserror",
644−]
645−
646−[[package]]
647−name = "gix-attributes"
648−version = "0.14.1"
649−source = "registry+https://github.com/rust-lang/crates.io-index"
650−checksum = "e3772b0129dcd1fc73e985bbd08a1482d082097d2915cb1ee31ce8092b8e4434"
651−dependencies = [
652− "bstr",
653− "gix-glob",
654− "gix-path",
655− "gix-quote",
656− "kstring",
657− "log",
658− "smallvec",
659− "thiserror",
660− "unicode-bom",
661−]
662−
663−[[package]]
664−name = "gix-bitmap"
665−version = "0.2.5"
666−source = "registry+https://github.com/rust-lang/crates.io-index"
667−checksum = "311e2fa997be6560c564b070c5da2d56d038b645a94e1e5796d5d85a350da33c"
668−dependencies = [
669 "thiserror",
574 "thiserror",
575+ "winnow 0.5.28",
670]
576]
671
577
672[[package]]
578[[package]]
673name = "gix-chunk"
579name = "gix-chunk"
674−version = "0.4.3"
580+version = "0.4.6"
675source = "registry+https://github.com/rust-lang/crates.io-index"
581source = "registry+https://github.com/rust-lang/crates.io-index"
676−checksum = "39db5ed0fc0a2e9b1b8265993f7efdbc30379dec268f3b91b7af0c2de4672fdd"
582+checksum = "2ade37ef69870de0ed966b97c57a3a947a22ff3482a52c3b99b205f77bcb08fb"
677dependencies = [
583dependencies = [
678 "thiserror",
584 "thiserror",
679]
585]
680
586
681−[[package]]
682−name = "gix-command"
683−version = "0.2.6"
684−source = "registry+https://github.com/rust-lang/crates.io-index"
685−checksum = "bb49ab557a37b0abb2415bca2b10e541277dff0565deb5bd5e99fd95f93f51eb"
686−dependencies = [
687− "bstr",
688−]
689−
690[[package]]
587[[package]]
691name = "gix-commitgraph"
588name = "gix-commitgraph"
692−version = "0.17.1"
589+version = "0.23.0"
693source = "registry+https://github.com/rust-lang/crates.io-index"
590source = "registry+https://github.com/rust-lang/crates.io-index"
694−checksum = "ed42baa50075d41c1a0931074ce1a97c5797c7c6fe7591d9f1f2dcd448532c26"
591+checksum = "e7559ea9cefee188cd88b05afcc8e3ef7a3cb4a5c647bccf06b981e591b02b77"
695dependencies = [
592dependencies = [
696 "bstr",
593 "bstr",
697 "gix-chunk",
594 "gix-chunk",
698 "gix-features",
595 "gix-features",
699 "gix-hash",
596 "gix-hash",
700− "memmap2 0.7.1",
597+ "memmap2",
701 "thiserror",
598 "thiserror",
702]
599]
703
600
704[[package]]
601[[package]]
705name = "gix-config"
602name = "gix-config"
706−version = "0.25.1"
603+version = "0.33.0"
707source = "registry+https://github.com/rust-lang/crates.io-index"
604source = "registry+https://github.com/rust-lang/crates.io-index"
708−checksum = "817688c7005a716d9363e267913526adea402dabd947f4ba63842d10cc5132af"
605+checksum = "9c35dc7f9c00a42bbc9cfa1ca2ec0a78ad1b76ff0736d3d35dfd612962244467"
709dependencies = [
606dependencies = [
710 "bstr",
607 "bstr",
711 "gix-config-value",
608 "gix-config-value",
@@ -714,49 +611,32 @@ dependencies = [
714 "gix-path",
611 "gix-path",
715 "gix-ref",
612 "gix-ref",
716 "gix-sec",
613 "gix-sec",
717− "log",
718 "memchr",
614 "memchr",
719− "nom",
720 "once_cell",
615 "once_cell",
721 "smallvec",
616 "smallvec",
722 "thiserror",
617 "thiserror",
723 "unicode-bom",
618 "unicode-bom",
619+ "winnow 0.5.28",
724]
620]
725
621
726[[package]]
622[[package]]
727name = "gix-config-value"
623name = "gix-config-value"
728−version = "0.12.3"
624+version = "0.14.2"
729source = "registry+https://github.com/rust-lang/crates.io-index"
625source = "registry+https://github.com/rust-lang/crates.io-index"
730−checksum = "83960be5e99266bcf55dae5a24731bbd39f643bfb68f27e939d6b06836b5b87d"
626+checksum = "39f388cb2396aee82d6f460a2e7770659bdf8854e9e5478f7d2b1324a9698284"
731dependencies = [
627dependencies = [
732− "bitflags 2.4.0",
628+ "bitflags 2.4.1",
733 "bstr",
629 "bstr",
734 "gix-path",
630 "gix-path",
735 "libc",
631 "libc",
736 "thiserror",
632 "thiserror",
737]
633]
738
634
739−[[package]]
740−name = "gix-credentials"
741−version = "0.16.1"
742−source = "registry+https://github.com/rust-lang/crates.io-index"
743−checksum = "75a75565e0e6e7f80cfa4eb1b05cc448c6846ddd48dcf413a28875fbc11ee9af"
744−dependencies = [
745− "bstr",
746− "gix-command",
747− "gix-config-value",
748− "gix-path",
749− "gix-prompt",
750− "gix-sec",
751− "gix-url",
752− "thiserror",
753−]
754−
755[[package]]
635[[package]]
756name = "gix-date"
636name = "gix-date"
757−version = "0.7.0"
637+version = "0.8.2"
758source = "registry+https://github.com/rust-lang/crates.io-index"
638source = "registry+https://github.com/rust-lang/crates.io-index"
759−checksum = "8e9a04a1d2387c955ec91059d56b673000dd24f3c07cad08ed253e36381782bf"
639+checksum = "9d85f4a01e0d05c3de585e28bae514d4baf01655e3fc3f14ce6f30bf62405345"
760dependencies = [
640dependencies = [
761 "bstr",
641 "bstr",
762 "itoa",
642 "itoa",
@@ -766,21 +646,21 @@ dependencies = [
766
646
767[[package]]
647[[package]]
768name = "gix-diff"
648name = "gix-diff"
769−version = "0.32.0"
649+version = "0.39.0"
770source = "registry+https://github.com/rust-lang/crates.io-index"
650source = "registry+https://github.com/rust-lang/crates.io-index"
771−checksum = "aaf5d9b9b521b284ebe53ee69eee33341835ec70edc314f36b2100ea81396121"
651+checksum = "ac0e75f5afd2f6c47c800b6b0a000a08045739d0450d20482e8faa42543f62d1"
772dependencies = [
652dependencies = [
653+ "bstr",
773 "gix-hash",
654 "gix-hash",
774 "gix-object",
655 "gix-object",
775− "imara-diff",
776 "thiserror",
656 "thiserror",
777]
657]
778
658
779[[package]]
659[[package]]
780name = "gix-discover"
660name = "gix-discover"
781−version = "0.21.1"
661+version = "0.28.0"
782source = "registry+https://github.com/rust-lang/crates.io-index"
662source = "registry+https://github.com/rust-lang/crates.io-index"
783−checksum = "272aad20dc63dedba76615373dd8885fb5aebe4795e5b5b0aa2a24e63c82085c"
663+checksum = "f0b63ce2ad81632ac1a84ac370f85a5e580c3261580bd85ea17ff35d3a0bba18"
784dependencies = [
664dependencies = [
785 "bstr",
665 "bstr",
786 "dunce",
666 "dunce",
@@ -793,9 +673,9 @@ dependencies = [
793
673
794[[package]]
674[[package]]
795name = "gix-features"
675name = "gix-features"
796−version = "0.31.1"
676+version = "0.37.0"
797source = "registry+https://github.com/rust-lang/crates.io-index"
677source = "registry+https://github.com/rust-lang/crates.io-index"
798−checksum = "06142d8cff5d17509399b04052b64d2f9b3a311d5cff0b1a32b220f62cd0d595"
678+checksum = "befe7edea299a824504b5acc96d7a3a538125b38c42f3a8379f6912a29c90c81"
799dependencies = [
679dependencies = [
800 "crc32fast",
680 "crc32fast",
801 "flate2",
681 "flate2",
@@ -811,20 +691,20 @@ dependencies = [
811
691
812[[package]]
692[[package]]
813name = "gix-fs"
693name = "gix-fs"
814−version = "0.3.0"
694+version = "0.9.0"
815source = "registry+https://github.com/rust-lang/crates.io-index"
695source = "registry+https://github.com/rust-lang/crates.io-index"
816−checksum = "bb15956bc0256594c62a2399fcf6958a02a11724217eddfdc2b49b21b6292496"
696+checksum = "007017ce93b819ea52c0ec68306f7d72212a2d307c3d70f1548c7141c015d0a1"
817dependencies = [
697dependencies = [
818 "gix-features",
698 "gix-features",
819]
699]
820
700
821[[package]]
701[[package]]
822name = "gix-glob"
702name = "gix-glob"
823−version = "0.9.1"
703+version = "0.15.0"
824source = "registry+https://github.com/rust-lang/crates.io-index"
704source = "registry+https://github.com/rust-lang/crates.io-index"
825−checksum = "c18bdff83143d61e7d60da6183b87542a870d026b2a2d0b30170b8e9c0cd321a"
705+checksum = "61fb116c2516d3a1170e010118f639944a6389872c875a008960cdab2a44ac72"
826dependencies = [
706dependencies = [
827− "bitflags 2.4.0",
707+ "bitflags 2.4.1",
828 "bstr",
708 "bstr",
829 "gix-features",
709 "gix-features",
830 "gix-path",
710 "gix-path",
@@ -832,64 +712,30 @@ dependencies = [
832
712
833[[package]]
713[[package]]
834name = "gix-hash"
714name = "gix-hash"
835−version = "0.11.3"
715+version = "0.14.0"
836source = "registry+https://github.com/rust-lang/crates.io-index"
716source = "registry+https://github.com/rust-lang/crates.io-index"
837−checksum = "a0dd58cdbe7ffa4032fc111864c80d5f8cecd9a2c9736c97ae7e5be834188272"
717+checksum = "c52c3170a17b6031833cd2eb4ad7bc23f2755d06e6e70f78dec21d42e8fe1b30"
838dependencies = [
718dependencies = [
839− "hex",
719+ "faster-hex",
840 "thiserror",
720 "thiserror",
841]
721]
842
722
843[[package]]
723[[package]]
844name = "gix-hashtable"
724name = "gix-hashtable"
845−version = "0.2.3"
725+version = "0.5.0"
846source = "registry+https://github.com/rust-lang/crates.io-index"
726source = "registry+https://github.com/rust-lang/crates.io-index"
847−checksum = "9e133bc56d938eaec1c675af7c681a51de9662b0ada779f45607b967a10da77a"
727+checksum = "40a838e6366a5e5b84668b6997ce0981b833136468e8ba949f424c0ef2927eba"
848dependencies = [
728dependencies = [
849 "gix-hash",
729 "gix-hash",
850− "hashbrown 0.14.0",
730+ "hashbrown 0.14.3",
851 "parking_lot",
731 "parking_lot",
852]
732]
853
733
854−[[package]]
855−name = "gix-ignore"
856−version = "0.4.1"
857−source = "registry+https://github.com/rust-lang/crates.io-index"
858−checksum = "ca801f2d0535210f77b33e2c067d565aedecacc82f1b3dbce26da1388ebc4634"
859−dependencies = [
860− "bstr",
861− "gix-glob",
862− "gix-path",
863− "unicode-bom",
864−]
865−
866−[[package]]
867−name = "gix-index"
868−version = "0.20.0"
869−source = "registry+https://github.com/rust-lang/crates.io-index"
870−checksum = "68099abdf6ee50ae3c897e8b05de96871cbe54d52a37cdf559101f911b883562"
871−dependencies = [
872− "bitflags 2.4.0",
873− "bstr",
874− "btoi",
875− "filetime",
876− "gix-bitmap",
877− "gix-features",
878− "gix-hash",
879− "gix-lock",
880− "gix-object",
881− "gix-traverse",
882− "itoa",
883− "memmap2 0.7.1",
884− "smallvec",
885− "thiserror",
886−]
887−
888[[package]]
734[[package]]
889name = "gix-lock"
735name = "gix-lock"
890−version = "7.0.0"
736+version = "12.0.0"
891source = "registry+https://github.com/rust-lang/crates.io-index"
737source = "registry+https://github.com/rust-lang/crates.io-index"
892−checksum = "328f50aad713ab606caeaf834459ef915ccdfbb9133ac6cd54616d601aa9249f"
738+checksum = "6cf112ddee94223c119a8534dad027740dc3aba3365ac5edeef8a7f6660c74db"
893dependencies = [
739dependencies = [
894 "gix-tempfile",
740 "gix-tempfile",
895 "gix-utils",
741 "gix-utils",
@@ -897,38 +743,21 @@ dependencies = [
897]
743]
898
744
899[[package]]
745[[package]]
900−name = "gix-mailmap"
746+name = "gix-macros"
901−version = "0.15.0"
902−source = "registry+https://github.com/rust-lang/crates.io-index"
903−checksum = "1787e3c37fc43b1f7c0e3be6196c6837b3ba5f869190dfeaa444b816f0a7f34b"
904−dependencies = [
905− "bstr",
906− "gix-actor",
907− "gix-date",
908− "thiserror",
909−]
910−
911−[[package]]
912−name = "gix-negotiate"
913−version = "0.4.0"
747+version = "0.1.2"
914source = "registry+https://github.com/rust-lang/crates.io-index"
748source = "registry+https://github.com/rust-lang/crates.io-index"
915−checksum = "4e7bce64d4452dd609f44d04b14b29da2e0ad2c45fcdf4ce1472a5f5f8ec21c2"
749+checksum = "fc207b64189cf71bcb17fc841ab99a5d63d0845546b611e2703ce467f659323a"
916dependencies = [
750dependencies = [
917− "bitflags 2.4.0",
751+ "proc-macro2",
918− "gix-commitgraph",
752+ "quote",
919− "gix-date",
753+ "syn 2.0.38",
920− "gix-hash",
921− "gix-object",
922− "gix-revwalk",
923− "smallvec",
924− "thiserror",
925]
754]
926
755
927[[package]]
756[[package]]
928name = "gix-object"
757name = "gix-object"
929−version = "0.32.0"
758+version = "0.40.0"
930source = "registry+https://github.com/rust-lang/crates.io-index"
759source = "registry+https://github.com/rust-lang/crates.io-index"
931−checksum = "a953f3d7ffad16734aa3ab1d05807972c80e339d1bd9dde03e0198716b99e2a6"
760+checksum = "e4c77e47ffba92127faf632a841fce23d19547e269bd8b88e68961a70eab4e93"
932dependencies = [
761dependencies = [
933 "bstr",
762 "bstr",
934 "btoi",
763 "btoi",
@@ -937,18 +766,17 @@ dependencies = [
937 "gix-features",
766 "gix-features",
938 "gix-hash",
767 "gix-hash",
939 "gix-validate",
768 "gix-validate",
940− "hex",
941 "itoa",
769 "itoa",
942− "nom",
943 "smallvec",
770 "smallvec",
944 "thiserror",
771 "thiserror",
772+ "winnow 0.5.28",
945]
773]
946
774
947[[package]]
775[[package]]
948name = "gix-odb"
776name = "gix-odb"
949−version = "0.49.1"
777+version = "0.56.0"
950source = "registry+https://github.com/rust-lang/crates.io-index"
778source = "registry+https://github.com/rust-lang/crates.io-index"
951−checksum = "f6418cff00ecc2713b58c8e04bff30dda808fbba1a080e7248b299d069894a01"
779+checksum = "a3254f2005cc7553ea78e85e816a09150c6f7a64e6b7627b8d1fdc56721bea73"
952dependencies = [
780dependencies = [
953 "arc-swap",
781 "arc-swap",
954 "gix-date",
782 "gix-date",
@@ -965,21 +793,19 @@ dependencies = [
965
793
966[[package]]
794[[package]]
967name = "gix-pack"
795name = "gix-pack"
968−version = "0.39.1"
796+version = "0.46.0"
969source = "registry+https://github.com/rust-lang/crates.io-index"
797source = "registry+https://github.com/rust-lang/crates.io-index"
970−checksum = "414935138d90043ea5898de7a93f02c2558e52652492719470e203ef26a8fd0a"
798+checksum = "02ebc8cd657eec207d82d8f876ca402361308ecd3c87a47935b0299506257b4f"
971dependencies = [
799dependencies = [
972 "clru",
800 "clru",
973 "gix-chunk",
801 "gix-chunk",
974− "gix-diff",
975 "gix-features",
802 "gix-features",
976 "gix-hash",
803 "gix-hash",
977 "gix-hashtable",
804 "gix-hashtable",
978 "gix-object",
805 "gix-object",
979 "gix-path",
806 "gix-path",
980 "gix-tempfile",
807 "gix-tempfile",
981− "gix-traverse",
982− "memmap2 0.7.1",
808+ "memmap2",
983 "parking_lot",
809 "parking_lot",
984 "smallvec",
810 "smallvec",
985 "thiserror",
811 "thiserror",
@@ -987,9 +813,9 @@ dependencies = [
987
813
988[[package]]
814[[package]]
989name = "gix-path"
815name = "gix-path"
990−version = "0.8.3"
816+version = "0.10.2"
991source = "registry+https://github.com/rust-lang/crates.io-index"
817source = "registry+https://github.com/rust-lang/crates.io-index"
992−checksum = "dfca182d2575ded2ed38280f1ebf75cd5d3790b77e0872de07854cf085821fbe"
818+checksum = "10931652a3da126990ac93bce1b1c600cc99d7c268d712b6360ed52174ce1b68"
993dependencies = [
819dependencies = [
994 "bstr",
820 "bstr",
995 "gix-trace",
821 "gix-trace",
@@ -998,24 +824,11 @@ dependencies = [
998 "thiserror",
824 "thiserror",
999]
825]
1000
826
1001−[[package]]
1002−name = "gix-prompt"
1003−version = "0.5.2"
1004−source = "registry+https://github.com/rust-lang/crates.io-index"
1005−checksum = "8dfd363fd89a40c1e7bff9c9c1b136cd2002480f724b0c627c1bc771cd5480ec"
1006−dependencies = [
1007− "gix-command",
1008− "gix-config-value",
1009− "parking_lot",
1010− "rustix 0.37.15",
1011− "thiserror",
1012−]
1013−
1014[[package]]
827[[package]]
1015name = "gix-quote"
828name = "gix-quote"
1016−version = "0.4.5"
829+version = "0.4.9"
1017source = "registry+https://github.com/rust-lang/crates.io-index"
830source = "registry+https://github.com/rust-lang/crates.io-index"
1018−checksum = "3874de636c2526de26a3405b8024b23ef1a327bebf4845d770d00d48700b6a40"
831+checksum = "6c43530cb94a7759807e6f8d180e17ac9c65673b891645c6c433831dc0cf4342"
1019dependencies = [
832dependencies = [
1020 "bstr",
833 "bstr",
1021 "btoi",
834 "btoi",
@@ -1024,9 +837,9 @@ dependencies = [
1024
837
1025[[package]]
838[[package]]
1026name = "gix-ref"
839name = "gix-ref"
1027−version = "0.32.1"
840+version = "0.40.0"
1028source = "registry+https://github.com/rust-lang/crates.io-index"
841source = "registry+https://github.com/rust-lang/crates.io-index"
1029−checksum = "39453f4e5f23cddc2e6e4cca2ba20adfdbec29379e3ca829714dfe98ae068ccd"
842+checksum = "baa951b3b850d6d1be4f900768e49af20b76bf9505beac22af723d57249a2f1d"
1030dependencies = [
843dependencies = [
1031 "gix-actor",
844 "gix-actor",
1032 "gix-date",
845 "gix-date",
@@ -1038,16 +851,16 @@ dependencies = [
1038 "gix-path",
851 "gix-path",
1039 "gix-tempfile",
852 "gix-tempfile",
1040 "gix-validate",
853 "gix-validate",
1041− "memmap2 0.7.1",
854+ "memmap2",
1042− "nom",
1043 "thiserror",
855 "thiserror",
856+ "winnow 0.5.28",
1044]
857]
1045
858
1046[[package]]
859[[package]]
1047name = "gix-refspec"
860name = "gix-refspec"
1048−version = "0.13.0"
861+version = "0.21.0"
1049source = "registry+https://github.com/rust-lang/crates.io-index"
862source = "registry+https://github.com/rust-lang/crates.io-index"
1050−checksum = "b8e76ff1f82fba295a121e31ab02f69642994e532c45c0c899aa393f4b740302"
863+checksum = "88c61f849d58c06e3068a0b601cf10127d2a07cdad00a725ed66cf303f76f6b3"
1051dependencies = [
864dependencies = [
1052 "bstr",
865 "bstr",
1053 "gix-hash",
866 "gix-hash",
@@ -1059,9 +872,9 @@ dependencies = [
1059
872
1060[[package]]
873[[package]]
1061name = "gix-revision"
874name = "gix-revision"
1062−version = "0.17.0"
875+version = "0.25.0"
1063source = "registry+https://github.com/rust-lang/crates.io-index"
876source = "registry+https://github.com/rust-lang/crates.io-index"
1064−checksum = "237428a7d3978e8572964e1e45d984027c2acc94df47e594baa6c4b0da7c9922"
877+checksum = "bcbbf91f4200c5c76802ef5f057b96f5a336827508881fe55a780be71a794d22"
1065dependencies = [
878dependencies = [
1066 "bstr",
879 "bstr",
1067 "gix-date",
880 "gix-date",
@@ -1069,14 +882,15 @@ dependencies = [
1069 "gix-hashtable",
882 "gix-hashtable",
1070 "gix-object",
883 "gix-object",
1071 "gix-revwalk",
884 "gix-revwalk",
885+ "gix-trace",
1072 "thiserror",
886 "thiserror",
1073]
887]
1074
888
1075[[package]]
889[[package]]
1076name = "gix-revwalk"
890name = "gix-revwalk"
1077−version = "0.3.0"
891+version = "0.11.0"
1078source = "registry+https://github.com/rust-lang/crates.io-index"
892source = "registry+https://github.com/rust-lang/crates.io-index"
1079−checksum = "028d50fcaf8326a8f79a359490d9ca9fb4e2b51ac9ac86503560d0bcc888d2eb"
893+checksum = "33ab66354d83f70f2730391747d0c75f94ef3c3dd40ebde2e206db9faaf7a0a7"
1080dependencies = [
894dependencies = [
1081 "gix-commitgraph",
895 "gix-commitgraph",
1082 "gix-date",
896 "gix-date",
@@ -1089,42 +903,40 @@ dependencies = [
1089
903
1090[[package]]
904[[package]]
1091name = "gix-sec"
905name = "gix-sec"
1092−version = "0.8.3"
906+version = "0.10.2"
1093source = "registry+https://github.com/rust-lang/crates.io-index"
907source = "registry+https://github.com/rust-lang/crates.io-index"
1094−checksum = "ede298863db2a0574a14070991710551e76d1f47c9783b62d4fcbca17f56371c"
908+checksum = "a9963f38a42144253ed4d571882d7db5ef644c12e6726e4b75135597cc9d0e1a"
1095dependencies = [
909dependencies = [
1096− "bitflags 2.4.0",
910+ "bitflags 2.4.1",
1097 "gix-path",
911 "gix-path",
1098 "libc",
912 "libc",
1099− "windows",
913+ "windows 0.52.0",
1100]
914]
1101
915
1102[[package]]
916[[package]]
1103name = "gix-tempfile"
917name = "gix-tempfile"
1104−version = "7.0.0"
918+version = "12.0.0"
1105source = "registry+https://github.com/rust-lang/crates.io-index"
919source = "registry+https://github.com/rust-lang/crates.io-index"
1106−checksum = "4fac8310c17406ea619af72f42ee46dac795110f68f41b4f4fa231b69889c6a2"
920+checksum = "e76a494bd530e1a1309188ff971825a24f159c76c2db0bf71fa5dfb469a2c915"
1107dependencies = [
921dependencies = [
1108 "gix-fs",
922 "gix-fs",
1109 "libc",
923 "libc",
1110 "once_cell",
924 "once_cell",
1111 "parking_lot",
925 "parking_lot",
1112− "signal-hook",
1113− "signal-hook-registry",
1114 "tempfile",
926 "tempfile",
1115]
927]
1116
928
1117[[package]]
929[[package]]
1118name = "gix-trace"
930name = "gix-trace"
1119−version = "0.1.2"
931+version = "0.1.5"
1120source = "registry+https://github.com/rust-lang/crates.io-index"
932source = "registry+https://github.com/rust-lang/crates.io-index"
1121−checksum = "103eac621617be3ebe0605c9065ca51a223279a23218aaf67d10daa6e452f663"
933+checksum = "bda62acb44dd86a40c7c3762a5403cfc1ac789ea559df54085cedf79864f809e"
1122
934
1123[[package]]
935[[package]]
1124name = "gix-traverse"
936name = "gix-traverse"
1125−version = "0.29.0"
937+version = "0.36.0"
1126source = "registry+https://github.com/rust-lang/crates.io-index"
938source = "registry+https://github.com/rust-lang/crates.io-index"
1127−checksum = "e3cdfd54598db4fae57d5ae6f52958422b2d13382d2745796bfe5c8015ffa86e"
939+checksum = "8661fab39985c9214e56d81a63ceb5886ac948cec2fba76c39494d1e0e307ea8"
1128dependencies = [
940dependencies = [
1129 "gix-commitgraph",
941 "gix-commitgraph",
1130 "gix-date",
942 "gix-date",
@@ -1138,9 +950,9 @@ dependencies = [
1138
950
1139[[package]]
951[[package]]
1140name = "gix-url"
952name = "gix-url"
1141−version = "0.20.1"
953+version = "0.26.0"
1142source = "registry+https://github.com/rust-lang/crates.io-index"
954source = "registry+https://github.com/rust-lang/crates.io-index"
1143−checksum = "beaede6dbc83f408b19adfd95bb52f1dbf01fb8862c3faf6c6243e2e67fcdfa1"
955+checksum = "10a0129c1e8b52736d7c5128300a4485dbc85863001371e2771ac1754bd89fd7"
1144dependencies = [
956dependencies = [
1145 "bstr",
957 "bstr",
1146 "gix-features",
958 "gix-features",
@@ -1152,94 +964,71 @@ dependencies = [
1152
964
1153[[package]]
965[[package]]
1154name = "gix-utils"
966name = "gix-utils"
1155−version = "0.1.4"
967+version = "0.1.7"
1156source = "registry+https://github.com/rust-lang/crates.io-index"
968source = "registry+https://github.com/rust-lang/crates.io-index"
1157−checksum = "7058c94f4164fcf5b8457d35f6d8f6e1007f9f7f938c9c7684a7e01d23c6ddde"
969+checksum = "ab9277a5e32e85d53f738096d872a4a9b76067ad471894ad31bd99c8fa2da1dc"
1158dependencies = [
970dependencies = [
1159 "fastrand",
971 "fastrand",
1160]
972]
1161
973
1162[[package]]
974[[package]]
1163name = "gix-validate"
975name = "gix-validate"
1164−version = "0.7.6"
976+version = "0.8.2"
1165−source = "registry+https://github.com/rust-lang/crates.io-index"
1166−checksum = "8d092b594c8af00a3a31fe526d363ee8a51a6f29d8496cdb991ed2f01ec0ec13"
1167−dependencies = [
1168− "bstr",
1169− "thiserror",
1170−]
1171−
1172−[[package]]
1173−name = "gix-worktree"
1174−version = "0.21.1"
1175source = "registry+https://github.com/rust-lang/crates.io-index"
977source = "registry+https://github.com/rust-lang/crates.io-index"
1176−checksum = "c1363b9aa66b9e14412ac04e1f759827203f491729d92172535a8ce6cde02efa"
978+checksum = "f805ebbdbaa4bfd98e2ee43e6d14099b8a4d9141f5d7b8202fea4d48e44263e7"
1177dependencies = [
979dependencies = [
1178 "bstr",
980 "bstr",
1179− "filetime",
1180− "gix-attributes",
1181− "gix-features",
1182− "gix-fs",
1183− "gix-glob",
1184− "gix-hash",
1185− "gix-ignore",
1186− "gix-index",
1187− "gix-object",
1188− "gix-path",
1189− "io-close",
1190 "thiserror",
981 "thiserror",
1191]
982]
1192
983
1193[[package]]
984[[package]]
1194name = "globset"
985name = "globset"
1195−version = "0.4.13"
986+version = "0.4.14"
1196source = "registry+https://github.com/rust-lang/crates.io-index"
987source = "registry+https://github.com/rust-lang/crates.io-index"
1197−checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d"
988+checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
1198dependencies = [
989dependencies = [
1199− "aho-corasick 1.0.2",
990+ "aho-corasick",
1200 "bstr",
991 "bstr",
1201− "fnv",
1202 "log",
992 "log",
1203− "regex",
993+ "regex-automata",
994+ "regex-syntax",
1204]
995]
1205
996
1206[[package]]
997[[package]]
1207name = "grep-matcher"
998name = "grep-matcher"
1208−version = "0.1.6"
999+version = "0.1.7"
1209source = "registry+https://github.com/rust-lang/crates.io-index"
1000source = "registry+https://github.com/rust-lang/crates.io-index"
1210−checksum = "3902ca28f26945fe35cad349d776f163981d777fee382ccd6ef451126f51b319"
1001+checksum = "47a3141a10a43acfedc7c98a60a834d7ba00dfe7bec9071cbfc19b55b292ac02"
1211dependencies = [
1002dependencies = [
1212 "memchr",
1003 "memchr",
1213]
1004]
1214
1005
1215[[package]]
1006[[package]]
1216name = "grep-regex"
1007name = "grep-regex"
1217−version = "0.1.11"
1008+version = "0.1.12"
1218source = "registry+https://github.com/rust-lang/crates.io-index"
1009source = "registry+https://github.com/rust-lang/crates.io-index"
1219−checksum = "997598b41d53a37a2e3fc5300d5c11d825368c054420a9c65125b8fe1078463f"
1010+checksum = "f748bb135ca835da5cbc67ca0e6955f968db9c5df74ca4f56b18e1ddbc68230d"
1220dependencies = [
1011dependencies = [
1221− "aho-corasick 0.7.20",
1222 "bstr",
1012 "bstr",
1223 "grep-matcher",
1013 "grep-matcher",
1224 "log",
1014 "log",
1225− "regex",
1015+ "regex-automata",
1226− "regex-syntax 0.6.29",
1016+ "regex-syntax",
1227− "thread_local",
1228]
1017]
1229
1018
1230[[package]]
1019[[package]]
1231name = "grep-searcher"
1020name = "grep-searcher"
1232−version = "0.1.11"
1021+version = "0.1.13"
1233source = "registry+https://github.com/rust-lang/crates.io-index"
1022source = "registry+https://github.com/rust-lang/crates.io-index"
1234−checksum = "5601c4b9f480f0c9ebb40b1f6cbf447b8a50c5369223937a6c5214368c58779f"
1023+checksum = "ba536ae4f69bec62d8839584dd3153d3028ef31bb229f04e09fb5a9e5a193c54"
1235dependencies = [
1024dependencies = [
1236 "bstr",
1025 "bstr",
1237− "bytecount",
1238 "encoding_rs",
1026 "encoding_rs",
1239 "encoding_rs_io",
1027 "encoding_rs_io",
1240 "grep-matcher",
1028 "grep-matcher",
1241 "log",
1029 "log",
1030+ "memchr",
1242− "memmap2 0.5.10",
1031+ "memmap2",
1243]
1032]
1244
1033
1245[[package]]
1034[[package]]
@@ -1250,9 +1039,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
1250
1039
1251[[package]]
1040[[package]]
1252name = "hashbrown"
1041name = "hashbrown"
1253−version = "0.14.0"
1042+version = "0.14.3"
1254source = "registry+https://github.com/rust-lang/crates.io-index"
1043source = "registry+https://github.com/rust-lang/crates.io-index"
1255−checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
1044+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
1256dependencies = [
1045dependencies = [
1257 "ahash",
1046 "ahash",
1258 "allocator-api2",
1047 "allocator-api2",
@@ -1260,16 +1049,16 @@ dependencies = [
1260
1049
1261[[package]]
1050[[package]]
1262name = "helix-core"
1051name = "helix-core"
1263−version = "0.6.0"
1052+version = "23.10.0"
1264dependencies = [
1053dependencies = [
1265 "ahash",
1054 "ahash",
1266 "arc-swap",
1055 "arc-swap",
1267− "bitflags 2.4.0",
1056+ "bitflags 2.4.1",
1268 "chrono",
1057 "chrono",
1269 "dunce",
1058 "dunce",
1270 "encoding_rs",
1059 "encoding_rs",
1271 "etcetera",
1060 "etcetera",
1272− "hashbrown 0.14.0",
1061+ "hashbrown 0.14.3",
1273 "helix-loader",
1062 "helix-loader",
1274 "imara-diff",
1063 "imara-diff",
1275 "indoc",
1064 "indoc",
@@ -1295,7 +1084,7 @@ dependencies = [
1295
1084
1296[[package]]
1085[[package]]
1297name = "helix-dap"
1086name = "helix-dap"
1298−version = "0.6.0"
1087+version = "23.10.0"
1299dependencies = [
1088dependencies = [
1300 "anyhow",
1089 "anyhow",
1301 "fern",
1090 "fern",
@@ -1310,7 +1099,7 @@ dependencies = [
1310
1099
1311[[package]]
1100[[package]]
1312name = "helix-event"
1101name = "helix-event"
1313−version = "0.6.0"
1102+version = "23.10.0"
1314dependencies = [
1103dependencies = [
1315 "parking_lot",
1104 "parking_lot",
1316 "tokio",
1105 "tokio",
@@ -1318,7 +1107,7 @@ dependencies = [
1318
1107
1319[[package]]
1108[[package]]
1320name = "helix-loader"
1109name = "helix-loader"
1321−version = "0.6.0"
1110+version = "23.10.0"
1322dependencies = [
1111dependencies = [
1323 "anyhow",
1112 "anyhow",
1324 "cc",
1113 "cc",
@@ -1337,7 +1126,7 @@ dependencies = [
1337
1126
1338[[package]]
1127[[package]]
1339name = "helix-lsp"
1128name = "helix-lsp"
1340−version = "0.6.0"
1129+version = "23.10.0"
1341dependencies = [
1130dependencies = [
1342 "anyhow",
1131 "anyhow",
1343 "futures-executor",
1132 "futures-executor",
@@ -1359,11 +1148,11 @@ dependencies = [
1359
1148
1360[[package]]
1149[[package]]
1361name = "helix-parsec"
1150name = "helix-parsec"
1362−version = "0.6.0"
1151+version = "23.10.0"
1363
1152
1364[[package]]
1153[[package]]
1365name = "helix-term"
1154name = "helix-term"
1366−version = "0.6.0"
1155+version = "23.10.0"
1367dependencies = [
1156dependencies = [
1368 "anyhow",
1157 "anyhow",
1369 "arc-swap",
1158 "arc-swap",
@@ -1388,6 +1177,7 @@ dependencies = [
1388 "log",
1177 "log",
1389 "nucleo",
1178 "nucleo",
1390 "once_cell",
1179 "once_cell",
1180+ "open",
1391 "pulldown-cmark",
1181 "pulldown-cmark",
1392 "serde",
1182 "serde",
1393 "serde_json",
1183 "serde_json",
@@ -1398,14 +1188,15 @@ dependencies = [
1398 "tokio",
1188 "tokio",
1399 "tokio-stream",
1189 "tokio-stream",
1400 "toml",
1190 "toml",
1191+ "url",
1401 "which",
1192 "which",
1402]
1193]
1403
1194
1404[[package]]
1195[[package]]
1405name = "helix-tui"
1196name = "helix-tui"
1406−version = "0.6.0"
1197+version = "23.10.0"
1407dependencies = [
1198dependencies = [
1408− "bitflags 2.4.0",
1199+ "bitflags 2.4.1",
1409 "cassowary",
1200 "cassowary",
1410 "crossterm",
1201 "crossterm",
1411 "helix-core",
1202 "helix-core",
@@ -1419,7 +1210,7 @@ dependencies = [
1419
1210
1420[[package]]
1211[[package]]
1421name = "helix-vcs"
1212name = "helix-vcs"
1422−version = "0.6.0"
1213+version = "23.10.0"
1423dependencies = [
1214dependencies = [
1424 "anyhow",
1215 "anyhow",
1425 "arc-swap",
1216 "arc-swap",
@@ -1435,11 +1226,11 @@ dependencies = [
1435
1226
1436[[package]]
1227[[package]]
1437name = "helix-view"
1228name = "helix-view"
1438−version = "0.6.0"
1229+version = "23.10.0"
1439dependencies = [
1230dependencies = [
1440 "anyhow",
1231 "anyhow",
1441 "arc-swap",
1232 "arc-swap",
1442− "bitflags 2.4.0",
1233+ "bitflags 2.4.1",
1443 "chardetng",
1234 "chardetng",
1444 "clipboard-win",
1235 "clipboard-win",
1445 "crossterm",
1236 "crossterm",
@@ -1455,7 +1246,7 @@ dependencies = [
1455 "log",
1246 "log",
1456 "once_cell",
1247 "once_cell",
1457 "parking_lot",
1248 "parking_lot",
1458− "rustix 0.38.13",
1249+ "rustix",
1459 "serde",
1250 "serde",
1460 "serde_json",
1251 "serde_json",
1461 "slotmap",
1252 "slotmap",
@@ -1475,25 +1266,13 @@ dependencies = [
1475 "libc",
1266 "libc",
1476]
1267]
1477
1268
1478−[[package]]
1479−name = "hermit-abi"
1480−version = "0.3.2"
1481−source = "registry+https://github.com/rust-lang/crates.io-index"
1482−checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
1483−
1484−[[package]]
1485−name = "hex"
1486−version = "0.4.3"
1487−source = "registry+https://github.com/rust-lang/crates.io-index"
1488−checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
1489−
1490[[package]]
1269[[package]]
1491name = "home"
1270name = "home"
1492−version = "0.5.4"
1271+version = "0.5.5"
1493source = "registry+https://github.com/rust-lang/crates.io-index"
1272source = "registry+https://github.com/rust-lang/crates.io-index"
1494−checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"
1273+checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
1495dependencies = [
1274dependencies = [
1496− "winapi",
1275+ "windows-sys 0.48.0",
1497]
1276]
1498
1277
1499[[package]]
1278[[package]]
@@ -1507,7 +1286,7 @@ dependencies = [
1507 "iana-time-zone-haiku",
1286 "iana-time-zone-haiku",
1508 "js-sys",
1287 "js-sys",
1509 "wasm-bindgen",
1288 "wasm-bindgen",
1510− "windows",
1289+ "windows 0.48.0",
1511]
1290]
1512
1291
1513[[package]]
1292[[package]]
@@ -1522,9 +1301,9 @@ dependencies = [
1522
1301
1523[[package]]
1302[[package]]
1524name = "idna"
1303name = "idna"
1525−version = "0.4.0"
1304+version = "0.5.0"
1526source = "registry+https://github.com/rust-lang/crates.io-index"
1305source = "registry+https://github.com/rust-lang/crates.io-index"
1527−checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
1306+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
1528dependencies = [
1307dependencies = [
1529 "unicode-bidi",
1308 "unicode-bidi",
1530 "unicode-normalization",
1309 "unicode-normalization",
@@ -1532,17 +1311,16 @@ dependencies = [
1532
1311
1533[[package]]
1312[[package]]
1534name = "ignore"
1313name = "ignore"
1535−version = "0.4.20"
1314+version = "0.4.21"
1536source = "registry+https://github.com/rust-lang/crates.io-index"
1315source = "registry+https://github.com/rust-lang/crates.io-index"
1537−checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
1316+checksum = "747ad1b4ae841a78e8aba0d63adbfbeaea26b517b63705d47856b73015d27060"
1538dependencies = [
1317dependencies = [
1318+ "crossbeam-deque",
1539 "globset",
1319 "globset",
1540− "lazy_static",
1541 "log",
1320 "log",
1542 "memchr",
1321 "memchr",
1543− "regex",
1322+ "regex-automata",
1544 "same-file",
1323 "same-file",
1545− "thread_local",
1546 "walkdir",
1324 "walkdir",
1547 "winapi-util",
1325 "winapi-util",
1548]
1326]
@@ -1564,34 +1342,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1564checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
1342checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
1565dependencies = [
1343dependencies = [
1566 "equivalent",
1344 "equivalent",
1567− "hashbrown 0.14.0",
1345+ "hashbrown 0.14.3",
1568]
1346]
1569
1347
1570[[package]]
1348[[package]]
1571name = "indoc"
1349name = "indoc"
1572−version = "2.0.3"
1350+version = "2.0.4"
1573source = "registry+https://github.com/rust-lang/crates.io-index"
1351source = "registry+https://github.com/rust-lang/crates.io-index"
1574−checksum = "2c785eefb63ebd0e33416dfcb8d6da0bf27ce752843a45632a67bf10d4d4b5c4"
1352+checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
1575
1353
1576[[package]]
1354[[package]]
1577−name = "io-close"
1355+name = "is-docker"
1578−version = "0.3.7"
1356+version = "0.2.0"
1579source = "registry+https://github.com/rust-lang/crates.io-index"
1357source = "registry+https://github.com/rust-lang/crates.io-index"
1580−checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc"
1358+checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
1581dependencies = [
1359dependencies = [
1582− "libc",
1360+ "once_cell",
1583− "winapi",
1584]
1361]
1585
1362
1586[[package]]
1363[[package]]
1587−name = "io-lifetimes"
1364+name = "is-wsl"
1588−version = "1.0.10"
1365+version = "0.4.0"
1589source = "registry+https://github.com/rust-lang/crates.io-index"
1366source = "registry+https://github.com/rust-lang/crates.io-index"
1590−checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
1367+checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
1591dependencies = [
1368dependencies = [
1592− "hermit-abi 0.3.2",
1369+ "is-docker",
1593− "libc",
1370+ "once_cell",
1594− "windows-sys 0.48.0",
1595]
1371]
1596
1372
1597[[package]]
1373[[package]]
@@ -1609,32 +1385,17 @@ dependencies = [
1609 "wasm-bindgen",
1385 "wasm-bindgen",
1610]
1386]
1611
1387
1612−[[package]]
1613−name = "kstring"
1614−version = "2.0.0"
1615−source = "registry+https://github.com/rust-lang/crates.io-index"
1616−checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747"
1617−dependencies = [
1618− "static_assertions",
1619−]
1620−
1621−[[package]]
1622−name = "lazy_static"
1623−version = "1.4.0"
1624−source = "registry+https://github.com/rust-lang/crates.io-index"
1625−checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
1626−
1627[[package]]
1388[[package]]
1628name = "libc"
1389name = "libc"
1629−version = "0.2.147"
1390+version = "0.2.151"
1630source = "registry+https://github.com/rust-lang/crates.io-index"
1391source = "registry+https://github.com/rust-lang/crates.io-index"
1631−checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
1392+checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
1632
1393
1633[[package]]
1394[[package]]
1634name = "libloading"
1395name = "libloading"
1635−version = "0.8.0"
1396+version = "0.8.1"
1636source = "registry+https://github.com/rust-lang/crates.io-index"
1397source = "registry+https://github.com/rust-lang/crates.io-index"
1637−checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb"
1398+checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
1638dependencies = [
1399dependencies = [
1639 "cfg-if",
1400 "cfg-if",
1640 "windows-sys 0.48.0",
1401 "windows-sys 0.48.0",
@@ -1651,15 +1412,9 @@ dependencies = [
1651
1412
1652[[package]]
1413[[package]]
1653name = "linux-raw-sys"
1414name = "linux-raw-sys"
1654−version = "0.3.4"
1415+version = "0.4.11"
1655source = "registry+https://github.com/rust-lang/crates.io-index"
1416source = "registry+https://github.com/rust-lang/crates.io-index"
1656−checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf"
1417+checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
1657−
1658−[[package]]
1659−name = "linux-raw-sys"
1660−version = "0.4.7"
1661−source = "registry+https://github.com/rust-lang/crates.io-index"
1662−checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
1663
1418
1664[[package]]
1419[[package]]
1665name = "lock_api"
1420name = "lock_api"
@@ -1679,9 +1434,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
1679
1434
1680[[package]]
1435[[package]]
1681name = "lsp-types"
1436name = "lsp-types"
1682−version = "0.94.1"
1437+version = "0.95.0"
1683source = "registry+https://github.com/rust-lang/crates.io-index"
1438source = "registry+https://github.com/rust-lang/crates.io-index"
1684−checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1"
1439+checksum = "158c1911354ef73e8fe42da6b10c0484cb65c7f1007f28022e847706c1ab6984"
1685dependencies = [
1440dependencies = [
1686 "bitflags 1.3.2",
1441 "bitflags 1.3.2",
1687 "serde",
1442 "serde",
@@ -1698,18 +1453,9 @@ checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
1698
1453
1699[[package]]
1454[[package]]
1700name = "memmap2"
1455name = "memmap2"
1701−version = "0.5.10"
1456+version = "0.9.0"
1702−source = "registry+https://github.com/rust-lang/crates.io-index"
1703−checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
1704−dependencies = [
1705− "libc",
1706−]
1707−
1708−[[package]]
1709−name = "memmap2"
1710−version = "0.7.1"
1711source = "registry+https://github.com/rust-lang/crates.io-index"
1457source = "registry+https://github.com/rust-lang/crates.io-index"
1712−checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6"
1458+checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375"
1713dependencies = [
1459dependencies = [
1714 "libc",
1460 "libc",
1715]
1461]
@@ -1723,12 +1469,6 @@ dependencies = [
1723 "autocfg",
1469 "autocfg",
1724]
1470]
1725
1471
1726−[[package]]
1727−name = "minimal-lexical"
1728−version = "0.2.1"
1729−source = "registry+https://github.com/rust-lang/crates.io-index"
1730−checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
1731−
1732[[package]]
1472[[package]]
1733name = "miniz_oxide"
1473name = "miniz_oxide"
1734version = "0.7.1"
1474version = "0.7.1"
@@ -1740,24 +1480,14 @@ dependencies = [
1740
1480
1741[[package]]
1481[[package]]
1742name = "mio"
1482name = "mio"
1743−version = "0.8.6"
1483+version = "0.8.9"
1744source = "registry+https://github.com/rust-lang/crates.io-index"
1484source = "registry+https://github.com/rust-lang/crates.io-index"
1745−checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
1485+checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
1746dependencies = [
1486dependencies = [
1747 "libc",
1487 "libc",
1748 "log",
1488 "log",
1749 "wasi",
1489 "wasi",
1750− "windows-sys 0.45.0",
1490+ "windows-sys 0.48.0",
1751−]
1752−
1753−[[package]]
1754−name = "nom"
1755−version = "7.1.3"
1756−source = "registry+https://github.com/rust-lang/crates.io-index"
1757−checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
1758−dependencies = [
1759− "memchr",
1760− "minimal-lexical",
1761]
1491]
1762
1492
1763[[package]]
1493[[package]]
@@ -1797,7 +1527,7 @@ version = "1.15.0"
1797source = "registry+https://github.com/rust-lang/crates.io-index"
1527source = "registry+https://github.com/rust-lang/crates.io-index"
1798checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
1528checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
1799dependencies = [
1529dependencies = [
1800− "hermit-abi 0.2.6",
1530+ "hermit-abi",
1801 "libc",
1531 "libc",
1802]
1532]
1803
1533
@@ -1821,15 +1551,20 @@ dependencies = [
1821
1551
1822[[package]]
1552[[package]]
1823name = "once_cell"
1553name = "once_cell"
1824−version = "1.18.0"
1554+version = "1.19.0"
1825source = "registry+https://github.com/rust-lang/crates.io-index"
1555source = "registry+https://github.com/rust-lang/crates.io-index"
1826−checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
1556+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
1827
1557
1828[[package]]
1558[[package]]
1829−name = "option-ext"
1559+name = "open"
1830−version = "0.2.0"
1560+version = "5.0.1"
1831source = "registry+https://github.com/rust-lang/crates.io-index"
1561source = "registry+https://github.com/rust-lang/crates.io-index"
1832−checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
1562+checksum = "90878fb664448b54c4e592455ad02831e23a3f7e157374a8b95654731aac7349"
1563+dependencies = [
1564+ "is-wsl",
1565+ "libc",
1566+ "pathdiff",
1567+]
1833
1568
1834[[package]]
1569[[package]]
1835name = "parking_lot"
1570name = "parking_lot"
@@ -1854,11 +1589,17 @@ dependencies = [
1854 "windows-sys 0.45.0",
1589 "windows-sys 0.45.0",
1855]
1590]
1856
1591
1592+[[package]]
1593+name = "pathdiff"
1594+version = "0.2.1"
1595+source = "registry+https://github.com/rust-lang/crates.io-index"
1596+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
1597+
1857[[package]]
1598[[package]]
1858name = "percent-encoding"
1599name = "percent-encoding"
1859−version = "2.3.0"
1600+version = "2.3.1"
1860source = "registry+https://github.com/rust-lang/crates.io-index"
1601source = "registry+https://github.com/rust-lang/crates.io-index"
1861−checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
1602+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
1862
1603
1863[[package]]
1604[[package]]
1864name = "pin-project-lite"
1605name = "pin-project-lite"
@@ -1874,18 +1615,18 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1874
1615
1875[[package]]
1616[[package]]
1876name = "proc-macro2"
1617name = "proc-macro2"
1877−version = "1.0.63"
1618+version = "1.0.69"
1878source = "registry+https://github.com/rust-lang/crates.io-index"
1619source = "registry+https://github.com/rust-lang/crates.io-index"
1879−checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
1620+checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
1880dependencies = [
1621dependencies = [
1881 "unicode-ident",
1622 "unicode-ident",
1882]
1623]
1883
1624
1884[[package]]
1625[[package]]
1885name = "prodash"
1626name = "prodash"
1886−version = "25.0.0"
1627+version = "28.0.0"
1887source = "registry+https://github.com/rust-lang/crates.io-index"
1628source = "registry+https://github.com/rust-lang/crates.io-index"
1888−checksum = "3236ce1618b6da4c7b618e0143c4d5b5dc190f75f81c49f248221382f7e9e9ae"
1629+checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79"
1889
1630
1890[[package]]
1631[[package]]
1891name = "pulldown-cmark"
1632name = "pulldown-cmark"
@@ -1967,64 +1708,47 @@ dependencies = [
1967
1708
1968[[package]]
1709[[package]]
1969name = "redox_syscall"
1710name = "redox_syscall"
1970−version = "0.3.5"
1711+version = "0.4.1"
1971source = "registry+https://github.com/rust-lang/crates.io-index"
1712source = "registry+https://github.com/rust-lang/crates.io-index"
1972−checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
1713+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
1973dependencies = [
1714dependencies = [
1974 "bitflags 1.3.2",
1715 "bitflags 1.3.2",
1975]
1716]
1976
1717
1977−[[package]]
1978−name = "redox_users"
1979−version = "0.4.3"
1980−source = "registry+https://github.com/rust-lang/crates.io-index"
1981−checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
1982−dependencies = [
1983− "getrandom",
1984− "redox_syscall 0.2.16",
1985− "thiserror",
1986−]
1987−
1988[[package]]
1718[[package]]
1989name = "regex"
1719name = "regex"
1990−version = "1.9.5"
1720+version = "1.10.2"
1991source = "registry+https://github.com/rust-lang/crates.io-index"
1721source = "registry+https://github.com/rust-lang/crates.io-index"
1992−checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
1722+checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
1993dependencies = [
1723dependencies = [
1994− "aho-corasick 1.0.2",
1724+ "aho-corasick",
1995 "memchr",
1725 "memchr",
1996 "regex-automata",
1726 "regex-automata",
1997− "regex-syntax 0.7.5",
1727+ "regex-syntax",
1998]
1728]
1999
1729
2000[[package]]
1730[[package]]
2001name = "regex-automata"
1731name = "regex-automata"
2002−version = "0.3.8"
1732+version = "0.4.3"
2003source = "registry+https://github.com/rust-lang/crates.io-index"
1733source = "registry+https://github.com/rust-lang/crates.io-index"
2004−checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
1734+checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
2005dependencies = [
1735dependencies = [
2006− "aho-corasick 1.0.2",
1736+ "aho-corasick",
2007 "memchr",
1737 "memchr",
2008− "regex-syntax 0.7.5",
1738+ "regex-syntax",
2009]
1739]
2010
1740
2011[[package]]
1741[[package]]
2012name = "regex-syntax"
1742name = "regex-syntax"
2013−version = "0.6.29"
1743+version = "0.8.2"
2014−source = "registry+https://github.com/rust-lang/crates.io-index"
2015−checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
2016−
2017−[[package]]
2018−name = "regex-syntax"
2019−version = "0.7.5"
2020source = "registry+https://github.com/rust-lang/crates.io-index"
1744source = "registry+https://github.com/rust-lang/crates.io-index"
2021−checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
1745+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
2022
1746
2023[[package]]
1747[[package]]
2024name = "ropey"
1748name = "ropey"
2025−version = "1.6.0"
1749+version = "1.6.1"
2026source = "registry+https://github.com/rust-lang/crates.io-index"
1750source = "registry+https://github.com/rust-lang/crates.io-index"
2027−checksum = "53ce7a2c43a32e50d666e33c5a80251b31147bb4b49024bcab11fb6f20c671ed"
1751+checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5"
2028dependencies = [
1752dependencies = [
2029 "smallvec",
1753 "smallvec",
2030 "str_indices",
1754 "str_indices",
@@ -2038,29 +1762,15 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
2038
1762
2039[[package]]
1763[[package]]
2040name = "rustix"
1764name = "rustix"
2041−version = "0.37.15"
1765+version = "0.38.28"
2042−source = "registry+https://github.com/rust-lang/crates.io-index"
2043−checksum = "a0661814f891c57c930a610266415528da53c4933e6dea5fb350cbfe048a9ece"
2044−dependencies = [
2045− "bitflags 1.3.2",
2046− "errno",
2047− "io-lifetimes",
2048− "libc",
2049− "linux-raw-sys 0.3.4",
2050− "windows-sys 0.48.0",
2051−]
2052−
2053−[[package]]
2054−name = "rustix"
2055−version = "0.38.13"
2056source = "registry+https://github.com/rust-lang/crates.io-index"
1766source = "registry+https://github.com/rust-lang/crates.io-index"
2057−checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
1767+checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
2058dependencies = [
1768dependencies = [
2059− "bitflags 2.4.0",
1769+ "bitflags 2.4.1",
2060 "errno",
1770 "errno",
2061 "libc",
1771 "libc",
2062− "linux-raw-sys 0.4.7",
1772+ "linux-raw-sys",
2063− "windows-sys 0.48.0",
1773+ "windows-sys 0.52.0",
2064]
1774]
2065
1775
2066[[package]]
1776[[package]]
@@ -2092,29 +1802,29 @@ checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
2092
1802
2093[[package]]
1803[[package]]
2094name = "serde"
1804name = "serde"
2095−version = "1.0.188"
1805+version = "1.0.193"
2096source = "registry+https://github.com/rust-lang/crates.io-index"
1806source = "registry+https://github.com/rust-lang/crates.io-index"
2097−checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
1807+checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
2098dependencies = [
1808dependencies = [
2099 "serde_derive",
1809 "serde_derive",
2100]
1810]
2101
1811
2102[[package]]
1812[[package]]
2103name = "serde_derive"
1813name = "serde_derive"
2104−version = "1.0.188"
1814+version = "1.0.193"
2105source = "registry+https://github.com/rust-lang/crates.io-index"
1815source = "registry+https://github.com/rust-lang/crates.io-index"
2106−checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
1816+checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
2107dependencies = [
1817dependencies = [
2108 "proc-macro2",
1818 "proc-macro2",
2109 "quote",
1819 "quote",
2110− "syn 2.0.28",
1820+ "syn 2.0.38",
2111]
1821]
2112
1822
2113[[package]]
1823[[package]]
2114name = "serde_json"
1824name = "serde_json"
2115−version = "1.0.105"
1825+version = "1.0.108"
2116source = "registry+https://github.com/rust-lang/crates.io-index"
1826source = "registry+https://github.com/rust-lang/crates.io-index"
2117−checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
1827+checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
2118dependencies = [
1828dependencies = [
2119 "itoa",
1829 "itoa",
2120 "ryu",
1830 "ryu",
@@ -2129,7 +1839,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab"
2129dependencies = [
1839dependencies = [
2130 "proc-macro2",
1840 "proc-macro2",
2131 "quote",
1841 "quote",
2132− "syn 2.0.28",
1842+ "syn 2.0.38",
2133]
1843]
2134
1844
2135[[package]]
1845[[package]]
@@ -2200,18 +1910,18 @@ dependencies = [
2200
1910
2201[[package]]
1911[[package]]
2202name = "slotmap"
1912name = "slotmap"
2203−version = "1.0.6"
1913+version = "1.0.7"
2204source = "registry+https://github.com/rust-lang/crates.io-index"
1914source = "registry+https://github.com/rust-lang/crates.io-index"
2205−checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342"
1915+checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
2206dependencies = [
1916dependencies = [
2207 "version_check",
1917 "version_check",
2208]
1918]
2209
1919
2210[[package]]
1920[[package]]
2211name = "smallvec"
1921name = "smallvec"
2212−version = "1.11.0"
1922+version = "1.11.2"
2213source = "registry+https://github.com/rust-lang/crates.io-index"
1923source = "registry+https://github.com/rust-lang/crates.io-index"
2214−checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
1924+checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
2215
1925
2216[[package]]
1926[[package]]
2217name = "smartstring"
1927name = "smartstring"
@@ -2232,9 +1942,9 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
2232
1942
2233[[package]]
1943[[package]]
2234name = "socket2"
1944name = "socket2"
2235−version = "0.5.3"
1945+version = "0.5.5"
2236source = "registry+https://github.com/rust-lang/crates.io-index"
1946source = "registry+https://github.com/rust-lang/crates.io-index"
2237−checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
1947+checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
2238dependencies = [
1948dependencies = [
2239 "libc",
1949 "libc",
2240 "windows-sys 0.48.0",
1950 "windows-sys 0.48.0",
@@ -2246,12 +1956,6 @@ version = "1.1.0"
2246source = "registry+https://github.com/rust-lang/crates.io-index"
1956source = "registry+https://github.com/rust-lang/crates.io-index"
2247checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1957checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
2248
1958
2249−[[package]]
2250−name = "str-buf"
2251−version = "1.0.6"
2252−source = "registry+https://github.com/rust-lang/crates.io-index"
2253−checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
2254−
2255[[package]]
1959[[package]]
2256name = "str_indices"
1960name = "str_indices"
2257version = "0.4.1"
1961version = "0.4.1"
@@ -2271,9 +1975,9 @@ dependencies = [
2271
1975
2272[[package]]
1976[[package]]
2273name = "syn"
1977name = "syn"
2274−version = "2.0.28"
1978+version = "2.0.38"
2275source = "registry+https://github.com/rust-lang/crates.io-index"
1979source = "registry+https://github.com/rust-lang/crates.io-index"
2276−checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
1980+checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
2277dependencies = [
1981dependencies = [
2278 "proc-macro2",
1982 "proc-macro2",
2279 "quote",
1983 "quote",
@@ -2282,14 +1986,14 @@ dependencies = [
2282
1986
2283[[package]]
1987[[package]]
2284name = "tempfile"
1988name = "tempfile"
2285−version = "3.8.0"
1989+version = "3.8.1"
2286source = "registry+https://github.com/rust-lang/crates.io-index"
1990source = "registry+https://github.com/rust-lang/crates.io-index"
2287−checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
1991+checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
2288dependencies = [
1992dependencies = [
2289 "cfg-if",
1993 "cfg-if",
2290 "fastrand",
1994 "fastrand",
2291− "redox_syscall 0.3.5",
1995+ "redox_syscall 0.4.1",
2292− "rustix 0.38.13",
1996+ "rustix",
2293 "windows-sys 0.48.0",
1997 "windows-sys 0.48.0",
2294]
1998]
2295
1999
@@ -2324,32 +2028,22 @@ dependencies = [
2324
2028
2325[[package]]
2029[[package]]
2326name = "thiserror"
2030name = "thiserror"
2327−version = "1.0.48"
2031+version = "1.0.52"
2328source = "registry+https://github.com/rust-lang/crates.io-index"
2032source = "registry+https://github.com/rust-lang/crates.io-index"
2329−checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
2033+checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d"
2330dependencies = [
2034dependencies = [
2331 "thiserror-impl",
2035 "thiserror-impl",
2332]
2036]
2333
2037
2334[[package]]
2038[[package]]
2335name = "thiserror-impl"
2039name = "thiserror-impl"
2336−version = "1.0.48"
2040+version = "1.0.52"
2337source = "registry+https://github.com/rust-lang/crates.io-index"
2041source = "registry+https://github.com/rust-lang/crates.io-index"
2338−checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
2042+checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3"
2339dependencies = [
2043dependencies = [
2340 "proc-macro2",
2044 "proc-macro2",
2341 "quote",
2045 "quote",
2342− "syn 2.0.28",
2046+ "syn 2.0.38",
2343−]
2344−
2345−[[package]]
2346−name = "thread_local"
2347−version = "1.1.7"
2348−source = "registry+https://github.com/rust-lang/crates.io-index"
2349−checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
2350−dependencies = [
2351− "cfg-if",
2352− "once_cell",
2353]
2047]
2354
2048
2355[[package]]
2049[[package]]
@@ -2363,9 +2057,9 @@ dependencies = [
2363
2057
2364[[package]]
2058[[package]]
2365name = "time"
2059name = "time"
2366−version = "0.3.20"
2060+version = "0.3.23"
2367source = "registry+https://github.com/rust-lang/crates.io-index"
2061source = "registry+https://github.com/rust-lang/crates.io-index"
2368−checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
2062+checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446"
2369dependencies = [
2063dependencies = [
2370 "itoa",
2064 "itoa",
2371 "libc",
2065 "libc",
@@ -2377,15 +2071,15 @@ dependencies = [
2377
2071
2378[[package]]
2072[[package]]
2379name = "time-core"
2073name = "time-core"
2380−version = "0.1.0"
2074+version = "0.1.1"
2381source = "registry+https://github.com/rust-lang/crates.io-index"
2075source = "registry+https://github.com/rust-lang/crates.io-index"
2382−checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
2076+checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
2383
2077
2384[[package]]
2078[[package]]
2385name = "time-macros"
2079name = "time-macros"
2386−version = "0.2.8"
2080+version = "0.2.10"
2387source = "registry+https://github.com/rust-lang/crates.io-index"
2081source = "registry+https://github.com/rust-lang/crates.io-index"
2388−checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
2082+checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4"
2389dependencies = [
2083dependencies = [
2390 "time-core",
2084 "time-core",
2391]
2085]
@@ -2407,9 +2101,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
2407
2101
2408[[package]]
2102[[package]]
2409name = "tokio"
2103name = "tokio"
2410−version = "1.32.0"
2104+version = "1.35.1"
2411source = "registry+https://github.com/rust-lang/crates.io-index"
2105source = "registry+https://github.com/rust-lang/crates.io-index"
2412−checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
2106+checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
2413dependencies = [
2107dependencies = [
2414 "backtrace",
2108 "backtrace",
2415 "bytes",
2109 "bytes",
@@ -2426,13 +2120,13 @@ dependencies = [
2426
2120
2427[[package]]
2121[[package]]
2428name = "tokio-macros"
2122name = "tokio-macros"
2429−version = "2.1.0"
2123+version = "2.2.0"
2430source = "registry+https://github.com/rust-lang/crates.io-index"
2124source = "registry+https://github.com/rust-lang/crates.io-index"
2431−checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
2125+checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
2432dependencies = [
2126dependencies = [
2433 "proc-macro2",
2127 "proc-macro2",
2434 "quote",
2128 "quote",
2435− "syn 2.0.28",
2129+ "syn 2.0.38",
2436]
2130]
2437
2131
2438[[package]]
2132[[package]]
@@ -2477,7 +2171,7 @@ dependencies = [
2477 "serde",
2171 "serde",
2478 "serde_spanned",
2172 "serde_spanned",
2479 "toml_datetime",
2173 "toml_datetime",
2480− "winnow",
2174+ "winnow 0.4.6",
2481]
2175]
2482
2176
2483[[package]]
2177[[package]]
@@ -2545,15 +2239,15 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
2545
2239
2546[[package]]
2240[[package]]
2547name = "unicode-width"
2241name = "unicode-width"
2548−version = "0.1.10"
2242+version = "0.1.11"
2549source = "registry+https://github.com/rust-lang/crates.io-index"
2243source = "registry+https://github.com/rust-lang/crates.io-index"
2550−checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
2244+checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
2551
2245
2552[[package]]
2246[[package]]
2553name = "url"
2247name = "url"
2554−version = "2.4.1"
2248+version = "2.5.0"
2555source = "registry+https://github.com/rust-lang/crates.io-index"
2249source = "registry+https://github.com/rust-lang/crates.io-index"
2556−checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
2250+checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
2557dependencies = [
2251dependencies = [
2558 "form_urlencoded",
2252 "form_urlencoded",
2559 "idna",
2253 "idna",
@@ -2569,9 +2263,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
2569
2263
2570[[package]]
2264[[package]]
2571name = "walkdir"
2265name = "walkdir"
2572−version = "2.3.3"
2266+version = "2.4.0"
2573source = "registry+https://github.com/rust-lang/crates.io-index"
2267source = "registry+https://github.com/rust-lang/crates.io-index"
2574−checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
2268+checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
2575dependencies = [
2269dependencies = [
2576 "same-file",
2270 "same-file",
2577 "winapi-util",
2271 "winapi-util",
@@ -2639,14 +2333,15 @@ checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
2639
2333
2640[[package]]
2334[[package]]
2641name = "which"
2335name = "which"
2642−version = "4.4.1"
2336+version = "5.0.0"
2643source = "registry+https://github.com/rust-lang/crates.io-index"
2337source = "registry+https://github.com/rust-lang/crates.io-index"
2644−checksum = "8ad25fe5717e59ada8ea33511bbbf7420b11031730a24c65e82428766c307006"
2338+checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14"
2645dependencies = [
2339dependencies = [
2646− "dirs",
2647 "either",
2340 "either",
2341+ "home",
2648 "once_cell",
2342 "once_cell",
2649− "rustix 0.38.13",
2343+ "rustix",
2344+ "windows-sys 0.48.0",
2650]
2345]
2651
2346
2652[[package]]
2347[[package]]
@@ -2689,6 +2384,25 @@ dependencies = [
2689 "windows-targets 0.48.0",
2384 "windows-targets 0.48.0",
2690]
2385]
2691
2386
2387+[[package]]
2388+name = "windows"
2389+version = "0.52.0"
2390+source = "registry+https://github.com/rust-lang/crates.io-index"
2391+checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
2392+dependencies = [
2393+ "windows-core",
2394+ "windows-targets 0.52.0",
2395+]
2396+
2397+[[package]]
2398+name = "windows-core"
2399+version = "0.52.0"
2400+source = "registry+https://github.com/rust-lang/crates.io-index"
2401+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
2402+dependencies = [
2403+ "windows-targets 0.52.0",
2404+]
2405+
2692[[package]]
2406[[package]]
2693name = "windows-sys"
2407name = "windows-sys"
2694version = "0.45.0"
2408version = "0.45.0"
@@ -2707,6 +2421,15 @@ dependencies = [
2707 "windows-targets 0.48.0",
2421 "windows-targets 0.48.0",
2708]
2422]
2709
2423
2424+[[package]]
2425+name = "windows-sys"
2426+version = "0.52.0"
2427+source = "registry+https://github.com/rust-lang/crates.io-index"
2428+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
2429+dependencies = [
2430+ "windows-targets 0.52.0",
2431+]
2432+
2710[[package]]
2433[[package]]
2711name = "windows-targets"
2434name = "windows-targets"
2712version = "0.42.2"
2435version = "0.42.2"
@@ -2737,6 +2460,21 @@ dependencies = [
2737 "windows_x86_64_msvc 0.48.0",
2460 "windows_x86_64_msvc 0.48.0",
2738]
2461]
2739
2462
2463+[[package]]
2464+name = "windows-targets"
2465+version = "0.52.0"
2466+source = "registry+https://github.com/rust-lang/crates.io-index"
2467+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
2468+dependencies = [
2469+ "windows_aarch64_gnullvm 0.52.0",
2470+ "windows_aarch64_msvc 0.52.0",
2471+ "windows_i686_gnu 0.52.0",
2472+ "windows_i686_msvc 0.52.0",
2473+ "windows_x86_64_gnu 0.52.0",
2474+ "windows_x86_64_gnullvm 0.52.0",
2475+ "windows_x86_64_msvc 0.52.0",
2476+]
2477+
2740[[package]]
2478[[package]]
2741name = "windows_aarch64_gnullvm"
2479name = "windows_aarch64_gnullvm"
2742version = "0.42.2"
2480version = "0.42.2"
@@ -2749,6 +2487,12 @@ version = "0.48.0"
2749source = "registry+https://github.com/rust-lang/crates.io-index"
2487source = "registry+https://github.com/rust-lang/crates.io-index"
2750checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
2488checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
2751
2489
2490+[[package]]
2491+name = "windows_aarch64_gnullvm"
2492+version = "0.52.0"
2493+source = "registry+https://github.com/rust-lang/crates.io-index"
2494+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
2495+
2752[[package]]
2496[[package]]
2753name = "windows_aarch64_msvc"
2497name = "windows_aarch64_msvc"
2754version = "0.42.2"
2498version = "0.42.2"
@@ -2761,6 +2505,12 @@ version = "0.48.0"
2761source = "registry+https://github.com/rust-lang/crates.io-index"
2505source = "registry+https://github.com/rust-lang/crates.io-index"
2762checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
2506checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
2763
2507
2508+[[package]]
2509+name = "windows_aarch64_msvc"
2510+version = "0.52.0"
2511+source = "registry+https://github.com/rust-lang/crates.io-index"
2512+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
2513+
2764[[package]]
2514[[package]]
2765name = "windows_i686_gnu"
2515name = "windows_i686_gnu"
2766version = "0.42.2"
2516version = "0.42.2"
@@ -2773,6 +2523,12 @@ version = "0.48.0"
2773source = "registry+https://github.com/rust-lang/crates.io-index"
2523source = "registry+https://github.com/rust-lang/crates.io-index"
2774checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
2524checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
2775
2525
2526+[[package]]
2527+name = "windows_i686_gnu"
2528+version = "0.52.0"
2529+source = "registry+https://github.com/rust-lang/crates.io-index"
2530+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
2531+
2776[[package]]
2532[[package]]
2777name = "windows_i686_msvc"
2533name = "windows_i686_msvc"
2778version = "0.42.2"
2534version = "0.42.2"
@@ -2785,6 +2541,12 @@ version = "0.48.0"
2785source = "registry+https://github.com/rust-lang/crates.io-index"
2541source = "registry+https://github.com/rust-lang/crates.io-index"
2786checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
2542checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
2787
2543
2544+[[package]]
2545+name = "windows_i686_msvc"
2546+version = "0.52.0"
2547+source = "registry+https://github.com/rust-lang/crates.io-index"
2548+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
2549+
2788[[package]]
2550[[package]]
2789name = "windows_x86_64_gnu"
2551name = "windows_x86_64_gnu"
2790version = "0.42.2"
2552version = "0.42.2"
@@ -2797,6 +2559,12 @@ version = "0.48.0"
2797source = "registry+https://github.com/rust-lang/crates.io-index"
2559source = "registry+https://github.com/rust-lang/crates.io-index"
2798checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
2560checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
2799
2561
2562+[[package]]
2563+name = "windows_x86_64_gnu"
2564+version = "0.52.0"
2565+source = "registry+https://github.com/rust-lang/crates.io-index"
2566+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
2567+
2800[[package]]
2568[[package]]
2801name = "windows_x86_64_gnullvm"
2569name = "windows_x86_64_gnullvm"
2802version = "0.42.2"
2570version = "0.42.2"
@@ -2809,6 +2577,12 @@ version = "0.48.0"
2809source = "registry+https://github.com/rust-lang/crates.io-index"
2577source = "registry+https://github.com/rust-lang/crates.io-index"
2810checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
2578checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
2811
2579
2580+[[package]]
2581+name = "windows_x86_64_gnullvm"
2582+version = "0.52.0"
2583+source = "registry+https://github.com/rust-lang/crates.io-index"
2584+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
2585+
2812[[package]]
2586[[package]]
2813name = "windows_x86_64_msvc"
2587name = "windows_x86_64_msvc"
2814version = "0.42.2"
2588version = "0.42.2"
@@ -2821,6 +2595,12 @@ version = "0.48.0"
2821source = "registry+https://github.com/rust-lang/crates.io-index"
2595source = "registry+https://github.com/rust-lang/crates.io-index"
2822checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
2596checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
2823
2597
2598+[[package]]
2599+name = "windows_x86_64_msvc"
2600+version = "0.52.0"
2601+source = "registry+https://github.com/rust-lang/crates.io-index"
2602+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
2603+
2824[[package]]
2604[[package]]
2825name = "winnow"
2605name = "winnow"
2826version = "0.4.6"
2606version = "0.4.6"
@@ -2830,9 +2610,18 @@ dependencies = [
2830 "memchr",
2610 "memchr",
2831]
2611]
2832
2612
2613+[[package]]
2614+name = "winnow"
2615+version = "0.5.28"
2616+source = "registry+https://github.com/rust-lang/crates.io-index"
2617+checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2"
2618+dependencies = [
2619+ "memchr",
2620+]
2621+
2833[[package]]
2622[[package]]
2834name = "xtask"
2623name = "xtask"
2835−version = "0.6.0"
2624+version = "23.10.0"
2836dependencies = [
2625dependencies = [
2837 "helix-core",
2626 "helix-core",
2838 "helix-loader",
2627 "helix-loader",
@@ -2840,3 +2629,23 @@ dependencies = [
2840 "helix-view",
2629 "helix-view",
2841 "toml",
2630 "toml",
2842]
2631]
2632+
2633+[[package]]
2634+name = "zerocopy"
2635+version = "0.7.31"
2636+source = "registry+https://github.com/rust-lang/crates.io-index"
2637+checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d"
2638+dependencies = [
2639+ "zerocopy-derive",
2640+]
2641+
2642+[[package]]
2643+name = "zerocopy-derive"
2644+version = "0.7.31"
2645+source = "registry+https://github.com/rust-lang/crates.io-index"
2646+checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
2647+dependencies = [
2648+ "proc-macro2",
2649+ "quote",
2650+ "syn 2.0.38",
2651+]
Cargo.toml+11
@@ -1,4 +1,5 @@
1[workspace]
1[workspace]
2+resolver = "2"
2members = [
3members = [
3 "helix-core",
4 "helix-core",
4 "helix-view",
5 "helix-view",
@@ -37,3 +38,13 @@ package.helix-term.opt-level = 2
37[workspace.dependencies]
38[workspace.dependencies]
38tree-sitter = { version = "0.20", git = "https://github.com/tree-sitter/tree-sitter", rev = "ab09ae20d640711174b8da8a654f6b3dec93da1a" }
39tree-sitter = { version = "0.20", git = "https://github.com/tree-sitter/tree-sitter", rev = "ab09ae20d640711174b8da8a654f6b3dec93da1a" }
39nucleo = "0.2.0"
40nucleo = "0.2.0"
41+
42+[workspace.package]
43+version = "23.10.0"
44+edition = "2021"
45+authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
46+categories = ["editor"]
47+repository = "https://github.com/helix-editor/helix"
48+homepage = "https://helix-editor.com"
49+license = "MPL-2.0"
50+rust-version = "1.70"
README.md+1−1
@@ -18,7 +18,7 @@
18
18
19![Screenshot](./screenshot.png)
19![Screenshot](./screenshot.png)
20
20
21−A Kakoune / Neovim inspired editor, written in Rust.
21+A [Kakoune](https://github.com/mawww/kakoune) / [Neovim](https://github.com/neovim/neovim) inspired editor, written in Rust.
22
22
23The editing model is very heavily based on Kakoune; during development I found
23The editing model is very heavily based on Kakoune; during development I found
24myself agreeing with most of Kakoune's design decisions.
24myself agreeing with most of Kakoune's design decisions.
VERSIONdeleted−1
@@ -1 +0,0 @@
1−23.05
book/src/configuration.md+26−9
@@ -51,7 +51,7 @@ Its settings will be merged with the configuration directory `config.toml` and t
51| `auto-completion` | Enable automatic pop up of auto-completion | `true` |
51| `auto-completion` | Enable automatic pop up of auto-completion | `true` |
52| `auto-format` | Enable automatic formatting on save | `true` |
52| `auto-format` | Enable automatic formatting on save | `true` |
53| `auto-save` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal | `false` |
53| `auto-save` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal | `false` |
54−| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant | `400` |
54+| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant | `250` |
55| `preview-completion-insert` | Whether to apply completion item instantly when selected | `true` |
55| `preview-completion-insert` | Whether to apply completion item instantly when selected | `true` |
56| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
56| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
57| `completion-replace` | Set to `true` to make completions always replace the entire word and not just the part before the cursor | `false` |
57| `completion-replace` | Set to `true` to make completions always replace the entire word and not just the part before the cursor | `false` |
@@ -65,6 +65,8 @@ Its settings will be merged with the configuration directory `config.toml` and t
65| `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml` | `[]` |
65| `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml` | `[]` |
66| `default-line-ending` | The line ending to use for new documents. Can be `native`, `lf`, `crlf`, `ff`, `cr` or `nel`. `native` uses the platform's native line ending (`crlf` on Windows, otherwise `lf`). | `native` |
66| `default-line-ending` | The line ending to use for new documents. Can be `native`, `lf`, `crlf`, `ff`, `cr` or `nel`. `native` uses the platform's native line ending (`crlf` on Windows, otherwise `lf`). | `native` |
67| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
67| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
68+| `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` |
69+| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
68
70
69### `[editor.statusline]` Section
71### `[editor.statusline]` Section
70
72
@@ -166,16 +168,31 @@ All git related options are only enabled in a git repository.
166
168
167| Key | Description | Default |
169| Key | Description | Default |
168|--|--|---------|
170|--|--|---------|
169−|`hidden` | Enables ignoring hidden files | true
171+|`hidden` | Enables ignoring hidden files | `true`
170−|`follow-symlinks` | Follow symlinks instead of ignoring them | true
172+|`follow-symlinks` | Follow symlinks instead of ignoring them | `true`
171−|`deduplicate-links` | Ignore symlinks that point at files already shown in the picker | true
173+|`deduplicate-links` | Ignore symlinks that point at files already shown in the picker | `true`
172−|`parents` | Enables reading ignore files from parent directories | true
174+|`parents` | Enables reading ignore files from parent directories | `true`
173−|`ignore` | Enables reading `.ignore` files | true
175+|`ignore` | Enables reading `.ignore` files | `true`
174−|`git-ignore` | Enables reading `.gitignore` files | true
176+|`git-ignore` | Enables reading `.gitignore` files | `true`
175−|`git-global` | Enables reading global `.gitignore`, whose path is specified in git's config: `core.excludefile` option | true
177+|`git-global` | Enables reading global `.gitignore`, whose path is specified in git's config: `core.excludesfile` option | `true`
176−|`git-exclude` | Enables reading `.git/info/exclude` files | true
178+|`git-exclude` | Enables reading `.git/info/exclude` files | `true`
177|`max-depth` | Set with an integer value for maximum depth to recurse | Defaults to `None`.
179|`max-depth` | Set with an integer value for maximum depth to recurse | Defaults to `None`.
178
180
181+Ignore files can be placed locally as `.ignore` or put in your home directory as `~/.ignore`. They support the usual ignore and negative ignore (unignore) rules used in `.gitignore` files.
182+
183+Additionally, you can use Helix-specific ignore files by creating a local `.helix/ignore` file in the current workspace or a global `ignore` file located in your Helix config directory:
184+- Linux and Mac: `~/.config/helix/ignore`
185+- Windows: `%AppData%\helix\ignore`
186+
187+Example:
188+
189+```ini
190+# unignore in file picker and global search
191+!.github/
192+!.gitignore
193+!.gitattributes
194+```
195+
179### `[editor.auto-pairs]` Section
196### `[editor.auto-pairs]` Section
180
197
181Enables automatic insertion of pairs to parentheses, brackets, etc. Can be a
198Enables automatic insertion of pairs to parentheses, brackets, etc. Can be a
book/src/generated/lang-support.md+20−10
@@ -1,5 +1,6 @@
1| Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP |
1| Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP |
2| --- | --- | --- | --- | --- |
2| --- | --- | --- | --- | --- |
3+| agda | ✓ | | | |
3| astro | ✓ | | | |
4| astro | ✓ | | | |
4| awk | ✓ | ✓ | | `awk-language-server` |
5| awk | ✓ | ✓ | | `awk-language-server` |
5| bash | ✓ | ✓ | ✓ | `bash-language-server` |
6| bash | ✓ | ✓ | ✓ | `bash-language-server` |
@@ -10,13 +11,13 @@
10| blueprint | ✓ | | | `blueprint-compiler` |
11| blueprint | ✓ | | | `blueprint-compiler` |
11| c | ✓ | ✓ | ✓ | `clangd` |
12| c | ✓ | ✓ | ✓ | `clangd` |
12| c-sharp | ✓ | ✓ | | `OmniSharp` |
13| c-sharp | ✓ | ✓ | | `OmniSharp` |
13−| cabal | | | | |
14+| cabal | | | | `haskell-language-server-wrapper` |
14| cairo | ✓ | ✓ | ✓ | `cairo-language-server` |
15| cairo | ✓ | ✓ | ✓ | `cairo-language-server` |
15| capnp | ✓ | | ✓ | |
16| capnp | ✓ | | ✓ | |
16| clojure | ✓ | | | `clojure-lsp` |
17| clojure | ✓ | | | `clojure-lsp` |
17| cmake | ✓ | ✓ | ✓ | `cmake-language-server` |
18| cmake | ✓ | ✓ | ✓ | `cmake-language-server` |
18| comment | ✓ | | | |
19| comment | ✓ | | | |
19−| common-lisp | ✓ | | | `cl-lsp` |
20+| common-lisp | ✓ | | ✓ | `cl-lsp` |
20| cpon | ✓ | | ✓ | |
21| cpon | ✓ | | ✓ | |
21| cpp | ✓ | ✓ | ✓ | `clangd` |
22| cpp | ✓ | ✓ | ✓ | `clangd` |
22| crystal | ✓ | ✓ | | `crystalline` |
23| crystal | ✓ | ✓ | | `crystalline` |
@@ -24,6 +25,7 @@
24| cue | ✓ | | | `cuelsp` |
25| cue | ✓ | | | `cuelsp` |
25| d | ✓ | ✓ | ✓ | `serve-d` |
26| d | ✓ | ✓ | ✓ | `serve-d` |
26| dart | ✓ | | ✓ | `dart` |
27| dart | ✓ | | ✓ | `dart` |
28+| dbml | ✓ | | | |
27| devicetree | ✓ | | | |
29| devicetree | ✓ | | | |
28| dhall | ✓ | ✓ | | `dhall-lsp-server` |
30| dhall | ✓ | ✓ | | `dhall-lsp-server` |
29| diff | ✓ | | | |
31| diff | ✓ | | | |
@@ -54,12 +56,13 @@
54| git-rebase | ✓ | | | |
56| git-rebase | ✓ | | | |
55| gleam | ✓ | ✓ | | `gleam` |
57| gleam | ✓ | ✓ | | `gleam` |
56| glsl | ✓ | ✓ | ✓ | |
58| glsl | ✓ | ✓ | ✓ | |
57−| go | ✓ | ✓ | ✓ | `gopls` |
59+| gn | ✓ | | | |
60+| go | ✓ | ✓ | ✓ | `gopls`, `golangci-lint-langserver` |
58| godot-resource | ✓ | | | |
61| godot-resource | ✓ | | | |
59| gomod | ✓ | | | `gopls` |
62| gomod | ✓ | | | `gopls` |
60| gotmpl | ✓ | | | `gopls` |
63| gotmpl | ✓ | | | `gopls` |
61| gowork | ✓ | | | `gopls` |
64| gowork | ✓ | | | `gopls` |
62−| graphql | ✓ | | | |
65+| graphql | ✓ | | | `graphql-lsp` |
63| hare | ✓ | | | |
66| hare | ✓ | | | |
64| haskell | ✓ | ✓ | | `haskell-language-server-wrapper` |
67| haskell | ✓ | ✓ | | `haskell-language-server-wrapper` |
65| haskell-persistent | ✓ | | | |
68| haskell-persistent | ✓ | | | |
@@ -71,16 +74,18 @@
71| idris | | | | `idris2-lsp` |
74| idris | | | | `idris2-lsp` |
72| iex | ✓ | | | |
75| iex | ✓ | | | |
73| ini | ✓ | | | |
76| ini | ✓ | | | |
77+| janet | ✓ | | | |
74| java | ✓ | ✓ | ✓ | `jdtls` |
78| java | ✓ | ✓ | ✓ | `jdtls` |
75| javascript | ✓ | ✓ | ✓ | `typescript-language-server` |
79| javascript | ✓ | ✓ | ✓ | `typescript-language-server` |
76| jinja | ✓ | | | |
80| jinja | ✓ | | | |
77| jsdoc | ✓ | | | |
81| jsdoc | ✓ | | | |
78| json | ✓ | | ✓ | `vscode-json-language-server` |
82| json | ✓ | | ✓ | `vscode-json-language-server` |
83+| json5 | ✓ | | | |
79| jsonnet | ✓ | | | `jsonnet-language-server` |
84| jsonnet | ✓ | | | `jsonnet-language-server` |
80| jsx | ✓ | ✓ | ✓ | `typescript-language-server` |
85| jsx | ✓ | ✓ | ✓ | `typescript-language-server` |
81| julia | ✓ | ✓ | ✓ | `julia` |
86| julia | ✓ | ✓ | ✓ | `julia` |
82| just | ✓ | ✓ | ✓ | |
87| just | ✓ | ✓ | ✓ | |
83−| kdl | ✓ | | | |
88+| kdl | ✓ | ✓ | ✓ | |
84| kotlin | ✓ | | | `kotlin-language-server` |
89| kotlin | ✓ | | | `kotlin-language-server` |
85| latex | ✓ | ✓ | | `texlab` |
90| latex | ✓ | ✓ | | `texlab` |
86| lean | ✓ | | | `lean` |
91| lean | ✓ | | | `lean` |
@@ -88,6 +93,8 @@
88| llvm | ✓ | ✓ | ✓ | |
93| llvm | ✓ | ✓ | ✓ | |
89| llvm-mir | ✓ | ✓ | ✓ | |
94| llvm-mir | ✓ | ✓ | ✓ | |
90| llvm-mir-yaml | ✓ | | ✓ | |
95| llvm-mir-yaml | ✓ | | ✓ | |
96+| log | ✓ | | | |
97+| lpf | ✓ | | | |
91| lua | ✓ | ✓ | ✓ | `lua-language-server` |
98| lua | ✓ | ✓ | ✓ | `lua-language-server` |
92| make | ✓ | | | |
99| make | ✓ | | | |
93| markdoc | ✓ | | | `markdoc-ls` |
100| markdoc | ✓ | | | `markdoc-ls` |
@@ -102,7 +109,7 @@
102| nickel | ✓ | | ✓ | `nls` |
109| nickel | ✓ | | ✓ | `nls` |
103| nim | ✓ | ✓ | ✓ | `nimlangserver` |
110| nim | ✓ | ✓ | ✓ | `nimlangserver` |
104| nix | ✓ | | | `nil` |
111| nix | ✓ | | | `nil` |
105−| nu | ✓ | | | |
112+| nu | ✓ | | | `nu` |
106| nunjucks | ✓ | | | |
113| nunjucks | ✓ | | | |
107| ocaml | ✓ | | ✓ | `ocamllsp` |
114| ocaml | ✓ | | ✓ | `ocamllsp` |
108| ocaml-interface | ✓ | | | `ocamllsp` |
115| ocaml-interface | ✓ | | | `ocamllsp` |
@@ -122,11 +129,11 @@
122| prolog | | | | `swipl` |
129| prolog | | | | `swipl` |
123| protobuf | ✓ | | ✓ | `bufls`, `pb` |
130| protobuf | ✓ | | ✓ | `bufls`, `pb` |
124| prql | ✓ | | | |
131| prql | ✓ | | | |
125−| purescript | ✓ | | | `purescript-language-server` |
132+| purescript | ✓ | ✓ | | `purescript-language-server` |
126| python | ✓ | ✓ | ✓ | `pylsp` |
133| python | ✓ | ✓ | ✓ | `pylsp` |
127| qml | ✓ | | ✓ | `qmlls` |
134| qml | ✓ | | ✓ | `qmlls` |
128| r | ✓ | | | `R` |
135| r | ✓ | | | `R` |
129−| racket | ✓ | | | `racket` |
136+| racket | ✓ | | ✓ | `racket` |
130| regex | ✓ | | | |
137| regex | ✓ | | | |
131| rego | ✓ | | | `regols` |
138| rego | ✓ | | | `regols` |
132| rescript | ✓ | ✓ | | `rescript-language-server` |
139| rescript | ✓ | ✓ | | `rescript-language-server` |
@@ -138,9 +145,10 @@
138| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
145| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
139| sage | ✓ | ✓ | | |
146| sage | ✓ | ✓ | | |
140| scala | ✓ | | ✓ | `metals` |
147| scala | ✓ | | ✓ | `metals` |
141−| scheme | ✓ | | | |
148+| scheme | ✓ | | ✓ | |
142| scss | ✓ | | | `vscode-css-language-server` |
149| scss | ✓ | | | `vscode-css-language-server` |
143| slint | ✓ | | ✓ | `slint-lsp` |
150| slint | ✓ | | ✓ | `slint-lsp` |
151+| smali | ✓ | | ✓ | |
144| smithy | ✓ | | | `cs` |
152| smithy | ✓ | | | `cs` |
145| sml | ✓ | | | |
153| sml | ✓ | | | |
146| solidity | ✓ | | | `solc` |
154| solidity | ✓ | | | `solc` |
@@ -154,6 +162,7 @@
154| t32 | ✓ | | | |
162| t32 | ✓ | | | |
155| tablegen | ✓ | ✓ | ✓ | |
163| tablegen | ✓ | ✓ | ✓ | |
156| task | ✓ | | | |
164| task | ✓ | | | |
165+| templ | ✓ | | | `templ` |
157| tfvars | ✓ | | ✓ | `terraform-ls` |
166| tfvars | ✓ | | ✓ | `terraform-ls` |
158| todotxt | ✓ | | | |
167| todotxt | ✓ | | | |
159| toml | ✓ | | | `taplo` |
168| toml | ✓ | | | `taplo` |
@@ -161,6 +170,7 @@
161| tsx | ✓ | ✓ | ✓ | `typescript-language-server` |
170| tsx | ✓ | ✓ | ✓ | `typescript-language-server` |
162| twig | ✓ | | | |
171| twig | ✓ | | | |
163| typescript | ✓ | ✓ | ✓ | `typescript-language-server` |
172| typescript | ✓ | ✓ | ✓ | `typescript-language-server` |
173+| typst | ✓ | | | `typst-lsp` |
164| ungrammar | ✓ | | | |
174| ungrammar | ✓ | | | |
165| unison | ✓ | | | |
175| unison | ✓ | | | |
166| uxntal | ✓ | | | |
176| uxntal | ✓ | | | |
@@ -178,6 +188,6 @@
178| wren | ✓ | ✓ | ✓ | |
188| wren | ✓ | ✓ | ✓ | |
179| xit | ✓ | | | |
189| xit | ✓ | | | |
180| xml | ✓ | | ✓ | |
190| xml | ✓ | | ✓ | |
181−| yaml | ✓ | | ✓ | `yaml-language-server` |
191+| yaml | ✓ | | ✓ | `yaml-language-server`, `ansible-language-server` |
182| yuck | ✓ | | | |
192| yuck | ✓ | | | |
183| zig | ✓ | ✓ | ✓ | `zls` |
193| zig | ✓ | ✓ | ✓ | `zls` |
book/src/generated/typable-cmd.md+2−1
@@ -17,7 +17,7 @@
17| `:write-buffer-close!`, `:wbc!` | Force write changes to disk creating necessary subdirectories and closes the buffer. Accepts an optional path (:write-buffer-close! some/path.txt) |
17| `:write-buffer-close!`, `:wbc!` | Force write changes to disk creating necessary subdirectories and closes the buffer. Accepts an optional path (:write-buffer-close! some/path.txt) |
18| `:new`, `:n` | Create a new scratch buffer. |
18| `:new`, `:n` | Create a new scratch buffer. |
19| `:format`, `:fmt` | Format the file using the LSP formatter. |
19| `:format`, `:fmt` | Format the file using the LSP formatter. |
20−| `:indent-style` | Set the indentation style for editing. ('t' for tabs or 1-8 for number of spaces.) |
20+| `:indent-style` | Set the indentation style for editing. ('t' for tabs or 1-16 for number of spaces.) |
21| `:line-ending` | Set the document's default line ending. Options: crlf, lf. |
21| `:line-ending` | Set the document's default line ending. Options: crlf, lf. |
22| `:earlier`, `:ear` | Jump back to an earlier point in edit history. Accepts a number of steps or a time span. |
22| `:earlier`, `:ear` | Jump back to an earlier point in edit history. Accepts a number of steps or a time span. |
23| `:later`, `:lat` | Jump to a later point in edit history. Accepts a number of steps or a time span. |
23| `:later`, `:lat` | Jump to a later point in edit history. Accepts a number of steps or a time span. |
@@ -85,3 +85,4 @@
85| `:reset-diff-change`, `:diffget`, `:diffg` | Reset the diff change at the cursor position. |
85| `:reset-diff-change`, `:diffget`, `:diffg` | Reset the diff change at the cursor position. |
86| `:clear-register` | Clear given register. If no argument is provided, clear all registers. |
86| `:clear-register` | Clear given register. If no argument is provided, clear all registers. |
87| `:redraw` | Clear and re-render the whole UI |
87| `:redraw` | Clear and re-render the whole UI |
88+| `:move` | Move the current buffer and its corresponding file to a different path |
book/src/guides/adding_languages.md+2
@@ -36,6 +36,7 @@ below.
363. Refer to the
363. Refer to the
37 [tree-sitter website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries)
37 [tree-sitter website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries)
38 for more information on writing queries.
38 for more information on writing queries.
39+4. A list of highlight captures can be found [on the themes page](https://docs.helix-editor.com/themes.html#scopes).
39
40
40> 💡 In Helix, the first matching query takes precedence when evaluating
41> 💡 In Helix, the first matching query takes precedence when evaluating
41> queries, which is different from other editors such as Neovim where the last
42> queries, which is different from other editors such as Neovim where the last
@@ -51,3 +52,4 @@ below.
51 grammars.
52 grammars.
52- If a parser is causing a segfault, or you want to remove it, make sure to
53- If a parser is causing a segfault, or you want to remove it, make sure to
53 remove the compiled parser located at `runtime/grammars/<name>.so`.
54 remove the compiled parser located at `runtime/grammars/<name>.so`.
55+- If you are attempting to add queries and Helix is unable to locate them, ensure that the environment variable `HELIX_RUNTIME` is set to the location of the `runtime` folder you're developing in.
book/src/guides/indent.md+9
@@ -12,6 +12,15 @@ Note that it matters where these added indents begin. For example,
12multiple indent level increases that start on the same line only increase
12multiple indent level increases that start on the same line only increase
13the total indent level by 1. See [Capture types](#capture-types).
13the total indent level by 1. See [Capture types](#capture-types).
14
14
15+By default, Helix uses the `hybrid` indentation heuristic. This means that
16+indent queries are not used to compute the expected absolute indentation of a
17+line but rather the expected difference in indentation between the new and an
18+already existing line. This difference is then added to the actual indentation
19+of the already existing line. Since this makes errors in the indent queries
20+harder to find, it is recommended to disable it when testing via
21+`:set indent-heuristic tree-sitter`. The rest of this guide assumes that
22+the `tree-sitter` heuristic is used.
23+
15## Indent queries
24## Indent queries
16
25
17When Helix is inserting a new line through `o`, `O`, or `<ret>`, to determine
26When Helix is inserting a new line through `o`, `O`, or `<ret>`, to determine
book/src/guides/injection.md+1−1
@@ -1,7 +1,7 @@
1# Adding Injection Queries
1# Adding Injection Queries
2
2
3Writing language injection queries allows one to highlight a specific node as a different language.
3Writing language injection queries allows one to highlight a specific node as a different language.
4−In addition to the [standard](upstream-docs) language injection options used by tree-sitter, there
4+In addition to the [standard][upstream-docs] language injection options used by tree-sitter, there
5are a few Helix specific extensions that allow for more control.
5are a few Helix specific extensions that allow for more control.
6
6
7And example of a simple query that would highlight all strings as bash in Nix:
7And example of a simple query that would highlight all strings as bash in Nix:
book/src/install.md+30−6
@@ -13,6 +13,7 @@
13 - [AppImage](#appimage)
13 - [AppImage](#appimage)
14- [macOS](#macos)
14- [macOS](#macos)
15 - [Homebrew Core](#homebrew-core)
15 - [Homebrew Core](#homebrew-core)
16+ - [MacPorts](#macports)
16- [Windows](#windows)
17- [Windows](#windows)
17 - [Winget](#winget)
18 - [Winget](#winget)
18 - [Scoop](#scoop)
19 - [Scoop](#scoop)
@@ -64,10 +65,7 @@ sudo apt install helix
64
65
65### Fedora/RHEL
66### Fedora/RHEL
66
67
67−Enable the `COPR` repository for Helix:
68−
69```sh
68```sh
70−sudo dnf copr enable varlad/helix
71sudo dnf install helix
69sudo dnf install helix
72```
70```
73
71
@@ -133,6 +131,12 @@ chmod +x helix-*.AppImage # change permission for executable mode
133brew install helix
131brew install helix
134```
132```
135
133
134+### MacPorts
135+
136+```sh
137+port install helix
138+```
139+
136## Windows
140## Windows
137
141
138Install on Windows using [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), [Scoop](https://scoop.sh/), [Chocolatey](https://chocolatey.org/)
142Install on Windows using [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), [Scoop](https://scoop.sh/), [Chocolatey](https://chocolatey.org/)
@@ -224,7 +228,7 @@ Or, create a symbolic link:
224ln -Ts $PWD/runtime ~/.config/helix/runtime
228ln -Ts $PWD/runtime ~/.config/helix/runtime
225```
229```
226
230
227−If the above command fails to create a symbolic link because the file exists either move `~/.config/helix/runtime` to a new location or delete it, then run the symlink command above again.
231+If the above command fails to create a symbolic link because the file exists either move `~/.config/helix/runtime` to a new location or delete it, then run the symlink command above again.
228
232
229#### Windows
233#### Windows
230
234
@@ -257,12 +261,32 @@ following order:
2571. `runtime/` sibling directory to `$CARGO_MANIFEST_DIR` directory (this is intended for
2611. `runtime/` sibling directory to `$CARGO_MANIFEST_DIR` directory (this is intended for
258 developing and testing helix only).
262 developing and testing helix only).
2592. `runtime/` subdirectory of OS-dependent helix user config directory.
2632. `runtime/` subdirectory of OS-dependent helix user config directory.
260−3. `$HELIX_RUNTIME`.
264+3. `$HELIX_RUNTIME`
265+4. Distribution-specific fallback directory (set at compile time—not run time—
266+ with the `HELIX_DEFAULT_RUNTIME` environment variable)
261−4. `runtime/` subdirectory of path to Helix executable.
267+5. `runtime/` subdirectory of path to Helix executable.
262
268
263This order also sets the priority for selecting which file will be used if multiple runtime
269This order also sets the priority for selecting which file will be used if multiple runtime
264directories have files with the same name.
270directories have files with the same name.
265
271
272+#### Note to packagers
273+
274+If you are making a package of Helix for end users, to provide a good out of
275+the box experience, you should set the `HELIX_DEFAULT_RUNTIME` environment
276+variable at build time (before invoking `cargo build`) to a directory which
277+will store the final runtime files after installation. For example, say you want
278+to package the runtime into `/usr/lib/helix/runtime`. The rough steps a build
279+script could follow are:
280+
281+1. `export HELIX_DEFAULT_RUNTIME=/usr/lib/helix/runtime`
282+1. `cargo build --profile opt --locked --path helix-term`
283+1. `cp -r runtime $BUILD_DIR/usr/lib/helix/`
284+1. `cp target/opt/hx $BUILD_DIR/usr/bin/hx`
285+
286+This way the resulting `hx` binary will always look for its runtime directory in
287+`/usr/lib/helix/runtime` if the user has no custom runtime in `~/.config/helix`
288+or `HELIX_RUNTIME`.
289+
266### Validating the installation
290### Validating the installation
267
291
268To make sure everything is set up as expected you should run the Helix health
292To make sure everything is set up as expected you should run the Helix health
book/src/keymap.md+1−1
@@ -25,7 +25,7 @@
25
25
26## Normal mode
26## Normal mode
27
27
28−Normal mode is the default mode when you launch helix. Return to it from other modes by typing `Escape`.
28+Normal mode is the default mode when you launch helix. You can return to it from other modes by pressing the `Escape` key.
29
29
30### Movement
30### Movement
31
31
book/src/languages.md+2
@@ -66,8 +66,10 @@ These configuration keys are available:
66| `language-servers` | The Language Servers used for this language. See below for more information in the section [Configuring Language Servers for a language](#configuring-language-servers-for-a-language) |
66| `language-servers` | The Language Servers used for this language. See below for more information in the section [Configuring Language Servers for a language](#configuring-language-servers-for-a-language) |
67| `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) |
67| `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) |
68| `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout |
68| `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout |
69+| `soft-wrap` | [editor.softwrap](./configuration.md#editorsoft-wrap-section)
69| `text-width` | Maximum line length. Used for the `:reflow` command and soft-wrapping if `soft-wrap.wrap-at-text-width` is set, defaults to `editor.text-width` |
70| `text-width` | Maximum line length. Used for the `:reflow` command and soft-wrapping if `soft-wrap.wrap-at-text-width` is set, defaults to `editor.text-width` |
70| `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml`. Overwrites the setting of the same name in `config.toml` if set. |
71| `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml`. Overwrites the setting of the same name in `config.toml` if set. |
72+| `persistent-diagnostic-sources` | An array of LSP diagnostic sources assumed unchanged when the language server resends the same set of diagnostics. Helix can track the position for these diagnostics internally instead. Useful for diagnostics that are recomputed on save.
71
73
72### File-type detection and the `file-types` key
74### File-type detection and the `file-types` key
73
75
book/src/themes.md+8−1
@@ -155,6 +155,7 @@ We use a similar set of scopes as
155
155
156- `type` - Types
156- `type` - Types
157 - `builtin` - Primitive types provided by the language (`int`, `usize`)
157 - `builtin` - Primitive types provided by the language (`int`, `usize`)
158+ - `parameter` - Generic type parameters (`T`)
158 - `enum`
159 - `enum`
159 - `variant`
160 - `variant`
160- `constructor`
161- `constructor`
@@ -245,9 +246,12 @@ We use a similar set of scopes as
245
246
246- `diff` - version control changes
247- `diff` - version control changes
247 - `plus` - additions
248 - `plus` - additions
249+ - `gutter` - gutter indicator
248 - `minus` - deletions
250 - `minus` - deletions
251+ - `gutter` - gutter indicator
249 - `delta` - modifications
252 - `delta` - modifications
250 - `moved` - renamed or moved files/changes
253 - `moved` - renamed or moved files/changes
254+ - `gutter` - gutter indicator
251
255
252#### Interface
256#### Interface
253
257
@@ -292,11 +296,14 @@ These scopes are used for theming the editor interface:
292| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
296| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
293| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
297| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
294| `ui.statusline.separator` | Separator character in statusline |
298| `ui.statusline.separator` | Separator character in statusline |
299+| `ui.bufferline` | Style for the buffer line |
300+| `ui.bufferline.active` | Style for the active buffer in buffer line |
301+| `ui.bufferline.background` | Style for bufferline background |
295| `ui.popup` | Documentation popups (e.g. Space + k) |
302| `ui.popup` | Documentation popups (e.g. Space + k) |
296| `ui.popup.info` | Prompt for multiple key options |
303| `ui.popup.info` | Prompt for multiple key options |
297| `ui.window` | Borderlines separating splits |
304| `ui.window` | Borderlines separating splits |
298| `ui.help` | Description box for commands |
305| `ui.help` | Description box for commands |
299−| `ui.text` | Command prompts, popup text, etc. |
306+| `ui.text` | Default text style, command prompts, popup text, etc. |
300| `ui.text.focus` | The currently selected line in the picker |
307| `ui.text.focus` | The currently selected line in the picker |
301| `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) |
308| `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) |
302| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
309| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
book/src/usage.md+2−2
@@ -59,8 +59,8 @@ Some registers have special behavior when read from and written to.
59| `#` | Selection indices (first selection is `1`, second is `2`, etc.) | This register is not writable |
59| `#` | Selection indices (first selection is `1`, second is `2`, etc.) | This register is not writable |
60| `.` | Contents of the current selections | This register is not writable |
60| `.` | Contents of the current selections | This register is not writable |
61| `%` | Name of the current file | This register is not writable |
61| `%` | Name of the current file | This register is not writable |
62−| `*` | Reads from the system clipboard | Joins and yanks to the system clipboard |
62+| `+` | Reads from the system clipboard | Joins and yanks to the system clipboard |
63−| `+` | Reads from the primary clipboard | Joins and yanks to the primary clipboard |
63+| `*` | Reads from the primary clipboard | Joins and yanks to the primary clipboard |
64
64
65When yanking multiple selections to the clipboard registers, the selections
65When yanking multiple selections to the clipboard registers, the selections
66are joined with newlines. Pasting from these registers will paste multiple
66are joined with newlines. Pasting from these registers will paste multiple
book/theme/index.hbs+18−15
@@ -1,11 +1,11 @@
1<!DOCTYPE HTML>
1<!DOCTYPE HTML>
2−<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
2+<html lang="{{ language }}" class="{{ default_theme }}" dir="{{ text_direction }}">
3 <head>
3 <head>
4 <!-- Book generated using mdBook -->
4 <!-- Book generated using mdBook -->
5 <meta charset="UTF-8">
5 <meta charset="UTF-8">
6 <title>{{ title }}</title>
6 <title>{{ title }}</title>
7 {{#if is_print }}
7 {{#if is_print }}
8− <meta name="robots" content="noindex" />
8+ <meta name="robots" content="noindex">
9 {{/if}}
9 {{/if}}
10 {{#if base_url}}
10 {{#if base_url}}
11 <base href="{{ base_url }}">
11 <base href="{{ base_url }}">
@@ -17,7 +17,7 @@
17
17
18 <meta name="description" content="{{ description }}">
18 <meta name="description" content="{{ description }}">
19 <meta name="viewport" content="width=device-width, initial-scale=1">
19 <meta name="viewport" content="width=device-width, initial-scale=1">
20− <meta name="theme-color" content="#ffffff" />
20+ <meta name="theme-color" content="#ffffff">
21
21
22 {{#if favicon_svg}}
22 {{#if favicon_svg}}
23 <link rel="icon" href="{{ path_to_root }}favicon.svg">
23 <link rel="icon" href="{{ path_to_root }}favicon.svg">
@@ -34,8 +34,6 @@
34
34
35 <!-- Fonts -->
35 <!-- Fonts -->
36 <link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
36 <link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
37− <link rel="preconnect" href="https://fonts.gstatic.com">
38− <link href="https://fonts.googleapis.com/css2?family=Inter:wght@200;400;500;700&display=swap" rel="stylesheet">
39 {{#if copy_fonts}}
37 {{#if copy_fonts}}
40 <link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
38 <link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
41 {{/if}}
39 {{/if}}
@@ -55,7 +53,7 @@
55 <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
53 <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
56 {{/if}}
54 {{/if}}
57 </head>
55 </head>
58− <body>
56+ <body class="sidebar-visible no-js">
59 <div id="body-container">
57 <div id="body-container">
60 <!-- Provide site root to javascript -->
58 <!-- Provide site root to javascript -->
61 <script>
59 <script>
@@ -85,24 +83,29 @@
85 try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
83 try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
86 if (theme === null || theme === undefined) { theme = default_theme; }
84 if (theme === null || theme === undefined) { theme = default_theme; }
87 var html = document.querySelector('html');
85 var html = document.querySelector('html');
88− html.classList.remove('no-js')
89 html.classList.remove('{{ default_theme }}')
86 html.classList.remove('{{ default_theme }}')
90 html.classList.add(theme);
87 html.classList.add(theme);
88+ var body = document.querySelector('body');
89+ body.classList.remove('no-js')
91− html.classList.add('js');
90+ body.classList.add('js');
92 </script>
91 </script>
93
92
93+ <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
94+
94 <!-- Hide / unhide sidebar before it is displayed -->
95 <!-- Hide / unhide sidebar before it is displayed -->
95 <script>
96 <script>
96− var html = document.querySelector('html');
97+ var body = document.querySelector('body');
97 var sidebar = null;
98 var sidebar = null;
99+ var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
98 if (document.body.clientWidth >= 1080) {
100 if (document.body.clientWidth >= 1080) {
99 try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
101 try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
100 sidebar = sidebar || 'visible';
102 sidebar = sidebar || 'visible';
101 } else {
103 } else {
102 sidebar = 'hidden';
104 sidebar = 'hidden';
103 }
105 }
106+ sidebar_toggle.checked = sidebar === 'visible';
104− html.classList.remove('sidebar-visible');
107+ body.classList.remove('sidebar-visible');
105− html.classList.add("sidebar-" + sidebar);
108+ body.classList.add("sidebar-" + sidebar);
106 </script>
109 </script>
107
110
108 <nav id="sidebar" class="sidebar" aria-label="Table of contents">
111 <nav id="sidebar" class="sidebar" aria-label="Table of contents">
@@ -141,9 +144,9 @@
141 <div id="menu-bar-hover-placeholder"></div>
144 <div id="menu-bar-hover-placeholder"></div>
142 <div id="menu-bar" class="menu-bar sticky">
145 <div id="menu-bar" class="menu-bar sticky">
143 <div class="left-buttons">
146 <div class="left-buttons">
144− <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
147+ <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
145 <i class="fa fa-bars"></i>
148 <i class="fa fa-bars"></i>
146− </button>
149+ </label>
147 <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
150 <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
148 <i class="fa fa-paint-brush"></i>
151 <i class="fa fa-paint-brush"></i>
149 </button>
152 </button>
@@ -220,7 +223,7 @@
220 {{/previous}}
223 {{/previous}}
221
224
222 {{#next}}
225 {{#next}}
223− <a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
226+ <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
224 <i class="fa fa-angle-right"></i>
227 <i class="fa fa-angle-right"></i>
225 </a>
228 </a>
226 {{/next}}
229 {{/next}}
@@ -238,7 +241,7 @@
238 {{/previous}}
241 {{/previous}}
239
242
240 {{#next}}
243 {{#next}}
241− <a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
244+ <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
242 <i class="fa fa-angle-right"></i>
245 <i class="fa fa-angle-right"></i>
243 </a>
246 </a>
244 {{/next}}
247 {{/next}}
contrib/Helix.appdata.xml+15
@@ -5,6 +5,7 @@
5 <project_license>MPL-2.0</project_license>
5 <project_license>MPL-2.0</project_license>
6 <name>Helix</name>
6 <name>Helix</name>
7 <summary>A post-modern text editor</summary>
7 <summary>A post-modern text editor</summary>
8+ <summary xml:lang="ar">مُحَرِّرُ نُصُوصٍ سَابِقٌ لِعَهدِه</summary>
8
9
9 <description>
10 <description>
10 <p>
11 <p>
@@ -17,6 +18,17 @@
17 <li>Smart, incremental syntax highlighting and code editing via tree-sitter</li>
18 <li>Smart, incremental syntax highlighting and code editing via tree-sitter</li>
18 </ul>
19 </ul>
19 </description>
20 </description>
21+ <description xml:lang="ar">
22+ <p>
23+ مُحَرِّرُ نُصُوصٍ يَعمَلُ فِي الطَّرَفِيَّة، مُستَلهَمٌ مِن Kakoune وَ Neovim وَمَكتُوبٌ بِلُغَةِ رَست البَرمَجِيَّة.
24+ </p>
25+ <ul>
26+ <li>تَحرِيرٌ وَضعِيٌّ شَبيهٌ بِـVim</li>
27+ <li>تَحدِيدَاتٌ لِلنَّصِ مُتَعَدِّدَة</li>
28+ <li>دَعْمٌ مُدمَجٌ لِخَوادِمِ اللُّغَات</li>
29+ <li>تَحرِيرُ التَّعلِيمَاتِ البَّرمَجِيَّةِ مَعَ تَمييزٍ لِلتَّركِيبِ النَّحُويِّ بِواسِطَةِ tree-sitter</li>
30+ </ul>
31+ </description>
20
32
21 <launchable type="desktop-id">Helix.desktop</launchable>
33 <launchable type="desktop-id">Helix.desktop</launchable>
22
34
@@ -36,6 +48,9 @@
36 <content_rating type="oars-1.1" />
48 <content_rating type="oars-1.1" />
37
49
38 <releases>
50 <releases>
51+ <release version="23.10" date="2023-10-24">
52+ <url>https://helix-editor.com/news/release-23-10-highlights/</url>
53+ </release>
39 <release version="23.05" date="2023-05-18">
54 <release version="23.05" date="2023-05-18">
40 <url>https://github.com/helix-editor/helix/releases/tag/23.05</url>
55 <url>https://github.com/helix-editor/helix/releases/tag/23.05</url>
41 </release>
56 </release>
contrib/Helix.desktop+3−1
@@ -1,6 +1,7 @@
1[Desktop Entry]
1[Desktop Entry]
2Name=Helix
2Name=Helix
3GenericName=Text Editor
3GenericName=Text Editor
4+GenericName[ar]=مُحَرِّرُ نُصُوص
4GenericName[de]=Texteditor
5GenericName[de]=Texteditor
5GenericName[fr]=Éditeur de texte
6GenericName[fr]=Éditeur de texte
6GenericName[ru]=Текстовый редактор
7GenericName[ru]=Текстовый редактор
@@ -9,7 +10,7 @@ GenericName[tr]=Metin Düzenleyici
9Comment=Edit text files
10Comment=Edit text files
10Comment[af]=Redigeer tekslêers
11Comment[af]=Redigeer tekslêers
11Comment[am]=የጽሑፍ ፋይሎች ያስተካክሉ
12Comment[am]=የጽሑፍ ፋይሎች ያስተካክሉ
12−Comment[ar]=حرّر ملفات نصية
13+Comment[ar]=مُحَرِّرُ مِلَفَّاتٍ نَصِّيَّة
13Comment[az]=Mətn fayllarını redaktə edin
14Comment[az]=Mətn fayllarını redaktə edin
14Comment[be]=Рэдагаваньне тэкставых файлаў
15Comment[be]=Рэдагаваньне тэкставых файлаў
15Comment[bg]=Редактиране на текстови файлове
16Comment[bg]=Редактиране на текстови файлове
@@ -79,6 +80,7 @@ Exec=hx %F
79Terminal=true
80Terminal=true
80Type=Application
81Type=Application
81Keywords=Text;editor;
82Keywords=Text;editor;
83+Keywords[ar]=نص;نصوص;محرر;
82Keywords[fr]=Texte;éditeur;
84Keywords[fr]=Texte;éditeur;
83Keywords[ru]=текст;текстовый редактор;
85Keywords[ru]=текст;текстовый редактор;
84Keywords[sr]=Текст;едитор;
86Keywords[sr]=Текст;едитор;
docs/releases.md+12−5
@@ -1,16 +1,23 @@
1## Checklist
1## Checklist
2
2
3Helix releases are versioned in the Calendar Versioning scheme:
3Helix releases are versioned in the Calendar Versioning scheme:
4−`YY.0M(.MICRO)`, for example, `22.05` for May of 2022. In these instructions
4+`YY.0M(.MICRO)`, for example, `22.05` for May of 2022, or in a patch release,
5−we'll use `<tag>` as a placeholder for the tag being published.
5+`22.05.1`. In these instructions we'll use `<tag>` as a placeholder for the tag
6+being published.
6
7
7* Merge the changelog PR
8* Merge the changelog PR
8* Add new `<release>` entry in `contrib/Helix.appdata.xml` with release information according to the [AppStream spec](https://www.freedesktop.org/software/appstream/docs/sect-Metadata-Releases.html)
9* Add new `<release>` entry in `contrib/Helix.appdata.xml` with release information according to the [AppStream spec](https://www.freedesktop.org/software/appstream/docs/sect-Metadata-Releases.html)
9* Tag and push
10* Tag and push
10 * `git tag -s -m "<tag>" -a <tag> && git push`
11 * `git tag -s -m "<tag>" -a <tag> && git push`
11 * Make sure to switch to master and pull first
12 * Make sure to switch to master and pull first
12−* Edit the `VERSION` file and change the date to the next planned release
13+* Edit the `Cargo.toml` file and change the date in the `version` field to the next planned release
14+ * Due to Cargo having a strict requirement on SemVer with 3 or more version
15+ numbers, a `0` is required in the micro version; however, unless we are
16+ publishing a patch release after a major release, the `.0` is dropped in
17+ the user facing version.
13− * Releases are planned to happen every two months, so `22.05` would change to `22.07`
18+ * Releases are planned to happen every two months, so `22.05.0` would change to `22.07.0`
19+ * If we are pushing a patch/bugfix release in the same month as the previous
20+ release, bump the micro version, e.g. `22.07.0` to `22.07.1`
14* Wait for the Release CI to finish
21* Wait for the Release CI to finish
15 * It will automatically turn the git tag into a GitHub release when it uploads artifacts
22 * It will automatically turn the git tag into a GitHub release when it uploads artifacts
16* Edit the new release
23* Edit the new release
@@ -57,4 +64,4 @@ versions for convenience:
57> release. For the full log, check out the git log.
64> release. For the full log, check out the git log.
58
65
59Typically, small changes like dependencies or documentation updates, refactors,
66Typically, small changes like dependencies or documentation updates, refactors,
60−or meta changes like GitHub Actions work are left out.
67+or meta changes like GitHub Actions work are left out.
flake.lock+12−35
@@ -2,23 +2,16 @@
2 "nodes": {
2 "nodes": {
3 "crane": {
3 "crane": {
4 "inputs": {
4 "inputs": {
5− "flake-compat": "flake-compat",
6− "flake-utils": [
7− "flake-utils"
8− ],
9 "nixpkgs": [
5 "nixpkgs": [
10 "nixpkgs"
6 "nixpkgs"
11− ],
12− "rust-overlay": [
13− "rust-overlay"
14 ]
7 ]
15 },
8 },
16 "locked": {
9 "locked": {
17− "lastModified": 1688772518,
10+ "lastModified": 1701025348,
18− "narHash": "sha256-ol7gZxwvgLnxNSZwFTDJJ49xVY5teaSvF7lzlo3YQfM=",
11+ "narHash": "sha256-42GHmYH+GF7VjwGSt+fVT1CQuNpGanJbNgVHTAZppUM=",
19 "owner": "ipetkov",
12 "owner": "ipetkov",
20 "repo": "crane",
13 "repo": "crane",
21− "rev": "8b08e96c9af8c6e3a2b69af5a7fa168750fcf88e",
14+ "rev": "42afaeb1a0325194a7cdb526332d2cb92fddd07b",
22 "type": "github"
15 "type": "github"
23 },
16 },
24 "original": {
17 "original": {
@@ -27,32 +20,16 @@
27 "type": "github"
20 "type": "github"
28 }
21 }
29 },
22 },
30− "flake-compat": {
31− "flake": false,
32− "locked": {
33− "lastModified": 1673956053,
34− "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
35− "owner": "edolstra",
36− "repo": "flake-compat",
37− "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
38− "type": "github"
39− },
40− "original": {
41− "owner": "edolstra",
42− "repo": "flake-compat",
43− "type": "github"
44− }
45− },
46 "flake-utils": {
23 "flake-utils": {
47 "inputs": {
24 "inputs": {
48 "systems": "systems"
25 "systems": "systems"
49 },
26 },
50 "locked": {
27 "locked": {
51− "lastModified": 1689068808,
28+ "lastModified": 1694529238,
52− "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
29+ "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
53 "owner": "numtide",
30 "owner": "numtide",
54 "repo": "flake-utils",
31 "repo": "flake-utils",
55− "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
32+ "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
56 "type": "github"
33 "type": "github"
57 },
34 },
58 "original": {
35 "original": {
@@ -63,11 +40,11 @@
63 },
40 },
64 "nixpkgs": {
41 "nixpkgs": {
65 "locked": {
42 "locked": {
66− "lastModified": 1690272529,
43+ "lastModified": 1700794826,
67− "narHash": "sha256-MakzcKXEdv/I4qJUtq/k/eG+rVmyOZLnYNC2w1mB59Y=",
44+ "narHash": "sha256-RyJTnTNKhO0yqRpDISk03I/4A67/dp96YRxc86YOPgU=",
68 "owner": "nixos",
45 "owner": "nixos",
69 "repo": "nixpkgs",
46 "repo": "nixpkgs",
70− "rev": "ef99fa5c5ed624460217c31ac4271cfb5cb2502c",
47+ "rev": "5a09cb4b393d58f9ed0d9ca1555016a8543c2ac8",
71 "type": "github"
48 "type": "github"
72 },
49 },
73 "original": {
50 "original": {
@@ -95,11 +72,11 @@
95 ]
72 ]
96 },
73 },
97 "locked": {
74 "locked": {
98− "lastModified": 1690424156,
75+ "lastModified": 1701137803,
99− "narHash": "sha256-Bpml+L280tHTQpwpC5/BJbU4HSvEzMvW8IZ4gAXimhE=",
76+ "narHash": "sha256-0LcPAdql5IhQSUXJx3Zna0dYTgdIoYO7zUrsKgiBd04=",
100 "owner": "oxalica",
77 "owner": "oxalica",
101 "repo": "rust-overlay",
78 "repo": "rust-overlay",
102− "rev": "f335a0213504c7e6481c359dc1009be9cf34432c",
79+ "rev": "9dd940c967502f844eacea52a61e9596268d4f70",
103 "type": "github"
80 "type": "github"
104 },
81 },
105 "original": {
82 "original": {
flake.nix+12−14
@@ -13,8 +13,6 @@
13 };
13 };
14 crane = {
14 crane = {
15 url = "github:ipetkov/crane";
15 url = "github:ipetkov/crane";
16− inputs.rust-overlay.follows = "rust-overlay";
17− inputs.flake-utils.follows = "flake-utils";
18 inputs.nixpkgs.follows = "nixpkgs";
16 inputs.nixpkgs.follows = "nixpkgs";
19 };
17 };
20 };
18 };
@@ -123,18 +121,18 @@
123 rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
121 rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
124 craneLibMSRV = (crane.mkLib pkgs).overrideToolchain rustToolchain;
122 craneLibMSRV = (crane.mkLib pkgs).overrideToolchain rustToolchain;
125 craneLibStable = (crane.mkLib pkgs).overrideToolchain pkgs.pkgsBuildHost.rust-bin.stable.latest.default;
123 craneLibStable = (crane.mkLib pkgs).overrideToolchain pkgs.pkgsBuildHost.rust-bin.stable.latest.default;
126− commonArgs =
124+ commonArgs = {
127− {
125+ inherit stdenv;
128− inherit stdenv;
126+ inherit (craneLibMSRV.crateNameFromCargoToml {cargoToml = ./helix-term/Cargo.toml;}) pname;
127+ inherit (craneLibMSRV.crateNameFromCargoToml {cargoToml = ./Cargo.toml;}) version;
129− src = filteredSource;
128+ src = filteredSource;
130− # disable fetching and building of tree-sitter grammars in the helix-term build.rs
129+ # disable fetching and building of tree-sitter grammars in the helix-term build.rs
131− HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1";
130+ HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1";
132− buildInputs = [stdenv.cc.cc.lib];
131+ buildInputs = [stdenv.cc.cc.lib];
133− # disable tests
132+ # disable tests
134− doCheck = false;
133+ doCheck = false;
135− meta.mainProgram = "hx";
134+ meta.mainProgram = "hx";
136− }
135+ };
137− // craneLibMSRV.crateNameFromCargoToml {cargoToml = ./helix-term/Cargo.toml;};
138 cargoArtifacts = craneLibMSRV.buildDepsOnly commonArgs;
136 cargoArtifacts = craneLibMSRV.buildDepsOnly commonArgs;
139 in {
137 in {
140 packages = {
138 packages = {
grammars.nix+24−21
@@ -5,6 +5,7 @@
5 runCommand,
5 runCommand,
6 yj,
6 yj,
7 includeGrammarIf ? _: true,
7 includeGrammarIf ? _: true,
8+ grammarOverlays ? [],
8 ...
9 ...
9}: let
10}: let
10 # HACK: nix < 2.6 has a bug in the toml parser, so we convert to JSON
11 # HACK: nix < 2.6 has a bug in the toml parser, so we convert to JSON
@@ -48,22 +49,22 @@
48 then sourceGitHub
49 then sourceGitHub
49 else sourceGit;
50 else sourceGit;
50 in
51 in
51− stdenv.mkDerivation rec {
52+ stdenv.mkDerivation {
52 # see https://github.com/NixOS/nixpkgs/blob/fbdd1a7c0bc29af5325e0d7dd70e804a972eb465/pkgs/development/tools/parsing/tree-sitter/grammar.nix
53 # see https://github.com/NixOS/nixpkgs/blob/fbdd1a7c0bc29af5325e0d7dd70e804a972eb465/pkgs/development/tools/parsing/tree-sitter/grammar.nix
53
54
54 pname = "helix-tree-sitter-${grammar.name}";
55 pname = "helix-tree-sitter-${grammar.name}";
55 version = grammar.source.rev;
56 version = grammar.source.rev;
56
57
57− src =
58+ src = source;
58− if builtins.hasAttr "subpath" grammar.source
59+ sourceRoot = if builtins.hasAttr "subpath" grammar.source then
59− then "${source}/${grammar.source.subpath}"
60+ "source/${grammar.source.subpath}"
61+ else
60− else source;
62+ "source";
61
63
62− dontUnpack = true;
63 dontConfigure = true;
64 dontConfigure = true;
64
65
65 FLAGS = [
66 FLAGS = [
66− "-I${src}/src"
67+ "-Isrc"
67 "-g"
68 "-g"
68 "-O3"
69 "-O3"
69 "-fPIC"
70 "-fPIC"
@@ -76,13 +77,13 @@
76 buildPhase = ''
77 buildPhase = ''
77 runHook preBuild
78 runHook preBuild
78
79
79− if [[ -e "$src/src/scanner.cc" ]]; then
80+ if [[ -e src/scanner.cc ]]; then
80− $CXX -c "$src/src/scanner.cc" -o scanner.o $FLAGS
81+ $CXX -c src/scanner.cc -o scanner.o $FLAGS
81− elif [[ -e "$src/src/scanner.c" ]]; then
82+ elif [[ -e src/scanner.c ]]; then
82− $CC -c "$src/src/scanner.c" -o scanner.o $FLAGS
83+ $CC -c src/scanner.c -o scanner.o $FLAGS
83 fi
84 fi
84
85
85− $CC -c "$src/src/parser.c" -o parser.o $FLAGS
86+ $CC -c src/parser.c -o parser.o $FLAGS
86 $CXX -shared -o $NAME.so *.o
87 $CXX -shared -o $NAME.so *.o
87
88
88 ls -al
89 ls -al
@@ -105,15 +106,17 @@
105 '';
106 '';
106 };
107 };
107 grammarsToBuild = builtins.filter includeGrammarIf gitGrammars;
108 grammarsToBuild = builtins.filter includeGrammarIf gitGrammars;
108− builtGrammars =
109− builtins.map (grammar: {
109+ builtGrammars = builtins.map (grammar: {
110− inherit (grammar) name;
110+ inherit (grammar) name;
111− artifact = buildGrammar grammar;
111+ value = buildGrammar grammar;
112− })
113− grammarsToBuild;
112+ }) grammarsToBuild;
113+ extensibleGrammars =
114+ lib.makeExtensible (self: builtins.listToAttrs builtGrammars);
115+ overlayedGrammars = lib.pipe extensibleGrammars
116+ (builtins.map (overlay: grammar: grammar.extend overlay) grammarOverlays);
114− grammarLinks =
117+ grammarLinks = lib.mapAttrsToList
115− builtins.map (grammar: "ln -s ${grammar.artifact}/${grammar.name}.so $out/${grammar.name}.so")
118+ (name: artifact: "ln -s ${artifact}/${name}.so $out/${name}.so")
116− builtGrammars;
119+ (lib.filterAttrs (n: v: lib.isDerivation v) overlayedGrammars);
117in
120in
118 runCommand "consolidated-helix-grammars" {} ''
121 runCommand "consolidated-helix-grammars" {} ''
119 mkdir -p $out
122 mkdir -p $out
helix-core/Cargo.toml+14−13
@@ -1,23 +1,24 @@
1[package]
1[package]
2name = "helix-core"
2name = "helix-core"
3−version = "0.6.0"
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5−edition = "2021"
6−license = "MPL-2.0"
7description = "Helix editor core editing primitives"
3description = "Helix editor core editing primitives"
8−categories = ["editor"]
9−repository = "https://github.com/helix-editor/helix"
10−homepage = "https://helix-editor.com"
11include = ["src/**/*", "README.md"]
4include = ["src/**/*", "README.md"]
5+version.workspace = true
6+authors.workspace = true
7+edition.workspace = true
8+license.workspace = true
9+rust-version.workspace = true
10+categories.workspace = true
11+repository.workspace = true
12+homepage.workspace = true
12
13
13[features]
14[features]
14unicode-lines = ["ropey/unicode_lines"]
15unicode-lines = ["ropey/unicode_lines"]
15integration = []
16integration = []
16
17
17[dependencies]
18[dependencies]
18−helix-loader = { version = "0.6", path = "../helix-loader" }
19+helix-loader = { path = "../helix-loader" }
19
20
20−ropey = { version = "1.6.0", default-features = false, features = ["simd"] }
21+ropey = { version = "1.6.1", default-features = false, features = ["simd"] }
21smallvec = "1.11"
22smallvec = "1.11"
22smartstring = "1.0.1"
23smartstring = "1.0.1"
23unicode-segmentation = "1.10"
24unicode-segmentation = "1.10"
@@ -26,12 +27,12 @@ unicode-general-category = "0.6"
26# slab = "0.4.2"
27# slab = "0.4.2"
27slotmap = "1.0"
28slotmap = "1.0"
28tree-sitter.workspace = true
29tree-sitter.workspace = true
29−once_cell = "1.18"
30+once_cell = "1.19"
30arc-swap = "1"
31arc-swap = "1"
31regex = "1"
32regex = "1"
32bitflags = "2.4"
33bitflags = "2.4"
33−ahash = "0.8.3"
34+ahash = "0.8.6"
34−hashbrown = { version = "0.14.0", features = ["raw"] }
35+hashbrown = { version = "0.14.3", features = ["raw"] }
35dunce = "1.0"
36dunce = "1.0"
36
37
37log = "0.4"
38log = "0.4"
@@ -53,4 +54,4 @@ parking_lot = "0.12"
53
54
54[dev-dependencies]
55[dev-dependencies]
55quickcheck = { version = "1", default-features = false }
56quickcheck = { version = "1", default-features = false }
56−indoc = "2.0.3"
57+indoc = "2.0.4"
helix-core/src/diagnostic.rs+4
@@ -39,6 +39,10 @@ pub enum DiagnosticTag {
39#[derive(Debug, Clone)]
39#[derive(Debug, Clone)]
40pub struct Diagnostic {
40pub struct Diagnostic {
41 pub range: Range,
41 pub range: Range,
42+ // whether this diagnostic ends at the end of(or inside) a word
43+ pub ends_at_word: bool,
44+ pub starts_at_word: bool,
45+ pub zero_width: bool,
42 pub line: usize,
46 pub line: usize,
43 pub message: String,
47 pub message: String,
44 pub severity: Option<Severity>,
48 pub severity: Option<Severity>,
helix-core/src/indent.rs+316−103
@@ -4,10 +4,11 @@ use tree_sitter::{Query, QueryCursor, QueryPredicateArg};
4
4
5use crate::{
5use crate::{
6 chars::{char_is_line_ending, char_is_whitespace},
6 chars::{char_is_line_ending, char_is_whitespace},
7+ find_first_non_whitespace_char,
7 graphemes::{grapheme_width, tab_width_at},
8 graphemes::{grapheme_width, tab_width_at},
8− syntax::{LanguageConfiguration, RopeProvider, Syntax},
9+ syntax::{IndentationHeuristic, LanguageConfiguration, RopeProvider, Syntax},
9 tree_sitter::Node,
10 tree_sitter::Node,
10− Rope, RopeGraphemes, RopeSlice,
11+ Position, Rope, RopeGraphemes, RopeSlice,
11};
12};
12
13
13/// Enum representing indentation style.
14/// Enum representing indentation style.
@@ -21,7 +22,7 @@ pub enum IndentStyle {
21
22
22// 16 spaces
23// 16 spaces
23const INDENTS: &str = " ";
24const INDENTS: &str = " ";
24−const MAX_INDENT: u8 = 16;
25+pub const MAX_INDENT: u8 = 16;
25
26
26impl IndentStyle {
27impl IndentStyle {
27 /// Creates an `IndentStyle` from an indentation string.
28 /// Creates an `IndentStyle` from an indentation string.
@@ -196,6 +197,56 @@ pub fn indent_level_for_line(line: RopeSlice, tab_width: usize, indent_width: us
196 len / indent_width
197 len / indent_width
197}
198}
198
199
200+/// Create a string of tabs & spaces that has the same visual width as the given RopeSlice (independent of the tab width).
201+fn whitespace_with_same_width(text: RopeSlice) -> String {
202+ let mut s = String::new();
203+ for grapheme in RopeGraphemes::new(text) {
204+ if grapheme == "\t" {
205+ s.push('\t');
206+ } else {
207+ s.extend(std::iter::repeat(' ').take(grapheme_width(&Cow::from(grapheme))));
208+ }
209+ }
210+ s
211+}
212+
213+fn add_indent_level(
214+ mut base_indent: String,
215+ added_indent_level: isize,
216+ indent_style: &IndentStyle,
217+ tab_width: usize,
218+) -> String {
219+ if added_indent_level >= 0 {
220+ // Adding a non-negative indent is easy, we can simply append the indent string
221+ base_indent.push_str(&indent_style.as_str().repeat(added_indent_level as usize));
222+ base_indent
223+ } else {
224+ // In this case, we want to return a prefix of `base_indent`.
225+ // Since the width of a tab depends on its offset, we cannot simply iterate over
226+ // the chars of `base_indent` in reverse until we have the desired indent reduction,
227+ // instead we iterate over them twice in forward direction.
228+ let base_indent_rope = RopeSlice::from(base_indent.as_str());
229+ #[allow(deprecated)]
230+ let base_indent_width =
231+ crate::visual_coords_at_pos(base_indent_rope, base_indent_rope.len_chars(), tab_width)
232+ .col;
233+ let target_indent_width = base_indent_width
234+ .saturating_sub((-added_indent_level) as usize * indent_style.indent_width(tab_width));
235+ #[allow(deprecated)]
236+ let char_end_idx = crate::pos_at_visual_coords(
237+ base_indent_rope,
238+ Position {
239+ row: 0,
240+ col: target_indent_width,
241+ },
242+ tab_width,
243+ );
244+ let byte_end_idx = base_indent_rope.char_to_byte(char_end_idx);
245+ base_indent.truncate(byte_end_idx);
246+ base_indent
247+ }
248+}
249+
199/// Computes for node and all ancestors whether they are the first node on their line.
250/// Computes for node and all ancestors whether they are the first node on their line.
200/// The first entry in the return value represents the root node, the last one the node itself
251/// The first entry in the return value represents the root node, the last one the node itself
201fn get_first_in_line(mut node: Node, new_line_byte_pos: Option<usize>) -> Vec<bool> {
252fn get_first_in_line(mut node: Node, new_line_byte_pos: Option<usize>) -> Vec<bool> {
@@ -241,21 +292,21 @@ fn get_first_in_line(mut node: Node, new_line_byte_pos: Option<usize>) -> Vec<bo
241/// - max(0, indent - outdent) tabs, if tabs are used for indentation
292/// - max(0, indent - outdent) tabs, if tabs are used for indentation
242/// - max(0, indent - outdent)*indent_width spaces, if spaces are used for indentation
293/// - max(0, indent - outdent)*indent_width spaces, if spaces are used for indentation
243#[derive(Default, Debug, PartialEq, Eq, Clone)]
294#[derive(Default, Debug, PartialEq, Eq, Clone)]
244−pub struct Indentation {
295+pub struct Indentation<'a> {
245 indent: usize,
296 indent: usize,
246 indent_always: usize,
297 indent_always: usize,
247 outdent: usize,
298 outdent: usize,
248 outdent_always: usize,
299 outdent_always: usize,
249 /// The alignment, as a string containing only tabs & spaces. Storing this as a string instead of e.g.
300 /// The alignment, as a string containing only tabs & spaces. Storing this as a string instead of e.g.
250 /// the (visual) width ensures that the alignment is preserved even if the tab width changes.
301 /// the (visual) width ensures that the alignment is preserved even if the tab width changes.
251− align: Option<String>,
302+ align: Option<RopeSlice<'a>>,
252}
303}
253
304
254−impl Indentation {
305+impl<'a> Indentation<'a> {
255 /// Add some other [Indentation] to this.
306 /// Add some other [Indentation] to this.
256 /// The added indent should be the total added indent from one line.
307 /// The added indent should be the total added indent from one line.
257 /// Indent should always be added starting from the bottom (or equivalently, the innermost tree-sitter node).
308 /// Indent should always be added starting from the bottom (or equivalently, the innermost tree-sitter node).
258− fn add_line(&mut self, added: Indentation) {
309+ fn add_line(&mut self, added: Indentation<'a>) {
259 // Align overrides the indent from outer scopes.
310 // Align overrides the indent from outer scopes.
260 if self.align.is_some() {
311 if self.align.is_some() {
261 return;
312 return;
@@ -271,8 +322,10 @@ impl Indentation {
271 }
322 }
272
323
273 /// Add an indent capture to this indent.
324 /// Add an indent capture to this indent.
274− /// All the captures that are added in this way should be on the same line.
325+ /// Only captures that apply to the same line should be added together in this way (otherwise use `add_line`)
326+ /// and the captures should be added starting from the innermost tree-sitter node (currently this only matters
327+ /// if multiple `@align` patterns occur on the same line).
275− fn add_capture(&mut self, added: IndentCaptureType) {
328+ fn add_capture(&mut self, added: IndentCaptureType<'a>) {
276 match added {
329 match added {
277 IndentCaptureType::Indent => {
330 IndentCaptureType::Indent => {
278 if self.indent_always == 0 {
331 if self.indent_always == 0 {
@@ -295,47 +348,68 @@ impl Indentation {
295 self.outdent = 0;
348 self.outdent = 0;
296 }
349 }
297 IndentCaptureType::Align(align) => {
350 IndentCaptureType::Align(align) => {
351+ if self.align.is_none() {
298− self.align = Some(align);
352+ self.align = Some(align);
353+ }
299 }
354 }
300 }
355 }
301 }
356 }
302− fn into_string(self, indent_style: &IndentStyle) -> String {
357+ fn net_indent(&self) -> isize {
303− let indent = self.indent_always + self.indent;
358+ (self.indent + self.indent_always) as isize
304− let outdent = self.outdent_always + self.outdent;
359+ - ((self.outdent + self.outdent_always) as isize)
305−
360+ }
306− let indent_level = if indent >= outdent {
361+ /// Convert `self` into a string, taking into account the computed and actual indentation of some other line.
307− indent - outdent
362+ fn relative_indent(
308− } else {
363+ &self,
309− log::warn!("Encountered more outdent than indent nodes while calculating indentation: {} outdent, {} indent", self.outdent, self.indent);
364+ other_computed_indent: &Self,
310− 0
365+ other_leading_whitespace: RopeSlice,
311− };
366+ indent_style: &IndentStyle,
312− let mut indent_string = if let Some(align) = self.align {
367+ tab_width: usize,
313− align
368+ ) -> Option<String> {
369+ if self.align == other_computed_indent.align {
370+ // If self and baseline are either not aligned to anything or both aligned the same way,
371+ // we can simply take `other_leading_whitespace` and add some indent / outdent to it (in the second
372+ // case, the alignment should already be accounted for in `other_leading_whitespace`).
373+ let indent_diff = self.net_indent() - other_computed_indent.net_indent();
374+ Some(add_indent_level(
375+ String::from(other_leading_whitespace),
376+ indent_diff,
377+ indent_style,
378+ tab_width,
379+ ))
314 } else {
380 } else {
315− String::new()
381+ // If the alignment of both lines is different, we cannot compare their indentation in any meaningful way
316− };
382+ None
317− indent_string.push_str(&indent_style.as_str().repeat(indent_level));
383+ }
318− indent_string
384+ }
385+ pub fn to_string(&self, indent_style: &IndentStyle, tab_width: usize) -> String {
386+ add_indent_level(
387+ self.align
388+ .map_or_else(String::new, whitespace_with_same_width),
389+ self.net_indent(),
390+ indent_style,
391+ tab_width,
392+ )
319 }
393 }
320}
394}
321
395
322/// An indent definition which corresponds to a capture from the indent query
396/// An indent definition which corresponds to a capture from the indent query
323#[derive(Debug)]
397#[derive(Debug)]
324−struct IndentCapture {
398+struct IndentCapture<'a> {
325− capture_type: IndentCaptureType,
399+ capture_type: IndentCaptureType<'a>,
326 scope: IndentScope,
400 scope: IndentScope,
327}
401}
328#[derive(Debug, Clone, PartialEq)]
402#[derive(Debug, Clone, PartialEq)]
329−enum IndentCaptureType {
403+enum IndentCaptureType<'a> {
330 Indent,
404 Indent,
331 IndentAlways,
405 IndentAlways,
332 Outdent,
406 Outdent,
333 OutdentAlways,
407 OutdentAlways,
334 /// Alignment given as a string of whitespace
408 /// Alignment given as a string of whitespace
335− Align(String),
409+ Align(RopeSlice<'a>),
336}
410}
337
411
338−impl IndentCaptureType {
412+impl<'a> IndentCaptureType<'a> {
339 fn default_scope(&self) -> IndentScope {
413 fn default_scope(&self) -> IndentScope {
340 match self {
414 match self {
341 IndentCaptureType::Indent | IndentCaptureType::IndentAlways => IndentScope::Tail,
415 IndentCaptureType::Indent | IndentCaptureType::IndentAlways => IndentScope::Tail,
@@ -367,8 +441,8 @@ enum ExtendCapture {
367/// each node (identified by its ID) the relevant captures (already filtered
441/// each node (identified by its ID) the relevant captures (already filtered
368/// by predicates).
442/// by predicates).
369#[derive(Debug)]
443#[derive(Debug)]
370−struct IndentQueryResult {
444+struct IndentQueryResult<'a> {
371− indent_captures: HashMap<usize, Vec<IndentCapture>>,
445+ indent_captures: HashMap<usize, Vec<IndentCapture<'a>>>,
372 extend_captures: HashMap<usize, Vec<ExtendCapture>>,
446 extend_captures: HashMap<usize, Vec<ExtendCapture>>,
373}
447}
374
448
@@ -389,14 +463,14 @@ fn get_node_end_line(node: Node, new_line_byte_pos: Option<usize>) -> usize {
389 node_line
463 node_line
390}
464}
391
465
392−fn query_indents(
466+fn query_indents<'a>(
393 query: &Query,
467 query: &Query,
394 syntax: &Syntax,
468 syntax: &Syntax,
395 cursor: &mut QueryCursor,
469 cursor: &mut QueryCursor,
396− text: RopeSlice,
470+ text: RopeSlice<'a>,
397 range: std::ops::Range<usize>,
471 range: std::ops::Range<usize>,
398 new_line_byte_pos: Option<usize>,
472 new_line_byte_pos: Option<usize>,
399−) -> IndentQueryResult {
473+) -> IndentQueryResult<'a> {
400 let mut indent_captures: HashMap<usize, Vec<IndentCapture>> = HashMap::new();
474 let mut indent_captures: HashMap<usize, Vec<IndentCapture>> = HashMap::new();
401 let mut extend_captures: HashMap<usize, Vec<ExtendCapture>> = HashMap::new();
475 let mut extend_captures: HashMap<usize, Vec<ExtendCapture>> = HashMap::new();
402 cursor.set_byte_range(range);
476 cursor.set_byte_range(range);
@@ -484,7 +558,7 @@ fn query_indents(
484 "outdent" => IndentCaptureType::Outdent,
558 "outdent" => IndentCaptureType::Outdent,
485 "outdent.always" => IndentCaptureType::OutdentAlways,
559 "outdent.always" => IndentCaptureType::OutdentAlways,
486 // The alignment will be updated to the correct value at the end, when the anchor is known.
560 // The alignment will be updated to the correct value at the end, when the anchor is known.
487− "align" => IndentCaptureType::Align(String::from("")),
561+ "align" => IndentCaptureType::Align(RopeSlice::from("")),
488 "anchor" => {
562 "anchor" => {
489 if anchor.is_some() {
563 if anchor.is_some() {
490 log::error!("Invalid indent query: Encountered more than one @anchor in the same match.")
564 log::error!("Invalid indent query: Encountered more than one @anchor in the same match.")
@@ -556,22 +630,10 @@ fn query_indents(
556 }
630 }
557 Some(anchor) => anchor,
631 Some(anchor) => anchor,
558 };
632 };
559− // Create a string of tabs & spaces that should have the same width
633+ capture.capture_type = IndentCaptureType::Align(
560− // as the string that precedes the anchor (independent of the tab width).
561− let mut align = String::new();
562− for grapheme in RopeGraphemes::new(
563 text.line(anchor.start_position().row)
634 text.line(anchor.start_position().row)
564 .byte_slice(0..anchor.start_position().column),
635 .byte_slice(0..anchor.start_position().column),
565− ) {
636+ );
566− if grapheme == "\t" {
567− align.push('\t');
568− } else {
569− align.extend(
570− std::iter::repeat(' ').take(grapheme_width(&Cow::from(grapheme))),
571− );
572− }
573− }
574− capture.capture_type = IndentCaptureType::Align(align);
575 }
637 }
576 indent_captures
638 indent_captures
577 .entry(node_id)
639 .entry(node_id)
@@ -657,56 +719,20 @@ fn extend_nodes<'a>(
657 }
719 }
658}
720}
659
721
660−/// Use the syntax tree to determine the indentation for a given position.
722+/// Prepare an indent query by computing:
661−/// This can be used in 2 ways:
723+/// - The node from which to start the query (this is non-trivial due to `@extend` captures)
662−///
724+/// - The indent captures for all relevant nodes.
663−/// - To get the correct indentation for an existing line (new_line=false), not necessarily equal to the current indentation.
664−/// - In this case, pos should be inside the first tree-sitter node on that line.
665−/// In most cases, this can just be the first non-whitespace on that line.
666−/// - To get the indentation for a new line (new_line=true). This behaves like the first usecase if the part of the current line
667−/// after pos were moved to a new line.
668−///
669−/// The indentation is determined by traversing all the tree-sitter nodes containing the position.
670−/// Each of these nodes produces some [Indentation] for:
671−///
672−/// - The line of the (beginning of the) node. This is defined by the scope `all` if this is the first node on its line.
673−/// - The line after the node. This is defined by:
674−/// - The scope `tail`.
675−/// - The scope `all` if this node is not the first node on its line.
676−/// Intuitively, `all` applies to everything contained in this node while `tail` applies to everything except for the first line of the node.
677−/// The indents from different nodes for the same line are then combined.
678−/// The result [Indentation] is simply the sum of the [Indentation] for all lines.
679−///
680−/// Specifying which line exactly an [Indentation] applies to is important because indents on the same line combine differently than indents on different lines:
681−/// ```ignore
682−/// some_function(|| {
683−/// // Both the function parameters as well as the contained block should be indented.
684−/// // Because they are on the same line, this only yields one indent level
685−/// });
686−/// ```
687−///
688−/// ```ignore
689−/// some_function(
690−/// param1,
691−/// || {
692−/// // Here we get 2 indent levels because the 'parameters' and the 'block' node begin on different lines
693−/// },
694−/// );
695−/// ```
696#[allow(clippy::too_many_arguments)]
725#[allow(clippy::too_many_arguments)]
697−pub fn treesitter_indent_for_pos(
726+fn init_indent_query<'a, 'b>(
698 query: &Query,
727 query: &Query,
699− syntax: &Syntax,
728+ syntax: &'a Syntax,
700− indent_style: &IndentStyle,
729+ text: RopeSlice<'b>,
701 tab_width: usize,
730 tab_width: usize,
702 indent_width: usize,
731 indent_width: usize,
703− text: RopeSlice,
704 line: usize,
732 line: usize,
705− pos: usize,
733+ byte_pos: usize,
706− new_line: bool,
734+ new_line_byte_pos: Option<usize>,
707−) -> Option<String> {
735+) -> Option<(Node<'a>, HashMap<usize, Vec<IndentCapture<'b>>>)> {
708− let byte_pos = text.char_to_byte(pos);
709− let new_line_byte_pos = new_line.then_some(byte_pos);
710 // The innermost tree-sitter node which is considered for the indent
736 // The innermost tree-sitter node which is considered for the indent
711 // computation. It may change if some predeceding node is extended
737 // computation. It may change if some predeceding node is extended
712 let mut node = syntax
738 let mut node = syntax
@@ -750,7 +776,6 @@ pub fn treesitter_indent_for_pos(
750 (query_result, deepest_preceding)
776 (query_result, deepest_preceding)
751 })
777 })
752 };
778 };
753− let mut indent_captures = query_result.indent_captures;
754 let extend_captures = query_result.extend_captures;
779 let extend_captures = query_result.extend_captures;
755
780
756 // Check for extend captures, potentially changing the node that the indent calculation starts with
781 // Check for extend captures, potentially changing the node that the indent calculation starts with
@@ -765,6 +790,68 @@ pub fn treesitter_indent_for_pos(
765 indent_width,
790 indent_width,
766 );
791 );
767 }
792 }
793+ Some((node, query_result.indent_captures))
794+}
795+
796+/// Use the syntax tree to determine the indentation for a given position.
797+/// This can be used in 2 ways:
798+///
799+/// - To get the correct indentation for an existing line (new_line=false), not necessarily equal to the current indentation.
800+/// - In this case, pos should be inside the first tree-sitter node on that line.
801+/// In most cases, this can just be the first non-whitespace on that line.
802+/// - To get the indentation for a new line (new_line=true). This behaves like the first usecase if the part of the current line
803+/// after pos were moved to a new line.
804+///
805+/// The indentation is determined by traversing all the tree-sitter nodes containing the position.
806+/// Each of these nodes produces some [Indentation] for:
807+///
808+/// - The line of the (beginning of the) node. This is defined by the scope `all` if this is the first node on its line.
809+/// - The line after the node. This is defined by:
810+/// - The scope `tail`.
811+/// - The scope `all` if this node is not the first node on its line.
812+/// Intuitively, `all` applies to everything contained in this node while `tail` applies to everything except for the first line of the node.
813+/// The indents from different nodes for the same line are then combined.
814+/// The result [Indentation] is simply the sum of the [Indentation] for all lines.
815+///
816+/// Specifying which line exactly an [Indentation] applies to is important because indents on the same line combine differently than indents on different lines:
817+/// ```ignore
818+/// some_function(|| {
819+/// // Both the function parameters as well as the contained block should be indented.
820+/// // Because they are on the same line, this only yields one indent level
821+/// });
822+/// ```
823+///
824+/// ```ignore
825+/// some_function(
826+/// param1,
827+/// || {
828+/// // Here we get 2 indent levels because the 'parameters' and the 'block' node begin on different lines
829+/// },
830+/// );
831+/// ```
832+#[allow(clippy::too_many_arguments)]
833+pub fn treesitter_indent_for_pos<'a>(
834+ query: &Query,
835+ syntax: &Syntax,
836+ tab_width: usize,
837+ indent_width: usize,
838+ text: RopeSlice<'a>,
839+ line: usize,
840+ pos: usize,
841+ new_line: bool,
842+) -> Option<Indentation<'a>> {
843+ let byte_pos = text.char_to_byte(pos);
844+ let new_line_byte_pos = new_line.then_some(byte_pos);
845+ let (mut node, mut indent_captures) = init_indent_query(
846+ query,
847+ syntax,
848+ text,
849+ tab_width,
850+ indent_width,
851+ line,
852+ byte_pos,
853+ new_line_byte_pos,
854+ )?;
768 let mut first_in_line = get_first_in_line(node, new_line.then_some(byte_pos));
855 let mut first_in_line = get_first_in_line(node, new_line.then_some(byte_pos));
769
856
770 let mut result = Indentation::default();
857 let mut result = Indentation::default();
@@ -832,7 +919,7 @@ pub fn treesitter_indent_for_pos(
832 break;
919 break;
833 }
920 }
834 }
921 }
835− Some(result.into_string(indent_style))
922+ Some(result)
836}
923}
837
924
838/// Returns the indentation for a new line.
925/// Returns the indentation for a new line.
@@ -841,6 +928,7 @@ pub fn treesitter_indent_for_pos(
841pub fn indent_for_newline(
928pub fn indent_for_newline(
842 language_config: Option<&LanguageConfiguration>,
929 language_config: Option<&LanguageConfiguration>,
843 syntax: Option<&Syntax>,
930 syntax: Option<&Syntax>,
931+ indent_heuristic: &IndentationHeuristic,
844 indent_style: &IndentStyle,
932 indent_style: &IndentStyle,
845 tab_width: usize,
933 tab_width: usize,
846 text: RopeSlice,
934 text: RopeSlice,
@@ -849,14 +937,18 @@ pub fn indent_for_newline(
849 current_line: usize,
937 current_line: usize,
850) -> String {
938) -> String {
851 let indent_width = indent_style.indent_width(tab_width);
939 let indent_width = indent_style.indent_width(tab_width);
940+ if let (
941+ IndentationHeuristic::TreeSitter | IndentationHeuristic::Hybrid,
942+ Some(query),
852− if let (Some(query), Some(syntax)) = (
943+ Some(syntax),
944+ ) = (
945+ indent_heuristic,
853 language_config.and_then(|config| config.indent_query()),
946 language_config.and_then(|config| config.indent_query()),
854 syntax,
947 syntax,
855 ) {
948 ) {
856 if let Some(indent) = treesitter_indent_for_pos(
949 if let Some(indent) = treesitter_indent_for_pos(
857 query,
950 query,
858 syntax,
951 syntax,
859− indent_style,
860 tab_width,
952 tab_width,
861 indent_width,
953 indent_width,
862 text,
954 text,
@@ -864,9 +956,57 @@ pub fn indent_for_newline(
864 line_before_end_pos,
956 line_before_end_pos,
865 true,
957 true,
866 ) {
958 ) {
959+ if *indent_heuristic == IndentationHeuristic::Hybrid {
960+ // We want to compute the indentation not only based on the
961+ // syntax tree but also on the actual indentation of a previous
962+ // line. This makes indentation computation more resilient to
963+ // incomplete queries, incomplete source code & differing indentation
964+ // styles for the same language.
965+ // However, using the indent of a previous line as a baseline may not
966+ // make sense, e.g. if it has a different alignment than the new line.
967+ // In order to prevent edge cases with long running times, we only try
968+ // a constant number of (non-empty) lines.
969+ const MAX_ATTEMPTS: usize = 4;
970+ let mut num_attempts = 0;
971+ for line_idx in (0..=line_before).rev() {
972+ let line = text.line(line_idx);
973+ let first_non_whitespace_char = match find_first_non_whitespace_char(line) {
974+ Some(i) => i,
975+ None => {
976+ continue;
977+ }
978+ };
979+ if let Some(indent) = (|| {
980+ let computed_indent = treesitter_indent_for_pos(
981+ query,
982+ syntax,
983+ tab_width,
984+ indent_width,
985+ text,
986+ line_idx,
987+ text.line_to_char(line_idx) + first_non_whitespace_char,
988+ false,
989+ )?;
990+ let leading_whitespace = line.slice(0..first_non_whitespace_char);
991+ indent.relative_indent(
992+ &computed_indent,
993+ leading_whitespace,
994+ indent_style,
995+ tab_width,
996+ )
997+ })() {
867− return indent;
998+ return indent;
999+ }
1000+ num_attempts += 1;
1001+ if num_attempts == MAX_ATTEMPTS {
1002+ break;
1003+ }
1004+ }
1005+ }
1006+ return indent.to_string(indent_style, tab_width);
868 };
1007 };
869 }
1008 }
1009+ // Fallback in case we either don't have indent queries or they failed for some reason
870 let indent_level = indent_level_for_line(text.line(current_line), tab_width, indent_width);
1010 let indent_level = indent_level_for_line(text.line(current_line), tab_width, indent_width);
871 indent_style.as_str().repeat(indent_level)
1011 indent_style.as_str().repeat(indent_level)
872}
1012}
@@ -958,10 +1098,13 @@ mod test {
958 ..Default::default()
1098 ..Default::default()
959 };
1099 };
960
1100
1101+ fn add_capture<'a>(
961− let add_capture = |mut indent: Indentation, capture| {
1102+ mut indent: Indentation<'a>,
1103+ capture: IndentCaptureType<'a>,
1104+ ) -> Indentation<'a> {
962 indent.add_capture(capture);
1105 indent.add_capture(capture);
963 indent
1106 indent
964− };
1107+ }
965
1108
966 // adding an indent to no indent makes an indent
1109 // adding an indent to no indent makes an indent
967 assert_eq!(
1110 assert_eq!(
@@ -1056,4 +1199,74 @@ mod test {
1056 )
1199 )
1057 );
1200 );
1058 }
1201 }
1202+
1203+ #[test]
1204+ fn test_relative_indent() {
1205+ let indent_style = IndentStyle::Spaces(4);
1206+ let tab_width: usize = 4;
1207+ let no_align = [
1208+ Indentation::default(),
1209+ Indentation {
1210+ indent: 1,
1211+ ..Default::default()
1212+ },
1213+ Indentation {
1214+ indent: 5,
1215+ outdent: 1,
1216+ ..Default::default()
1217+ },
1218+ ];
1219+ let align = no_align.clone().map(|indent| Indentation {
1220+ align: Some(RopeSlice::from("12345")),
1221+ ..indent
1222+ });
1223+ let different_align = Indentation {
1224+ align: Some(RopeSlice::from("123456")),
1225+ ..Default::default()
1226+ };
1227+
1228+ // Check that relative and absolute indentation computation are the same when the line we compare to is
1229+ // indented as we expect.
1230+ let check_consistency = |indent: &Indentation, other: &Indentation| {
1231+ assert_eq!(
1232+ indent.relative_indent(
1233+ other,
1234+ RopeSlice::from(other.to_string(&indent_style, tab_width).as_str()),
1235+ &indent_style,
1236+ tab_width
1237+ ),
1238+ Some(indent.to_string(&indent_style, tab_width))
1239+ );
1240+ };
1241+ for a in &no_align {
1242+ for b in &no_align {
1243+ check_consistency(a, b);
1244+ }
1245+ }
1246+ for a in &align {
1247+ for b in &align {
1248+ check_consistency(a, b);
1249+ }
1250+ }
1251+
1252+ // Relative indent computation makes no sense if the alignment differs
1253+ assert_eq!(
1254+ align[0].relative_indent(
1255+ &no_align[0],
1256+ RopeSlice::from(" "),
1257+ &indent_style,
1258+ tab_width
1259+ ),
1260+ None
1261+ );
1262+ assert_eq!(
1263+ align[0].relative_indent(
1264+ &different_align,
1265+ RopeSlice::from(" "),
1266+ &indent_style,
1267+ tab_width
1268+ ),
1269+ None
1270+ );
1271+ }
1059}
1272}
helix-core/src/syntax.rs+21−5
@@ -101,7 +101,8 @@ pub struct LanguageConfiguration {
101 pub file_types: Vec<FileType>, // filename extension or ends_with? <Gemfile, rb, etc>
101 pub file_types: Vec<FileType>, // filename extension or ends_with? <Gemfile, rb, etc>
102 #[serde(default)]
102 #[serde(default)]
103 pub shebangs: Vec<String>, // interpreter(s) associated with language
103 pub shebangs: Vec<String>, // interpreter(s) associated with language
104+ #[serde(default)]
104− pub roots: Vec<String>, // these indicate project roots <.git, Cargo.toml>
105+ pub roots: Vec<String>, // these indicate project roots <.git, Cargo.toml>
105 pub comment_token: Option<String>,
106 pub comment_token: Option<String>,
106 pub text_width: Option<usize>,
107 pub text_width: Option<usize>,
107 pub soft_wrap: Option<SoftWrap>,
108 pub soft_wrap: Option<SoftWrap>,
@@ -154,6 +155,8 @@ pub struct LanguageConfiguration {
154 /// Hardcoded LSP root directories relative to the workspace root, like `examples` or `tools/fuzz`.
155 /// Hardcoded LSP root directories relative to the workspace root, like `examples` or `tools/fuzz`.
155 /// Falling back to the current working directory if none are configured.
156 /// Falling back to the current working directory if none are configured.
156 pub workspace_lsp_roots: Option<Vec<PathBuf>>,
157 pub workspace_lsp_roots: Option<Vec<PathBuf>>,
158+ #[serde(default)]
159+ pub persistent_diagnostic_sources: Vec<String>,
157}
160}
158
161
159#[derive(Debug, PartialEq, Eq, Hash)]
162#[derive(Debug, PartialEq, Eq, Hash)]
@@ -211,10 +214,7 @@ impl<'de> Deserialize<'de> for FileType {
211 {
214 {
212 match map.next_entry::<String, String>()? {
215 match map.next_entry::<String, String>()? {
213 Some((key, suffix)) if key == "suffix" => Ok(FileType::Suffix({
216 Some((key, suffix)) if key == "suffix" => Ok(FileType::Suffix({
214− // FIXME: use `suffix.replace('/', std::path::MAIN_SEPARATOR_STR)`
217+ suffix.replace('/', std::path::MAIN_SEPARATOR_STR)
215− // if MSRV is updated to 1.68
216− let mut separator = [0; 1];
217− suffix.replace('/', std::path::MAIN_SEPARATOR.encode_utf8(&mut separator))
218 })),
218 })),
219 Some((key, _value)) => Err(serde::de::Error::custom(format!(
219 Some((key, _value)) => Err(serde::de::Error::custom(format!(
220 "unknown key in `file-types` list: {}",
220 "unknown key in `file-types` list: {}",
@@ -444,6 +444,22 @@ pub struct IndentationConfiguration {
444 pub unit: String,
444 pub unit: String,
445}
445}
446
446
447+/// How the indentation for a newly inserted line should be determined.
448+/// If the selected heuristic is not available (e.g. because the current
449+/// language has no tree-sitter indent queries), a simpler one will be used.
450+#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
451+#[serde(rename_all = "kebab-case")]
452+pub enum IndentationHeuristic {
453+ /// Just copy the indentation of the line that the cursor is currently on.
454+ Simple,
455+ /// Use tree-sitter indent queries to compute the expected absolute indentation level of the new line.
456+ TreeSitter,
457+ /// Use tree-sitter indent queries to compute the expected difference in indentation between the new line
458+ /// and the line before. Add this to the actual indentation level of the line before.
459+ #[default]
460+ Hybrid,
461+}
462+
447/// Configuration for auto pairs
463/// Configuration for auto pairs
448#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
464#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
449#[serde(rename_all = "kebab-case", deny_unknown_fields, untagged)]
465#[serde(rename_all = "kebab-case", deny_unknown_fields, untagged)]
helix-core/src/transaction.rs+73−14
@@ -1,7 +1,7 @@
1use ropey::RopeSlice;
1use ropey::RopeSlice;
2use smallvec::SmallVec;
2use smallvec::SmallVec;
3
3
4−use crate::{Range, Rope, Selection, Tendril};
4+use crate::{chars::char_is_word, Range, Rope, Selection, Tendril};
5use std::{borrow::Cow, iter::once};
5use std::{borrow::Cow, iter::once};
6
6
7/// (from, to, replacement)
7/// (from, to, replacement)
@@ -23,6 +23,30 @@ pub enum Operation {
23pub enum Assoc {
23pub enum Assoc {
24 Before,
24 Before,
25 After,
25 After,
26+ /// Acts like `After` if a word character is inserted
27+ /// after the position, otherwise acts like `Before`
28+ AfterWord,
29+ /// Acts like `Before` if a word character is inserted
30+ /// before the position, otherwise acts like `After`
31+ BeforeWord,
32+}
33+
34+impl Assoc {
35+ /// Whether to stick to gaps
36+ fn stay_at_gaps(self) -> bool {
37+ !matches!(self, Self::BeforeWord | Self::AfterWord)
38+ }
39+
40+ fn insert_offset(self, s: &str) -> usize {
41+ let chars = s.chars().count();
42+ match self {
43+ Assoc::After => chars,
44+ Assoc::AfterWord => s.chars().take_while(|&c| char_is_word(c)).count(),
45+ // return position before inserted text
46+ Assoc::Before => 0,
47+ Assoc::BeforeWord => chars - s.chars().rev().take_while(|&c| char_is_word(c)).count(),
48+ }
49+ }
26}
50}
27
51
28#[derive(Debug, Default, Clone, PartialEq, Eq)]
52#[derive(Debug, Default, Clone, PartialEq, Eq)]
@@ -415,8 +439,6 @@ impl ChangeSet {
415 map!(|pos, _| (old_end > pos).then_some(new_pos), i);
439 map!(|pos, _| (old_end > pos).then_some(new_pos), i);
416 }
440 }
417 Insert(s) => {
441 Insert(s) => {
418− let ins = s.chars().count();
419−
420 // a subsequent delete means a replace, consume it
442 // a subsequent delete means a replace, consume it
421 if let Some((_, Delete(len))) = iter.peek() {
443 if let Some((_, Delete(len))) = iter.peek() {
422 iter.next();
444 iter.next();
@@ -424,13 +446,13 @@ impl ChangeSet {
424 old_end = old_pos + len;
446 old_end = old_pos + len;
425 // in range of replaced text
447 // in range of replaced text
426 map!(
448 map!(
427− |pos, assoc| (old_end > pos).then(|| {
449+ |pos, assoc: Assoc| (old_end > pos).then(|| {
428 // at point or tracking before
450 // at point or tracking before
429− if pos == old_pos || assoc == Assoc::Before {
451+ if pos == old_pos && assoc.stay_at_gaps() {
430 new_pos
452 new_pos
431 } else {
453 } else {
432 // place to end of insert
454 // place to end of insert
433− new_pos + ins
455+ new_pos + assoc.insert_offset(s)
434 }
456 }
435 }),
457 }),
436 i
458 i
@@ -438,20 +460,15 @@ impl ChangeSet {
438 } else {
460 } else {
439 // at insert point
461 // at insert point
440 map!(
462 map!(
441− |pos, assoc| (old_pos == pos).then(|| {
463+ |pos, assoc: Assoc| (old_pos == pos).then(|| {
442 // return position before inserted text
464 // return position before inserted text
443− if assoc == Assoc::Before {
465+ new_pos + assoc.insert_offset(s)
444− new_pos
445− } else {
446− // after text
447− new_pos + ins
448− }
449 }),
466 }),
450 i
467 i
451 );
468 );
452 }
469 }
453
470
454− new_pos += ins;
471+ new_pos += s.chars().count();
455 }
472 }
456 }
473 }
457 old_pos = old_end;
474 old_pos = old_end;
@@ -884,6 +901,48 @@ mod test {
884 let mut positions = [4, 2];
901 let mut positions = [4, 2];
885 cs.update_positions(positions.iter_mut().map(|pos| (pos, Assoc::After)));
902 cs.update_positions(positions.iter_mut().map(|pos| (pos, Assoc::After)));
886 assert_eq!(positions, [4, 2]);
903 assert_eq!(positions, [4, 2]);
904+ // stays at word boundary
905+ let cs = ChangeSet {
906+ changes: vec![
907+ Retain(2), // <space><space>
908+ Insert(" ab".into()),
909+ Retain(2), // cd
910+ Insert("de ".into()),
911+ ],
912+ len: 4,
913+ len_after: 10,
914+ };
915+ assert_eq!(cs.map_pos(2, Assoc::BeforeWord), 3);
916+ assert_eq!(cs.map_pos(4, Assoc::AfterWord), 9);
917+ let cs = ChangeSet {
918+ changes: vec![
919+ Retain(1), // <space>
920+ Insert(" b".into()),
921+ Delete(1), // c
922+ Retain(1), // d
923+ Insert("e ".into()),
924+ Delete(1), // <space>
925+ ],
926+ len: 5,
927+ len_after: 7,
928+ };
929+ assert_eq!(cs.map_pos(1, Assoc::BeforeWord), 2);
930+ assert_eq!(cs.map_pos(3, Assoc::AfterWord), 5);
931+ let cs = ChangeSet {
932+ changes: vec![
933+ Retain(1), // <space>
934+ Insert("a".into()),
935+ Delete(2), // <space>b
936+ Retain(1), // d
937+ Insert("e".into()),
938+ Delete(1), // f
939+ Retain(1), // <space>
940+ ],
941+ len: 5,
942+ len_after: 7,
943+ };
944+ assert_eq!(cs.map_pos(2, Assoc::BeforeWord), 1);
945+ assert_eq!(cs.map_pos(4, Assoc::AfterWord), 4);
887 }
946 }
888
947
889 #[test]
948 #[test]
helix-core/src/wrap.rs+3−1
@@ -1,7 +1,9 @@
1use smartstring::{LazyCompact, SmartString};
1use smartstring::{LazyCompact, SmartString};
2+use textwrap::{Options, WordSplitter::NoHyphenation};
2
3
3/// Given a slice of text, return the text re-wrapped to fit it
4/// Given a slice of text, return the text re-wrapped to fit it
4/// within the given width.
5/// within the given width.
5pub fn reflow_hard_wrap(text: &str, text_width: usize) -> SmartString<LazyCompact> {
6pub fn reflow_hard_wrap(text: &str, text_width: usize) -> SmartString<LazyCompact> {
7+ let options = Options::new(text_width).word_splitter(NoHyphenation);
6− textwrap::refill(text, text_width).into()
8+ textwrap::refill(text, options).into()
7}
9}
helix-core/tests/indent.rs+2−2
@@ -210,7 +210,6 @@ fn test_treesitter_indent(
210 let suggested_indent = treesitter_indent_for_pos(
210 let suggested_indent = treesitter_indent_for_pos(
211 indent_query,
211 indent_query,
212 &syntax,
212 &syntax,
213− &indent_style,
214 tab_width,
213 tab_width,
215 indent_style.indent_width(tab_width),
214 indent_style.indent_width(tab_width),
216 text,
215 text,
@@ -218,7 +217,8 @@ fn test_treesitter_indent(
218 text.line_to_char(i) + pos,
217 text.line_to_char(i) + pos,
219 false,
218 false,
220 )
219 )
221− .unwrap();
220+ .unwrap()
221+ .to_string(&indent_style, tab_width);
222 assert!(
222 assert!(
223 line.get_slice(..pos).map_or(false, |s| s == suggested_indent),
223 line.get_slice(..pos).map_or(false, |s| s == suggested_indent),
224 "Wrong indentation for file {:?} on line {}:\n\"{}\" (original line)\n\"{}\" (suggested indentation)\n",
224 "Wrong indentation for file {:?} on line {}:\n\"{}\" (original line)\n\"{}\" (suggested indentation)\n",
helix-dap/Cargo.toml+11−9
@@ -1,25 +1,27 @@
1[package]
1[package]
2name = "helix-dap"
2name = "helix-dap"
3−version = "0.6.0"
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5−edition = "2018"
6−license = "MPL-2.0"
7description = "DAP client implementation for Helix project"
3description = "DAP client implementation for Helix project"
4+version.workspace = true
5+authors.workspace = true
6+edition.workspace = true
7+license.workspace = true
8+rust-version.workspace = true
8−categories = ["editor"]
9+categories.workspace = true
9−repository = "https://github.com/helix-editor/helix"
10+repository.workspace = true
10−homepage = "https://helix-editor.com"
11+homepage.workspace = true
11
12
12# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13
14
14[dependencies]
15[dependencies]
15−helix-core = { version = "0.6", path = "../helix-core" }
16+helix-core = { path = "../helix-core" }
17+
16anyhow = "1.0"
18anyhow = "1.0"
17log = "0.4"
19log = "0.4"
18serde = { version = "1.0", features = ["derive"] }
20serde = { version = "1.0", features = ["derive"] }
19serde_json = "1.0"
21serde_json = "1.0"
20thiserror = "1.0"
22thiserror = "1.0"
21tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "net", "sync"] }
23tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "net", "sync"] }
22−which = "4.4"
24+which = "5.0.0"
23
25
24[dev-dependencies]
26[dev-dependencies]
25fern = "0.6"
27fern = "0.6"
helix-event/Cargo.toml+8−7
@@ -1,12 +1,13 @@
1[package]
1[package]
2name = "helix-event"
2name = "helix-event"
3−version = "0.6.0"
3+version.workspace = true
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
4+authors.workspace = true
5−edition = "2021"
5+edition.workspace = true
6−license = "MPL-2.0"
6+license.workspace = true
7+rust-version.workspace = true
7−categories = ["editor"]
8+categories.workspace = true
8−repository = "https://github.com/helix-editor/helix"
9+repository.workspace = true
9−homepage = "https://helix-editor.com"
10+homepage.workspace = true
10
11
11# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12
13
helix-loader/Cargo.toml+12−11
@@ -1,13 +1,14 @@
1[package]
1[package]
2name = "helix-loader"
2name = "helix-loader"
3−version = "0.6.0"
3+description = "Build bootstrapping for Helix crates"
4−description = "A post-modern text editor."
4+version.workspace = true
5−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5+authors.workspace = true
6−edition = "2021"
6+edition.workspace = true
7−license = "MPL-2.0"
7+license.workspace = true
8+rust-version.workspace = true
8−categories = ["editor"]
9+categories.workspace = true
9−repository = "https://github.com/helix-editor/helix"
10+repository.workspace = true
10−homepage = "https://helix-editor.com"
11+homepage.workspace = true
11
12
12[[bin]]
13[[bin]]
13name = "hx-loader"
14name = "hx-loader"
@@ -19,16 +20,16 @@ serde = { version = "1.0", features = ["derive"] }
19toml = "0.7"
20toml = "0.7"
20etcetera = "0.8"
21etcetera = "0.8"
21tree-sitter.workspace = true
22tree-sitter.workspace = true
22−once_cell = "1.18"
23+once_cell = "1.19"
23log = "0.4"
24log = "0.4"
24−which = "4.4"
25+which = "5.0.0"
25
26
26# TODO: these two should be on !wasm32 only
27# TODO: these two should be on !wasm32 only
27
28
28# cloning/compiling tree-sitter grammars
29# cloning/compiling tree-sitter grammars
29cc = { version = "1" }
30cc = { version = "1" }
30threadpool = { version = "1.0" }
31threadpool = { version = "1.0" }
31−tempfile = "3.8.0"
32+tempfile = "3.8.1"
32dunce = "1.0.4"
33dunce = "1.0.4"
33
34
34[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
35[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
helix-loader/build.rs+14−4
@@ -2,7 +2,17 @@ use std::borrow::Cow;
2use std::path::Path;
2use std::path::Path;
3use std::process::Command;
3use std::process::Command;
4
4
5−const VERSION: &str = include_str!("../VERSION");
5+const MAJOR: &str = env!("CARGO_PKG_VERSION_MAJOR");
6+const MINOR: &str = env!("CARGO_PKG_VERSION_MINOR");
7+const PATCH: &str = env!("CARGO_PKG_VERSION_PATCH");
8+
9+fn get_calver() -> String {
10+ if PATCH == "0" {
11+ format!("{MAJOR}.{MINOR}")
12+ } else {
13+ format!("{MAJOR}.{MINOR}.{PATCH}")
14+ }
15+}
6
16
7fn main() {
17fn main() {
8 let git_hash = Command::new("git")
18 let git_hash = Command::new("git")
@@ -12,9 +22,10 @@ fn main() {
12 .filter(|output| output.status.success())
22 .filter(|output| output.status.success())
13 .and_then(|x| String::from_utf8(x.stdout).ok());
23 .and_then(|x| String::from_utf8(x.stdout).ok());
14
24
25+ let calver = get_calver();
15 let version: Cow<_> = match &git_hash {
26 let version: Cow<_> = match &git_hash {
16− Some(git_hash) => format!("{} ({})", VERSION, &git_hash[..8]).into(),
27+ Some(git_hash) => format!("{} ({})", calver, &git_hash[..8]).into(),
17− None => VERSION.into(),
28+ None => calver.into(),
18 };
29 };
19
30
20 println!(
31 println!(
@@ -22,7 +33,6 @@ fn main() {
22 std::env::var("TARGET").unwrap()
33 std::env::var("TARGET").unwrap()
23 );
34 );
24
35
25− println!("cargo:rerun-if-changed=../VERSION");
26 println!("cargo:rustc-env=VERSION_AND_GIT_HASH={}", version);
36 println!("cargo:rustc-env=VERSION_AND_GIT_HASH={}", version);
27
37
28 if git_hash.is_none() {
38 if git_hash.is_none() {
helix-loader/src/lib.rs+13−4
@@ -33,9 +33,9 @@ pub fn current_working_dir() -> PathBuf {
33 path
33 path
34}
34}
35
35
36−pub fn set_current_working_dir(path: PathBuf) -> std::io::Result<()> {
36+pub fn set_current_working_dir(path: impl AsRef<Path>) -> std::io::Result<()> {
37 let path = dunce::canonicalize(path)?;
37 let path = dunce::canonicalize(path)?;
38− std::env::set_current_dir(path.clone())?;
38+ std::env::set_current_dir(&path)?;
39 let mut cwd = CWD.write().unwrap();
39 let mut cwd = CWD.write().unwrap();
40 *cwd = Some(path);
40 *cwd = Some(path);
41 Ok(())
41 Ok(())
@@ -60,7 +60,8 @@ pub fn initialize_log_file(specified_file: Option<PathBuf>) {
60/// 1. sibling directory to `CARGO_MANIFEST_DIR` (if environment variable is set)
60/// 1. sibling directory to `CARGO_MANIFEST_DIR` (if environment variable is set)
61/// 2. subdirectory of user config directory (always included)
61/// 2. subdirectory of user config directory (always included)
62/// 3. `HELIX_RUNTIME` (if environment variable is set)
62/// 3. `HELIX_RUNTIME` (if environment variable is set)
63+/// 4. `HELIX_DEFAULT_RUNTIME` (if environment variable is set *at build time*)
63−/// 4. subdirectory of path to helix executable (always included)
64+/// 5. subdirectory of path to helix executable (always included)
64///
65///
65/// Postcondition: returns at least two paths (they might not exist).
66/// Postcondition: returns at least two paths (they might not exist).
66fn prioritize_runtime_dirs() -> Vec<PathBuf> {
67fn prioritize_runtime_dirs() -> Vec<PathBuf> {
@@ -81,6 +82,14 @@ fn prioritize_runtime_dirs() -> Vec<PathBuf> {
81 rt_dirs.push(dir.into());
82 rt_dirs.push(dir.into());
82 }
83 }
83
84
85+ // If this variable is set during build time, it will always be included
86+ // in the lookup list. This allows downstream packagers to set a fallback
87+ // directory to a location that is conventional on their distro so that they
88+ // need not resort to a wrapper script or a global environment variable.
89+ if let Some(dir) = std::option_env!("HELIX_DEFAULT_RUNTIME") {
90+ rt_dirs.push(dir.into());
91+ }
92+
84 // fallback to location of the executable being run
93 // fallback to location of the executable being run
85 // canonicalize the path in case the executable is symlinked
94 // canonicalize the path in case the executable is symlinked
86 let exe_rt_dir = std::env::current_exe()
95 let exe_rt_dir = std::env::current_exe()
@@ -280,7 +289,7 @@ mod merge_toml_tests {
280 let cwd = current_working_dir();
289 let cwd = current_working_dir();
281 assert_ne!(cwd, new_path);
290 assert_ne!(cwd, new_path);
282
291
283− set_current_working_dir(new_path.clone()).expect("Couldn't set new path");
292+ set_current_working_dir(&new_path).expect("Couldn't set new path");
284
293
285 let cwd = current_working_dir();
294 let cwd = current_working_dir();
286 assert_eq!(cwd, new_path);
295 assert_eq!(cwd, new_path);
helix-lsp/Cargo.toml+15−14
@@ -1,31 +1,32 @@
1[package]
1[package]
2name = "helix-lsp"
2name = "helix-lsp"
3−version = "0.6.0"
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5−edition = "2021"
6−license = "MPL-2.0"
7description = "LSP client implementation for Helix project"
3description = "LSP client implementation for Helix project"
4+version.workspace = true
5+authors.workspace = true
6+edition.workspace = true
7+license.workspace = true
8+rust-version.workspace = true
8−categories = ["editor"]
9+categories.workspace = true
9−repository = "https://github.com/helix-editor/helix"
10+repository.workspace = true
10−homepage = "https://helix-editor.com"
11+homepage.workspace = true
11
12
12# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13
14
14[dependencies]
15[dependencies]
15−helix-core = { version = "0.6", path = "../helix-core" }
16+helix-core = { path = "../helix-core" }
16−helix-loader = { version = "0.6", path = "../helix-loader" }
17+helix-loader = { path = "../helix-loader" }
17−helix-parsec = { version = "0.6", path = "../helix-parsec" }
18+helix-parsec = { path = "../helix-parsec" }
18
19
19anyhow = "1.0"
20anyhow = "1.0"
20futures-executor = "0.3"
21futures-executor = "0.3"
21futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false }
22futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false }
22−globset = "0.4.13"
23+globset = "0.4.14"
23log = "0.4"
24log = "0.4"
24−lsp-types = { version = "0.94" }
25+lsp-types = { version = "0.95" }
25serde = { version = "1.0", features = ["derive"] }
26serde = { version = "1.0", features = ["derive"] }
26serde_json = "1.0"
27serde_json = "1.0"
27thiserror = "1.0"
28thiserror = "1.0"
28−tokio = { version = "1.32", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] }
29+tokio = { version = "1.35", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] }
29tokio-stream = "0.1.14"
30tokio-stream = "0.1.14"
30−which = "4.4"
31+which = "5.0.0"
31parking_lot = "0.12.1"
32parking_lot = "0.12.1"
helix-lsp/src/client.rs+87−13
@@ -401,12 +401,22 @@ impl Client {
401 &self,
401 &self,
402 params: R::Params,
402 params: R::Params,
403 ) -> impl Future<Output = Result<Value>>
403 ) -> impl Future<Output = Result<Value>>
404+ where
405+ R::Params: serde::Serialize,
406+ {
407+ self.call_with_timeout::<R>(params, self.req_timeout)
408+ }
409+
410+ fn call_with_timeout<R: lsp::request::Request>(
411+ &self,
412+ params: R::Params,
413+ timeout_secs: u64,
414+ ) -> impl Future<Output = Result<Value>>
404 where
415 where
405 R::Params: serde::Serialize,
416 R::Params: serde::Serialize,
406 {
417 {
407 let server_tx = self.server_tx.clone();
418 let server_tx = self.server_tx.clone();
408 let id = self.next_request_id();
419 let id = self.next_request_id();
409− let timeout_secs = self.req_timeout;
410
420
411 async move {
421 async move {
412 use std::time::Duration;
422 use std::time::Duration;
@@ -548,6 +558,11 @@ impl Client {
548 dynamic_registration: Some(true),
558 dynamic_registration: Some(true),
549 relative_pattern_support: Some(false),
559 relative_pattern_support: Some(false),
550 }),
560 }),
561+ file_operations: Some(lsp::WorkspaceFileOperationsClientCapabilities {
562+ will_rename: Some(true),
563+ did_rename: Some(true),
564+ ..Default::default()
565+ }),
551 ..Default::default()
566 ..Default::default()
552 }),
567 }),
553 text_document: Some(lsp::TextDocumentClientCapabilities {
568 text_document: Some(lsp::TextDocumentClientCapabilities {
@@ -652,6 +667,7 @@ impl Client {
652 version: Some(String::from(VERSION_AND_GIT_HASH)),
667 version: Some(String::from(VERSION_AND_GIT_HASH)),
653 }),
668 }),
654 locale: None, // TODO
669 locale: None, // TODO
670+ work_done_progress_params: lsp::WorkDoneProgressParams::default(),
655 };
671 };
656
672
657 self.request::<lsp::request::Initialize>(params).await
673 self.request::<lsp::request::Initialize>(params).await
@@ -700,6 +716,65 @@ impl Client {
700 })
716 })
701 }
717 }
702
718
719+ pub fn prepare_file_rename(
720+ &self,
721+ old_uri: &lsp::Url,
722+ new_uri: &lsp::Url,
723+ ) -> Option<impl Future<Output = Result<lsp::WorkspaceEdit>>> {
724+ let capabilities = self.capabilities.get().unwrap();
725+
726+ // Return early if the server does not support willRename feature
727+ match &capabilities.workspace {
728+ Some(workspace) => match &workspace.file_operations {
729+ Some(op) => {
730+ op.will_rename.as_ref()?;
731+ }
732+ _ => return None,
733+ },
734+ _ => return None,
735+ }
736+
737+ let files = vec![lsp::FileRename {
738+ old_uri: old_uri.to_string(),
739+ new_uri: new_uri.to_string(),
740+ }];
741+ let request = self.call_with_timeout::<lsp::request::WillRenameFiles>(
742+ lsp::RenameFilesParams { files },
743+ 5,
744+ );
745+
746+ Some(async move {
747+ let json = request.await?;
748+ let response: Option<lsp::WorkspaceEdit> = serde_json::from_value(json)?;
749+ Ok(response.unwrap_or_default())
750+ })
751+ }
752+
753+ pub fn did_file_rename(
754+ &self,
755+ old_uri: &lsp::Url,
756+ new_uri: &lsp::Url,
757+ ) -> Option<impl Future<Output = std::result::Result<(), Error>>> {
758+ let capabilities = self.capabilities.get().unwrap();
759+
760+ // Return early if the server does not support DidRename feature
761+ match &capabilities.workspace {
762+ Some(workspace) => match &workspace.file_operations {
763+ Some(op) => {
764+ op.did_rename.as_ref()?;
765+ }
766+ _ => return None,
767+ },
768+ _ => return None,
769+ }
770+
771+ let files = vec![lsp::FileRename {
772+ old_uri: old_uri.to_string(),
773+ new_uri: new_uri.to_string(),
774+ }];
775+ Some(self.notify::<lsp::notification::DidRenameFiles>(lsp::RenameFilesParams { files }))
776+ }
777+
703 // -------------------------------------------------------------------------------------------
778 // -------------------------------------------------------------------------------------------
704 // Text document
779 // Text document
705 // -------------------------------------------------------------------------------------------
780 // -------------------------------------------------------------------------------------------
@@ -895,20 +970,19 @@ impl Client {
895 ) -> Option<impl Future<Output = Result<()>>> {
970 ) -> Option<impl Future<Output = Result<()>>> {
896 let capabilities = self.capabilities.get().unwrap();
971 let capabilities = self.capabilities.get().unwrap();
897
972
898− let include_text = match &capabilities.text_document_sync {
973+ let include_text = match &capabilities.text_document_sync.as_ref()? {
899− Some(lsp::TextDocumentSyncCapability::Options(lsp::TextDocumentSyncOptions {
974+ lsp::TextDocumentSyncCapability::Options(lsp::TextDocumentSyncOptions {
900− save: Some(options),
975+ save: options,
901 ..
976 ..
902− })) => match options {
977+ }) => match options.as_ref()? {
903 lsp::TextDocumentSyncSaveOptions::Supported(true) => false,
978 lsp::TextDocumentSyncSaveOptions::Supported(true) => false,
904 lsp::TextDocumentSyncSaveOptions::SaveOptions(lsp_types::SaveOptions {
979 lsp::TextDocumentSyncSaveOptions::SaveOptions(lsp_types::SaveOptions {
905 include_text,
980 include_text,
906 }) => include_text.unwrap_or(false),
981 }) => include_text.unwrap_or(false),
907− // Supported(false)
982+ lsp::TextDocumentSyncSaveOptions::Supported(false) => return None,
908− _ => return None,
909 },
983 },
910− // unsupported
984+ // see: https://github.com/microsoft/language-server-protocol/issues/288
911− _ => return None,
985+ lsp::TextDocumentSyncCapability::Kind(..) => false,
912 };
986 };
913
987
914 Some(self.notify::<lsp::notification::DidSaveTextDocument>(
988 Some(self.notify::<lsp::notification::DidSaveTextDocument>(
@@ -971,12 +1045,12 @@ impl Client {
971 ) -> Option<impl Future<Output = Result<Value>>> {
1045 ) -> Option<impl Future<Output = Result<Value>>> {
972 let capabilities = self.capabilities.get().unwrap();
1046 let capabilities = self.capabilities.get().unwrap();
973
1047
974− // Return early if the server does not support resolving code action.
1048+ // Return early if the server does not support resolving code actions.
975− match capabilities.completion_provider {
1049+ match capabilities.code_action_provider {
976− Some(lsp::CompletionOptions {
1050+ Some(lsp::CodeActionProviderCapability::Options(lsp::CodeActionOptions {
977 resolve_provider: Some(true),
1051 resolve_provider: Some(true),
978 ..
1052 ..
979− }) => (),
1053+ })) => (),
980 _ => return None,
1054 _ => return None,
981 }
1055 }
982
1056
helix-lsp/src/lib.rs+32−28
@@ -445,36 +445,36 @@ pub mod util {
445 // the tabstop closest to the range simply replaces `head` while anchor remains in place
445 // the tabstop closest to the range simply replaces `head` while anchor remains in place
446 // the remaining tabstops receive their own single-width cursor
446 // the remaining tabstops receive their own single-width cursor
447 if range.head < range.anchor {
447 if range.head < range.anchor {
448+ let last_idx = tabstops.len() - 1;
448− let first_tabstop = tabstop_anchor + tabstops[0].1;
449+ let last_tabstop = tabstop_anchor + tabstops[last_idx].0;
449
450
450 // if selection is forward but was moved to the right it is
451 // if selection is forward but was moved to the right it is
451 // contained entirely in the replacement text, just do a point
452 // contained entirely in the replacement text, just do a point
452 // selection (fallback below)
453 // selection (fallback below)
453− if range.anchor >= first_tabstop {
454+ if range.anchor > last_tabstop {
454− let range = Range::new(range.anchor, first_tabstop);
455+ let range = Range::new(range.anchor, last_tabstop);
455 mapped_selection.push(range);
456 mapped_selection.push(range);
456− let rem_tabstops = tabstops[1..]
457+ let rem_tabstops = tabstops[..last_idx]
457 .iter()
458 .iter()
458− .map(|tabstop| Range::point(tabstop_anchor + tabstop.1));
459+ .map(|tabstop| Range::point(tabstop_anchor + tabstop.0));
459 mapped_selection.extend(rem_tabstops);
460 mapped_selection.extend(rem_tabstops);
460 continue;
461 continue;
461 }
462 }
462 } else {
463 } else {
463− let last_idx = tabstops.len() - 1;
464− let last_tabstop = tabstop_anchor + tabstops[last_idx].1;
464+ let first_tabstop = tabstop_anchor + tabstops[0].0;
465
465
466 // if selection is forward but was moved to the right it is
466 // if selection is forward but was moved to the right it is
467 // contained entirely in the replacement text, just do a point
467 // contained entirely in the replacement text, just do a point
468 // selection (fallback below)
468 // selection (fallback below)
469− if range.anchor <= last_tabstop {
469+ if range.anchor < first_tabstop {
470 // we can't properly compute the the next grapheme
470 // we can't properly compute the the next grapheme
471 // here because the transaction hasn't been applied yet
471 // here because the transaction hasn't been applied yet
472 // that is not a problem because the range gets grapheme aligned anyway
472 // that is not a problem because the range gets grapheme aligned anyway
473 // tough so just adding one will always cause head to be grapheme
473 // tough so just adding one will always cause head to be grapheme
474 // aligned correctly when applied to the document
474 // aligned correctly when applied to the document
475− let range = Range::new(range.anchor, last_tabstop + 1);
475+ let range = Range::new(range.anchor, first_tabstop + 1);
476 mapped_selection.push(range);
476 mapped_selection.push(range);
477− let rem_tabstops = tabstops[..last_idx]
477+ let rem_tabstops = tabstops[1..]
478 .iter()
478 .iter()
479 .map(|tabstop| Range::point(tabstop_anchor + tabstop.0));
479 .map(|tabstop| Range::point(tabstop_anchor + tabstop.0));
480 mapped_selection.extend(rem_tabstops);
480 mapped_selection.extend(rem_tabstops);
@@ -749,36 +749,40 @@ impl Registry {
749 }
749 }
750 }
750 }
751
751
752− pub fn get(
752+ pub fn get<'a>(
753− &mut self,
753+ &'a mut self,
754− language_config: &LanguageConfiguration,
754+ language_config: &'a LanguageConfiguration,
755− doc_path: Option<&std::path::PathBuf>,
755+ doc_path: Option<&'a std::path::PathBuf>,
756− root_dirs: &[PathBuf],
756+ root_dirs: &'a [PathBuf],
757 enable_snippets: bool,
757 enable_snippets: bool,
758− ) -> Result<HashMap<LanguageServerName, Arc<Client>>> {
758+ ) -> impl Iterator<Item = (LanguageServerName, Result<Arc<Client>>)> + 'a {
759− language_config
760− .language_servers
759+ language_config.language_servers.iter().map(
761− .iter()
762− .map(|LanguageServerFeatures { name, .. }| {
760+ move |LanguageServerFeatures { name, .. }| {
763 if let Some(clients) = self.inner.get(name) {
761 if let Some(clients) = self.inner.get(name) {
764 if let Some((_, client)) = clients.iter().enumerate().find(|(i, client)| {
762 if let Some((_, client)) = clients.iter().enumerate().find(|(i, client)| {
765 client.try_add_doc(&language_config.roots, root_dirs, doc_path, *i == 0)
763 client.try_add_doc(&language_config.roots, root_dirs, doc_path, *i == 0)
766 }) {
764 }) {
767− return Ok((name.to_owned(), client.clone()));
765+ return (name.to_owned(), Ok(client.clone()));
768 }
766 }
769 }
767 }
770− let client = self.start_client(
768+ match self.start_client(
771 name.clone(),
769 name.clone(),
772 language_config,
770 language_config,
773 doc_path,
771 doc_path,
774 root_dirs,
772 root_dirs,
775 enable_snippets,
773 enable_snippets,
776− )?;
774+ ) {
777− let clients = self.inner.entry(name.clone()).or_default();
775+ Ok(client) => {
776+ self.inner
777+ .entry(name.to_owned())
778+ .or_default()
778− clients.push(client.clone());
779+ .push(client.clone());
779− Ok((name.clone(), client))
780+ (name.clone(), Ok(client))
780− })
781+ }
781− .collect()
782+ Err(err) => (name.to_owned(), Err(err)),
783+ }
784+ },
785+ )
782 }
786 }
783
787
784 pub fn iter_clients(&self) -> impl Iterator<Item = &Arc<Client>> {
788 pub fn iter_clients(&self) -> impl Iterator<Item = &Arc<Client>> {
helix-parsec/Cargo.toml+8−7
@@ -1,13 +1,14 @@
1[package]
1[package]
2name = "helix-parsec"
2name = "helix-parsec"
3−version = "0.6.0"
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5−edition = "2021"
6−license = "MPL-2.0"
7description = "Parser combinators for Helix"
3description = "Parser combinators for Helix"
8−categories = ["editor"]
9−repository = "https://github.com/helix-editor/helix"
10−homepage = "https://helix-editor.com"
11include = ["src/**/*", "README.md"]
4include = ["src/**/*", "README.md"]
5+version.workspace = true
6+authors.workspace = true
7+edition.workspace = true
8+license.workspace = true
9+rust-version.workspace = true
10+categories.workspace = true
11+repository.workspace = true
12+homepage.workspace = true
12
13
13[dependencies]
14[dependencies]
helix-term/Cargo.toml+27−23
@@ -1,16 +1,16 @@
1[package]
1[package]
2name = "helix-term"
2name = "helix-term"
3−version = "0.6.0"
4description = "A post-modern text editor."
3description = "A post-modern text editor."
5−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
6−edition = "2021"
7−license = "MPL-2.0"
8−categories = ["editor", "command-line-utilities"]
9−repository = "https://github.com/helix-editor/helix"
10−homepage = "https://helix-editor.com"
11include = ["src/**/*", "README.md"]
4include = ["src/**/*", "README.md"]
12default-run = "hx"
5default-run = "hx"
6+version.workspace = true
7+authors.workspace = true
8+edition.workspace = true
9+license.workspace = true
13−rust-version = "1.65"
10+rust-version.workspace = true
11+categories.workspace = true
12+repository.workspace = true
13+homepage.workspace = true
14
14
15[features]
15[features]
16default = ["git"]
16default = ["git"]
@@ -23,18 +23,18 @@ name = "hx"
23path = "src/main.rs"
23path = "src/main.rs"
24
24
25[dependencies]
25[dependencies]
26−helix-core = { version = "0.6", path = "../helix-core" }
26+helix-core = { path = "../helix-core" }
27−helix-event = { version = "0.6", path = "../helix-event" }
27+helix-event = { path = "../helix-event" }
28−helix-view = { version = "0.6", path = "../helix-view" }
28+helix-view = { path = "../helix-view" }
29−helix-lsp = { version = "0.6", path = "../helix-lsp" }
29+helix-lsp = { path = "../helix-lsp" }
30−helix-dap = { version = "0.6", path = "../helix-dap" }
30+helix-dap = { path = "../helix-dap" }
31−helix-vcs = { version = "0.6", path = "../helix-vcs" }
31+helix-vcs = { path = "../helix-vcs" }
32−helix-loader = { version = "0.6", path = "../helix-loader" }
32+helix-loader = { path = "../helix-loader" }
33
33
34anyhow = "1"
34anyhow = "1"
35−once_cell = "1.18"
35+once_cell = "1.19"
36
36
37−which = "4.4"
37+which = "5.0.0"
38
38
39tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] }
39tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot"] }
40tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = ["crossterm"] }
40tui = { path = "../helix-tui", package = "helix-tui", default-features = false, features = ["crossterm"] }
@@ -57,6 +57,10 @@ pulldown-cmark = { version = "0.9", default-features = false }
57# file type detection
57# file type detection
58content_inspector = "0.2.4"
58content_inspector = "0.2.4"
59
59
60+# opening URLs
61+open = "5.0.1"
62+url = "2.5.0"
63+
60# config
64# config
61toml = "0.7"
65toml = "0.7"
62
66
@@ -64,20 +68,20 @@ serde_json = "1.0"
64serde = { version = "1.0", features = ["derive"] }
68serde = { version = "1.0", features = ["derive"] }
65
69
66# ripgrep for global search
70# ripgrep for global search
67−grep-regex = "0.1.11"
71+grep-regex = "0.1.12"
68−grep-searcher = "0.1.11"
72+grep-searcher = "0.1.13"
69
73
70[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
74[target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100
71signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
75signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] }
72−libc = "0.2.147"
76+libc = "0.2.151"
73
77
74[target.'cfg(target_os = "macos")'.dependencies]
78[target.'cfg(target_os = "macos")'.dependencies]
75crossterm = { version = "0.27", features = ["event-stream", "use-dev-tty"] }
79crossterm = { version = "0.27", features = ["event-stream", "use-dev-tty"] }
76
80
77[build-dependencies]
81[build-dependencies]
78−helix-loader = { version = "0.6", path = "../helix-loader" }
82+helix-loader = { path = "../helix-loader" }
79
83
80[dev-dependencies]
84[dev-dependencies]
81smallvec = "1.11"
85smallvec = "1.11"
82−indoc = "2.0.3"
86+indoc = "2.0.4"
83−tempfile = "3.8.0"
87+tempfile = "3.8.1"
helix-term/src/application.rs+95−47
@@ -1,6 +1,7 @@
1use arc_swap::{access::Map, ArcSwap};
1use arc_swap::{access::Map, ArcSwap};
2use futures_util::Stream;
2use futures_util::Stream;
3use helix_core::{
3use helix_core::{
4+ chars::char_is_word,
4 diagnostic::{DiagnosticTag, NumberOrString},
5 diagnostic::{DiagnosticTag, NumberOrString},
5 path::get_relative_path,
6 path::get_relative_path,
6 pos_at_coords, syntax, Selection,
7 pos_at_coords, syntax, Selection,
@@ -162,15 +163,19 @@ impl Application {
162 // Unset path to prevent accidentally saving to the original tutor file.
163 // Unset path to prevent accidentally saving to the original tutor file.
163 doc_mut!(editor).set_path(None);
164 doc_mut!(editor).set_path(None);
164 } else if !args.files.is_empty() {
165 } else if !args.files.is_empty() {
165− let first = &args.files[0].0; // we know it's not empty
166+ let mut files_it = args.files.into_iter().peekable();
167+
168+ // If the first file is a directory, skip it and open a picker
166− if first.is_dir() {
169+ if let Some((first, _)) = files_it.next_if(|(p, _)| p.is_dir()) {
167− helix_loader::set_current_working_dir(first.clone())?;
168− editor.new_file(Action::VerticalSplit);
169− let picker = ui::file_picker(".".into(), &config.load().editor);
170+ let picker = ui::file_picker(first, &config.load().editor);
170 compositor.push(Box::new(overlaid(picker)));
171 compositor.push(Box::new(overlaid(picker)));
171− } else {
172+ }
173+
174+ // If there are any more files specified, open them
175+ if files_it.peek().is_some() {
172− let nr_of_files = args.files.len();
176+ let mut nr_of_files = 0;
173− for (i, (file, pos)) in args.files.into_iter().enumerate() {
177+ for (file, pos) in files_it {
178+ nr_of_files += 1;
174 if file.is_dir() {
179 if file.is_dir() {
175 return Err(anyhow::anyhow!(
180 return Err(anyhow::anyhow!(
176 "expected a path to file, found a directory. (to open a directory pass it as first argument)"
181 "expected a path to file, found a directory. (to open a directory pass it as first argument)"
@@ -182,7 +187,7 @@ impl Application {
182 // option. If neither of those two arguments are passed
187 // option. If neither of those two arguments are passed
183 // in, just load the files normally.
188 // in, just load the files normally.
184 let action = match args.split {
189 let action = match args.split {
185− _ if i == 0 => Action::VerticalSplit,
190+ _ if nr_of_files == 1 => Action::VerticalSplit,
186 Some(Layout::Vertical) => Action::VerticalSplit,
191 Some(Layout::Vertical) => Action::VerticalSplit,
187 Some(Layout::Horizontal) => Action::HorizontalSplit,
192 Some(Layout::Horizontal) => Action::HorizontalSplit,
188 None => Action::Load,
193 None => Action::Load,
@@ -209,6 +214,8 @@ impl Application {
209 // does not affect views without pos since it is at the top
214 // does not affect views without pos since it is at the top
210 let (view, doc) = current!(editor);
215 let (view, doc) = current!(editor);
211 align_view(doc, view, Align::Center);
216 align_view(doc, view, Align::Center);
217+ } else {
218+ editor.new_file(Action::VerticalSplit);
212 }
219 }
213 } else if stdin().is_tty() || cfg!(feature = "integration") {
220 } else if stdin().is_tty() || cfg!(feature = "integration") {
214 editor.new_file(Action::VerticalSplit);
221 editor.new_file(Action::VerticalSplit);
@@ -711,7 +718,7 @@ impl Application {
711 ));
718 ));
712 }
719 }
713 }
720 }
714− Notification::PublishDiagnostics(params) => {
721+ Notification::PublishDiagnostics(mut params) => {
715 let path = match params.uri.to_file_path() {
722 let path = match params.uri.to_file_path() {
716 Ok(path) => path,
723 Ok(path) => path,
717 Err(_) => {
724 Err(_) => {
@@ -725,31 +732,69 @@ impl Application {
725 return;
732 return;
726 }
733 }
727 let offset_encoding = language_server.offset_encoding();
734 let offset_encoding = language_server.offset_encoding();
728− let doc = self.editor.document_by_path_mut(&path).filter(|doc| {
735+ // have to inline the function because of borrow checking...
736+ let doc = self.editor.documents.values_mut()
737+ .find(|doc| doc.path().map(|p| p == &path).unwrap_or(false))
738+ .filter(|doc| {
729− if let Some(version) = params.version {
739+ if let Some(version) = params.version {
730− if version != doc.version() {
740+ if version != doc.version() {
731− log::info!("Version ({version}) is out of date for {path:?} (expected ({}), dropping PublishDiagnostic notification", doc.version());
741+ log::info!("Version ({version}) is out of date for {path:?} (expected ({}), dropping PublishDiagnostic notification", doc.version());
732− return false;
742+ return false;
743+ }
733 }
744 }
734− }
735−
736− true
745+ true
737− });
746+ });
738
747
739 if let Some(doc) = doc {
748 if let Some(doc) = doc {
740− let lang_conf = doc.language_config();
749+ let lang_conf = doc.language.clone();
741− let text = doc.text();
750+ let text = doc.text().clone();
751+
752+ let mut unchaged_diag_sources_ = Vec::new();
753+ if let Some(lang_conf) = &lang_conf {
754+ if let Some(old_diagnostics) =
755+ self.editor.diagnostics.get(&params.uri)
756+ {
757+ if !lang_conf.persistent_diagnostic_sources.is_empty() {
758+ // Sort diagnostics first by severity and then by line numbers.
759+ // Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order
760+ params
761+ .diagnostics
762+ .sort_unstable_by_key(|d| (d.severity, d.range.start));
763+ }
764+ for source in &lang_conf.persistent_diagnostic_sources {
765+ let new_diagnostics = params
766+ .diagnostics
767+ .iter()
768+ .filter(|d| d.source.as_ref() == Some(source));
769+ let old_diagnostics = old_diagnostics
770+ .iter()
771+ .filter(|(d, d_server)| {
772+ *d_server == server_id
773+ && d.source.as_ref() == Some(source)
774+ })
775+ .map(|(d, _)| d);
776+ if new_diagnostics.eq(old_diagnostics) {
777+ unchaged_diag_sources_.push(source.clone())
778+ }
779+ }
780+ }
781+ }
742
782
783+ let unchaged_diag_sources = &unchaged_diag_sources_;
743− let diagnostics = params
784+ let diagnostics =
744− .diagnostics
745− .iter()
746− .filter_map(|diagnostic| {
785+ params.diagnostics.iter().filter_map(move |diagnostic| {
747 use helix_core::diagnostic::{Diagnostic, Range, Severity::*};
786 use helix_core::diagnostic::{Diagnostic, Range, Severity::*};
748 use lsp::DiagnosticSeverity;
787 use lsp::DiagnosticSeverity;
749
788
789+ if diagnostic.source.as_ref().map_or(false, |source| {
790+ unchaged_diag_sources.contains(source)
791+ }) {
792+ return None;
793+ }
794+
750 // TODO: convert inside server
795 // TODO: convert inside server
751 let start = if let Some(start) = lsp_pos_to_pos(
796 let start = if let Some(start) = lsp_pos_to_pos(
752− text,
797+ &text,
753 diagnostic.range.start,
798 diagnostic.range.start,
754 offset_encoding,
799 offset_encoding,
755 ) {
800 ) {
@@ -760,14 +805,13 @@ impl Application {
760 };
805 };
761
806
762 let end = if let Some(end) =
807 let end = if let Some(end) =
763− lsp_pos_to_pos(text, diagnostic.range.end, offset_encoding)
808+ lsp_pos_to_pos(&text, diagnostic.range.end, offset_encoding)
764 {
809 {
765 end
810 end
766 } else {
811 } else {
767 log::warn!("lsp position out of bounds - {:?}", diagnostic);
812 log::warn!("lsp position out of bounds - {:?}", diagnostic);
768 return None;
813 return None;
769 };
814 };
770−
771 let severity =
815 let severity =
772 diagnostic.severity.map(|severity| match severity {
816 diagnostic.severity.map(|severity| match severity {
773 DiagnosticSeverity::ERROR => Error,
817 DiagnosticSeverity::ERROR => Error,
@@ -780,7 +824,7 @@ impl Application {
780 ),
824 ),
781 });
825 });
782
826
783− if let Some(lang_conf) = lang_conf {
827+ if let Some(lang_conf) = &lang_conf {
784 if let Some(severity) = severity {
828 if let Some(severity) = severity {
785 if severity < lang_conf.diagnostic_severity {
829 if severity < lang_conf.diagnostic_severity {
786 return None;
830 return None;
@@ -819,8 +863,17 @@ impl Application {
819 Vec::new()
863 Vec::new()
820 };
864 };
821
865
866+ let ends_at_word = start != end
867+ && end != 0
868+ && text.get_char(end - 1).map_or(false, char_is_word);
869+ let starts_at_word = start != end
870+ && text.get_char(start).map_or(false, char_is_word);
871+
822 Some(Diagnostic {
872 Some(Diagnostic {
823 range: Range { start, end },
873 range: Range { start, end },
874+ ends_at_word,
875+ starts_at_word,
876+ zero_width: start == end,
824 line: diagnostic.range.start.line as usize,
877 line: diagnostic.range.start.line as usize,
825 message: diagnostic.message.clone(),
878 message: diagnostic.message.clone(),
826 severity,
879 severity,
@@ -830,38 +883,33 @@ impl Application {
830 data: diagnostic.data.clone(),
883 data: diagnostic.data.clone(),
831 language_server_id: server_id,
884 language_server_id: server_id,
832 })
885 })
833− })
886+ });
834− .collect();
835
887
836− doc.replace_diagnostics(diagnostics, server_id);
888+ doc.replace_diagnostics(diagnostics, unchaged_diag_sources, server_id);
837 }
889 }
838
890
839− let mut diagnostics = params
891+ let diagnostics = params.diagnostics.into_iter().map(|d| (d, server_id));
840− .diagnostics
841− .into_iter()
842− .map(|d| (d, server_id))
843− .collect();
844
892
845 // Insert the original lsp::Diagnostics here because we may have no open document
893 // Insert the original lsp::Diagnostics here because we may have no open document
846 // for diagnosic message and so we can't calculate the exact position.
894 // for diagnosic message and so we can't calculate the exact position.
847 // When using them later in the diagnostics picker, we calculate them on-demand.
895 // When using them later in the diagnostics picker, we calculate them on-demand.
848− match self.editor.diagnostics.entry(params.uri) {
896+ let diagnostics = match self.editor.diagnostics.entry(params.uri) {
849 Entry::Occupied(o) => {
897 Entry::Occupied(o) => {
850 let current_diagnostics = o.into_mut();
898 let current_diagnostics = o.into_mut();
851 // there may entries of other language servers, which is why we can't overwrite the whole entry
899 // there may entries of other language servers, which is why we can't overwrite the whole entry
852 current_diagnostics.retain(|(_, lsp_id)| *lsp_id != server_id);
900 current_diagnostics.retain(|(_, lsp_id)| *lsp_id != server_id);
853− current_diagnostics.append(&mut diagnostics);
901+ current_diagnostics.extend(diagnostics);
854− // Sort diagnostics first by severity and then by line numbers.
855− // Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order
856 current_diagnostics
902 current_diagnostics
857− .sort_unstable_by_key(|(d, _)| (d.severity, d.range.start));
903+ // Sort diagnostics first by severity and then by line numbers.
858− }
859− Entry::Vacant(v) => {
860− diagnostics
861− .sort_unstable_by_key(|(d, _)| (d.severity, d.range.start));
862− v.insert(diagnostics);
863 }
904 }
905+ Entry::Vacant(v) => v.insert(diagnostics.collect()),
864 };
906 };
907+
908+ // Sort diagnostics first by severity and then by line numbers.
909+ // Note: The `lsp::DiagnosticSeverity` enum is already defined in decreasing order
910+ diagnostics.sort_unstable_by_key(|(d, server_id)| {
911+ (d.severity, d.range.start, *server_id)
912+ });
865 }
913 }
866 Notification::ShowMessage(params) => {
914 Notification::ShowMessage(params) => {
867 log::warn!("unhandled window/showMessage: {:?}", params);
915 log::warn!("unhandled window/showMessage: {:?}", params);
helix-term/src/args.rs+29
@@ -17,12 +17,14 @@ pub struct Args {
17 pub log_file: Option<PathBuf>,
17 pub log_file: Option<PathBuf>,
18 pub config_file: Option<PathBuf>,
18 pub config_file: Option<PathBuf>,
19 pub files: Vec<(PathBuf, Position)>,
19 pub files: Vec<(PathBuf, Position)>,
20+ pub working_directory: Option<PathBuf>,
20}
21}
21
22
22impl Args {
23impl Args {
23 pub fn parse_args() -> Result<Args> {
24 pub fn parse_args() -> Result<Args> {
24 let mut args = Args::default();
25 let mut args = Args::default();
25 let mut argv = std::env::args().peekable();
26 let mut argv = std::env::args().peekable();
27+ let mut line_number = 0;
26
28
27 argv.next(); // skip the program, we don't care about that
29 argv.next(); // skip the program, we don't care about that
28
30
@@ -59,6 +61,20 @@ impl Args {
59 Some(path) => args.log_file = Some(path.into()),
61 Some(path) => args.log_file = Some(path.into()),
60 None => anyhow::bail!("--log must specify a path to write"),
62 None => anyhow::bail!("--log must specify a path to write"),
61 },
63 },
64+ "-w" | "--working-dir" => match argv.next().as_deref() {
65+ Some(path) => {
66+ args.working_directory = if Path::new(path).is_dir() {
67+ Some(PathBuf::from(path))
68+ } else {
69+ anyhow::bail!(
70+ "--working-dir specified does not exist or is not a directory"
71+ )
72+ }
73+ }
74+ None => {
75+ anyhow::bail!("--working-dir must specify an initial working directory")
76+ }
77+ },
62 arg if arg.starts_with("--") => {
78 arg if arg.starts_with("--") => {
63 anyhow::bail!("unexpected double dash argument: {}", arg)
79 anyhow::bail!("unexpected double dash argument: {}", arg)
64 }
80 }
@@ -73,6 +89,13 @@ impl Args {
73 }
89 }
74 }
90 }
75 }
91 }
92+ arg if arg.starts_with('+') => {
93+ let arg = &arg[1..];
94+ line_number = match arg.parse::<usize>() {
95+ Ok(n) => n.saturating_sub(1),
96+ _ => anyhow::bail!("bad line number after +"),
97+ };
98+ }
76 arg => args.files.push(parse_file(arg)),
99 arg => args.files.push(parse_file(arg)),
77 }
100 }
78 }
101 }
@@ -82,6 +105,12 @@ impl Args {
82 args.files.push(parse_file(&arg));
105 args.files.push(parse_file(&arg));
83 }
106 }
84
107
108+ if let Some(file) = args.files.first_mut() {
109+ if line_number != 0 {
110+ file.1.row = line_number;
111+ }
112+ }
113+
85 Ok(args)
114 Ok(args)
86 }
115 }
87}
116}
helix-term/src/commands.rs+193−97
@@ -60,8 +60,13 @@ use crate::{
60
60
61use crate::job::{self, Jobs};
61use crate::job::{self, Jobs};
62use futures_util::{stream::FuturesUnordered, TryStreamExt};
62use futures_util::{stream::FuturesUnordered, TryStreamExt};
63+use std::{
63−use std::{collections::HashMap, fmt, future::Future};
64+ collections::{HashMap, HashSet},
65+ fmt,
66+ future::Future,
67+ io::Read,
64−use std::{collections::HashSet, num::NonZeroUsize};
68+ num::NonZeroUsize,
69+};
65
70
66use std::{
71use std::{
67 borrow::Cow,
72 borrow::Cow,
@@ -70,6 +75,7 @@ use std::{
70
75
71use once_cell::sync::Lazy;
76use once_cell::sync::Lazy;
72use serde::de::{self, Deserialize, Deserializer};
77use serde::de::{self, Deserialize, Deserializer};
78+use url::Url;
73
79
74use grep_regex::RegexMatcherBuilder;
80use grep_regex::RegexMatcherBuilder;
75use grep_searcher::{sinks, BinaryDetection, SearcherBuilder};
81use grep_searcher::{sinks, BinaryDetection, SearcherBuilder};
@@ -331,7 +337,7 @@ impl MappableCommand {
331 goto_implementation, "Goto implementation",
337 goto_implementation, "Goto implementation",
332 goto_file_start, "Goto line number <n> else file start",
338 goto_file_start, "Goto line number <n> else file start",
333 goto_file_end, "Goto file end",
339 goto_file_end, "Goto file end",
334− goto_file, "Goto files in selection",
340+ goto_file, "Goto files/URLs in selection",
335 goto_file_hsplit, "Goto files in selection (hsplit)",
341 goto_file_hsplit, "Goto files in selection (hsplit)",
336 goto_file_vsplit, "Goto files in selection (vsplit)",
342 goto_file_vsplit, "Goto files in selection (vsplit)",
337 goto_reference, "Goto references",
343 goto_reference, "Goto references",
@@ -984,6 +990,7 @@ fn align_selections(cx: &mut Context) {
984
990
985 let transaction = Transaction::change(doc.text(), changes.into_iter());
991 let transaction = Transaction::change(doc.text(), changes.into_iter());
986 doc.apply(&transaction, view.id);
992 doc.apply(&transaction, view.id);
993+ exit_select_mode(cx);
987}
994}
988
995
989fn goto_window(cx: &mut Context, align: Align) {
996fn goto_window(cx: &mut Context, align: Align) {
@@ -1189,10 +1196,53 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
1189 .to_string(),
1196 .to_string(),
1190 );
1197 );
1191 }
1198 }
1199+
1192 for sel in paths {
1200 for sel in paths {
1193 let p = sel.trim();
1201 let p = sel.trim();
1194− if !p.is_empty() {
1202+ if p.is_empty() {
1203+ continue;
1204+ }
1205+
1206+ if let Ok(url) = Url::parse(p) {
1207+ return open_url(cx, url, action);
1208+ }
1209+
1195− let path = &rel_path.join(p);
1210+ let path = &rel_path.join(p);
1211+ if path.is_dir() {
1212+ let picker = ui::file_picker(path.into(), &cx.editor.config());
1213+ cx.push_layer(Box::new(overlaid(picker)));
1214+ } else if let Err(e) = cx.editor.open(path, action) {
1215+ cx.editor.set_error(format!("Open file failed: {:?}", e));
1216+ }
1217+ }
1218+}
1219+
1220+/// Opens the given url. If the URL points to a valid textual file it is open in helix.
1221+// Otherwise, the file is open using external program.
1222+fn open_url(cx: &mut Context, url: Url, action: Action) {
1223+ let doc = doc!(cx.editor);
1224+ let rel_path = doc
1225+ .relative_path()
1226+ .map(|path| path.parent().unwrap().to_path_buf())
1227+ .unwrap_or_default();
1228+
1229+ if url.scheme() != "file" {
1230+ return open_external_url(cx, url);
1231+ }
1232+
1233+ let content_type = std::fs::File::open(url.path()).and_then(|file| {
1234+ // Read up to 1kb to detect the content type
1235+ let mut read_buffer = Vec::new();
1236+ let n = file.take(1024).read_to_end(&mut read_buffer)?;
1237+ Ok(content_inspector::inspect(&read_buffer[..n]))
1238+ });
1239+
1240+ // we attempt to open binary files - files that can't be open in helix - using external
1241+ // program as well, e.g. pdf files or images
1242+ match content_type {
1243+ Ok(content_inspector::ContentType::BINARY) => open_external_url(cx, url),
1244+ Ok(_) | Err(_) => {
1245+ let path = &rel_path.join(url.path());
1196 if path.is_dir() {
1246 if path.is_dir() {
1197 let picker = ui::file_picker(path.into(), &cx.editor.config());
1247 let picker = ui::file_picker(path.into(), &cx.editor.config());
1198 cx.push_layer(Box::new(overlaid(picker)));
1248 cx.push_layer(Box::new(overlaid(picker)));
@@ -1203,6 +1253,23 @@ fn goto_file_impl(cx: &mut Context, action: Action) {
1203 }
1253 }
1204}
1254}
1205
1255
1256+/// Opens URL in external program.
1257+fn open_external_url(cx: &mut Context, url: Url) {
1258+ let commands = open::commands(url.as_str());
1259+ cx.jobs.callback(async {
1260+ for cmd in commands {
1261+ let mut command = tokio::process::Command::new(cmd.get_program());
1262+ command.args(cmd.get_args());
1263+ if command.output().await.is_ok() {
1264+ return Ok(job::Callback::Editor(Box::new(|_| {})));
1265+ }
1266+ }
1267+ Ok(job::Callback::Editor(Box::new(move |editor| {
1268+ editor.set_error("Opening URL in external program failed")
1269+ })))
1270+ });
1271+}
1272+
1206fn extend_word_impl<F>(cx: &mut Context, extend_fn: F)
1273fn extend_word_impl<F>(cx: &mut Context, extend_fn: F)
1207where
1274where
1208 F: Fn(RopeSlice, Range, usize) -> Range,
1275 F: Fn(RopeSlice, Range, usize) -> Range,
@@ -1251,7 +1318,7 @@ fn extend_next_long_word_end(cx: &mut Context) {
1251 extend_word_impl(cx, movement::move_next_long_word_end)
1318 extend_word_impl(cx, movement::move_next_long_word_end)
1252}
1319}
1253
1320
1254−/// Separate branch to find_char designed only for <ret> char.
1321+/// Separate branch to find_char designed only for `<ret>` char.
1255//
1322//
1256// This is necessary because the one document can have different line endings inside. And we
1323// This is necessary because the one document can have different line endings inside. And we
1257// cannot predict what character to find when <ret> is pressed. On the current line it can be `lf`
1324// cannot predict what character to find when <ret> is pressed. On the current line it can be `lf`
@@ -1527,6 +1594,7 @@ where
1527 });
1594 });
1528
1595
1529 doc.apply(&transaction, view.id);
1596 doc.apply(&transaction, view.id);
1597+ exit_select_mode(cx);
1530}
1598}
1531
1599
1532fn switch_case(cx: &mut Context) {
1600fn switch_case(cx: &mut Context) {
@@ -2184,7 +2252,10 @@ fn global_search(cx: &mut Context) {
2184 let searcher = SearcherBuilder::new()
2252 let searcher = SearcherBuilder::new()
2185 .binary_detection(BinaryDetection::quit(b'\x00'))
2253 .binary_detection(BinaryDetection::quit(b'\x00'))
2186 .build();
2254 .build();
2255+
2187− WalkBuilder::new(search_root)
2256+ let mut walk_builder = WalkBuilder::new(search_root);
2257+
2258+ walk_builder
2188 .hidden(file_picker_config.hidden)
2259 .hidden(file_picker_config.hidden)
2189 .parents(file_picker_config.parents)
2260 .parents(file_picker_config.parents)
2190 .ignore(file_picker_config.ignore)
2261 .ignore(file_picker_config.ignore)
@@ -2195,73 +2266,77 @@ fn global_search(cx: &mut Context) {
2195 .max_depth(file_picker_config.max_depth)
2266 .max_depth(file_picker_config.max_depth)
2196 .filter_entry(move |entry| {
2267 .filter_entry(move |entry| {
2197 filter_picker_entry(entry, &absolute_root, dedup_symlinks)
2268 filter_picker_entry(entry, &absolute_root, dedup_symlinks)
2198− })
2269+ });
2199− .build_parallel()
2200− .run(|| {
2201− let mut searcher = searcher.clone();
2202− let matcher = matcher.clone();
2203− let injector = injector_.clone();
2204− let documents = &documents;
2205− Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
2206− let entry = match entry {
2207− Ok(entry) => entry,
2208− Err(_) => return WalkState::Continue,
2209− };
2210−
2211− match entry.file_type() {
2212− Some(entry) if entry.is_file() => {}
2213− // skip everything else
2214− _ => return WalkState::Continue,
2215− };
2216−
2217− let mut stop = false;
2218− let sink = sinks::UTF8(|line_num, _| {
2219− stop = injector
2220− .push(FileResult::new(entry.path(), line_num as usize - 1))
2221− .is_err();
2222−
2223− Ok(!stop)
2224− });
2225− let doc = documents.iter().find(|&(doc_path, _)| {
2226− doc_path
2227− .as_ref()
2228− .map_or(false, |doc_path| doc_path == entry.path())
2229− });
2230−
2231− let result = if let Some((_, doc)) = doc {
2232− // there is already a buffer for this file
2233− // search the buffer instead of the file because it's faster
2234− // and captures new edits without requiring a save
2235− if searcher.multi_line_with_matcher(&matcher) {
2236− // in this case a continous buffer is required
2237− // convert the rope to a string
2238− let text = doc.to_string();
2239− searcher.search_slice(&matcher, text.as_bytes(), sink)
2240− } else {
2241− searcher.search_reader(
2242− &matcher,
2243− RopeReader::new(doc.slice(..)),
2244− sink,
2245− )
2246− }
2247− } else {
2248− searcher.search_path(&matcher, entry.path(), sink)
2249− };
2250
2270
2251− if let Err(err) = result {
2271+ walk_builder
2252− log::error!(
2272+ .add_custom_ignore_filename(helix_loader::config_dir().join("ignore"));
2253− "Global search error: {}, {}",
2273+ walk_builder.add_custom_ignore_filename(".helix/ignore");
2254− entry.path().display(),
2274+
2255− err
2275+ walk_builder.build_parallel().run(|| {
2256− );
2276+ let mut searcher = searcher.clone();
2257− }
2277+ let matcher = matcher.clone();
2258− if stop {
2278+ let injector = injector_.clone();
2259− WalkState::Quit
2279+ let documents = &documents;
2280+ Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
2281+ let entry = match entry {
2282+ Ok(entry) => entry,
2283+ Err(_) => return WalkState::Continue,
2284+ };
2285+
2286+ match entry.file_type() {
2287+ Some(entry) if entry.is_file() => {}
2288+ // skip everything else
2289+ _ => return WalkState::Continue,
2290+ };
2291+
2292+ let mut stop = false;
2293+ let sink = sinks::UTF8(|line_num, _| {
2294+ stop = injector
2295+ .push(FileResult::new(entry.path(), line_num as usize - 1))
2296+ .is_err();
2297+
2298+ Ok(!stop)
2299+ });
2300+ let doc = documents.iter().find(|&(doc_path, _)| {
2301+ doc_path
2302+ .as_ref()
2303+ .map_or(false, |doc_path| doc_path == entry.path())
2304+ });
2305+
2306+ let result = if let Some((_, doc)) = doc {
2307+ // there is already a buffer for this file
2308+ // search the buffer instead of the file because it's faster
2309+ // and captures new edits without requiring a save
2310+ if searcher.multi_line_with_matcher(&matcher) {
2311+ // in this case a continous buffer is required
2312+ // convert the rope to a string
2313+ let text = doc.to_string();
2314+ searcher.search_slice(&matcher, text.as_bytes(), sink)
2260 } else {
2315 } else {
2261− WalkState::Continue
2316+ searcher.search_reader(
2317+ &matcher,
2318+ RopeReader::new(doc.slice(..)),
2319+ sink,
2320+ )
2262 }
2321 }
2263− })
2322+ } else {
2323+ searcher.search_path(&matcher, entry.path(), sink)
2324+ };
2325+
2326+ if let Err(err) = result {
2327+ log::error!(
2328+ "Global search error: {}, {}",
2329+ entry.path().display(),
2330+ err
2331+ );
2332+ }
2333+ if stop {
2334+ WalkState::Quit
2335+ } else {
2336+ WalkState::Continue
2337+ }
2264− });
2338+ })
2339+ });
2265 });
2340 });
2266
2341
2267 cx.jobs.callback(async move {
2342 cx.jobs.callback(async move {
@@ -2978,6 +3053,7 @@ fn insert_with_indent(cx: &mut Context, cursor_fallback: IndentFallbackPos) {
2978 let indent = indent::indent_for_newline(
3053 let indent = indent::indent_for_newline(
2979 language_config,
3054 language_config,
2980 syntax,
3055 syntax,
3056+ &doc.config.load().indent_heuristic,
2981 &doc.indent_style,
3057 &doc.indent_style,
2982 tab_width,
3058 tab_width,
2983 text,
3059 text,
@@ -3106,6 +3182,7 @@ fn open(cx: &mut Context, open: Open) {
3106 let indent = indent::indent_for_newline(
3182 let indent = indent::indent_for_newline(
3107 doc.language_config(),
3183 doc.language_config(),
3108 doc.syntax(),
3184 doc.syntax(),
3185+ &doc.config.load().indent_heuristic,
3109 &doc.indent_style,
3186 &doc.indent_style,
3110 doc.tab_width(),
3187 doc.tab_width(),
3111 text,
3188 text,
@@ -3645,6 +3722,7 @@ pub mod insert {
3645 let indent = indent::indent_for_newline(
3722 let indent = indent::indent_for_newline(
3646 doc.language_config(),
3723 doc.language_config(),
3647 doc.syntax(),
3724 doc.syntax(),
3725+ &doc.config.load().indent_heuristic,
3648 &doc.indent_style,
3726 &doc.indent_style,
3649 doc.tab_width(),
3727 doc.tab_width(),
3650 text,
3728 text,
@@ -3890,12 +3968,12 @@ fn yank(cx: &mut Context) {
3890}
3968}
3891
3969
3892fn yank_to_clipboard(cx: &mut Context) {
3970fn yank_to_clipboard(cx: &mut Context) {
3893− yank_impl(cx.editor, '*');
3971+ yank_impl(cx.editor, '+');
3894 exit_select_mode(cx);
3972 exit_select_mode(cx);
3895}
3973}
3896
3974
3897fn yank_to_primary_clipboard(cx: &mut Context) {
3975fn yank_to_primary_clipboard(cx: &mut Context) {
3898− yank_impl(cx.editor, '+');
3976+ yank_impl(cx.editor, '*');
3899 exit_select_mode(cx);
3977 exit_select_mode(cx);
3900}
3978}
3901
3979
@@ -3952,13 +4030,13 @@ fn yank_joined(cx: &mut Context) {
3952
4030
3953fn yank_joined_to_clipboard(cx: &mut Context) {
4031fn yank_joined_to_clipboard(cx: &mut Context) {
3954 let line_ending = doc!(cx.editor).line_ending;
4032 let line_ending = doc!(cx.editor).line_ending;
3955− yank_joined_impl(cx.editor, line_ending.as_str(), '*');
4033+ yank_joined_impl(cx.editor, line_ending.as_str(), '+');
3956 exit_select_mode(cx);
4034 exit_select_mode(cx);
3957}
4035}
3958
4036
3959fn yank_joined_to_primary_clipboard(cx: &mut Context) {
4037fn yank_joined_to_primary_clipboard(cx: &mut Context) {
3960 let line_ending = doc!(cx.editor).line_ending;
4038 let line_ending = doc!(cx.editor).line_ending;
3961− yank_joined_impl(cx.editor, line_ending.as_str(), '+');
4039+ yank_joined_impl(cx.editor, line_ending.as_str(), '*');
3962 exit_select_mode(cx);
4040 exit_select_mode(cx);
3963}
4041}
3964
4042
@@ -3975,12 +4053,12 @@ fn yank_primary_selection_impl(editor: &mut Editor, register: char) {
3975}
4053}
3976
4054
3977fn yank_main_selection_to_clipboard(cx: &mut Context) {
4055fn yank_main_selection_to_clipboard(cx: &mut Context) {
3978− yank_primary_selection_impl(cx.editor, '*');
4056+ yank_primary_selection_impl(cx.editor, '+');
3979 exit_select_mode(cx);
4057 exit_select_mode(cx);
3980}
4058}
3981
4059
3982fn yank_main_selection_to_primary_clipboard(cx: &mut Context) {
4060fn yank_main_selection_to_primary_clipboard(cx: &mut Context) {
3983− yank_primary_selection_impl(cx.editor, '+');
4061+ yank_primary_selection_impl(cx.editor, '*');
3984 exit_select_mode(cx);
4062 exit_select_mode(cx);
3985}
4063}
3986
4064
@@ -4078,22 +4156,27 @@ pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
4078 };
4156 };
4079 let (view, doc) = current!(cx.editor);
4157 let (view, doc) = current!(cx.editor);
4080 paste_impl(&[contents], doc, view, paste, count, cx.editor.mode);
4158 paste_impl(&[contents], doc, view, paste, count, cx.editor.mode);
4159+ exit_select_mode(cx);
4081}
4160}
4082
4161
4083fn paste_clipboard_after(cx: &mut Context) {
4162fn paste_clipboard_after(cx: &mut Context) {
4084− paste(cx.editor, '*', Paste::After, cx.count());
4163+ paste(cx.editor, '+', Paste::After, cx.count());
4164+ exit_select_mode(cx);
4085}
4165}
4086
4166
4087fn paste_clipboard_before(cx: &mut Context) {
4167fn paste_clipboard_before(cx: &mut Context) {
4088− paste(cx.editor, '*', Paste::Before, cx.count());
4168+ paste(cx.editor, '+', Paste::Before, cx.count());
4169+ exit_select_mode(cx);
4089}
4170}
4090
4171
4091fn paste_primary_clipboard_after(cx: &mut Context) {
4172fn paste_primary_clipboard_after(cx: &mut Context) {
4092− paste(cx.editor, '+', Paste::After, cx.count());
4173+ paste(cx.editor, '*', Paste::After, cx.count());
4174+ exit_select_mode(cx);
4093}
4175}
4094
4176
4095fn paste_primary_clipboard_before(cx: &mut Context) {
4177fn paste_primary_clipboard_before(cx: &mut Context) {
4096− paste(cx.editor, '+', Paste::Before, cx.count());
4178+ paste(cx.editor, '*', Paste::Before, cx.count());
4179+ exit_select_mode(cx);
4097}
4180}
4098
4181
4099fn replace_with_yanked(cx: &mut Context) {
4182fn replace_with_yanked(cx: &mut Context) {
@@ -4131,11 +4214,13 @@ fn replace_with_yanked_impl(editor: &mut Editor, register: char, count: usize) {
4131}
4214}
4132
4215
4133fn replace_selections_with_clipboard(cx: &mut Context) {
4216fn replace_selections_with_clipboard(cx: &mut Context) {
4134− replace_with_yanked_impl(cx.editor, '*', cx.count());
4217+ replace_with_yanked_impl(cx.editor, '+', cx.count());
4218+ exit_select_mode(cx);
4135}
4219}
4136
4220
4137fn replace_selections_with_primary_clipboard(cx: &mut Context) {
4221fn replace_selections_with_primary_clipboard(cx: &mut Context) {
4138− replace_with_yanked_impl(cx.editor, '+', cx.count());
4222+ replace_with_yanked_impl(cx.editor, '*', cx.count());
4223+ exit_select_mode(cx);
4139}
4224}
4140
4225
4141fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) {
4226fn paste(editor: &mut Editor, register: char, pos: Paste, count: usize) {
@@ -4153,6 +4238,7 @@ fn paste_after(cx: &mut Context) {
4153 Paste::After,
4238 Paste::After,
4154 cx.count(),
4239 cx.count(),
4155 );
4240 );
4241+ exit_select_mode(cx);
4156}
4242}
4157
4243
4158fn paste_before(cx: &mut Context) {
4244fn paste_before(cx: &mut Context) {
@@ -4162,6 +4248,7 @@ fn paste_before(cx: &mut Context) {
4162 Paste::Before,
4248 Paste::Before,
4163 cx.count(),
4249 cx.count(),
4164 );
4250 );
4251+ exit_select_mode(cx);
4165}
4252}
4166
4253
4167fn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {
4254fn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {
@@ -4200,6 +4287,7 @@ fn indent(cx: &mut Context) {
4200 }),
4287 }),
4201 );
4288 );
4202 doc.apply(&transaction, view.id);
4289 doc.apply(&transaction, view.id);
4290+ exit_select_mode(cx);
4203}
4291}
4204
4292
4205fn unindent(cx: &mut Context) {
4293fn unindent(cx: &mut Context) {
@@ -4239,6 +4327,7 @@ fn unindent(cx: &mut Context) {
4239 let transaction = Transaction::change(doc.text(), changes.into_iter());
4327 let transaction = Transaction::change(doc.text(), changes.into_iter());
4240
4328
4241 doc.apply(&transaction, view.id);
4329 doc.apply(&transaction, view.id);
4330+ exit_select_mode(cx);
4242}
4331}
4243
4332
4244fn format_selections(cx: &mut Context) {
4333fn format_selections(cx: &mut Context) {
@@ -4305,10 +4394,9 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
4305 use movement::skip_while;
4394 use movement::skip_while;
4306 let (view, doc) = current!(cx.editor);
4395 let (view, doc) = current!(cx.editor);
4307 let text = doc.text();
4396 let text = doc.text();
4308− let slice = doc.text().slice(..);
4397+ let slice = text.slice(..);
4309
4398
4310 let mut changes = Vec::new();
4399 let mut changes = Vec::new();
4311− let fragment = Tendril::from(" ");
4312
4400
4313 for selection in doc.selection(view.id) {
4401 for selection in doc.selection(view.id) {
4314 let (start, mut end) = selection.line_range(slice);
4402 let (start, mut end) = selection.line_range(slice);
@@ -4324,9 +4412,13 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
4324 let mut end = text.line_to_char(line + 1);
4412 let mut end = text.line_to_char(line + 1);
4325 end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\t')).unwrap_or(end);
4413 end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\t')).unwrap_or(end);
4326
4414
4327− // need to skip from start, not end
4415+ let separator = if end == line_end_char_index(&slice, line + 1) {
4328− let change = (start, end, Some(fragment.clone()));
4416+ // the joining line contains only space-characters => don't include a whitespace when joining
4417+ None
4418+ } else {
4419+ Some(Tendril::from(" "))
4420+ };
4329− changes.push(change);
4421+ changes.push((start, end, separator));
4330 }
4422 }
4331 }
4423 }
4332
4424
@@ -4338,9 +4430,6 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
4338 changes.sort_unstable_by_key(|(from, _to, _text)| *from);
4430 changes.sort_unstable_by_key(|(from, _to, _text)| *from);
4339 changes.dedup();
4431 changes.dedup();
4340
4432
4341− // TODO: joining multiple empty lines should be replaced by a single space.
4342− // need to merge change ranges that touch
4343−
4344 // select inserted spaces
4433 // select inserted spaces
4345 let transaction = if select_space {
4434 let transaction = if select_space {
4346 let ranges: SmallVec<_> = changes
4435 let ranges: SmallVec<_> = changes
@@ -4352,9 +4441,9 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
4352 })
4441 })
4353 .collect();
4442 .collect();
4354 let selection = Selection::new(ranges, 0);
4443 let selection = Selection::new(ranges, 0);
4355− Transaction::change(doc.text(), changes.into_iter()).with_selection(selection)
4444+ Transaction::change(text, changes.into_iter()).with_selection(selection)
4356 } else {
4445 } else {
4357− Transaction::change(doc.text(), changes.into_iter())
4446+ Transaction::change(text, changes.into_iter())
4358 };
4447 };
4359
4448
4360 doc.apply(&transaction, view.id);
4449 doc.apply(&transaction, view.id);
@@ -5520,12 +5609,18 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
5520 };
5609 };
5521
5610
5522 // These `usize`s cannot underflow because selection ranges cannot overlap.
5611 // These `usize`s cannot underflow because selection ranges cannot overlap.
5523− // Once the MSRV is 1.66.0 (mixed_integer_ops is stabilized), we can use checked
5612+ let anchor = to
5524− // arithmetic to assert this.
5613+ .checked_add_signed(offset)
5525− let anchor = (to as isize + offset - deleted_len as isize) as usize;
5614+ .expect("Selection ranges cannot overlap")
5615+ .checked_sub(deleted_len)
5616+ .expect("Selection ranges cannot overlap");
5526 let new_range = Range::new(anchor, anchor + output_len).with_direction(range.direction());
5617 let new_range = Range::new(anchor, anchor + output_len).with_direction(range.direction());
5527 ranges.push(new_range);
5618 ranges.push(new_range);
5528− offset = offset + output_len as isize - deleted_len as isize;
5619+ offset = offset
5620+ .checked_add_unsigned(output_len)
5621+ .expect("Selection ranges cannot overlap")
5622+ .checked_sub_unsigned(deleted_len)
5623+ .expect("Selection ranges cannot overlap");
5529
5624
5530 changes.push((from, to, Some(output)));
5625 changes.push((from, to, Some(output)));
5531 }
5626 }
@@ -5664,6 +5759,7 @@ fn increment_impl(cx: &mut Context, increment_direction: IncrementDirection) {
5664 let transaction = Transaction::change(doc.text(), changes.into_iter());
5759 let transaction = Transaction::change(doc.text(), changes.into_iter());
5665 let transaction = transaction.with_selection(new_selection);
5760 let transaction = transaction.with_selection(new_selection);
5666 doc.apply(&transaction, view.id);
5761 doc.apply(&transaction, view.id);
5762+ exit_select_mode(cx);
5667 }
5763 }
5668}
5764}
5669
5765
helix-term/src/commands/dap.rs+7−2
@@ -8,7 +8,7 @@ use dap::{StackFrame, Thread, ThreadStates};
8use helix_core::syntax::{DebugArgumentValue, DebugConfigCompletion, DebugTemplate};
8use helix_core::syntax::{DebugArgumentValue, DebugConfigCompletion, DebugTemplate};
9use helix_dap::{self as dap, Client};
9use helix_dap::{self as dap, Client};
10use helix_lsp::block_on;
10use helix_lsp::block_on;
11−use helix_view::editor::Breakpoint;
11+use helix_view::{editor::Breakpoint, graphics::Margin};
12
12
13use serde_json::{to_value, Value};
13use serde_json::{to_value, Value};
14use tokio_stream::wrappers::UnboundedReceiverStream;
14use tokio_stream::wrappers::UnboundedReceiverStream;
@@ -581,7 +581,12 @@ pub fn dap_variables(cx: &mut Context) {
581 }
581 }
582
582
583 let contents = Text::from(tui::text::Text::from(variables));
583 let contents = Text::from(tui::text::Text::from(variables));
584+ let margin = if cx.editor.popup_border() {
585+ Margin::all(1)
586+ } else {
587+ Margin::none()
588+ };
584− let popup = Popup::new("dap-variables", contents);
589+ let popup = Popup::new("dap-variables", contents).margin(margin);
585 cx.replace_or_push_layer("dap-variables", popup);
590 cx.replace_or_push_layer("dap-variables", popup);
586}
591}
587
592
helix-term/src/commands/lsp.rs+12−2
@@ -23,6 +23,7 @@ use helix_core::{
23use helix_view::{
23use helix_view::{
24 document::{DocumentInlayHints, DocumentInlayHintsId, Mode},
24 document::{DocumentInlayHints, DocumentInlayHintsId, Mode},
25 editor::Action,
25 editor::Action,
26+ graphics::Margin,
26 theme::Style,
27 theme::Style,
27 Document, View,
28 Document, View,
28};
29};
@@ -49,7 +50,7 @@ use std::{
49/// If there is no configured language server that supports the feature, this displays a status message.
50/// If there is no configured language server that supports the feature, this displays a status message.
50/// Using this macro in a context where the editor automatically queries the LSP
51/// Using this macro in a context where the editor automatically queries the LSP
51/// (instead of when the user explicitly does so via a keybind like `gd`)
52/// (instead of when the user explicitly does so via a keybind like `gd`)
52−/// will spam the "No configured language server supports <feature>" status message confusingly.
53+/// will spam the "No configured language server supports \<feature>" status message confusingly.
53#[macro_export]
54#[macro_export]
54macro_rules! language_server_with_feature {
55macro_rules! language_server_with_feature {
55 ($editor:expr, $doc:expr, $feature:expr) => {{
56 ($editor:expr, $doc:expr, $feature:expr) => {{
@@ -744,7 +745,16 @@ pub fn code_action(cx: &mut Context) {
744 });
745 });
745 picker.move_down(); // pre-select the first item
746 picker.move_down(); // pre-select the first item
746
747
748+ let margin = if editor.menu_border() {
749+ Margin::vertical(1)
750+ } else {
751+ Margin::none()
752+ };
753+
747− let popup = Popup::new("code-action", picker).with_scrollbar(false);
754+ let popup = Popup::new("code-action", picker)
755+ .with_scrollbar(false)
756+ .margin(margin);
757+
748 compositor.replace_or_push("code-action", popup);
758 compositor.replace_or_push("code-action", popup);
749 };
759 };
750
760
helix-term/src/commands/typed.rs+97−16
@@ -6,7 +6,9 @@ use crate::job::Job;
6use super::*;
6use super::*;
7
7
8use helix_core::fuzzy::fuzzy_match;
8use helix_core::fuzzy::fuzzy_match;
9+use helix_core::indent::MAX_INDENT;
9−use helix_core::{encoding, line_ending, shellwords::Shellwords};
10+use helix_core::{encoding, line_ending, path::get_canonicalized_path, shellwords::Shellwords};
11+use helix_lsp::{OffsetEncoding, Url};
10use helix_view::document::DEFAULT_LANGUAGE_NAME;
12use helix_view::document::DEFAULT_LANGUAGE_NAME;
11use helix_view::editor::{Action, CloseError, ConfigEvent};
13use helix_view::editor::{Action, CloseError, ConfigEvent};
12use serde_json::Value;
14use serde_json::Value;
@@ -475,8 +477,7 @@ fn set_indent_style(
475 cx.editor.set_status(match style {
477 cx.editor.set_status(match style {
476 Tabs => "tabs".to_owned(),
478 Tabs => "tabs".to_owned(),
477 Spaces(1) => "1 space".to_owned(),
479 Spaces(1) => "1 space".to_owned(),
478− Spaces(n) if (2..=8).contains(&n) => format!("{} spaces", n),
480+ Spaces(n) => format!("{} spaces", n),
479− _ => unreachable!(), // Shouldn't happen.
480 });
481 });
481 return Ok(());
482 return Ok(());
482 }
483 }
@@ -488,7 +489,7 @@ fn set_indent_style(
488 Some(arg) => arg
489 Some(arg) => arg
489 .parse::<u8>()
490 .parse::<u8>()
490 .ok()
491 .ok()
491− .filter(|n| (1..=8).contains(n))
492+ .filter(|n| (1..=MAX_INDENT).contains(n))
492 .map(Spaces),
493 .map(Spaces),
493 _ => None,
494 _ => None,
494 };
495 };
@@ -573,7 +574,6 @@ fn set_line_ending(
573
574
574 Ok(())
575 Ok(())
575}
576}
576−
577fn earlier(
577fn earlier(
578 cx: &mut compositor::Context,
578 cx: &mut compositor::Context,
579 args: &[Cow<str>],
579 args: &[Cow<str>],
@@ -921,7 +921,7 @@ fn yank_main_selection_to_clipboard(
921 return Ok(());
921 return Ok(());
922 }
922 }
923
923
924− yank_primary_selection_impl(cx.editor, '*');
924+ yank_primary_selection_impl(cx.editor, '+');
925 Ok(())
925 Ok(())
926}
926}
927
927
@@ -956,7 +956,7 @@ fn yank_joined_to_clipboard(
956 let doc = doc!(cx.editor);
956 let doc = doc!(cx.editor);
957 let default_sep = Cow::Borrowed(doc.line_ending.as_str());
957 let default_sep = Cow::Borrowed(doc.line_ending.as_str());
958 let separator = args.first().unwrap_or(&default_sep);
958 let separator = args.first().unwrap_or(&default_sep);
959− yank_joined_impl(cx.editor, separator, '*');
959+ yank_joined_impl(cx.editor, separator, '+');
960 Ok(())
960 Ok(())
961}
961}
962
962
@@ -969,7 +969,7 @@ fn yank_main_selection_to_primary_clipboard(
969 return Ok(());
969 return Ok(());
970 }
970 }
971
971
972− yank_primary_selection_impl(cx.editor, '+');
972+ yank_primary_selection_impl(cx.editor, '*');
973 Ok(())
973 Ok(())
974}
974}
975
975
@@ -985,7 +985,7 @@ fn yank_joined_to_primary_clipboard(
985 let doc = doc!(cx.editor);
985 let doc = doc!(cx.editor);
986 let default_sep = Cow::Borrowed(doc.line_ending.as_str());
986 let default_sep = Cow::Borrowed(doc.line_ending.as_str());
987 let separator = args.first().unwrap_or(&default_sep);
987 let separator = args.first().unwrap_or(&default_sep);
988− yank_joined_impl(cx.editor, separator, '+');
988+ yank_joined_impl(cx.editor, separator, '*');
989 Ok(())
989 Ok(())
990}
990}
991
991
@@ -998,7 +998,7 @@ fn paste_clipboard_after(
998 return Ok(());
998 return Ok(());
999 }
999 }
1000
1000
1001− paste(cx.editor, '*', Paste::After, 1);
1001+ paste(cx.editor, '+', Paste::After, 1);
1002 Ok(())
1002 Ok(())
1003}
1003}
1004
1004
@@ -1011,7 +1011,7 @@ fn paste_clipboard_before(
1011 return Ok(());
1011 return Ok(());
1012 }
1012 }
1013
1013
1014− paste(cx.editor, '*', Paste::Before, 1);
1014+ paste(cx.editor, '+', Paste::Before, 1);
1015 Ok(())
1015 Ok(())
1016}
1016}
1017
1017
@@ -1024,7 +1024,7 @@ fn paste_primary_clipboard_after(
1024 return Ok(());
1024 return Ok(());
1025 }
1025 }
1026
1026
1027− paste(cx.editor, '+', Paste::After, 1);
1027+ paste(cx.editor, '*', Paste::After, 1);
1028 Ok(())
1028 Ok(())
1029}
1029}
1030
1030
@@ -1037,7 +1037,7 @@ fn paste_primary_clipboard_before(
1037 return Ok(());
1037 return Ok(());
1038 }
1038 }
1039
1039
1040− paste(cx.editor, '+', Paste::Before, 1);
1040+ paste(cx.editor, '*', Paste::Before, 1);
1041 Ok(())
1041 Ok(())
1042}
1042}
1043
1043
@@ -1050,7 +1050,7 @@ fn replace_selections_with_clipboard(
1050 return Ok(());
1050 return Ok(());
1051 }
1051 }
1052
1052
1053− replace_with_yanked_impl(cx.editor, '*', 1);
1053+ replace_with_yanked_impl(cx.editor, '+', 1);
1054 Ok(())
1054 Ok(())
1055}
1055}
1056
1056
@@ -1063,7 +1063,7 @@ fn replace_selections_with_primary_clipboard(
1063 return Ok(());
1063 return Ok(());
1064 }
1064 }
1065
1065
1066− replace_with_yanked_impl(cx.editor, '+', 1);
1066+ replace_with_yanked_impl(cx.editor, '*', 1);
1067 Ok(())
1067 Ok(())
1068}
1068}
1069
1069
@@ -2408,6 +2408,80 @@ fn redraw(
2408 Ok(())
2408 Ok(())
2409}
2409}
2410
2410
2411+fn move_buffer(
2412+ cx: &mut compositor::Context,
2413+ args: &[Cow<str>],
2414+ event: PromptEvent,
2415+) -> anyhow::Result<()> {
2416+ if event != PromptEvent::Validate {
2417+ return Ok(());
2418+ }
2419+
2420+ ensure!(args.len() == 1, format!(":move takes one argument"));
2421+ let doc = doc!(cx.editor);
2422+
2423+ let new_path = get_canonicalized_path(&PathBuf::from(args.first().unwrap().to_string()));
2424+ let old_path = doc
2425+ .path()
2426+ .ok_or_else(|| anyhow!("Scratch buffer cannot be moved. Use :write instead"))?
2427+ .clone();
2428+ let old_path_as_url = doc.url().unwrap();
2429+ let new_path_as_url = Url::from_file_path(&new_path).unwrap();
2430+
2431+ let edits: Vec<(
2432+ helix_lsp::Result<helix_lsp::lsp::WorkspaceEdit>,
2433+ OffsetEncoding,
2434+ String,
2435+ )> = doc
2436+ .language_servers()
2437+ .map(|lsp| {
2438+ (
2439+ lsp.prepare_file_rename(&old_path_as_url, &new_path_as_url),
2440+ lsp.offset_encoding(),
2441+ lsp.name().to_owned(),
2442+ )
2443+ })
2444+ .filter(|(f, _, _)| f.is_some())
2445+ .map(|(f, encoding, name)| (helix_lsp::block_on(f.unwrap()), encoding, name))
2446+ .collect();
2447+
2448+ for (lsp_reply, encoding, name) in edits {
2449+ match lsp_reply {
2450+ Ok(edit) => {
2451+ if let Err(e) = apply_workspace_edit(cx.editor, encoding, &edit) {
2452+ log::error!(
2453+ ":move command failed to apply edits from lsp {}: {:?}",
2454+ name,
2455+ e
2456+ );
2457+ };
2458+ }
2459+ Err(e) => {
2460+ log::error!("LSP {} failed to treat willRename request: {:?}", name, e);
2461+ }
2462+ };
2463+ }
2464+
2465+ let doc = doc_mut!(cx.editor);
2466+
2467+ doc.set_path(Some(new_path.as_path()));
2468+ if let Err(e) = std::fs::rename(&old_path, &new_path) {
2469+ doc.set_path(Some(old_path.as_path()));
2470+ bail!("Could not move file: {}", e);
2471+ };
2472+
2473+ doc.language_servers().for_each(|lsp| {
2474+ lsp.did_file_rename(&old_path_as_url, &new_path_as_url);
2475+ });
2476+
2477+ cx.editor
2478+ .language_servers
2479+ .file_event_handler
2480+ .file_changed(new_path);
2481+
2482+ Ok(())
2483+}
2484+
2411pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
2485pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
2412 TypableCommand {
2486 TypableCommand {
2413 name: "quit",
2487 name: "quit",
@@ -2531,7 +2605,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
2531 TypableCommand {
2605 TypableCommand {
2532 name: "indent-style",
2606 name: "indent-style",
2533 aliases: &[],
2607 aliases: &[],
2534− doc: "Set the indentation style for editing. ('t' for tabs or 1-8 for number of spaces.)",
2608+ doc: "Set the indentation style for editing. ('t' for tabs or 1-16 for number of spaces.)",
2535 fun: set_indent_style,
2609 fun: set_indent_style,
2536 signature: CommandSignature::none(),
2610 signature: CommandSignature::none(),
2537 },
2611 },
@@ -3008,6 +3082,13 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
3008 fun: redraw,
3082 fun: redraw,
3009 signature: CommandSignature::none(),
3083 signature: CommandSignature::none(),
3010 },
3084 },
3085+ TypableCommand {
3086+ name: "move",
3087+ aliases: &[],
3088+ doc: "Move the current buffer and its corresponding file to a different path",
3089+ fun: move_buffer,
3090+ signature: CommandSignature::positional(&[completers::filename]),
3091+ },
3011];
3092];
3012
3093
3013pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
3094pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableCommand>> =
helix-term/src/health.rs+44−16
@@ -181,8 +181,8 @@ pub fn languages_all() -> std::io::Result<()> {
181 .language
181 .language
182 .sort_unstable_by_key(|l| l.language_id.clone());
182 .sort_unstable_by_key(|l| l.language_id.clone());
183
183
184− let check_binary = |cmd: Option<String>| match cmd {
184+ let check_binary = |cmd: Option<&str>| match cmd {
185− Some(cmd) => match which::which(&cmd) {
185+ Some(cmd) => match which::which(cmd) {
186 Ok(_) => column(&format!("✓ {}", cmd), Color::Green),
186 Ok(_) => column(&format!("✓ {}", cmd), Color::Green),
187 Err(_) => column(&format!("✘ {}", cmd), Color::Red),
187 Err(_) => column(&format!("✘ {}", cmd), Color::Red),
188 },
188 },
@@ -192,17 +192,15 @@ pub fn languages_all() -> std::io::Result<()> {
192 for lang in &syn_loader_conf.language {
192 for lang in &syn_loader_conf.language {
193 column(&lang.language_id, Color::Reset);
193 column(&lang.language_id, Color::Reset);
194
194
195− // TODO multiple language servers (check binary for each supported language server, not just the first)
196−
197− let lsp = lang.language_servers.first().and_then(|ls| {
195+ let mut cmds = lang.language_servers.iter().filter_map(|ls| {
198 syn_loader_conf
196 syn_loader_conf
199 .language_server
197 .language_server
200 .get(&ls.name)
198 .get(&ls.name)
201− .map(|config| config.command.clone())
199+ .map(|config| config.command.as_str())
202 });
200 });
203− check_binary(lsp);
201+ check_binary(cmds.next());
204
202
205− let dap = lang.debugger.as_ref().map(|dap| dap.command.to_string());
203+ let dap = lang.debugger.as_ref().map(|dap| dap.command.as_str());
206 check_binary(dap);
204 check_binary(dap);
207
205
208 for ts_feat in TsFeature::all() {
206 for ts_feat in TsFeature::all() {
@@ -213,6 +211,12 @@ pub fn languages_all() -> std::io::Result<()> {
213 }
211 }
214
212
215 writeln!(stdout)?;
213 writeln!(stdout)?;
214+
215+ for cmd in cmds {
216+ column("", Color::Reset);
217+ check_binary(Some(cmd));
218+ writeln!(stdout)?;
219+ }
216 }
220 }
217
221
218 Ok(())
222 Ok(())
@@ -268,15 +272,12 @@ pub fn language(lang_str: String) -> std::io::Result<()> {
268 }
272 }
269 };
273 };
270
274
271− // TODO multiple language servers
275+ probe_protocols(
272− probe_protocol(
273 "language server",
276 "language server",
274− lang.language_servers.first().and_then(|ls| {
277+ lang.language_servers
278+ .iter()
275− syn_loader_conf
279+ .filter_map(|ls| syn_loader_conf.language_server.get(&ls.name))
276− .language_server
277− .get(&ls.name)
278− .map(|config| config.command.clone())
280+ .map(|config| config.command.as_str()),
279− }),
280 )?;
281 )?;
281
282
282 probe_protocol(
283 probe_protocol(
@@ -291,6 +292,33 @@ pub fn language(lang_str: String) -> std::io::Result<()> {
291 Ok(())
292 Ok(())
292}
293}
293
294
295+/// Display diagnostics about multiple LSPs and DAPs.
296+fn probe_protocols<'a, I: Iterator<Item = &'a str> + 'a>(
297+ protocol_name: &str,
298+ server_cmds: I,
299+) -> std::io::Result<()> {
300+ let stdout = std::io::stdout();
301+ let mut stdout = stdout.lock();
302+ let mut server_cmds = server_cmds.peekable();
303+
304+ write!(stdout, "Configured {}s:", protocol_name)?;
305+ if server_cmds.peek().is_none() {
306+ writeln!(stdout, "{}", " None".yellow())?;
307+ return Ok(());
308+ }
309+ writeln!(stdout)?;
310+
311+ for cmd in server_cmds {
312+ let (path, icon) = match which::which(cmd) {
313+ Ok(path) => (path.display().to_string().green(), "✓".green()),
314+ Err(_) => (format!("'{}' not found in $PATH", cmd).red(), "✘".red()),
315+ };
316+ writeln!(stdout, " {} {}: {}", icon, cmd, path)?;
317+ }
318+
319+ Ok(())
320+}
321+
294/// Display diagnostics about LSP and DAP.
322/// Display diagnostics about LSP and DAP.
295fn probe_protocol(protocol_name: &str, server_cmd: Option<String>) -> std::io::Result<()> {
323fn probe_protocol(protocol_name: &str, server_cmd: Option<String>) -> std::io::Result<()> {
296 let stdout = std::io::stdout();
324 let stdout = std::io::stdout();
helix-term/src/main.rs+17−1
@@ -66,6 +66,8 @@ FLAGS:
66 -V, --version Prints version information
66 -V, --version Prints version information
67 --vsplit Splits all given files vertically into different windows
67 --vsplit Splits all given files vertically into different windows
68 --hsplit Splits all given files horizontally into different windows
68 --hsplit Splits all given files horizontally into different windows
69+ -w, --working-dir <path> Specify an initial working directory
70+ +N Open the first given file at line number N
69",
71",
70 env!("CARGO_PKG_NAME"),
72 env!("CARGO_PKG_NAME"),
71 VERSION_AND_GIT_HASH,
73 VERSION_AND_GIT_HASH,
@@ -74,7 +76,7 @@ FLAGS:
74 helix_loader::default_log_file().display(),
76 helix_loader::default_log_file().display(),
75 );
77 );
76
78
77− let args = Args::parse_args().context("could not parse arguments")?;
79+ let mut args = Args::parse_args().context("could not parse arguments")?;
78
80
79 helix_loader::initialize_config_file(args.config_file.clone());
81 helix_loader::initialize_config_file(args.config_file.clone());
80 helix_loader::initialize_log_file(args.log_file.clone());
82 helix_loader::initialize_log_file(args.log_file.clone());
@@ -114,6 +116,20 @@ FLAGS:
114
116
115 setup_logging(args.verbosity).context("failed to initialize logging")?;
117 setup_logging(args.verbosity).context("failed to initialize logging")?;
116
118
119+ // Before setting the working directory, resolve all the paths in args.files
120+ for (path, _) in args.files.iter_mut() {
121+ *path = helix_core::path::get_canonicalized_path(path);
122+ }
123+
124+ // NOTE: Set the working directory early so the correct configuration is loaded. Be aware that
125+ // Application::new() depends on this logic so it must be updated if this changes.
126+ if let Some(path) = &args.working_directory {
127+ helix_loader::set_current_working_dir(path)?;
128+ } else if let Some((path, _)) = args.files.first().filter(|p| p.0.is_dir()) {
129+ // If the first file is a directory, it will be the working directory unless -w was specified
130+ helix_loader::set_current_working_dir(path)?;
131+ }
132+
117 let config = match Config::load_default() {
133 let config = match Config::load_default() {
118 Ok(config) => config,
134 Ok(config) => config,
119 Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => {
135 Err(ConfigLoadError::Error(err)) if err.kind() == std::io::ErrorKind::NotFound => {
helix-term/src/ui/completion.rs+17−1
@@ -2,6 +2,7 @@ use crate::compositor::{Component, Context, Event, EventResult};
2use helix_view::{
2use helix_view::{
3 document::SavePoint,
3 document::SavePoint,
4 editor::CompleteAction,
4 editor::CompleteAction,
5+ graphics::Margin,
5 theme::{Modifier, Style},
6 theme::{Modifier, Style},
6 ViewId,
7 ViewId,
7};
8};
@@ -326,9 +327,18 @@ impl Completion {
326 }
327 }
327 };
328 };
328 });
329 });
330+
331+ let margin = if editor.menu_border() {
332+ Margin::vertical(1)
333+ } else {
334+ Margin::none()
335+ };
336+
329 let popup = Popup::new(Self::ID, menu)
337 let popup = Popup::new(Self::ID, menu)
330 .with_scrollbar(false)
338 .with_scrollbar(false)
331− .ignore_escape_key(true);
339+ .ignore_escape_key(true)
340+ .margin(margin);
341+
332 let mut completion = Self {
342 let mut completion = Self {
333 popup,
343 popup,
334 start_offset,
344 start_offset,
@@ -569,6 +579,12 @@ impl Component for Completion {
569 // clear area
579 // clear area
570 let background = cx.editor.theme.get("ui.popup");
580 let background = cx.editor.theme.get("ui.popup");
571 surface.clear_with(doc_area, background);
581 surface.clear_with(doc_area, background);
582+
583+ if cx.editor.popup_border() {
584+ use tui::widgets::{Block, Borders, Widget};
585+ Widget::render(Block::default().borders(Borders::ALL), doc_area, surface);
586+ }
587+
572 markdown_doc.render(doc_area, surface, cx);
588 markdown_doc.render(doc_area, surface, cx);
573 }
589 }
574}
590}
helix-term/src/ui/document.rs+60−24
@@ -97,7 +97,8 @@ pub fn render_document(
97 doc: &Document,
97 doc: &Document,
98 offset: ViewPosition,
98 offset: ViewPosition,
99 doc_annotations: &TextAnnotations,
99 doc_annotations: &TextAnnotations,
100+ syntax_highlight_iter: impl Iterator<Item = HighlightEvent>,
100− highlight_iter: impl Iterator<Item = HighlightEvent>,
101+ overlay_highlight_iter: impl Iterator<Item = HighlightEvent>,
101 theme: &Theme,
102 theme: &Theme,
102 line_decoration: &mut [Box<dyn LineDecoration + '_>],
103 line_decoration: &mut [Box<dyn LineDecoration + '_>],
103 translated_positions: &mut [TranslatedPosition],
104 translated_positions: &mut [TranslatedPosition],
@@ -109,7 +110,8 @@ pub fn render_document(
109 offset,
110 offset,
110 &doc.text_format(viewport.width, Some(theme)),
111 &doc.text_format(viewport.width, Some(theme)),
111 doc_annotations,
112 doc_annotations,
112− highlight_iter,
113+ syntax_highlight_iter,
114+ overlay_highlight_iter,
113 theme,
115 theme,
114 line_decoration,
116 line_decoration,
115 translated_positions,
117 translated_positions,
@@ -157,7 +159,8 @@ pub fn render_text<'t>(
157 offset: ViewPosition,
159 offset: ViewPosition,
158 text_fmt: &TextFormat,
160 text_fmt: &TextFormat,
159 text_annotations: &TextAnnotations,
161 text_annotations: &TextAnnotations,
162+ syntax_highlight_iter: impl Iterator<Item = HighlightEvent>,
160− highlight_iter: impl Iterator<Item = HighlightEvent>,
163+ overlay_highlight_iter: impl Iterator<Item = HighlightEvent>,
161 theme: &Theme,
164 theme: &Theme,
162 line_decorations: &mut [Box<dyn LineDecoration + '_>],
165 line_decorations: &mut [Box<dyn LineDecoration + '_>],
163 translated_positions: &mut [TranslatedPosition],
166 translated_positions: &mut [TranslatedPosition],
@@ -178,10 +181,16 @@ pub fn render_text<'t>(
178
181
179 let (mut formatter, mut first_visible_char_idx) =
182 let (mut formatter, mut first_visible_char_idx) =
180 DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, text_annotations, offset.anchor);
183 DocumentFormatter::new_at_prev_checkpoint(text, text_fmt, text_annotations, offset.anchor);
181− let mut styles = StyleIter {
184+ let mut syntax_styles = StyleIter {
182 text_style: renderer.text_style,
185 text_style: renderer.text_style,
183 active_highlights: Vec::with_capacity(64),
186 active_highlights: Vec::with_capacity(64),
184− highlight_iter,
187+ highlight_iter: syntax_highlight_iter,
188+ theme,
189+ };
190+ let mut overlay_styles = StyleIter {
191+ text_style: Style::default(),
192+ active_highlights: Vec::with_capacity(64),
193+ highlight_iter: overlay_highlight_iter,
185 theme,
194 theme,
186 };
195 };
187
196
@@ -193,7 +202,10 @@ pub fn render_text<'t>(
193 };
202 };
194 let mut is_in_indent_area = true;
203 let mut is_in_indent_area = true;
195 let mut last_line_indent_level = 0;
204 let mut last_line_indent_level = 0;
196− let mut style_span = styles
205+ let mut syntax_style_span = syntax_styles
206+ .next()
207+ .unwrap_or_else(|| (Style::default(), usize::MAX));
208+ let mut overlay_style_span = overlay_styles
197 .next()
209 .next()
198 .unwrap_or_else(|| (Style::default(), usize::MAX));
210 .unwrap_or_else(|| (Style::default(), usize::MAX));
199
211
@@ -221,9 +233,16 @@ pub fn render_text<'t>(
221
233
222 // skip any graphemes on visual lines before the block start
234 // skip any graphemes on visual lines before the block start
223 if pos.row < row_off {
235 if pos.row < row_off {
224− if char_pos >= style_span.1 {
236+ if char_pos >= syntax_style_span.1 {
225− style_span = if let Some(style_span) = styles.next() {
237+ syntax_style_span = if let Some(syntax_style_span) = syntax_styles.next() {
226− style_span
238+ syntax_style_span
239+ } else {
240+ break;
241+ }
242+ }
243+ if char_pos >= overlay_style_span.1 {
244+ overlay_style_span = if let Some(overlay_style_span) = overlay_styles.next() {
245+ overlay_style_span
227 } else {
246 } else {
228 break;
247 break;
229 }
248 }
@@ -260,8 +279,15 @@ pub fn render_text<'t>(
260 }
279 }
261
280
262 // acquire the correct grapheme style
281 // acquire the correct grapheme style
263− if char_pos >= style_span.1 {
282+ if char_pos >= syntax_style_span.1 {
283+ syntax_style_span = syntax_styles
284+ .next()
285+ .unwrap_or((Style::default(), usize::MAX));
286+ }
287+ if char_pos >= overlay_style_span.1 {
288+ overlay_style_span = overlay_styles
289+ .next()
264− style_span = styles.next().unwrap_or((Style::default(), usize::MAX));
290+ .unwrap_or((Style::default(), usize::MAX));
265 }
291 }
266 char_pos += grapheme.doc_chars();
292 char_pos += grapheme.doc_chars();
267
293
@@ -275,22 +301,25 @@ pub fn render_text<'t>(
275 pos,
301 pos,
276 );
302 );
277
303
304+ let (syntax_style, overlay_style) =
278− let grapheme_style = if let GraphemeSource::VirtualText { highlight } = grapheme.source {
305+ if let GraphemeSource::VirtualText { highlight } = grapheme.source {
279− let style = renderer.text_style;
306+ let mut style = renderer.text_style;
280− if let Some(highlight) = highlight {
307+ if let Some(highlight) = highlight {
281− style.patch(theme.highlight(highlight.0))
308+ style = style.patch(theme.highlight(highlight.0))
309+ }
310+ (style, Style::default())
282 } else {
311 } else {
283− style
312+ (syntax_style_span.0, overlay_style_span.0)
284− }
285− } else {
286− style_span.0
287− };
313+ };
288
314
289− let virt = grapheme.is_virtual();
315+ let is_virtual = grapheme.is_virtual();
290 renderer.draw_grapheme(
316 renderer.draw_grapheme(
291 grapheme.grapheme,
317 grapheme.grapheme,
292− grapheme_style,
318+ GraphemeStyle {
293− virt,
319+ syntax_style,
320+ overlay_style,
321+ },
322+ is_virtual,
294 &mut last_line_indent_level,
323 &mut last_line_indent_level,
295 &mut is_in_indent_area,
324 &mut is_in_indent_area,
296 pos,
325 pos,
@@ -322,6 +351,11 @@ pub struct TextRenderer<'a> {
322 pub viewport: Rect,
351 pub viewport: Rect,
323}
352}
324
353
354+pub struct GraphemeStyle {
355+ syntax_style: Style,
356+ overlay_style: Style,
357+}
358+
325impl<'a> TextRenderer<'a> {
359impl<'a> TextRenderer<'a> {
326 pub fn new(
360 pub fn new(
327 surface: &'a mut Surface,
361 surface: &'a mut Surface,
@@ -395,7 +429,7 @@ impl<'a> TextRenderer<'a> {
395 pub fn draw_grapheme(
429 pub fn draw_grapheme(
396 &mut self,
430 &mut self,
397 grapheme: Grapheme,
431 grapheme: Grapheme,
398− mut style: Style,
432+ grapheme_style: GraphemeStyle,
399 is_virtual: bool,
433 is_virtual: bool,
400 last_indent_level: &mut usize,
434 last_indent_level: &mut usize,
401 is_in_indent_area: &mut bool,
435 is_in_indent_area: &mut bool,
@@ -405,9 +439,11 @@ impl<'a> TextRenderer<'a> {
405 let is_whitespace = grapheme.is_whitespace();
439 let is_whitespace = grapheme.is_whitespace();
406
440
407 // TODO is it correct to apply the whitespace style to all unicode white spaces?
441 // TODO is it correct to apply the whitespace style to all unicode white spaces?
442+ let mut style = grapheme_style.syntax_style;
408 if is_whitespace {
443 if is_whitespace {
409 style = style.patch(self.whitespace_style);
444 style = style.patch(self.whitespace_style);
410 }
445 }
446+ style = style.patch(grapheme_style.overlay_style);
411
447
412 let width = grapheme.width();
448 let width = grapheme.width();
413 let space = if is_virtual { " " } else { &self.space };
449 let space = if is_virtual { " " } else { &self.space };
helix-term/src/ui/editor.rs+77−44
@@ -124,16 +124,20 @@ impl EditorView {
124 line_decorations.push(Box::new(line_decoration));
124 line_decorations.push(Box::new(line_decoration));
125 }
125 }
126
126
127− let mut highlights =
127+ let syntax_highlights =
128 Self::doc_syntax_highlights(doc, view.offset.anchor, inner.height, theme);
128 Self::doc_syntax_highlights(doc, view.offset.anchor, inner.height, theme);
129+
129− let overlay_highlights = Self::overlay_syntax_highlights(
130+ let mut overlay_highlights =
131+ Self::empty_highlight_iter(doc, view.offset.anchor, inner.height);
132+ let overlay_syntax_highlights = Self::overlay_syntax_highlights(
130 doc,
133 doc,
131 view.offset.anchor,
134 view.offset.anchor,
132 inner.height,
135 inner.height,
133 &text_annotations,
136 &text_annotations,
134 );
137 );
135− if !overlay_highlights.is_empty() {
138+ if !overlay_syntax_highlights.is_empty() {
136− highlights = Box::new(syntax::merge(highlights, overlay_highlights));
139+ overlay_highlights =
140+ Box::new(syntax::merge(overlay_highlights, overlay_syntax_highlights));
137 }
141 }
138
142
139 for diagnostic in Self::doc_diagnostics_highlights(doc, theme) {
143 for diagnostic in Self::doc_diagnostics_highlights(doc, theme) {
@@ -142,29 +146,28 @@ impl EditorView {
142 if diagnostic.is_empty() {
146 if diagnostic.is_empty() {
143 continue;
147 continue;
144 }
148 }
145− highlights = Box::new(syntax::merge(highlights, diagnostic));
149+ overlay_highlights = Box::new(syntax::merge(overlay_highlights, diagnostic));
146 }
150 }
147
151
148− let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
152+ if is_focused {
149 let highlights = syntax::merge(
153 let highlights = syntax::merge(
150− highlights,
154+ overlay_highlights,
151 Self::doc_selection_highlights(
155 Self::doc_selection_highlights(
152 editor.mode(),
156 editor.mode(),
153 doc,
157 doc,
154 view,
158 view,
155 theme,
159 theme,
156 &config.cursor_shape,
160 &config.cursor_shape,
161+ self.terminal_focused,
157 ),
162 ),
158 );
163 );
159 let focused_view_elements = Self::highlight_focused_view_elements(view, doc, theme);
164 let focused_view_elements = Self::highlight_focused_view_elements(view, doc, theme);
160 if focused_view_elements.is_empty() {
165 if focused_view_elements.is_empty() {
161− Box::new(highlights)
166+ overlay_highlights = Box::new(highlights)
162 } else {
167 } else {
163− Box::new(syntax::merge(highlights, focused_view_elements))
168+ overlay_highlights = Box::new(syntax::merge(highlights, focused_view_elements))
164 }
169 }
165− } else {
170+ }
166− Box::new(highlights)
167− };
168
171
169 let gutter_overflow = view.gutter_offset(doc) == 0;
172 let gutter_overflow = view.gutter_offset(doc) == 0;
170 if !gutter_overflow {
173 if !gutter_overflow {
@@ -197,7 +200,8 @@ impl EditorView {
197 doc,
200 doc,
198 view.offset,
201 view.offset,
199 &text_annotations,
202 &text_annotations,
200− highlights,
203+ syntax_highlights,
204+ overlay_highlights,
201 theme,
205 theme,
202 &mut line_decorations,
206 &mut line_decorations,
203 &mut translated_positions,
207 &mut translated_positions,
@@ -257,27 +261,39 @@ impl EditorView {
257 .for_each(|area| surface.set_style(area, ruler_theme))
261 .for_each(|area| surface.set_style(area, ruler_theme))
258 }
262 }
259
263
260− pub fn overlay_syntax_highlights(
264+ fn viewport_byte_range(
265+ text: helix_core::RopeSlice,
266+ row: usize,
267+ height: u16,
268+ ) -> std::ops::Range<usize> {
269+ // Calculate viewport byte ranges:
270+ // Saturating subs to make it inclusive zero indexing.
271+ let last_line = text.len_lines().saturating_sub(1);
272+ let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);
273+ let start = text.line_to_byte(row.min(last_line));
274+ let end = text.line_to_byte(last_visible_line + 1);
275+
276+ start..end
277+ }
278+
279+ pub fn empty_highlight_iter(
261 doc: &Document,
280 doc: &Document,
262 anchor: usize,
281 anchor: usize,
263 height: u16,
282 height: u16,
264− text_annotations: &TextAnnotations,
283+ ) -> Box<dyn Iterator<Item = HighlightEvent>> {
265− ) -> Vec<(usize, std::ops::Range<usize>)> {
266 let text = doc.text().slice(..);
284 let text = doc.text().slice(..);
267 let row = text.char_to_line(anchor.min(text.len_chars()));
285 let row = text.char_to_line(anchor.min(text.len_chars()));
268
286
269− let range = {
270− // Calculate viewport byte ranges:
287+ // Calculate viewport byte ranges:
271− // Saturating subs to make it inclusive zero indexing.
288+ // Saturating subs to make it inclusive zero indexing.
272− let last_line = text.len_lines().saturating_sub(1);
289+ let range = Self::viewport_byte_range(text, row, height);
273− let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);
290+ Box::new(
274− let start = text.line_to_byte(row.min(last_line));
291+ [HighlightEvent::Source {
275− let end = text.line_to_byte(last_visible_line + 1);
292+ start: text.byte_to_char(range.start),
276−
293+ end: text.byte_to_char(range.end),
277− start..end
278− };
294+ }]
279−
295+ .into_iter(),
280− text_annotations.collect_overlay_highlights(range)
296+ )
281 }
297 }
282
298
283 /// Get syntax highlights for a document in a view represented by the first line
299 /// Get syntax highlights for a document in a view represented by the first line
@@ -292,16 +308,7 @@ impl EditorView {
292 let text = doc.text().slice(..);
308 let text = doc.text().slice(..);
293 let row = text.char_to_line(anchor.min(text.len_chars()));
309 let row = text.char_to_line(anchor.min(text.len_chars()));
294
310
295− let range = {
311+ let range = Self::viewport_byte_range(text, row, height);
296− // Calculate viewport byte ranges:
297− // Saturating subs to make it inclusive zero indexing.
298− let last_line = text.len_lines().saturating_sub(1);
299− let last_visible_line = (row + height as usize).saturating_sub(1).min(last_line);
300− let start = text.line_to_byte(row.min(last_line));
301− let end = text.line_to_byte(last_visible_line + 1);
302−
303− start..end
304− };
305
312
306 match doc.syntax() {
313 match doc.syntax() {
307 Some(syntax) => {
314 Some(syntax) => {
@@ -334,6 +341,20 @@ impl EditorView {
334 }
341 }
335 }
342 }
336
343
344+ pub fn overlay_syntax_highlights(
345+ doc: &Document,
346+ anchor: usize,
347+ height: u16,
348+ text_annotations: &TextAnnotations,
349+ ) -> Vec<(usize, std::ops::Range<usize>)> {
350+ let text = doc.text().slice(..);
351+ let row = text.char_to_line(anchor.min(text.len_chars()));
352+
353+ let range = Self::viewport_byte_range(text, row, height);
354+
355+ text_annotations.collect_overlay_highlights(range)
356+ }
357+
337 /// Get highlight spans for document diagnostics
358 /// Get highlight spans for document diagnostics
338 pub fn doc_diagnostics_highlights(
359 pub fn doc_diagnostics_highlights(
339 doc: &Document,
360 doc: &Document,
@@ -365,7 +386,7 @@ impl EditorView {
365 let mut warning_vec = Vec::new();
386 let mut warning_vec = Vec::new();
366 let mut error_vec = Vec::new();
387 let mut error_vec = Vec::new();
367
388
368− for diagnostic in doc.diagnostics() {
389+ for diagnostic in doc.shown_diagnostics() {
369 // Separate diagnostics into different Vecs by severity.
390 // Separate diagnostics into different Vecs by severity.
370 let (vec, scope) = match diagnostic.severity {
391 let (vec, scope) = match diagnostic.severity {
371 Some(Severity::Info) => (&mut info_vec, info),
392 Some(Severity::Info) => (&mut info_vec, info),
@@ -400,6 +421,7 @@ impl EditorView {
400 view: &View,
421 view: &View,
401 theme: &Theme,
422 theme: &Theme,
402 cursor_shape_config: &CursorShapeConfig,
423 cursor_shape_config: &CursorShapeConfig,
424+ is_terminal_focused: bool,
403 ) -> Vec<(usize, std::ops::Range<usize>)> {
425 ) -> Vec<(usize, std::ops::Range<usize>)> {
404 let text = doc.text().slice(..);
426 let text = doc.text().slice(..);
405 let selection = doc.selection(view.id);
427 let selection = doc.selection(view.id);
@@ -447,7 +469,7 @@ impl EditorView {
447
469
448 // Special-case: cursor at end of the rope.
470 // Special-case: cursor at end of the rope.
449 if range.head == range.anchor && range.head == text.len_chars() {
471 if range.head == range.anchor && range.head == text.len_chars() {
450− if !selection_is_primary || cursor_is_block {
472+ if !selection_is_primary || (cursor_is_block && is_terminal_focused) {
451 // Bar and underline cursors are drawn by the terminal
473 // Bar and underline cursors are drawn by the terminal
452 // BUG: If the editor area loses focus while having a bar or
474 // BUG: If the editor area loses focus while having a bar or
453 // underline cursor (eg. when a regex prompt has focus) then
475 // underline cursor (eg. when a regex prompt has focus) then
@@ -470,13 +492,17 @@ impl EditorView {
470 cursor_start
492 cursor_start
471 };
493 };
472 spans.push((selection_scope, range.anchor..selection_end));
494 spans.push((selection_scope, range.anchor..selection_end));
495+ // add block cursors
496+ // skip primary cursor if terminal is unfocused - crossterm cursor is used in that case
473− if !selection_is_primary || cursor_is_block {
497+ if !selection_is_primary || (cursor_is_block && is_terminal_focused) {
474 spans.push((cursor_scope, cursor_start..range.head));
498 spans.push((cursor_scope, cursor_start..range.head));
475 }
499 }
476 } else {
500 } else {
477 // Reverse case.
501 // Reverse case.
478 let cursor_end = next_grapheme_boundary(text, range.head);
502 let cursor_end = next_grapheme_boundary(text, range.head);
503+ // add block cursors
504+ // skip primary cursor if terminal is unfocused - crossterm cursor is used in that case
479− if !selection_is_primary || cursor_is_block {
505+ if !selection_is_primary || (cursor_is_block && is_terminal_focused) {
480 spans.push((cursor_scope, range.head..cursor_end));
506 spans.push((cursor_scope, range.head..cursor_end));
481 }
507 }
482 // non block cursors look like they exclude the cursor
508 // non block cursors look like they exclude the cursor
@@ -1500,8 +1526,15 @@ impl Component for EditorView {
1500
1526
1501 fn cursor(&self, _area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {
1527 fn cursor(&self, _area: Rect, editor: &Editor) -> (Option<Position>, CursorKind) {
1502 match editor.cursor() {
1528 match editor.cursor() {
1503− // All block cursors are drawn manually
1529+ // all block cursors are drawn manually
1530+ (pos, CursorKind::Block) => {
1531+ if self.terminal_focused {
1504− (pos, CursorKind::Block) => (pos, CursorKind::Hidden),
1532+ (pos, CursorKind::Hidden)
1533+ } else {
1534+ // use crossterm cursor when terminal loses focus
1535+ (pos, CursorKind::Underline)
1536+ }
1537+ }
1505 cursor => cursor,
1538 cursor => cursor,
1506 }
1539 }
1507 }
1540 }
helix-term/src/ui/lsp.rs+3−1
@@ -92,7 +92,9 @@ impl Component for SignatureHelp {
92 Some(doc) => Markdown::new(doc.clone(), Arc::clone(&self.config_loader)),
92 Some(doc) => Markdown::new(doc.clone(), Arc::clone(&self.config_loader)),
93 };
93 };
94 let sig_doc = sig_doc.parse(Some(&cx.editor.theme));
94 let sig_doc = sig_doc.parse(Some(&cx.editor.theme));
95+ let sig_doc_area = area
95− let sig_doc_area = area.clip_top(sig_text_area.height + 2);
96+ .clip_top(sig_text_area.height + 2)
97+ .clip_bottom(u16::from(cx.editor.popup_border()));
96 let sig_doc_para = Paragraph::new(sig_doc)
98 let sig_doc_para = Paragraph::new(sig_doc)
97 .wrap(Wrap { trim: false })
99 .wrap(Wrap { trim: false })
98 .scroll((cx.scroll.unwrap_or_default() as u16, 0));
100 .scroll((cx.scroll.unwrap_or_default() as u16, 0));
helix-term/src/ui/markdown.rs+12−5
@@ -14,6 +14,7 @@ use helix_core::{
14};
14};
15use helix_view::{
15use helix_view::{
16 graphics::{Margin, Rect, Style},
16 graphics::{Margin, Rect, Style},
17+ theme::Modifier,
17 Theme,
18 Theme,
18};
19};
19
20
@@ -183,7 +184,9 @@ impl Markdown {
183 // Transform text in `<code>` blocks into `Event::Code`
184 // Transform text in `<code>` blocks into `Event::Code`
184 let mut in_code = false;
185 let mut in_code = false;
185 let parser = parser.filter_map(|event| match event {
186 let parser = parser.filter_map(|event| match event {
186− Event::Html(tag) if *tag == *"<code>" => {
187+ Event::Html(tag)
188+ if tag.starts_with("<code") && matches!(tag.chars().nth(5), Some(' ' | '>')) =>
189+ {
187 in_code = true;
190 in_code = true;
188 None
191 None
189 }
192 }
@@ -275,17 +278,21 @@ impl Markdown {
275 );
278 );
276 lines.extend(tui_text.lines.into_iter());
279 lines.extend(tui_text.lines.into_iter());
277 } else {
280 } else {
281+ let style = match tags.last() {
278− let style = if let Some(Tag::Heading(level, ..)) = tags.last() {
282+ Some(Tag::Heading(level, ..)) => match level {
279− match level {
280 HeadingLevel::H1 => heading_styles[0],
283 HeadingLevel::H1 => heading_styles[0],
281 HeadingLevel::H2 => heading_styles[1],
284 HeadingLevel::H2 => heading_styles[1],
282 HeadingLevel::H3 => heading_styles[2],
285 HeadingLevel::H3 => heading_styles[2],
283 HeadingLevel::H4 => heading_styles[3],
286 HeadingLevel::H4 => heading_styles[3],
284 HeadingLevel::H5 => heading_styles[4],
287 HeadingLevel::H5 => heading_styles[4],
285 HeadingLevel::H6 => heading_styles[5],
288 HeadingLevel::H6 => heading_styles[5],
289+ },
290+ Some(Tag::Emphasis) => text_style.add_modifier(Modifier::ITALIC),
291+ Some(Tag::Strong) => text_style.add_modifier(Modifier::BOLD),
292+ Some(Tag::Strikethrough) => {
293+ text_style.add_modifier(Modifier::CROSSED_OUT)
286 }
294 }
287− } else {
288− text_style
295+ _ => text_style,
289 };
296 };
290 spans.push(Span::styled(text, style));
297 spans.push(Span::styled(text, style));
291 }
298 }
helix-term/src/ui/menu.rs+34−13
@@ -7,11 +7,18 @@ use crate::{
7use helix_core::fuzzy::MATCHER;
7use helix_core::fuzzy::MATCHER;
8use nucleo::pattern::{Atom, AtomKind, CaseMatching};
8use nucleo::pattern::{Atom, AtomKind, CaseMatching};
9use nucleo::{Config, Utf32Str};
9use nucleo::{Config, Utf32Str};
10+use tui::{
10−use tui::{buffer::Buffer as Surface, widgets::Table};
11+ buffer::Buffer as Surface,
12+ widgets::{Block, Borders, Table, Widget},
13+};
11
14
12pub use tui::widgets::{Cell, Row};
15pub use tui::widgets::{Cell, Row};
13
16
17+use helix_view::{
14−use helix_view::{editor::SmartTabConfig, graphics::Rect, Editor};
18+ editor::SmartTabConfig,
19+ graphics::{Margin, Rect},
20+ Editor,
21+};
15use tui::layout::Constraint;
22use tui::layout::Constraint;
16
23
17pub trait Item: Sync + Send + 'static {
24pub trait Item: Sync + Send + 'static {
@@ -322,6 +329,15 @@ impl<T: Item + 'static> Component for Menu<T> {
322 let selected = theme.get("ui.menu.selected");
329 let selected = theme.get("ui.menu.selected");
323 surface.clear_with(area, style);
330 surface.clear_with(area, style);
324
331
332+ let render_borders = cx.editor.menu_border();
333+
334+ let area = if render_borders {
335+ Widget::render(Block::default().borders(Borders::ALL), area, surface);
336+ area.inner(&Margin::vertical(1))
337+ } else {
338+ area
339+ };
340+
325 let scroll = self.scroll;
341 let scroll = self.scroll;
326
342
327 let options: Vec<_> = self
343 let options: Vec<_> = self
@@ -362,15 +378,19 @@ impl<T: Item + 'static> Component for Menu<T> {
362 false,
378 false,
363 );
379 );
364
380
381+ let render_borders = cx.editor.menu_border();
382+
383+ if !render_borders {
365− if let Some(cursor) = self.cursor {
384+ if let Some(cursor) = self.cursor {
366− let offset_from_top = cursor - scroll;
385+ let offset_from_top = cursor - scroll;
367− let left = &mut surface[(area.left(), area.y + offset_from_top as u16)];
386+ let left = &mut surface[(area.left(), area.y + offset_from_top as u16)];
368− left.set_style(selected);
387+ left.set_style(selected);
369− let right = &mut surface[(
388+ let right = &mut surface[(
370− area.right().saturating_sub(1),
389+ area.right().saturating_sub(1),
371− area.y + offset_from_top as u16,
390+ area.y + offset_from_top as u16,
372− )];
391+ )];
373− right.set_style(selected);
392+ right.set_style(selected);
393+ }
374 }
394 }
375
395
376 let fits = len <= win_height;
396 let fits = len <= win_height;
@@ -385,12 +405,13 @@ impl<T: Item + 'static> Component for Menu<T> {
385 for i in 0..win_height {
405 for i in 0..win_height {
386 cell = &mut surface[(area.right() - 1, area.top() + i as u16)];
406 cell = &mut surface[(area.right() - 1, area.top() + i as u16)];
387
407
388− cell.set_symbol("▐"); // right half block
408+ let half_block = if render_borders { "▌" } else { "▐" };
389
409
390 if scroll_line <= i && i < scroll_line + scroll_height {
410 if scroll_line <= i && i < scroll_line + scroll_height {
391 // Draw scroll thumb
411 // Draw scroll thumb
412+ cell.set_symbol(half_block);
392 cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));
413 cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));
393− } else {
414+ } else if !render_borders {
394 // Draw scroll track
415 // Draw scroll track
395 cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));
416 cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));
396 }
417 }
helix-term/src/ui/mod.rs+3
@@ -177,6 +177,9 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> Picker
177 .max_depth(config.file_picker.max_depth)
177 .max_depth(config.file_picker.max_depth)
178 .filter_entry(move |entry| filter_picker_entry(entry, &absolute_root, dedup_symlinks));
178 .filter_entry(move |entry| filter_picker_entry(entry, &absolute_root, dedup_symlinks));
179
179
180+ walk_builder.add_custom_ignore_filename(helix_loader::config_dir().join("ignore"));
181+ walk_builder.add_custom_ignore_filename(".helix/ignore");
182+
180 // We want to exclude files that the editor can't handle yet
183 // We want to exclude files that the editor can't handle yet
181 let mut type_builder = TypesBuilder::new();
184 let mut type_builder = TypesBuilder::new();
182 type_builder
185 type_builder
helix-term/src/ui/picker.rs+9−4
@@ -736,17 +736,20 @@ impl<T: Item + 'static> Picker<T> {
736 }
736 }
737 }
737 }
738
738
739− let mut highlights = EditorView::doc_syntax_highlights(
739+ let syntax_highlights = EditorView::doc_syntax_highlights(
740 doc,
740 doc,
741 offset.anchor,
741 offset.anchor,
742 area.height,
742 area.height,
743 &cx.editor.theme,
743 &cx.editor.theme,
744 );
744 );
745+
746+ let mut overlay_highlights =
747+ EditorView::empty_highlight_iter(doc, offset.anchor, area.height);
745 for spans in EditorView::doc_diagnostics_highlights(doc, &cx.editor.theme) {
748 for spans in EditorView::doc_diagnostics_highlights(doc, &cx.editor.theme) {
746 if spans.is_empty() {
749 if spans.is_empty() {
747 continue;
750 continue;
748 }
751 }
749− highlights = Box::new(helix_core::syntax::merge(highlights, spans));
752+ overlay_highlights = Box::new(helix_core::syntax::merge(overlay_highlights, spans));
750 }
753 }
751 let mut decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
754 let mut decorations: Vec<Box<dyn LineDecoration>> = Vec::new();
752
755
@@ -777,7 +780,8 @@ impl<T: Item + 'static> Picker<T> {
777 offset,
780 offset,
778 // TODO: compute text annotations asynchronously here (like inlay hints)
781 // TODO: compute text annotations asynchronously here (like inlay hints)
779 &TextAnnotations::default(),
782 &TextAnnotations::default(),
780− highlights,
783+ syntax_highlights,
784+ overlay_highlights,
781 &cx.editor.theme,
785 &cx.editor.theme,
782 &mut decorations,
786 &mut decorations,
783 &mut [],
787 &mut [],
@@ -795,7 +799,8 @@ impl<T: Item + 'static + Send + Sync> Component for Picker<T> {
795 // | | | |
799 // | | | |
796 // +---------+ +---------+
800 // +---------+ +---------+
797
801
802+ let render_preview =
798− let render_preview = self.show_preview && area.width > MIN_AREA_WIDTH_FOR_PREVIEW;
803+ self.show_preview && self.file_fn.is_some() && area.width > MIN_AREA_WIDTH_FOR_PREVIEW;
799
804
800 let picker_width = if render_preview {
805 let picker_width = if render_preview {
801 area.width / 2
806 area.width / 2
helix-term/src/ui/popup.rs+27−7
@@ -3,7 +3,10 @@ use crate::{
3 compositor::{Callback, Component, Context, Event, EventResult},
3 compositor::{Callback, Component, Context, Event, EventResult},
4 ctrl, key,
4 ctrl, key,
5};
5};
6+use tui::{
6−use tui::buffer::Buffer as Surface;
7+ buffer::Buffer as Surface,
8+ widgets::{Block, Borders, Widget},
9+};
7
10
8use helix_core::Position;
11use helix_core::Position;
9use helix_view::{
12use helix_view::{
@@ -252,13 +255,29 @@ impl<T: Component> Component for Popup<T> {
252 let background = cx.editor.theme.get("ui.popup");
255 let background = cx.editor.theme.get("ui.popup");
253 surface.clear_with(area, background);
256 surface.clear_with(area, background);
254
257
258+ let render_borders = cx.editor.popup_border();
259+
260+ let inner = if self
261+ .contents
262+ .type_name()
263+ .starts_with("helix_term::ui::menu::Menu")
264+ {
265+ area
266+ } else {
255− let inner = area.inner(&self.margin);
267+ area.inner(&self.margin)
268+ };
269+
270+ let border = usize::from(render_borders);
271+ if render_borders {
272+ Widget::render(Block::default().borders(Borders::ALL), area, surface);
273+ }
274+
256 self.contents.render(inner, surface, cx);
275 self.contents.render(inner, surface, cx);
257
276
258 // render scrollbar if contents do not fit
277 // render scrollbar if contents do not fit
259 if self.has_scrollbar {
278 if self.has_scrollbar {
260− let win_height = inner.height as usize;
279+ let win_height = (inner.height as usize).saturating_sub(2 * border);
261− let len = self.child_size.1 as usize;
280+ let len = (self.child_size.1 as usize).saturating_sub(2 * border);
262 let fits = len <= win_height;
281 let fits = len <= win_height;
263 let scroll = self.scroll;
282 let scroll = self.scroll;
264 let scroll_style = cx.editor.theme.get("ui.menu.scroll");
283 let scroll_style = cx.editor.theme.get("ui.menu.scroll");
@@ -274,14 +293,15 @@ impl<T: Component> Component for Popup<T> {
274
293
275 let mut cell;
294 let mut cell;
276 for i in 0..win_height {
295 for i in 0..win_height {
277− cell = &mut surface[(inner.right() - 1, inner.top() + i as u16)];
296+ cell = &mut surface[(inner.right() - 1, inner.top() + (border + i) as u16)];
278
297
279− cell.set_symbol("▐"); // right half block
298+ let half_block = if render_borders { "▌" } else { "▐" };
280
299
281 if scroll_line <= i && i < scroll_line + scroll_height {
300 if scroll_line <= i && i < scroll_line + scroll_height {
282 // Draw scroll thumb
301 // Draw scroll thumb
302+ cell.set_symbol(half_block);
283 cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));
303 cell.set_fg(scroll_style.fg.unwrap_or(helix_view::theme::Color::Reset));
284− } else {
304+ } else if !render_borders {
285 // Draw scroll track
305 // Draw scroll track
286 cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));
306 cell.set_fg(scroll_style.bg.unwrap_or(helix_view::theme::Color::Reset));
287 }
307 }
helix-term/tests/test/commands.rs+46
@@ -480,3 +480,49 @@ fn bar() {#(\n|)#\
480
480
481 Ok(())
481 Ok(())
482}
482}
483+
484+#[tokio::test(flavor = "multi_thread")]
485+async fn test_join_selections() -> anyhow::Result<()> {
486+ // normal join
487+ test((
488+ platform_line(indoc! {"\
489+ #[a|]#bc
490+ def
491+ "}),
492+ "J",
493+ platform_line(indoc! {"\
494+ #[a|]#bc def
495+ "}),
496+ ))
497+ .await?;
498+
499+ // join with empty line
500+ test((
501+ platform_line(indoc! {"\
502+ #[a|]#bc
503+
504+ def
505+ "}),
506+ "JJ",
507+ platform_line(indoc! {"\
508+ #[a|]#bc def
509+ "}),
510+ ))
511+ .await?;
512+
513+ // join with additional space in non-empty line
514+ test((
515+ platform_line(indoc! {"\
516+ #[a|]#bc
517+
518+ def
519+ "}),
520+ "JJ",
521+ platform_line(indoc! {"\
522+ #[a|]#bc def
523+ "}),
524+ ))
525+ .await?;
526+
527+ Ok(())
528+}
helix-term/tests/test/helpers.rs+8
@@ -320,6 +320,14 @@ impl AppBuilder {
320 }
320 }
321
321
322 pub fn build(self) -> anyhow::Result<Application> {
322 pub fn build(self) -> anyhow::Result<Application> {
323+ if let Some(path) = &self.args.working_directory {
324+ bail!("Changing the working directory to {path:?} is not yet supported for integration tests");
325+ }
326+
327+ if let Some((path, _)) = self.args.files.first().filter(|p| p.0.is_dir()) {
328+ bail!("Having the directory {path:?} in args.files[0] is not yet supported for integration tests");
329+ }
330+
323 let mut app = Application::new(self.args, self.config, self.syn_conf)?;
331 let mut app = Application::new(self.args, self.config, self.syn_conf)?;
324
332
325 if let Some((text, selection)) = self.input {
333 if let Some((text, selection)) = self.input {
helix-tui/Cargo.toml+13−13
@@ -1,28 +1,28 @@
1[package]
1[package]
2name = "helix-tui"
2name = "helix-tui"
3−version = "0.6.0"
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5−description = """
6−A library to build rich terminal user interfaces or dashboards
3+description = """A library to build rich terminal user interfaces or dashboards"""
7−"""
8−edition = "2021"
9−license = "MPL-2.0"
10−categories = ["editor"]
11−repository = "https://github.com/helix-editor/helix"
12−homepage = "https://helix-editor.com"
13include = ["src/**/*", "README.md"]
4include = ["src/**/*", "README.md"]
5+version.workspace = true
6+authors.workspace = true
7+edition.workspace = true
8+license.workspace = true
9+rust-version.workspace = true
10+categories.workspace = true
11+repository.workspace = true
12+homepage.workspace = true
14
13
15[features]
14[features]
16default = ["crossterm"]
15default = ["crossterm"]
17
16
18[dependencies]
17[dependencies]
18+helix-view = { path = "../helix-view", features = ["term"] }
19+helix-core = { path = "../helix-core" }
20+
19bitflags = "2.4"
21bitflags = "2.4"
20cassowary = "0.3"
22cassowary = "0.3"
21unicode-segmentation = "1.10"
23unicode-segmentation = "1.10"
22crossterm = { version = "0.27", optional = true }
24crossterm = { version = "0.27", optional = true }
23termini = "1.0"
25termini = "1.0"
24serde = { version = "1", "optional" = true, features = ["derive"]}
26serde = { version = "1", "optional" = true, features = ["derive"]}
25−once_cell = "1.18"
27+once_cell = "1.19"
26log = "~0.4"
28log = "~0.4"
27−helix-view = { version = "0.6", path = "../helix-view", features = ["term"] }
28−helix-core = { version = "0.6", path = "../helix-core" }
helix-tui/src/backend/crossterm.rs+18−2
@@ -32,10 +32,21 @@ fn vte_version() -> Option<usize> {
32}
32}
33
33
34/// Describes terminal capabilities like extended underline, truecolor, etc.
34/// Describes terminal capabilities like extended underline, truecolor, etc.
35−#[derive(Copy, Clone, Debug, Default)]
35+#[derive(Clone, Debug)]
36struct Capabilities {
36struct Capabilities {
37 /// Support for undercurled, underdashed, etc.
37 /// Support for undercurled, underdashed, etc.
38 has_extended_underlines: bool,
38 has_extended_underlines: bool,
39+ /// Support for resetting the cursor style back to normal.
40+ reset_cursor_command: String,
41+}
42+
43+impl Default for Capabilities {
44+ fn default() -> Self {
45+ Self {
46+ has_extended_underlines: false,
47+ reset_cursor_command: "\x1B[0 q".to_string(),
48+ }
49+ }
39}
50}
40
51
41impl Capabilities {
52impl Capabilities {
@@ -54,6 +65,10 @@ impl Capabilities {
54 || t.extended_cap("Su").is_some()
65 || t.extended_cap("Su").is_some()
55 || vte_version() >= Some(5102)
66 || vte_version() >= Some(5102)
56 || matches!(term_program().as_deref(), Some("WezTerm")),
67 || matches!(term_program().as_deref(), Some("WezTerm")),
68+ reset_cursor_command: t
69+ .utf8_string_cap(termini::StringCapability::CursorNormal)
70+ .unwrap_or("\x1B[0 q")
71+ .to_string(),
57 },
72 },
58 }
73 }
59 }
74 }
@@ -154,7 +169,8 @@ where
154
169
155 fn restore(&mut self, config: Config) -> io::Result<()> {
170 fn restore(&mut self, config: Config) -> io::Result<()> {
156 // reset cursor shape
171 // reset cursor shape
157− write!(self.buffer, "\x1B[0 q")?;
172+ self.buffer
173+ .write_all(self.capabilities.reset_cursor_command.as_bytes())?;
158 if config.enable_mouse_capture {
174 if config.enable_mouse_capture {
159 execute!(self.buffer, DisableMouseCapture)?;
175 execute!(self.buffer, DisableMouseCapture)?;
160 }
176 }
helix-tui/src/buffer.rs+2−2
@@ -213,7 +213,7 @@ impl Buffer {
213 && y < self.area.bottom()
213 && y < self.area.bottom()
214 }
214 }
215
215
216− /// Returns the index in the Vec<Cell> for the given global (x, y) coordinates.
216+ /// Returns the index in the `Vec<Cell>` for the given global (x, y) coordinates.
217 ///
217 ///
218 /// Global coordinates are offset by the Buffer's area offset (`x`/`y`).
218 /// Global coordinates are offset by the Buffer's area offset (`x`/`y`).
219 ///
219 ///
@@ -242,7 +242,7 @@ impl Buffer {
242 ((y - self.area.y) as usize) * (self.area.width as usize) + ((x - self.area.x) as usize)
242 ((y - self.area.y) as usize) * (self.area.width as usize) + ((x - self.area.x) as usize)
243 }
243 }
244
244
245− /// Returns the index in the Vec<Cell> for the given global (x, y) coordinates,
245+ /// Returns the index in the `Vec<Cell>` for the given global (x, y) coordinates,
246 /// or `None` if the coordinates are outside the buffer's area.
246 /// or `None` if the coordinates are outside the buffer's area.
247 fn index_of_opt(&self, x: u16, y: u16) -> Option<usize> {
247 fn index_of_opt(&self, x: u16, y: u16) -> Option<usize> {
248 if self.in_bounds(x, y) {
248 if self.in_bounds(x, y) {
helix-vcs/Cargo.toml+12−11
@@ -1,24 +1,25 @@
1[package]
1[package]
2name = "helix-vcs"
2name = "helix-vcs"
3−version = "0.6.0"
3+version.workspace = true
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
4+authors.workspace = true
5−edition = "2021"
5+edition.workspace = true
6−license = "MPL-2.0"
6+license.workspace = true
7+rust-version.workspace = true
7−categories = ["editor"]
8+categories.workspace = true
8−repository = "https://github.com/helix-editor/helix"
9+repository.workspace = true
9−homepage = "https://helix-editor.com"
10+homepage.workspace = true
10
11
11# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12
13
13[dependencies]
14[dependencies]
14−helix-core = { version = "0.6", path = "../helix-core" }
15+helix-core = { path = "../helix-core" }
15−helix-event = { version = "0.6", path = "../helix-event" }
16+helix-event = { path = "../helix-event" }
16
17
17tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] }
18tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "parking_lot", "macros"] }
18parking_lot = "0.12"
19parking_lot = "0.12"
19arc-swap = { version = "1.6.0" }
20arc-swap = { version = "1.6.0" }
20
21
21−gix = { version = "0.48.0", default-features = false , optional = true }
22+gix = { version = "0.57.0", default-features = false , optional = true }
22imara-diff = "0.1.5"
23imara-diff = "0.1.5"
23anyhow = "1"
24anyhow = "1"
24
25
@@ -28,4 +29,4 @@ log = "0.4"
28git = ["gix"]
29git = ["gix"]
29
30
30[dev-dependencies]
31[dev-dependencies]
31−tempfile = "3.8"
32+tempfile = "3.8"
helix-vcs/src/git.rs+5−5
@@ -3,7 +3,7 @@ use arc_swap::ArcSwap;
3use std::path::Path;
3use std::path::Path;
4use std::sync::Arc;
4use std::sync::Arc;
5
5
6−use gix::objs::tree::EntryMode;
6+use gix::objs::tree::EntryKind;
7use gix::sec::trust::DefaultForLevel;
7use gix::sec::trust::DefaultForLevel;
8use gix::{Commit, ObjectId, Repository, ThreadSafeRepository};
8use gix::{Commit, ObjectId, Repository, ThreadSafeRepository};
9
9
@@ -126,14 +126,14 @@ fn find_file_in_commit(repo: &Repository, commit: &Commit, file: &Path) -> Resul
126 let rel_path = file.strip_prefix(repo_dir)?;
126 let rel_path = file.strip_prefix(repo_dir)?;
127 let tree = commit.tree()?;
127 let tree = commit.tree()?;
128 let tree_entry = tree
128 let tree_entry = tree
129− .lookup_entry_by_path(rel_path)?
129+ .lookup_entry_by_path(rel_path, &mut Vec::new())?
130 .context("file is untracked")?;
130 .context("file is untracked")?;
131− match tree_entry.mode() {
131+ match tree_entry.mode().kind() {
132 // not a file, everything is new, do not show diff
132 // not a file, everything is new, do not show diff
133− mode @ (EntryMode::Tree | EntryMode::Commit | EntryMode::Link) => {
133+ mode @ (EntryKind::Tree | EntryKind::Commit | EntryKind::Link) => {
134 bail!("entry at {} is not a file but a {mode:?}", file.display())
134 bail!("entry at {} is not a file but a {mode:?}", file.display())
135 }
135 }
136 // found a file
136 // found a file
137− EntryMode::Blob | EntryMode::BlobExecutable => Ok(tree_entry.object_id()),
137+ EntryKind::Blob | EntryKind::BlobExecutable => Ok(tree_entry.object_id()),
138 }
138 }
139}
139}
helix-view/Cargo.toml+19−17
@@ -1,32 +1,34 @@
1[package]
1[package]
2name = "helix-view"
2name = "helix-view"
3−version = "0.6.0"
4−authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
5−edition = "2021"
6−license = "MPL-2.0"
7description = "UI abstractions for use in backends"
3description = "UI abstractions for use in backends"
4+version.workspace = true
5+authors.workspace = true
6+edition.workspace = true
7+license.workspace = true
8+rust-version.workspace = true
8−categories = ["editor"]
9+categories.workspace = true
9−repository = "https://github.com/helix-editor/helix"
10+repository.workspace = true
10−homepage = "https://helix-editor.com"
11+homepage.workspace = true
11
12
12[features]
13[features]
13default = []
14default = []
14term = ["crossterm"]
15term = ["crossterm"]
15
16
16[dependencies]
17[dependencies]
18+helix-core = { path = "../helix-core" }
19+helix-event = { path = "../helix-event" }
20+helix-loader = { path = "../helix-loader" }
21+helix-lsp = { path = "../helix-lsp" }
22+helix-dap = { path = "../helix-dap" }
23+helix-vcs = { path = "../helix-vcs" }
24+
17bitflags = "2.4"
25bitflags = "2.4"
18anyhow = "1"
26anyhow = "1"
19−helix-core = { version = "0.6", path = "../helix-core" }
20−helix-event = { version = "0.6", path = "../helix-event" }
21−helix-loader = { version = "0.6", path = "../helix-loader" }
22−helix-lsp = { version = "0.6", path = "../helix-lsp" }
23−helix-dap = { version = "0.6", path = "../helix-dap" }
24crossterm = { version = "0.27", optional = true }
27crossterm = { version = "0.27", optional = true }
25−helix-vcs = { version = "0.6", path = "../helix-vcs" }
26
28
27# Conversion traits
29# Conversion traits
28−once_cell = "1.18"
30+once_cell = "1.19"
29−url = "2"
31+url = "2.5.0"
30
32
31arc-swap = { version = "1.6.0" }
33arc-swap = { version = "1.6.0" }
32
34
@@ -43,12 +45,12 @@ serde_json = "1.0"
43toml = "0.7"
45toml = "0.7"
44log = "~0.4"
46log = "~0.4"
45
47
46−which = "4.4"
48+which = "5.0.0"
47parking_lot = "0.12.1"
49parking_lot = "0.12.1"
48
50
49
51
50[target.'cfg(windows)'.dependencies]
52[target.'cfg(windows)'.dependencies]
51−clipboard-win = { version = "4.5", features = ["std"] }
53+clipboard-win = { version = "5.0", features = ["std"] }
52
54
53[target.'cfg(unix)'.dependencies]
55[target.'cfg(unix)'.dependencies]
54libc = "0.2"
56libc = "0.2"
helix-view/src/document.rs+57−20
@@ -1213,23 +1213,40 @@ impl Document {
1213
1213
1214 let changes = transaction.changes();
1214 let changes = transaction.changes();
1215
1215
1216− changes.update_positions(
1217− self.diagnostics
1218− .iter_mut()
1219− .map(|diagnostic| (&mut diagnostic.range.start, Assoc::After)),
1220− );
1221− changes.update_positions(
1222− self.diagnostics
1223− .iter_mut()
1224− .map(|diagnostic| (&mut diagnostic.range.end, Assoc::After)),
1225− );
1226− // map state.diagnostics over changes::map_pos too
1216+ // map diagnostics over changes too
1217+ changes.update_positions(self.diagnostics.iter_mut().map(|diagnostic| {
1218+ let assoc = if diagnostic.starts_at_word {
1219+ Assoc::BeforeWord
1220+ } else {
1221+ Assoc::After
1222+ };
1223+ (&mut diagnostic.range.start, assoc)
1224+ }));
1225+ changes.update_positions(self.diagnostics.iter_mut().map(|diagnostic| {
1226+ let assoc = if diagnostic.ends_at_word {
1227+ Assoc::AfterWord
1228+ } else {
1229+ Assoc::Before
1230+ };
1231+ (&mut diagnostic.range.end, assoc)
1232+ }));
1227− for diagnostic in &mut self.diagnostics {
1233+ self.diagnostics.retain_mut(|diagnostic| {
1234+ if diagnostic.range.start > diagnostic.range.end
1235+ || (!diagnostic.zero_width && diagnostic.range.start == diagnostic.range.end)
1236+ {
1237+ return false;
1238+ }
1228 diagnostic.line = self.text.char_to_line(diagnostic.range.start);
1239 diagnostic.line = self.text.char_to_line(diagnostic.range.start);
1240+ true
1229− }
1241+ });
1230
1242
1231− self.diagnostics
1232− .sort_unstable_by_key(|diagnostic| diagnostic.range);
1243+ self.diagnostics.sort_unstable_by_key(|diagnostic| {
1244+ (
1245+ diagnostic.range,
1246+ diagnostic.severity,
1247+ diagnostic.language_server_id,
1248+ )
1249+ });
1233
1250
1234 // Update the inlay hint annotations' positions, helping ensure they are displayed in the proper place
1251 // Update the inlay hint annotations' positions, helping ensure they are displayed in the proper place
1235 let apply_inlay_hint_changes = |annotations: &mut Rc<[InlineAnnotation]>| {
1252 let apply_inlay_hint_changes = |annotations: &mut Rc<[InlineAnnotation]>| {
@@ -1706,13 +1723,33 @@ impl Document {
1706
1723
1707 pub fn replace_diagnostics(
1724 pub fn replace_diagnostics(
1708 &mut self,
1725 &mut self,
1709− mut diagnostics: Vec<Diagnostic>,
1726+ diagnostics: impl IntoIterator<Item = Diagnostic>,
1727+ unchanged_sources: &[String],
1710 language_server_id: usize,
1728 language_server_id: usize,
1711 ) {
1729 ) {
1730+ if unchanged_sources.is_empty() {
1712− self.clear_diagnostics(language_server_id);
1731+ self.clear_diagnostics(language_server_id);
1732+ } else {
1713− self.diagnostics.append(&mut diagnostics);
1733+ self.diagnostics.retain(|d| {
1714− self.diagnostics
1734+ if d.language_server_id != language_server_id {
1735+ return true;
1736+ }
1737+
1738+ if let Some(source) = &d.source {
1739+ unchanged_sources.contains(source)
1740+ } else {
1741+ false
1742+ }
1743+ });
1744+ }
1745+ self.diagnostics.extend(diagnostics);
1715− .sort_unstable_by_key(|diagnostic| diagnostic.range);
1746+ self.diagnostics.sort_unstable_by_key(|diagnostic| {
1747+ (
1748+ diagnostic.range,
1749+ diagnostic.severity,
1750+ diagnostic.language_server_id,
1751+ )
1752+ });
1716 }
1753 }
1717
1754
1718 pub fn clear_diagnostics(&mut self, language_server_id: usize) {
1755 pub fn clear_diagnostics(&mut self, language_server_id: usize) {
helix-view/src/editor.rs+83−54
@@ -42,10 +42,9 @@ use anyhow::{anyhow, bail, Error};
42pub use helix_core::diagnostic::Severity;
42pub use helix_core::diagnostic::Severity;
43use helix_core::{
43use helix_core::{
44 auto_pairs::AutoPairs,
44 auto_pairs::AutoPairs,
45− syntax::{self, AutoPairConfig, SoftWrap},
45+ syntax::{self, AutoPairConfig, IndentationHeuristic, SoftWrap},
46− Change, LineEnding, NATIVE_LINE_ENDING,
46+ Change, LineEnding, Position, Selection, NATIVE_LINE_ENDING,
47};
47};
48−use helix_core::{Position, Selection};
49use helix_dap as dap;
48use helix_dap as dap;
50use helix_lsp::lsp;
49use helix_lsp::lsp;
51
50
@@ -291,6 +290,11 @@ pub struct Config {
291 pub insert_final_newline: bool,
290 pub insert_final_newline: bool,
292 /// Enables smart tab
291 /// Enables smart tab
293 pub smart_tab: Option<SmartTabConfig>,
292 pub smart_tab: Option<SmartTabConfig>,
293+ /// Draw border around popups.
294+ pub popup_border: PopupBorderConfig,
295+ /// Which indent heuristic to use when a new line is inserted
296+ #[serde(default)]
297+ pub indent_heuristic: IndentationHeuristic,
294}
298}
295
299
296#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
300#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Eq, PartialOrd, Ord)]
@@ -727,7 +731,7 @@ pub struct WhitespaceCharacters {
727impl Default for WhitespaceCharacters {
731impl Default for WhitespaceCharacters {
728 fn default() -> Self {
732 fn default() -> Self {
729 Self {
733 Self {
730− space: '·', // U+00B7
734+ space: '·', // U+00B7
731 nbsp: '⍽', // U+237D
735 nbsp: '⍽', // U+237D
732 tab: '→', // U+2192
736 tab: '→', // U+2192
733 newline: '⏎', // U+23CE
737 newline: '⏎', // U+23CE
@@ -755,12 +759,13 @@ impl Default for IndentGuidesConfig {
755}
759}
756
760
757/// Line ending configuration.
761/// Line ending configuration.
758−#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
762+#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
759#[serde(rename_all = "lowercase")]
763#[serde(rename_all = "lowercase")]
760pub enum LineEndingConfig {
764pub enum LineEndingConfig {
761 /// The platform's native line ending.
765 /// The platform's native line ending.
762 ///
766 ///
763 /// `crlf` on Windows, otherwise `lf`.
767 /// `crlf` on Windows, otherwise `lf`.
768+ #[default]
764 Native,
769 Native,
765 /// Line feed.
770 /// Line feed.
766 LF,
771 LF,
@@ -777,12 +782,6 @@ pub enum LineEndingConfig {
777 Nel,
782 Nel,
778}
783}
779
784
780−impl Default for LineEndingConfig {
781− fn default() -> Self {
782− LineEndingConfig::Native
783− }
784−}
785−
786impl From<LineEndingConfig> for LineEnding {
785impl From<LineEndingConfig> for LineEnding {
787 fn from(line_ending: LineEndingConfig) -> Self {
786 fn from(line_ending: LineEndingConfig) -> Self {
788 match line_ending {
787 match line_ending {
@@ -799,6 +798,15 @@ impl From<LineEndingConfig> for LineEnding {
799 }
798 }
800}
799}
801
800
801+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
802+#[serde(rename_all = "kebab-case")]
803+pub enum PopupBorderConfig {
804+ None,
805+ All,
806+ Popup,
807+ Menu,
808+}
809+
802impl Default for Config {
810impl Default for Config {
803 fn default() -> Self {
811 fn default() -> Self {
804 Self {
812 Self {
@@ -846,6 +854,8 @@ impl Default for Config {
846 default_line_ending: LineEndingConfig::default(),
854 default_line_ending: LineEndingConfig::default(),
847 insert_final_newline: true,
855 insert_final_newline: true,
848 smart_tab: Some(SmartTabConfig::default()),
856 smart_tab: Some(SmartTabConfig::default()),
857+ popup_border: PopupBorderConfig::None,
858+ indent_heuristic: IndentationHeuristic::default(),
849 }
859 }
850 }
860 }
851}
861}
@@ -1065,6 +1075,16 @@ impl Editor {
1065 }
1075 }
1066 }
1076 }
1067
1077
1078+ pub fn popup_border(&self) -> bool {
1079+ self.config().popup_border == PopupBorderConfig::All
1080+ || self.config().popup_border == PopupBorderConfig::Popup
1081+ }
1082+
1083+ pub fn menu_border(&self) -> bool {
1084+ self.config().popup_border == PopupBorderConfig::All
1085+ || self.config().popup_border == PopupBorderConfig::Menu
1086+ }
1087+
1068 pub fn apply_motion<F: Fn(&mut Self) + 'static>(&mut self, motion: F) {
1088 pub fn apply_motion<F: Fn(&mut Self) + 'static>(&mut self, motion: F) {
1069 motion(self);
1089 motion(self);
1070 self.last_motion = Some(Box::new(motion));
1090 self.last_motion = Some(Box::new(motion));
@@ -1188,71 +1208,80 @@ impl Editor {
1188 }
1208 }
1189
1209
1190 /// Refreshes the language server for a given document
1210 /// Refreshes the language server for a given document
1191− pub fn refresh_language_servers(&mut self, doc_id: DocumentId) -> Option<()> {
1211+ pub fn refresh_language_servers(&mut self, doc_id: DocumentId) {
1192 self.launch_language_servers(doc_id)
1212 self.launch_language_servers(doc_id)
1193 }
1213 }
1194
1214
1195 /// Launch a language server for a given document
1215 /// Launch a language server for a given document
1196− fn launch_language_servers(&mut self, doc_id: DocumentId) -> Option<()> {
1216+ fn launch_language_servers(&mut self, doc_id: DocumentId) {
1197 if !self.config().lsp.enable {
1217 if !self.config().lsp.enable {
1198− return None;
1218+ return;
1199 }
1219 }
1200 // if doc doesn't have a URL it's a scratch buffer, ignore it
1220 // if doc doesn't have a URL it's a scratch buffer, ignore it
1201− let doc = self.documents.get_mut(&doc_id)?;
1221+ let Some(doc) = self.documents.get_mut(&doc_id) else {
1222+ return;
1223+ };
1202− let doc_url = doc.url()?;
1224+ let Some(doc_url) = doc.url() else {
1225+ return;
1226+ };
1203 let (lang, path) = (doc.language.clone(), doc.path().cloned());
1227 let (lang, path) = (doc.language.clone(), doc.path().cloned());
1204 let config = doc.config.load();
1228 let config = doc.config.load();
1205 let root_dirs = &config.workspace_lsp_roots;
1229 let root_dirs = &config.workspace_lsp_roots;
1206
1230
1207− // try to find language servers based on the language name
1231+ // store only successfully started language servers
1208− let language_servers = lang.as_ref().and_then(|language| {
1232+ let language_servers = lang.as_ref().map_or_else(HashMap::default, |language| {
1209 self.language_servers
1233 self.language_servers
1210 .get(language, path.as_ref(), root_dirs, config.lsp.snippets)
1234 .get(language, path.as_ref(), root_dirs, config.lsp.snippets)
1211− .map_err(|e| {
1235+ .filter_map(|(lang, client)| match client {
1236+ Ok(client) => Some((lang, client)),
1237+ Err(err) => {
1212− log::error!(
1238+ log::error!(
1213− "Failed to initialize the language servers for `{}` {{ {} }}",
1239+ "Failed to initialize the language servers for `{}` - `{}` {{ {} }}",
1214− language.scope(),
1240+ language.scope(),
1215− e
1241+ lang,
1216− )
1242+ err
1243+ );
1244+ None
1245+ }
1217 })
1246 })
1218− .ok()
1247+ .collect::<HashMap<_, _>>()
1219 });
1248 });
1220
1249
1221− if let Some(language_servers) = language_servers {
1250+ if language_servers.is_empty() {
1222− let language_id = doc.language_id().map(ToOwned::to_owned).unwrap_or_default();
1251+ return;
1223−
1224− // only spawn new language servers if the servers aren't the same
1225−
1226− let doc_language_servers_not_in_registry =
1227− doc.language_servers.iter().filter(|(name, doc_ls)| {
1228− language_servers
1229− .get(*name)
1230− .map_or(true, |ls| ls.id() != doc_ls.id())
1231− });
1252+ }
1232
1253
1233− for (_, language_server) in doc_language_servers_not_in_registry {
1254+ let language_id = doc.language_id().map(ToOwned::to_owned).unwrap_or_default();
1234− tokio::spawn(language_server.text_document_did_close(doc.identifier()));
1235− }
1236
1255
1256+ // only spawn new language servers if the servers aren't the same
1257+ let doc_language_servers_not_in_registry =
1237− let language_servers_not_in_doc = language_servers.iter().filter(|(name, ls)| {
1258+ doc.language_servers.iter().filter(|(name, doc_ls)| {
1238− doc.language_servers
1259+ language_servers
1239 .get(*name)
1260 .get(*name)
1240− .map_or(true, |doc_ls| ls.id() != doc_ls.id())
1261+ .map_or(true, |ls| ls.id() != doc_ls.id())
1241 });
1262 });
1242
1263
1243− for (_, language_server) in language_servers_not_in_doc {
1264+ for (_, language_server) in doc_language_servers_not_in_registry {
1244− // TODO: this now races with on_init code if the init happens too quickly
1245− tokio::spawn(language_server.text_document_did_open(
1265+ tokio::spawn(language_server.text_document_did_close(doc.identifier()));
1246− doc_url.clone(),
1266+ }
1247− doc.version(),
1267+
1248− doc.text(),
1268+ let language_servers_not_in_doc = language_servers.iter().filter(|(name, ls)| {
1249− language_id.clone(),
1269+ doc.language_servers
1250− ));
1270+ .get(*name)
1271+ .map_or(true, |doc_ls| ls.id() != doc_ls.id())
1251− }
1272+ });
1252
1273
1253− doc.language_servers = language_servers;
1274+ for (_, language_server) in language_servers_not_in_doc {
1275+ // TODO: this now races with on_init code if the init happens too quickly
1276+ tokio::spawn(language_server.text_document_did_open(
1277+ doc_url.clone(),
1278+ doc.version(),
1279+ doc.text(),
1280+ language_id.clone(),
1281+ ));
1254 }
1282 }
1255− Some(())
1283+
1284+ doc.language_servers = language_servers;
1256 }
1285 }
1257
1286
1258 fn _refresh(&mut self) {
1287 fn _refresh(&mut self) {
@@ -1454,7 +1483,7 @@ impl Editor {
1454 doc.set_version_control_head(self.diff_providers.get_current_head_name(&path));
1483 doc.set_version_control_head(self.diff_providers.get_current_head_name(&path));
1455
1484
1456 let id = self.new_document(doc);
1485 let id = self.new_document(doc);
1457− let _ = self.launch_language_servers(id);
1486+ self.launch_language_servers(id);
1458
1487
1459 id
1488 id
1460 };
1489 };
helix-view/src/gutter.rs+4−5
@@ -9,8 +9,7 @@ use crate::{
9};
9};
10
10
11fn count_digits(n: usize) -> usize {
11fn count_digits(n: usize) -> usize {
12− // TODO: use checked_log10 when MSRV reaches 1.67
12+ (usize::checked_ilog10(n).unwrap_or(0) + 1) as usize
13− std::iter::successors(Some(n), |&n| (n >= 10).then_some(n / 10)).count()
14}
13}
15
14
16pub type GutterFn<'doc> = Box<dyn FnMut(usize, bool, bool, &mut String) -> Option<Style> + 'doc>;
15pub type GutterFn<'doc> = Box<dyn FnMut(usize, bool, bool, &mut String) -> Option<Style> + 'doc>;
@@ -94,9 +93,9 @@ pub fn diff<'doc>(
94 theme: &Theme,
93 theme: &Theme,
95 _is_focused: bool,
94 _is_focused: bool,
96) -> GutterFn<'doc> {
95) -> GutterFn<'doc> {
97− let added = theme.get("diff.plus");
96+ let added = theme.get("diff.plus.gutter");
98− let deleted = theme.get("diff.minus");
97+ let deleted = theme.get("diff.minus.gutter");
99− let modified = theme.get("diff.delta");
98+ let modified = theme.get("diff.delta.gutter");
100 if let Some(diff_handle) = doc.diff_handle() {
99 if let Some(diff_handle) = doc.diff_handle() {
101 let hunks = diff_handle.load();
100 let hunks = diff_handle.load();
102 let mut hunk_i = 0;
101 let mut hunk_i = 0;
helix-view/src/handlers/dap.rs+1−3
@@ -369,9 +369,7 @@ impl Editor {
369 {
369 {
370 Ok(process) => process,
370 Ok(process) => process,
371 Err(err) => {
371 Err(err) => {
372− // TODO replace the pretty print {:?} with a regular format {}
373− // when the MSRV is raised to 1.60.0
374− self.set_error(format!("Error starting external terminal: {:?}", err));
372+ self.set_error(format!("Error starting external terminal: {}", err));
375 return true;
373 return true;
376 }
374 }
377 };
375 };
helix-view/src/input.rs+59−1
@@ -549,7 +549,7 @@ pub fn parse_macro(keys_str: &str) -> anyhow::Result<Vec<KeyEvent>> {
549 if c == ">" {
549 if c == ">" {
550 keys_res = Err(anyhow!("Unmatched '>'"));
550 keys_res = Err(anyhow!("Unmatched '>'"));
551 } else if c != "<" {
551 } else if c != "<" {
552− keys.push(c);
552+ keys.push(if c == "-" { keys::MINUS } else { c });
553 i += end_i;
553 i += end_i;
554 } else {
554 } else {
555 match s.find('>').context("'>' expected") {
555 match s.find('>').context("'>' expected") {
@@ -813,6 +813,64 @@ mod test {
813 },
813 },
814 ])
814 ])
815 );
815 );
816+
817+ assert_eq!(
818+ parse_macro(":w aa-bb.txt<ret>").ok(),
819+ Some(vec![
820+ KeyEvent {
821+ code: KeyCode::Char(':'),
822+ modifiers: KeyModifiers::NONE,
823+ },
824+ KeyEvent {
825+ code: KeyCode::Char('w'),
826+ modifiers: KeyModifiers::NONE,
827+ },
828+ KeyEvent {
829+ code: KeyCode::Char(' '),
830+ modifiers: KeyModifiers::NONE,
831+ },
832+ KeyEvent {
833+ code: KeyCode::Char('a'),
834+ modifiers: KeyModifiers::NONE,
835+ },
836+ KeyEvent {
837+ code: KeyCode::Char('a'),
838+ modifiers: KeyModifiers::NONE,
839+ },
840+ KeyEvent {
841+ code: KeyCode::Char('-'),
842+ modifiers: KeyModifiers::NONE,
843+ },
844+ KeyEvent {
845+ code: KeyCode::Char('b'),
846+ modifiers: KeyModifiers::NONE,
847+ },
848+ KeyEvent {
849+ code: KeyCode::Char('b'),
850+ modifiers: KeyModifiers::NONE,
851+ },
852+ KeyEvent {
853+ code: KeyCode::Char('.'),
854+ modifiers: KeyModifiers::NONE,
855+ },
856+ KeyEvent {
857+ code: KeyCode::Char('t'),
858+ modifiers: KeyModifiers::NONE,
859+ },
860+ KeyEvent {
861+ code: KeyCode::Char('x'),
862+ modifiers: KeyModifiers::NONE,
863+ },
864+ KeyEvent {
865+ code: KeyCode::Char('t'),
866+ modifiers: KeyModifiers::NONE,
867+ },
868+ KeyEvent {
869+ code: KeyCode::Enter,
870+ modifiers: KeyModifiers::NONE,
871+ },
872+ ])
873+ );
816 }
874 }
817
875
818 #[test]
876 #[test]
helix-view/src/register.rs+10−10
@@ -75,8 +75,8 @@ impl Registers {
75 self.clipboard_provider.as_ref(),
75 self.clipboard_provider.as_ref(),
76 self.inner.get(&name),
76 self.inner.get(&name),
77 match name {
77 match name {
78− '*' => ClipboardType::Clipboard,
78+ '+' => ClipboardType::Clipboard,
79− '+' => ClipboardType::Selection,
79+ '*' => ClipboardType::Selection,
80 _ => unreachable!(),
80 _ => unreachable!(),
81 },
81 },
82 )),
82 )),
@@ -95,8 +95,8 @@ impl Registers {
95 self.clipboard_provider.set_contents(
95 self.clipboard_provider.set_contents(
96 values.join(NATIVE_LINE_ENDING.as_str()),
96 values.join(NATIVE_LINE_ENDING.as_str()),
97 match name {
97 match name {
98− '*' => ClipboardType::Clipboard,
98+ '+' => ClipboardType::Clipboard,
99− '+' => ClipboardType::Selection,
99+ '*' => ClipboardType::Selection,
100 _ => unreachable!(),
100 _ => unreachable!(),
101 },
101 },
102 )?;
102 )?;
@@ -118,8 +118,8 @@ impl Registers {
118 '#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support pushing")),
118 '#' | '.' | '%' => Err(anyhow::anyhow!("Register {name} does not support pushing")),
119 '*' | '+' => {
119 '*' | '+' => {
120 let clipboard_type = match name {
120 let clipboard_type = match name {
121− '*' => ClipboardType::Clipboard,
121+ '+' => ClipboardType::Clipboard,
122− '+' => ClipboardType::Selection,
122+ '*' => ClipboardType::Selection,
123 _ => unreachable!(),
123 _ => unreachable!(),
124 };
124 };
125 let contents = self.clipboard_provider.get_contents(clipboard_type)?;
125 let contents = self.clipboard_provider.get_contents(clipboard_type)?;
@@ -172,8 +172,8 @@ impl Registers {
172 ('#', "<selection indices>"),
172 ('#', "<selection indices>"),
173 ('.', "<selection contents>"),
173 ('.', "<selection contents>"),
174 ('%', "<document path>"),
174 ('%', "<document path>"),
175− ('*', "<system clipboard>"),
175+ ('+', "<system clipboard>"),
176− ('+', "<primary clipboard>"),
176+ ('*', "<primary clipboard>"),
177 ]
177 ]
178 .iter()
178 .iter()
179 .copied(),
179 .copied(),
@@ -190,8 +190,8 @@ impl Registers {
190 match name {
190 match name {
191 '*' | '+' => {
191 '*' | '+' => {
192 self.clear_clipboard(match name {
192 self.clear_clipboard(match name {
193− '*' => ClipboardType::Clipboard,
193+ '+' => ClipboardType::Clipboard,
194− '+' => ClipboardType::Selection,
194+ '*' => ClipboardType::Selection,
195 _ => unreachable!(),
195 _ => unreachable!(),
196 });
196 });
197 self.inner.remove(&name);
197 self.inner.remove(&name);
languages.toml+374−186
@@ -3,6 +3,7 @@
3
3
4[language-server]
4[language-server]
5
5
6+als = { command = "als" }
6awk-language-server = { command = "awk-language-server" }
7awk-language-server = { command = "awk-language-server" }
7bash-language-server = { command = "bash-language-server", args = ["start"] }
8bash-language-server = { command = "bash-language-server", args = ["start"] }
8bass = { command = "bass", args = ["--lsp"] }
9bass = { command = "bass", args = ["--lsp"] }
@@ -30,6 +31,7 @@ forth-lsp = { command = "forth-lsp" }
30fortls = { command = "fortls", args = ["--lowercase_intrinsics"] }
31fortls = { command = "fortls", args = ["--lowercase_intrinsics"] }
31fsharp-ls = { command = "fsautocomplete", config = { AutomaticWorkspaceInit = true } }
32fsharp-ls = { command = "fsautocomplete", config = { AutomaticWorkspaceInit = true } }
32gleam = { command = "gleam", args = ["lsp"] }
33gleam = { command = "gleam", args = ["lsp"] }
34+graphql-language-service = { command = "graphql-lsp", args = ["server", "-m", "stream"] }
33haskell-language-server = { command = "haskell-language-server-wrapper", args = ["--lsp"] }
35haskell-language-server = { command = "haskell-language-server-wrapper", args = ["--lsp"] }
34idris2-lsp = { command = "idris2-lsp" }
36idris2-lsp = { command = "idris2-lsp" }
35intelephense = { command = "intelephense", args = ["--stdio"] }
37intelephense = { command = "intelephense", args = ["--stdio"] }
@@ -46,6 +48,7 @@ mint = { command = "mint", args = ["ls"] }
46nil = { command = "nil" }
48nil = { command = "nil" }
47nimlangserver = { command = "nimlangserver" }
49nimlangserver = { command = "nimlangserver" }
48nls = { command = "nls" }
50nls = { command = "nls" }
51+nu-lsp = { command = "nu", args = [ "--lsp" ] }
49ocamllsp = { command = "ocamllsp" }
52ocamllsp = { command = "ocamllsp" }
50ols = { command = "ols", args = [] }
53ols = { command = "ols", args = [] }
51omnisharp = { command = "OmniSharp", args = [ "--languageserver" ] }
54omnisharp = { command = "OmniSharp", args = [ "--languageserver" ] }
@@ -71,24 +74,30 @@ solc = { command = "solc", args = ["--lsp"] }
71sourcekit-lsp = { command = "sourcekit-lsp" }
74sourcekit-lsp = { command = "sourcekit-lsp" }
72svlangserver = { command = "svlangserver", args = [] }
75svlangserver = { command = "svlangserver", args = [] }
73swipl = { command = "swipl", args = [ "-g", "use_module(library(lsp_server))", "-g", "lsp_server:main", "-t", "halt", "--", "stdio" ] }
76swipl = { command = "swipl", args = [ "-g", "use_module(library(lsp_server))", "-g", "lsp_server:main", "-t", "halt", "--", "stdio" ] }
77+tailwindcss-ls = { command = "tailwindcss-language-server", args = ["--stdio"] }
74taplo = { command = "taplo", args = ["lsp", "stdio"] }
78taplo = { command = "taplo", args = ["lsp", "stdio"] }
79+templ = { command = "templ", args = ["lsp"] }
75terraform-ls = { command = "terraform-ls", args = ["serve"] }
80terraform-ls = { command = "terraform-ls", args = ["serve"] }
76texlab = { command = "texlab" }
81texlab = { command = "texlab" }
77vala-language-server = { command = "vala-language-server" }
82vala-language-server = { command = "vala-language-server" }
78vhdl_ls = { command = "vhdl_ls", args = [] }
83vhdl_ls = { command = "vhdl_ls", args = [] }
79vlang-language-server = { command = "v-analyzer" }
84vlang-language-server = { command = "v-analyzer" }
80−vscode-css-language-server = { command = "vscode-css-language-server", args = ["--stdio"], config = { "provideFormatter" = true }}
85+vscode-css-language-server = { command = "vscode-css-language-server", args = ["--stdio"], config = { provideFormatter = true, css = { validate = { enable = true } } } }
81vscode-html-language-server = { command = "vscode-html-language-server", args = ["--stdio"], config = { provideFormatter = true } }
86vscode-html-language-server = { command = "vscode-html-language-server", args = ["--stdio"], config = { provideFormatter = true } }
82−vscode-json-language-server = { command = "vscode-json-language-server", args = ["--stdio"], config = { provideFormatter = true } }
87+vscode-json-language-server = { command = "vscode-json-language-server", args = ["--stdio"], config = { provideFormatter = true, json = { validate = { enable = true } } } }
83vuels = { command = "vue-language-server", args = ["--stdio"], config = { typescript = { tsdk = "node_modules/typescript/lib/" } } }
88vuels = { command = "vue-language-server", args = ["--stdio"], config = { typescript = { tsdk = "node_modules/typescript/lib/" } } }
84wgsl_analyzer = { command = "wgsl_analyzer" }
89wgsl_analyzer = { command = "wgsl_analyzer" }
85yaml-language-server = { command = "yaml-language-server", args = ["--stdio"] }
90yaml-language-server = { command = "yaml-language-server", args = ["--stdio"] }
86zls = { command = "zls" }
91zls = { command = "zls" }
87blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] }
92blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] }
93+typst-lsp = { command = "typst-lsp" }
88
94
95+[language-server.ansible-language-server]
96+command = "ansible-language-server"
97+args = ["--stdio"]
89
98
90[language-server.lua-language-server]
99[language-server.lua-language-server]
91−command = "lua-language-server"
100+command = "lua-language-server"
92
101
93[language-server.lua-language-server.config.Lua.hint]
102[language-server.lua-language-server.config.Lua.hint]
94enable = true
103enable = true
@@ -110,6 +119,12 @@ functionTypeParameters = true
110parameterNames = true
119parameterNames = true
111rangeVariableTypes = true
120rangeVariableTypes = true
112
121
122+[language-server.golangci-lint-lsp]
123+command = "golangci-lint-langserver"
124+
125+[language-server.golangci-lint-lsp.config]
126+command = ["golangci-lint", "run", "--out-format", "json", "--issues-exit-code=1"]
127+
113
128
114[language-server.rust-analyzer]
129[language-server.rust-analyzer]
115command = "rust-analyzer"
130command = "rust-analyzer"
@@ -176,6 +191,7 @@ auto-format = true
176comment-token = "//"
191comment-token = "//"
177language-servers = [ "rust-analyzer" ]
192language-servers = [ "rust-analyzer" ]
178indent = { tab-width = 4, unit = " " }
193indent = { tab-width = 4, unit = " " }
194+persistent-diagnostic-sources = ["rustc", "clippy"]
179
195
180[language.auto-pairs]
196[language.auto-pairs]
181'(' = ')'
197'(' = ')'
@@ -236,7 +252,6 @@ name = "toml"
236scope = "source.toml"
252scope = "source.toml"
237injection-regex = "toml"
253injection-regex = "toml"
238file-types = ["toml", "poetry.lock", "Cargo.lock"]
254file-types = ["toml", "poetry.lock", "Cargo.lock"]
239−roots = []
240comment-token = "#"
255comment-token = "#"
241language-servers = [ "taplo" ]
256language-servers = [ "taplo" ]
242indent = { tab-width = 2, unit = " " }
257indent = { tab-width = 2, unit = " " }
@@ -250,7 +265,6 @@ name = "awk"
250scope = "source.awk"
265scope = "source.awk"
251injection-regex = "awk"
266injection-regex = "awk"
252file-types = ["awk", "gawk", "nawk", "mawk"]
267file-types = ["awk", "gawk", "nawk", "mawk"]
253−roots = []
254comment-token = "#"
268comment-token = "#"
255language-servers = [ "awk-language-server" ]
269language-servers = [ "awk-language-server" ]
256indent = { tab-width = 2, unit = " " }
270indent = { tab-width = 2, unit = " " }
@@ -265,7 +279,6 @@ scope = "source.proto"
265injection-regex = "protobuf"
279injection-regex = "protobuf"
266file-types = ["proto"]
280file-types = ["proto"]
267language-servers = [ "bufls", "pbkit" ]
281language-servers = [ "bufls", "pbkit" ]
268−roots = []
269comment-token = "//"
282comment-token = "//"
270indent = { tab-width = 2, unit = " " }
283indent = { tab-width = 2, unit = " " }
271
284
@@ -294,7 +307,6 @@ scope = "source.fish"
294injection-regex = "fish"
307injection-regex = "fish"
295file-types = ["fish"]
308file-types = ["fish"]
296shebangs = ["fish"]
309shebangs = ["fish"]
297−roots = []
298comment-token = "#"
310comment-token = "#"
299indent = { tab-width = 4, unit = " " }
311indent = { tab-width = 4, unit = " " }
300
312
@@ -308,7 +320,6 @@ scope = "source.mint"
308injection-regex = "mint"
320injection-regex = "mint"
309file-types = ["mint"]
321file-types = ["mint"]
310shebangs = []
322shebangs = []
311−roots = []
312comment-token = "//"
323comment-token = "//"
313language-servers = [ "mint" ]
324language-servers = [ "mint" ]
314indent = { tab-width = 2, unit = " " }
325indent = { tab-width = 2, unit = " " }
@@ -317,8 +328,28 @@ indent = { tab-width = 2, unit = " " }
317name = "json"
328name = "json"
318scope = "source.json"
329scope = "source.json"
319injection-regex = "json"
330injection-regex = "json"
320−file-types = ["json", "jsonc", "arb", "ipynb", "geojson", "gltf"]
331+file-types = [
321−roots = []
332+ "json",
333+ "jsonc",
334+ "arb",
335+ "ipynb",
336+ "geojson",
337+ "gltf",
338+ "webmanifest",
339+ "flake.lock",
340+ ".babelrc",
341+ ".bowerrc",
342+ ".jscrc",
343+ "js.map",
344+ "ts.map",
345+ "css.map",
346+ ".jslintrc",
347+ "jsonld",
348+ ".vuerc",
349+ "composer.lock",
350+ ".watchmanconfig",
351+ "avsc"
352+]
322language-servers = [ "vscode-json-language-server" ]
353language-servers = [ "vscode-json-language-server" ]
323auto-format = true
354auto-format = true
324indent = { tab-width = 2, unit = " " }
355indent = { tab-width = 2, unit = " " }
@@ -327,12 +358,26 @@ indent = { tab-width = 2, unit = " " }
327name = "json"
358name = "json"
328source = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "73076754005a460947cafe8e03a8cf5fa4fa2938" }
359source = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "73076754005a460947cafe8e03a8cf5fa4fa2938" }
329
360
361+
362+[[language]]
363+name = "json5"
364+scope = "source.json5"
365+injection-regex = "json5"
366+file-types = ["json5"]
367+language-servers = []
368+comment-token = "//"
369+indent = { tab-width = 4, unit = " " }
370+# https://json5.org
371+
372+[[grammar]]
373+name = "json5"
374+source = { git = "https://github.com/Joakker/tree-sitter-json5", rev = "c23f7a9b1ee7d45f516496b1e0e4be067264fa0d" }
375+
330[[language]]
376[[language]]
331name = "c"
377name = "c"
332scope = "source.c"
378scope = "source.c"
333injection-regex = "c"
379injection-regex = "c"
334file-types = ["c"] # TODO: ["h"]
380file-types = ["c"] # TODO: ["h"]
335−roots = []
336comment-token = "//"
381comment-token = "//"
337language-servers = [ "clangd" ]
382language-servers = [ "clangd" ]
338indent = { tab-width = 2, unit = " " }
383indent = { tab-width = 2, unit = " " }
@@ -368,8 +413,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-c", rev = "7175a6dd
368name = "cpp"
413name = "cpp"
369scope = "source.cpp"
414scope = "source.cpp"
370injection-regex = "cpp"
415injection-regex = "cpp"
371−file-types = ["cc", "hh", "c++", "cpp", "hpp", "h", "ipp", "tpp", "cxx", "hxx", "ixx", "txx", "ino", "C", "H", "cu", "cuh", "cppm"]
416+file-types = ["cc", "hh", "c++", "cpp", "hpp", "h", "ipp", "tpp", "cxx", "hxx", "ixx", "txx", "ino", "C", "H", "cu", "cuh", "cppm", "h++", "ii", "inl", { suffix = ".hpp.in" }, { suffix = ".h.in" }]
372−roots = []
373comment-token = "//"
417comment-token = "//"
374language-servers = [ "clangd" ]
418language-servers = [ "clangd" ]
375indent = { tab-width = 2, unit = " " }
419indent = { tab-width = 2, unit = " " }
@@ -415,7 +459,7 @@ language-servers = [ "crystalline" ]
415name = "c-sharp"
459name = "c-sharp"
416scope = "source.csharp"
460scope = "source.csharp"
417injection-regex = "c-?sharp"
461injection-regex = "c-?sharp"
418−file-types = ["cs"]
462+file-types = ["cs", "csx", "cake"]
419roots = ["sln", "csproj"]
463roots = ["sln", "csproj"]
420comment-token = "//"
464comment-token = "//"
421indent = { tab-width = 4, unit = "\t" }
465indent = { tab-width = 4, unit = "\t" }
@@ -452,7 +496,7 @@ file-types = ["go"]
452roots = ["go.work", "go.mod"]
496roots = ["go.work", "go.mod"]
453auto-format = true
497auto-format = true
454comment-token = "//"
498comment-token = "//"
455−language-servers = [ "gopls" ]
499+language-servers = [ "gopls", "golangci-lint-lsp" ]
456# TODO: gopls needs utf-8 offsets?
500# TODO: gopls needs utf-8 offsets?
457indent = { tab-width = 4, unit = "\t" }
501indent = { tab-width = 4, unit = "\t" }
458
502
@@ -502,7 +546,6 @@ name = "gomod"
502scope = "source.gomod"
546scope = "source.gomod"
503injection-regex = "gomod"
547injection-regex = "gomod"
504file-types = ["go.mod"]
548file-types = ["go.mod"]
505−roots = []
506auto-format = true
549auto-format = true
507comment-token = "//"
550comment-token = "//"
508language-servers = [ "gopls" ]
551language-servers = [ "gopls" ]
@@ -517,7 +560,6 @@ name = "gotmpl"
517scope = "source.gotmpl"
560scope = "source.gotmpl"
518injection-regex = "gotmpl"
561injection-regex = "gotmpl"
519file-types = ["gotmpl"]
562file-types = ["gotmpl"]
520−roots = []
521comment-token = "//"
563comment-token = "//"
522language-servers = [ "gopls" ]
564language-servers = [ "gopls" ]
523indent = { tab-width = 2, unit = " " }
565indent = { tab-width = 2, unit = " " }
@@ -531,7 +573,6 @@ name = "gowork"
531scope = "source.gowork"
573scope = "source.gowork"
532injection-regex = "gowork"
574injection-regex = "gowork"
533file-types = ["go.work"]
575file-types = ["go.work"]
534−roots = []
535auto-format = true
576auto-format = true
536comment-token = "//"
577comment-token = "//"
537language-servers = [ "gopls" ]
578language-servers = [ "gopls" ]
@@ -546,9 +587,8 @@ name = "javascript"
546scope = "source.js"
587scope = "source.js"
547injection-regex = "(js|javascript)"
588injection-regex = "(js|javascript)"
548language-id = "javascript"
589language-id = "javascript"
549−file-types = ["js", "mjs", "cjs"]
590+file-types = ["js", "mjs", "cjs", "rules", "es6", "pac", "jakefile"]
550shebangs = ["node"]
591shebangs = ["node"]
551−roots = []
552comment-token = "//"
592comment-token = "//"
553language-servers = [ "typescript-language-server" ]
593language-servers = [ "typescript-language-server" ]
554indent = { tab-width = 2, unit = " " }
594indent = { tab-width = 2, unit = " " }
@@ -575,7 +615,6 @@ scope = "source.jsx"
575injection-regex = "jsx"
615injection-regex = "jsx"
576language-id = "javascriptreact"
616language-id = "javascriptreact"
577file-types = ["jsx"]
617file-types = ["jsx"]
578−roots = []
579comment-token = "//"
618comment-token = "//"
580language-servers = [ "typescript-language-server" ]
619language-servers = [ "typescript-language-server" ]
581indent = { tab-width = 2, unit = " " }
620indent = { tab-width = 2, unit = " " }
@@ -588,7 +627,6 @@ injection-regex = "(ts|typescript)"
588file-types = ["ts", "mts", "cts"]
627file-types = ["ts", "mts", "cts"]
589language-id = "typescript"
628language-id = "typescript"
590shebangs = ["deno", "ts-node"]
629shebangs = ["deno", "ts-node"]
591−roots = []
592language-servers = [ "typescript-language-server" ]
630language-servers = [ "typescript-language-server" ]
593indent = { tab-width = 2, unit = " " }
631indent = { tab-width = 2, unit = " " }
594
632
@@ -602,7 +640,6 @@ scope = "source.tsx"
602injection-regex = "(tsx)" # |typescript
640injection-regex = "(tsx)" # |typescript
603language-id = "typescriptreact"
641language-id = "typescriptreact"
604file-types = ["tsx"]
642file-types = ["tsx"]
605−roots = []
606language-servers = [ "typescript-language-server" ]
643language-servers = [ "typescript-language-server" ]
607indent = { tab-width = 2, unit = " " }
644indent = { tab-width = 2, unit = " " }
608
645
@@ -615,7 +652,6 @@ name = "css"
615scope = "source.css"
652scope = "source.css"
616injection-regex = "css"
653injection-regex = "css"
617file-types = ["css", "scss"]
654file-types = ["css", "scss"]
618−roots = []
619language-servers = [ "vscode-css-language-server" ]
655language-servers = [ "vscode-css-language-server" ]
620auto-format = true
656auto-format = true
621indent = { tab-width = 2, unit = " " }
657indent = { tab-width = 2, unit = " " }
@@ -629,7 +665,6 @@ name = "scss"
629scope = "source.scss"
665scope = "source.scss"
630injection-regex = "scss"
666injection-regex = "scss"
631file-types = ["scss"]
667file-types = ["scss"]
632−roots = []
633language-servers = [ "vscode-css-language-server" ]
668language-servers = [ "vscode-css-language-server" ]
634auto-format = true
669auto-format = true
635indent = { tab-width = 2, unit = " " }
670indent = { tab-width = 2, unit = " " }
@@ -642,8 +677,7 @@ source = { git = "https://github.com/serenadeai/tree-sitter-scss", rev = "c478c6
642name = "html"
677name = "html"
643scope = "text.html.basic"
678scope = "text.html.basic"
644injection-regex = "html"
679injection-regex = "html"
645−file-types = ["html"]
680+file-types = ["html", "htm", "shtml", "xhtml", "xht", "jsp", "asp", "aspx", "jshtm", "volt", "rhtml"]
646−roots = []
647language-servers = [ "vscode-html-language-server" ]
681language-servers = [ "vscode-html-language-server" ]
648auto-format = true
682auto-format = true
649indent = { tab-width = 2, unit = " " }
683indent = { tab-width = 2, unit = " " }
@@ -656,7 +690,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-html", rev = "29f53
656name = "python"
690name = "python"
657scope = "source.python"
691scope = "source.python"
658injection-regex = "python"
692injection-regex = "python"
659−file-types = ["py","pyi","py3","pyw","ptl",".pythonstartup",".pythonrc","SConstruct"]
693+file-types = ["py","pyi","py3","pyw","ptl",".pythonstartup",".pythonrc","SConstruct", "rpy", "cpy", "ipy", "pyt", "SConscript"]
660shebangs = ["python"]
694shebangs = ["python"]
661roots = ["pyproject.toml", "setup.py", "poetry.lock", "pyrightconfig.json"]
695roots = ["pyproject.toml", "setup.py", "poetry.lock", "pyrightconfig.json"]
662comment-token = "#"
696comment-token = "#"
@@ -666,7 +700,7 @@ indent = { tab-width = 4, unit = " " }
666
700
667[[grammar]]
701[[grammar]]
668name = "python"
702name = "python"
669−source = { git = "https://github.com/tree-sitter/tree-sitter-python", rev = "de221eccf9a221f5b85474a553474a69b4b5784d" }
703+source = { git = "https://github.com/tree-sitter/tree-sitter-python", rev = "4bfdd9033a2225cc95032ce77066b7aeca9e2efc" }
670
704
671[[language]]
705[[language]]
672name = "nickel"
706name = "nickel"
@@ -674,7 +708,6 @@ scope = "source.nickel"
674injection-regex = "nickel"
708injection-regex = "nickel"
675file-types = ["ncl"]
709file-types = ["ncl"]
676shebangs = []
710shebangs = []
677−roots = []
678comment-token = "#"
711comment-token = "#"
679language-servers = [ "nls" ]
712language-servers = [ "nls" ]
680indent = { tab-width = 2, unit = " " }
713indent = { tab-width = 2, unit = " " }
@@ -695,7 +728,6 @@ scope = "source.nix"
695injection-regex = "nix"
728injection-regex = "nix"
696file-types = ["nix"]
729file-types = ["nix"]
697shebangs = []
730shebangs = []
698−roots = []
699comment-token = "#"
731comment-token = "#"
700language-servers = [ "nil" ]
732language-servers = [ "nil" ]
701indent = { tab-width = 2, unit = " " }
733indent = { tab-width = 2, unit = " " }
@@ -708,9 +740,43 @@ source = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "1b69
708name = "ruby"
740name = "ruby"
709scope = "source.ruby"
741scope = "source.ruby"
710injection-regex = "ruby"
742injection-regex = "ruby"
711−file-types = ["rb", "rake", "rakefile", "irb", "gemfile", "gemspec", "Rakefile", "Gemfile", "rabl", "jbuilder", "jb", "Podfile", "podspec", "Vagrantfile", "Brewfile"]
743+file-types = [
744+ "rb",
745+ "rake",
746+ "rakefile",
747+ "irb",
748+ "gemfile",
749+ "gemspec",
750+ "Rakefile",
751+ "Gemfile",
752+ "rabl",
753+ "jbuilder",
754+ "jb",
755+ "Podfile",
756+ "podspec",
757+ "Vagrantfile",
758+ "Brewfile",
759+ "rjs",
760+ "rbi",
761+ "Guardfile",
762+ "Capfile",
763+ "Cheffile",
764+ "Hobofile",
765+ "Appraisals",
766+ "Rantfile",
767+ "Berksfile",
768+ "Berksfile.lock",
769+ "Thorfile",
770+ "Puppetfile",
771+ "Fastfile",
772+ "Appfile",
773+ "Deliverfile",
774+ "Matchfile",
775+ "Scanfile",
776+ "Snapfile",
777+ "Gymfile"
778+]
712shebangs = ["ruby"]
779shebangs = ["ruby"]
713−roots = []
714comment-token = "#"
780comment-token = "#"
715language-servers = [ "solargraph" ]
781language-servers = [ "solargraph" ]
716indent = { tab-width = 2, unit = " " }
782indent = { tab-width = 2, unit = " " }
@@ -723,9 +789,48 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-ruby", rev = "206c7
723name = "bash"
789name = "bash"
724scope = "source.bash"
790scope = "source.bash"
725injection-regex = "(shell|bash|zsh|sh)"
791injection-regex = "(shell|bash|zsh|sh)"
726−file-types = ["sh", "bash", "zsh", ".bash_login", ".bash_logout", ".bash_profile", ".bashrc", ".profile", ".zshenv", "zshenv", ".zlogin", "zlogin", ".zlogout", "zlogout", ".zprofile", "zprofile", ".zshrc", "zshrc", ".zimrc", "APKBUILD", "PKGBUILD", "eclass", "ebuild", "bazelrc", ".bash_aliases", "Renviron", ".Renviron"]
792+file-types = [
793+ "sh",
794+ "bash",
795+ "zsh",
796+ ".bash_login",
797+ ".bash_logout",
798+ ".bash_profile",
799+ ".bashrc",
800+ ".profile",
801+ ".zshenv",
802+ "zshenv",
803+ ".zlogin",
804+ "zlogin",
805+ ".zlogout",
806+ "zlogout",
807+ ".zprofile",
808+ "zprofile",
809+ ".zshrc",
810+ "zshrc",
811+ ".zimrc",
812+ "APKBUILD",
813+ "PKGBUILD",
814+ "eclass",
815+ "ebuild",
816+ "bazelrc",
817+ ".bash_aliases",
818+ "Renviron",
819+ ".Renviron",
820+ ".xprofile",
821+ ".xsession",
822+ ".xsessionrc",
823+ "zsh-theme",
824+ "ksh",
825+ "cshrc",
826+ "tcshrc",
827+ ".yashrc",
828+ ".yash_profile",
829+ ".hushlogin",
830+ "bashrc_Apple_Terminal",
831+ "zshrc_Apple_Terminal"
832+]
727shebangs = ["sh", "bash", "dash", "zsh"]
833shebangs = ["sh", "bash", "dash", "zsh"]
728−roots = []
729comment-token = "#"
834comment-token = "#"
730language-servers = [ "bash-language-server" ]
835language-servers = [ "bash-language-server" ]
731indent = { tab-width = 2, unit = " " }
836indent = { tab-width = 2, unit = " " }
@@ -738,7 +843,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "275ef
738name = "php"
843name = "php"
739scope = "source.php"
844scope = "source.php"
740injection-regex = "php"
845injection-regex = "php"
741−file-types = ["php", "inc"]
846+file-types = ["php", "inc", "php4", "php5", "phtml", "ctp"]
742shebangs = ["php"]
847shebangs = ["php"]
743roots = ["composer.json", "index.php"]
848roots = ["composer.json", "index.php"]
744language-servers = [ "intelephense" ]
849language-servers = [ "intelephense" ]
@@ -753,7 +858,6 @@ name = "twig"
753scope = "source.twig"
858scope = "source.twig"
754injection-regex = "twig"
859injection-regex = "twig"
755file-types = ["twig"]
860file-types = ["twig"]
756−roots = []
757indent = { tab-width = 2, unit = " " }
861indent = { tab-width = 2, unit = " " }
758
862
759[[grammar]]
863[[grammar]]
@@ -764,8 +868,7 @@ source = { git = "https://github.com/gbprod/tree-sitter-twig", rev = "807b293fec
764name = "latex"
868name = "latex"
765scope = "source.tex"
869scope = "source.tex"
766injection-regex = "tex"
870injection-regex = "tex"
767−file-types = ["tex", "sty", "cls", "Rd"]
871+file-types = ["tex", "sty", "cls", "Rd", "bbx", "cbx"]
768−roots = []
769comment-token = "%"
872comment-token = "%"
770language-servers = [ "texlab" ]
873language-servers = [ "texlab" ]
771indent = { tab-width = 4, unit = "\t" }
874indent = { tab-width = 4, unit = "\t" }
@@ -779,7 +882,6 @@ name = "bibtex"
779scope = "source.bib"
882scope = "source.bib"
780injection-regex = "bib"
883injection-regex = "bib"
781file-types = ["bib"]
884file-types = ["bib"]
782−roots = []
783comment-token = "%"
885comment-token = "%"
784language-servers = [ "texlab" ]
886language-servers = [ "texlab" ]
785indent = { tab-width = 4, unit = "\t" }
887indent = { tab-width = 4, unit = "\t" }
@@ -816,6 +918,17 @@ indent = { tab-width = 2, unit = " " }
816name = "lean"
918name = "lean"
817source = { git = "https://github.com/Julian/tree-sitter-lean", rev = "d98426109258b266e1e92358c5f11716d2e8f638" }
919source = { git = "https://github.com/Julian/tree-sitter-lean", rev = "d98426109258b266e1e92358c5f11716d2e8f638" }
818
920
921+
922+[[language]]
923+name = "lpf"
924+comment-token = "#"
925+scope = "source.lpf"
926+file-types = ["lpf"]
927+
928+[[grammar]]
929+name = "lpf"
930+source = { git = "https://gitlab.com/TheZoq2/tree-sitter-lpf", rev = "db7372e60c722ca7f12ab359e57e6bf7611ab126" }
931+
819[[language]]
932[[language]]
820name = "julia"
933name = "julia"
821scope = "source.julia"
934scope = "source.julia"
@@ -844,12 +957,24 @@ indent = { tab-width = 2, unit = " " }
844name = "java"
957name = "java"
845source = { git = "https://github.com/tree-sitter/tree-sitter-java", rev = "09d650def6cdf7f479f4b78f595e9ef5b58ce31e" }
958source = { git = "https://github.com/tree-sitter/tree-sitter-java", rev = "09d650def6cdf7f479f4b78f595e9ef5b58ce31e" }
846
959
960+[[language]]
961+name = "smali"
962+scope = "source.smali"
963+injection-regex = "smali"
964+file-types = ["smali"]
965+comment-token = "#"
966+roots = []
967+indent = { tab-width = 4, unit = " " }
968+
969+[[grammar]]
970+name = "smali"
971+source = { git = "https://github.com/amaanq/tree-sitter-smali", rev = "5ae51e15c4d1ac93cba6127caf3d1f0a072c140c" }
972+
847[[language]]
973[[language]]
848name = "ledger"
974name = "ledger"
849scope = "source.ledger"
975scope = "source.ledger"
850injection-regex = "ledger"
976injection-regex = "ledger"
851file-types = ["ldg", "ledger", "journal"]
977file-types = ["ldg", "ledger", "journal"]
852−roots = []
853comment-token = ";"
978comment-token = ";"
854indent = { tab-width = 4, unit = " " }
979indent = { tab-width = 4, unit = " " }
855
980
@@ -862,13 +987,12 @@ name = "beancount"
862scope = "source.beancount"
987scope = "source.beancount"
863injection-regex = "beancount"
988injection-regex = "beancount"
864file-types = ["beancount", "bean"]
989file-types = ["beancount", "bean"]
865−roots = []
866comment-token = ";"
990comment-token = ";"
867indent = { tab-width = 2, unit = " " }
991indent = { tab-width = 2, unit = " " }
868
992
869[[grammar]]
993[[grammar]]
870name = "beancount"
994name = "beancount"
871−source = { git = "https://github.com/polarmutex/tree-sitter-beancount", rev = "4cbd1f09cd07c1f1fabf867c2cf354f9da53cc4c" }
995+source = { git = "https://github.com/polarmutex/tree-sitter-beancount", rev = "f3741a3a68ade59ec894ed84a64673494d2ba8f3" }
872
996
873[[language]]
997[[language]]
874name = "ocaml"
998name = "ocaml"
@@ -876,7 +1000,6 @@ scope = "source.ocaml"
876injection-regex = "ocaml"
1000injection-regex = "ocaml"
877file-types = ["ml"]
1001file-types = ["ml"]
878shebangs = ["ocaml", "ocamlrun", "ocamlscript"]
1002shebangs = ["ocaml", "ocamlrun", "ocamlscript"]
879−roots = []
880comment-token = "(**)"
1003comment-token = "(**)"
881language-servers = [ "ocamllsp" ]
1004language-servers = [ "ocamllsp" ]
882indent = { tab-width = 2, unit = " " }
1005indent = { tab-width = 2, unit = " " }
@@ -896,7 +1019,6 @@ name = "ocaml-interface"
896scope = "source.ocaml.interface"
1019scope = "source.ocaml.interface"
897file-types = ["mli"]
1020file-types = ["mli"]
898shebangs = []
1021shebangs = []
899−roots = []
900comment-token = "(**)"
1022comment-token = "(**)"
901language-servers = [ "ocamllsp" ]
1023language-servers = [ "ocamllsp" ]
902indent = { tab-width = 2, unit = " " }
1024indent = { tab-width = 2, unit = " " }
@@ -931,7 +1053,6 @@ name = "svelte"
931scope = "source.svelte"
1053scope = "source.svelte"
932injection-regex = "svelte"
1054injection-regex = "svelte"
933file-types = ["svelte"]
1055file-types = ["svelte"]
934−roots = []
935indent = { tab-width = 2, unit = " " }
1056indent = { tab-width = 2, unit = " " }
936language-servers = [ "svelteserver" ]
1057language-servers = [ "svelteserver" ]
937
1058
@@ -956,10 +1077,9 @@ source = { git = "https://github.com/ikatyang/tree-sitter-vue", rev = "91fe27547
956name = "yaml"
1077name = "yaml"
957scope = "source.yaml"
1078scope = "source.yaml"
958file-types = ["yml", "yaml"]
1079file-types = ["yml", "yaml"]
959−roots = []
960comment-token = "#"
1080comment-token = "#"
961indent = { tab-width = 2, unit = " " }
1081indent = { tab-width = 2, unit = " " }
962−language-servers = [ "yaml-language-server" ]
1082+language-servers = [ "yaml-language-server", "ansible-language-server" ]
963injection-regex = "yml|yaml"
1083injection-regex = "yml|yaml"
964
1084
965[[grammar]]
1085[[grammar]]
@@ -978,13 +1098,12 @@ indent = { tab-width = 2, unit = " " }
978
1098
979[[grammar]]
1099[[grammar]]
980name = "haskell"
1100name = "haskell"
981−source = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "98fc7f59049aeb713ab9b72a8ff25dcaaef81087" }
1101+source = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "d7ac98f49e3ed7e17541256fe3881a967d7ffdd3" }
982
1102
983[[language]]
1103[[language]]
984name = "haskell-persistent"
1104name = "haskell-persistent"
985scope = "source.persistentmodels"
1105scope = "source.persistentmodels"
986file-types = ["persistentmodels"]
1106file-types = ["persistentmodels"]
987−roots = []
988comment-token = "--"
1107comment-token = "--"
989indent = { tab-width = 2, unit = " " }
1108indent = { tab-width = 2, unit = " " }
990
1109
@@ -1003,7 +1122,10 @@ language-servers = [ "purescript-language-server" ]
1003indent = { tab-width = 2, unit = " " }
1122indent = { tab-width = 2, unit = " " }
1004auto-format = true
1123auto-format = true
1005formatter = { command = "purs-tidy", args = ["format"] }
1124formatter = { command = "purs-tidy", args = ["format"] }
1125+
1006−grammar = "haskell"
1126+[[grammar]]
1127+name = "purescript"
1128+source = { git = "https://github.com/postsolar/tree-sitter-purescript", rev = "5ef5592674ea42de75fc2792972e4ea0b6e3da6c" }
1007
1129
1008[[language]]
1130[[language]]
1009name = "zig"
1131name = "zig"
@@ -1047,7 +1169,6 @@ source = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "0d08703e4
1047[[language]]
1169[[language]]
1048name = "prolog"
1170name = "prolog"
1049scope = "source.prolog"
1171scope = "source.prolog"
1050−roots = []
1051file-types = ["pl", "prolog"]
1172file-types = ["pl", "prolog"]
1052shebangs = ["swipl"]
1173shebangs = ["swipl"]
1053comment-token = "%"
1174comment-token = "%"
@@ -1057,7 +1178,6 @@ language-servers = [ "swipl" ]
1057name = "tsq"
1178name = "tsq"
1058scope = "source.tsq"
1179scope = "source.tsq"
1059file-types = ["tsq"]
1180file-types = ["tsq"]
1060−roots = []
1061comment-token = ";"
1181comment-token = ";"
1062injection-regex = "tsq"
1182injection-regex = "tsq"
1063indent = { tab-width = 2, unit = " " }
1183indent = { tab-width = 2, unit = " " }
@@ -1070,7 +1190,6 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-tsq", rev = "48b5
1070name = "cmake"
1190name = "cmake"
1071scope = "source.cmake"
1191scope = "source.cmake"
1072file-types = ["cmake", "CMakeLists.txt"]
1192file-types = ["cmake", "CMakeLists.txt"]
1073−roots = []
1074comment-token = "#"
1193comment-token = "#"
1075indent = { tab-width = 2, unit = " " }
1194indent = { tab-width = 2, unit = " " }
1076language-servers = [ "cmake-language-server" ]
1195language-servers = [ "cmake-language-server" ]
@@ -1083,9 +1202,9 @@ source = { git = "https://github.com/uyha/tree-sitter-cmake", rev = "6e51463ef30
1083[[language]]
1202[[language]]
1084name = "make"
1203name = "make"
1085scope = "source.make"
1204scope = "source.make"
1086−file-types = ["Makefile", "makefile", "make", "mk"]
1205+file-types = ["Makefile", "makefile", "make", "mk", "mak", "GNUmakefile", "OCamlMakefile"]
1206+shebangs = ["make", "gmake"]
1087injection-regex = "(make|makefile|Makefile|mk)"
1207injection-regex = "(make|makefile|Makefile|mk)"
1088−roots = []
1089comment-token = "#"
1208comment-token = "#"
1090indent = { tab-width = 4, unit = "\t" }
1209indent = { tab-width = 4, unit = "\t" }
1091
1210
@@ -1097,7 +1216,6 @@ source = { git = "https://github.com/alemuller/tree-sitter-make", rev = "a4b9187
1097name = "glsl"
1216name = "glsl"
1098scope = "source.glsl"
1217scope = "source.glsl"
1099file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp" ]
1218file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp" ]
1100−roots = []
1101comment-token = "//"
1219comment-token = "//"
1102indent = { tab-width = 4, unit = " " }
1220indent = { tab-width = 4, unit = " " }
1103injection-regex = "glsl"
1221injection-regex = "glsl"
@@ -1109,22 +1227,20 @@ source = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "88408ff
1109[[language]]
1227[[language]]
1110name = "perl"
1228name = "perl"
1111scope = "source.perl"
1229scope = "source.perl"
1112−file-types = ["pl", "pm", "t"]
1230+file-types = ["pl", "pm", "t", "psgi", "raku", "rakumod", "rakutest", "rakudoc", "nqp", "p6", "pl6", "pm6"]
1113shebangs = ["perl"]
1231shebangs = ["perl"]
1114−roots = []
1115comment-token = "#"
1232comment-token = "#"
1116language-servers = [ "perlnavigator" ]
1233language-servers = [ "perlnavigator" ]
1117indent = { tab-width = 2, unit = " " }
1234indent = { tab-width = 2, unit = " " }
1118
1235
1119[[grammar]]
1236[[grammar]]
1120name = "perl"
1237name = "perl"
1121−source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "9f3166800d40267fa68ed8273e96baf74f390517" }
1238+source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "e99bb5283805db4cb86c964722d709df21b0ac16" }
1122
1239
1123[[language]]
1240[[language]]
1124name = "pod"
1241name = "pod"
1125scope = "source.pod"
1242scope = "source.pod"
1126injection-regex = "pod"
1243injection-regex = "pod"
1127−roots = []
1128file-types = ["pod"]
1244file-types = ["pod"]
1129
1245
1130[[grammar]]
1246[[grammar]]
@@ -1134,17 +1250,16 @@ source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "d
1134[[language]]
1250[[language]]
1135name = "racket"
1251name = "racket"
1136scope = "source.racket"
1252scope = "source.racket"
1137−roots = []
1138file-types = ["rkt", "rktd", "rktl", "scrbl"]
1253file-types = ["rkt", "rktd", "rktl", "scrbl"]
1139shebangs = ["racket"]
1254shebangs = ["racket"]
1140comment-token = ";"
1255comment-token = ";"
1256+indent = { tab-width = 2, unit = " " }
1141language-servers = [ "racket" ]
1257language-servers = [ "racket" ]
1142grammar = "scheme"
1258grammar = "scheme"
1143
1259
1144[[language]]
1260[[language]]
1145name = "common-lisp"
1261name = "common-lisp"
1146scope = "source.lisp"
1262scope = "source.lisp"
1147−roots = []
1148file-types = ["lisp", "asd", "cl", "l", "lsp", "ny", "podsl", "sexp"]
1263file-types = ["lisp", "asd", "cl", "l", "lsp", "ny", "podsl", "sexp"]
1149shebangs = ["lisp", "sbcl", "ccl", "clisp", "ecl"]
1264shebangs = ["lisp", "sbcl", "ccl", "clisp", "ecl"]
1150comment-token = ";"
1265comment-token = ";"
@@ -1161,19 +1276,17 @@ grammar = "scheme"
1161[[language]]
1276[[language]]
1162name = "comment"
1277name = "comment"
1163scope = "scope.comment"
1278scope = "scope.comment"
1164−roots = []
1165file-types = []
1279file-types = []
1166injection-regex = "comment"
1280injection-regex = "comment"
1167
1281
1168[[grammar]]
1282[[grammar]]
1169name = "comment"
1283name = "comment"
1170−source = { git = "https://github.com/stsewd/tree-sitter-comment", rev = "5dd3c62f1bbe378b220fe16b317b85247898639e" }
1284+source = { git = "https://github.com/stsewd/tree-sitter-comment", rev = "a37ca370310ac6f89b6e0ebf2b86b2219780494e" }
1171
1285
1172[[language]]
1286[[language]]
1173name = "wgsl"
1287name = "wgsl"
1174scope = "source.wgsl"
1288scope = "source.wgsl"
1175file-types = ["wgsl"]
1289file-types = ["wgsl"]
1176−roots = []
1177comment-token = "//"
1290comment-token = "//"
1178language-servers = [ "wgsl_analyzer" ]
1291language-servers = [ "wgsl_analyzer" ]
1179indent = { tab-width = 4, unit = " " }
1292indent = { tab-width = 4, unit = " " }
@@ -1185,7 +1298,6 @@ source = { git = "https://github.com/szebniok/tree-sitter-wgsl", rev = "272e89ef
1185[[language]]
1298[[language]]
1186name = "llvm"
1299name = "llvm"
1187scope = "source.llvm"
1300scope = "source.llvm"
1188−roots = []
1189file-types = ["ll"]
1301file-types = ["ll"]
1190comment-token = ";"
1302comment-token = ";"
1191indent = { tab-width = 2, unit = " " }
1303indent = { tab-width = 2, unit = " " }
@@ -1193,12 +1305,11 @@ injection-regex = "llvm"
1193
1305
1194[[grammar]]
1306[[grammar]]
1195name = "llvm"
1307name = "llvm"
1196−source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "3b213925b9c4f42c1acfe2e10bfbb438d9c6834d" }
1308+source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "e9948edc41e9e5869af99dddb2b5ff5cc5581af6" }
1197
1309
1198[[language]]
1310[[language]]
1199name = "llvm-mir"
1311name = "llvm-mir"
1200scope = "source.llvm_mir"
1312scope = "source.llvm_mir"
1201−roots = []
1202file-types = []
1313file-types = []
1203comment-token = ";"
1314comment-token = ";"
1204indent = { tab-width = 2, unit = " " }
1315indent = { tab-width = 2, unit = " " }
@@ -1214,7 +1325,6 @@ name = "llvm-mir-yaml"
1214#
1325#
1215# grammar = "yaml"
1326# grammar = "yaml"
1216scope = "source.yaml"
1327scope = "source.yaml"
1217−roots = []
1218file-types = ["mir"]
1328file-types = ["mir"]
1219comment-token = "#"
1329comment-token = "#"
1220indent = { tab-width = 2, unit = " " }
1330indent = { tab-width = 2, unit = " " }
@@ -1222,7 +1332,6 @@ indent = { tab-width = 2, unit = " " }
1222[[language]]
1332[[language]]
1223name = "tablegen"
1333name = "tablegen"
1224scope = "source.tablegen"
1334scope = "source.tablegen"
1225−roots = []
1226file-types = ["td"]
1335file-types = ["td"]
1227comment-token = "//"
1336comment-token = "//"
1228indent = { tab-width = 2, unit = " " }
1337indent = { tab-width = 2, unit = " " }
@@ -1236,26 +1345,25 @@ source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "568dd
1236name = "markdown"
1345name = "markdown"
1237scope = "source.md"
1346scope = "source.md"
1238injection-regex = "md|markdown"
1347injection-regex = "md|markdown"
1239−file-types = ["md", "markdown", "PULLREQ_EDITMSG"]
1348+file-types = ["md", "markdown", "PULLREQ_EDITMSG", "mkd", "mdwn", "mdown", "markdn", "mdtxt", "mdtext", "workbook"]
1240roots = [".marksman.toml"]
1349roots = [".marksman.toml"]
1241language-servers = [ "marksman" ]
1350language-servers = [ "marksman" ]
1242indent = { tab-width = 2, unit = " " }
1351indent = { tab-width = 2, unit = " " }
1243
1352
1244[[grammar]]
1353[[grammar]]
1245name = "markdown"
1354name = "markdown"
1246−source = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "fa6bfd51727e4bef99f7eec5f43947f73d64ea7d", subpath = "tree-sitter-markdown" }
1355+source = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "aaf76797aa8ecd9a5e78e0ec3681941de6c945ee", subpath = "tree-sitter-markdown" }
1247
1356
1248[[language]]
1357[[language]]
1249name = "markdown.inline"
1358name = "markdown.inline"
1250scope = "source.markdown.inline"
1359scope = "source.markdown.inline"
1251injection-regex = "markdown\\.inline"
1360injection-regex = "markdown\\.inline"
1252file-types = []
1361file-types = []
1253−roots = []
1254grammar = "markdown_inline"
1362grammar = "markdown_inline"
1255
1363
1256[[grammar]]
1364[[grammar]]
1257name = "markdown_inline"
1365name = "markdown_inline"
1258−source = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "fa6bfd51727e4bef99f7eec5f43947f73d64ea7d", subpath = "tree-sitter-markdown-inline" }
1366+source = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "aaf76797aa8ecd9a5e78e0ec3681941de6c945ee", subpath = "tree-sitter-markdown-inline" }
1259
1367
1260[[language]]
1368[[language]]
1261name = "dart"
1369name = "dart"
@@ -1301,7 +1409,6 @@ source = { git = "https://github.com/camdencheek/tree-sitter-dockerfile", rev =
1301[[language]]
1409[[language]]
1302name = "git-commit"
1410name = "git-commit"
1303scope = "git.commitmsg"
1411scope = "git.commitmsg"
1304−roots = []
1305file-types = ["COMMIT_EDITMSG"]
1412file-types = ["COMMIT_EDITMSG"]
1306comment-token = "#"
1413comment-token = "#"
1307indent = { tab-width = 2, unit = " " }
1414indent = { tab-width = 2, unit = " " }
@@ -1315,8 +1422,7 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-git-commit", rev
1315[[language]]
1422[[language]]
1316name = "diff"
1423name = "diff"
1317scope = "source.diff"
1424scope = "source.diff"
1318−roots = []
1319−file-types = ["diff", "patch"]
1425+file-types = ["diff", "patch", "rej"]
1320injection-regex = "diff"
1426injection-regex = "diff"
1321comment-token = "#"
1427comment-token = "#"
1322indent = { tab-width = 2, unit = " " }
1428indent = { tab-width = 2, unit = " " }
@@ -1328,7 +1434,6 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-diff", rev = "fd7
1328[[language]]
1434[[language]]
1329name = "git-rebase"
1435name = "git-rebase"
1330scope = "source.gitrebase"
1436scope = "source.gitrebase"
1331−roots = []
1332file-types = ["git-rebase-todo"]
1437file-types = ["git-rebase-todo"]
1333injection-regex = "git-rebase"
1438injection-regex = "git-rebase"
1334comment-token = "#"
1439comment-token = "#"
@@ -1343,7 +1448,6 @@ name = "regex"
1343scope = "source.regex"
1448scope = "source.regex"
1344injection-regex = "regex"
1449injection-regex = "regex"
1345file-types = ["regex", ".Rbuildignore"]
1450file-types = ["regex", ".Rbuildignore"]
1346−roots = []
1347
1451
1348[[grammar]]
1452[[grammar]]
1349name = "regex"
1453name = "regex"
@@ -1352,7 +1456,6 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-regex", rev = "e1cf
1352[[language]]
1456[[language]]
1353name = "git-config"
1457name = "git-config"
1354scope = "source.gitconfig"
1458scope = "source.gitconfig"
1355−roots = []
1356file-types = [".gitmodules", ".gitconfig", { suffix = ".git/config" }, { suffix = ".config/git/config" }]
1459file-types = [".gitmodules", ".gitconfig", { suffix = ".git/config" }, { suffix = ".config/git/config" }]
1357injection-regex = "git-config"
1460injection-regex = "git-config"
1358comment-token = "#"
1461comment-token = "#"
@@ -1365,7 +1468,6 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-git-config", rev
1365[[language]]
1468[[language]]
1366name = "git-attributes"
1469name = "git-attributes"
1367scope = "source.gitattributes"
1470scope = "source.gitattributes"
1368−roots = []
1369file-types = [".gitattributes"]
1471file-types = [".gitattributes"]
1370injection-regex = "git-attributes"
1472injection-regex = "git-attributes"
1371comment-token = "#"
1473comment-token = "#"
@@ -1378,7 +1480,6 @@ source = { git = "https://github.com/mtoohey31/tree-sitter-gitattributes", rev =
1378[[language]]
1480[[language]]
1379name = "git-ignore"
1481name = "git-ignore"
1380scope = "source.gitignore"
1482scope = "source.gitignore"
1381−roots = []
1382file-types = [".gitignore", ".gitignore_global", ".ignore", ".prettierignore", ".eslintignore", ".npmignore", "CODEOWNERS"]
1483file-types = [".gitignore", ".gitignore_global", ".ignore", ".prettierignore", ".eslintignore", ".npmignore", "CODEOWNERS"]
1383injection-regex = "git-ignore"
1484injection-regex = "git-ignore"
1384comment-token = "#"
1485comment-token = "#"
@@ -1393,7 +1494,7 @@ name = "graphql"
1393scope = "source.graphql"
1494scope = "source.graphql"
1394injection-regex = "graphql"
1495injection-regex = "graphql"
1395file-types = ["gql", "graphql", "graphqls"]
1496file-types = ["gql", "graphql", "graphqls"]
1396−roots = []
1497+language-servers = [ "graphql-language-service" ]
1397indent = { tab-width = 2, unit = " " }
1498indent = { tab-width = 2, unit = " " }
1398
1499
1399[[grammar]]
1500[[grammar]]
@@ -1420,7 +1521,6 @@ name = "iex"
1420scope = "source.iex"
1521scope = "source.iex"
1421injection-regex = "iex"
1522injection-regex = "iex"
1422file-types = ["iex"]
1523file-types = ["iex"]
1423−roots = []
1424
1524
1425[[grammar]]
1525[[grammar]]
1426name = "iex"
1526name = "iex"
@@ -1439,7 +1539,7 @@ indent = { tab-width = 2, unit = " " }
1439
1539
1440[[grammar]]
1540[[grammar]]
1441name = "rescript"
1541name = "rescript"
1442−source = { git = "https://github.com/jaredramirez/tree-sitter-rescript", rev = "65609807c628477f3b94052e7ef895885ac51c3c" }
1542+source = { git = "https://github.com/jaredramirez/tree-sitter-rescript", rev = "467dcf99f68c47823d7b378779a6b282d7ef9782" }
1443
1543
1444[[language]]
1544[[language]]
1445name = "erlang"
1545name = "erlang"
@@ -1483,7 +1583,6 @@ scope = "source.hcl"
1483injection-regex = "(hcl|tf|nomad)"
1583injection-regex = "(hcl|tf|nomad)"
1484language-id = "terraform"
1584language-id = "terraform"
1485file-types = ["hcl", "tf", "nomad"]
1585file-types = ["hcl", "tf", "nomad"]
1486−roots = []
1487comment-token = "#"
1586comment-token = "#"
1488indent = { tab-width = 2, unit = " " }
1587indent = { tab-width = 2, unit = " " }
1489language-servers = [ "terraform-ls" ]
1588language-servers = [ "terraform-ls" ]
@@ -1498,7 +1597,6 @@ name = "tfvars"
1498scope = "source.tfvars"
1597scope = "source.tfvars"
1499language-id = "terraform-vars"
1598language-id = "terraform-vars"
1500file-types = ["tfvars"]
1599file-types = ["tfvars"]
1501−roots = []
1502comment-token = "#"
1600comment-token = "#"
1503indent = { tab-width = 2, unit = " " }
1601indent = { tab-width = 2, unit = " " }
1504language-servers = [ "terraform-ls" ]
1602language-servers = [ "terraform-ls" ]
@@ -1510,7 +1608,6 @@ name = "org"
1510scope = "source.org"
1608scope = "source.org"
1511injection-regex = "org"
1609injection-regex = "org"
1512file-types = ["org"]
1610file-types = ["org"]
1513−roots = []
1514indent = { tab-width = 2, unit = " " }
1611indent = { tab-width = 2, unit = " " }
1515
1612
1516[[grammar]]
1613[[grammar]]
@@ -1522,7 +1619,6 @@ name = "solidity"
1522scope = "source.sol"
1619scope = "source.sol"
1523injection-regex = "(sol|solidity)"
1620injection-regex = "(sol|solidity)"
1524file-types = ["sol"]
1621file-types = ["sol"]
1525−roots = []
1526comment-token = "//"
1622comment-token = "//"
1527indent = { tab-width = 4, unit = " " }
1623indent = { tab-width = 4, unit = " " }
1528language-servers = [ "solc" ]
1624language-servers = [ "solc" ]
@@ -1544,17 +1640,19 @@ auto-format = true
1544
1640
1545[[grammar]]
1641[[grammar]]
1546name = "gleam"
1642name = "gleam"
1547−source = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "a59aadf3d7c11702cad244e7cd6b67b34ca9c16a" }
1643+source = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "b2afa4fd6bb41a7bf912b034c653c90af7ae5122" }
1548
1644
1549[[language]]
1645[[language]]
1550name = "ron"
1646name = "ron"
1551scope = "source.ron"
1647scope = "source.ron"
1552injection-regex = "ron"
1648injection-regex = "ron"
1553file-types = ["ron"]
1649file-types = ["ron"]
1554−roots = []
1555comment-token = "//"
1650comment-token = "//"
1556indent = { tab-width = 4, unit = " " }
1651indent = { tab-width = 4, unit = " " }
1652+
1557−grammar = "rust"
1653+[[grammar]]
1654+name = "ron"
1655+source = { git = "https://github.com/zee-editor/tree-sitter-ron", rev = "7762d709a0f7c1f9e269d0125a2e8a7a69006146" }
1558
1656
1559[[language]]
1657[[language]]
1560name = "robot"
1658name = "robot"
@@ -1562,7 +1660,6 @@ scope = "source.robot"
1562injection-regex = "robot"
1660injection-regex = "robot"
1563file-types = ["robot", "resource"]
1661file-types = ["robot", "resource"]
1564comment-token = "#"
1662comment-token = "#"
1565−roots = []
1566indent = { tab-width = 4, unit = " " }
1663indent = { tab-width = 4, unit = " " }
1567language-servers = [ "robotframework_ls" ]
1664language-servers = [ "robotframework_ls" ]
1568
1665
@@ -1574,9 +1671,8 @@ source = { git = "https://github.com/Hubro/tree-sitter-robot", rev = "322e4cc657
1574name = "r"
1671name = "r"
1575scope = "source.r"
1672scope = "source.r"
1576injection-regex = "(r|R)"
1673injection-regex = "(r|R)"
1577−file-types = ["r", "R", ".Rprofile", "Rprofile.site"]
1674+file-types = ["r", "R", ".Rprofile", "Rprofile.site", ".RHistory"]
1578shebangs = ["r", "R"]
1675shebangs = ["r", "R"]
1579−roots = []
1580comment-token = "#"
1676comment-token = "#"
1581indent = { tab-width = 2, unit = " " }
1677indent = { tab-width = 2, unit = " " }
1582language-servers = [ "r" ]
1678language-servers = [ "r" ]
@@ -1588,9 +1684,9 @@ source = { git = "https://github.com/r-lib/tree-sitter-r", rev = "cc04302e1bff76
1588[[language]]
1684[[language]]
1589name = "rmarkdown"
1685name = "rmarkdown"
1590scope = "source.rmd"
1686scope = "source.rmd"
1687+language-id = "rmd"
1591injection-regex = "(r|R)md"
1688injection-regex = "(r|R)md"
1592file-types = ["rmd", "Rmd"]
1689file-types = ["rmd", "Rmd"]
1593−roots = []
1594indent = { tab-width = 2, unit = " " }
1690indent = { tab-width = 2, unit = " " }
1595grammar = "markdown"
1691grammar = "markdown"
1596language-servers = [ "r" ]
1692language-servers = [ "r" ]
@@ -1614,7 +1710,6 @@ name = "erb"
1614scope = "text.html.erb"
1710scope = "text.html.erb"
1615injection-regex = "erb"
1711injection-regex = "erb"
1616file-types = ["erb"]
1712file-types = ["erb"]
1617−roots = []
1618indent = { tab-width = 2, unit = " " }
1713indent = { tab-width = 2, unit = " " }
1619grammar = "embedded-template"
1714grammar = "embedded-template"
1620
1715
@@ -1623,7 +1718,6 @@ name = "ejs"
1623scope = "text.html.ejs"
1718scope = "text.html.ejs"
1624injection-regex = "ejs"
1719injection-regex = "ejs"
1625file-types = ["ejs"]
1720file-types = ["ejs"]
1626−roots = []
1627indent = { tab-width = 2, unit = " " }
1721indent = { tab-width = 2, unit = " " }
1628grammar = "embedded-template"
1722grammar = "embedded-template"
1629
1723
@@ -1659,15 +1753,14 @@ source = { git = "https://github.com/phoenixframework/tree-sitter-heex", rev = "
1659[[language]]
1753[[language]]
1660name = "sql"
1754name = "sql"
1661scope = "source.sql"
1755scope = "source.sql"
1662−file-types = ["sql"]
1756+file-types = ["sql", "dsql"]
1663−roots = []
1664comment-token = "--"
1757comment-token = "--"
1665indent = { tab-width = 4, unit = " " }
1758indent = { tab-width = 4, unit = " " }
1666injection-regex = "sql"
1759injection-regex = "sql"
1667
1760
1668[[grammar]]
1761[[grammar]]
1669name = "sql"
1762name = "sql"
1670−source = { git = "https://github.com/DerekStride/tree-sitter-sql", rev = "7cbac0472e5b8f8486ce64ffbcf1982d5cd5fc8d" }
1763+source = { git = "https://github.com/DerekStride/tree-sitter-sql", rev = "25be0b8f17e9189ad9e1b875869d025c5aec1286" }
1671
1764
1672[[language]]
1765[[language]]
1673name = "gdscript"
1766name = "gdscript"
@@ -1706,9 +1799,9 @@ scope = "source.nu"
1706injection-regex = "nu"
1799injection-regex = "nu"
1707file-types = ["nu"]
1800file-types = ["nu"]
1708shebangs = ["nu"]
1801shebangs = ["nu"]
1709−roots = []
1710comment-token = "#"
1802comment-token = "#"
1711indent = { tab-width = 2, unit = " " }
1803indent = { tab-width = 2, unit = " " }
1804+language-servers = [ "nu-lsp" ]
1712
1805
1713[[grammar]]
1806[[grammar]]
1714name = "nu"
1807name = "nu"
@@ -1719,7 +1812,6 @@ name = "vala"
1719scope = "source.vala"
1812scope = "source.vala"
1720injection-regex = "vala"
1813injection-regex = "vala"
1721file-types = ["vala", "vapi"]
1814file-types = ["vala", "vapi"]
1722−roots = []
1723comment-token = "//"
1815comment-token = "//"
1724indent = { tab-width = 2, unit = " " }
1816indent = { tab-width = 2, unit = " " }
1725language-servers = [ "vala-language-server" ]
1817language-servers = [ "vala-language-server" ]
@@ -1733,7 +1825,6 @@ name = "hare"
1733scope = "source.hare"
1825scope = "source.hare"
1734injection-regex = "hare"
1826injection-regex = "hare"
1735file-types = ["ha"]
1827file-types = ["ha"]
1736−roots = []
1737comment-token = "//"
1828comment-token = "//"
1738indent = { tab-width = 8, unit = "\t" }
1829indent = { tab-width = 8, unit = "\t" }
1739
1830
@@ -1746,7 +1837,6 @@ name = "devicetree"
1746scope = "source.devicetree"
1837scope = "source.devicetree"
1747injection-regex = "(dtsi?|devicetree|fdt)"
1838injection-regex = "(dtsi?|devicetree|fdt)"
1748file-types = ["dts", "dtsi"]
1839file-types = ["dts", "dtsi"]
1749−roots = []
1750comment-token = "//"
1840comment-token = "//"
1751indent = { tab-width = 4, unit = "\t" }
1841indent = { tab-width = 4, unit = "\t" }
1752
1842
@@ -1759,7 +1849,6 @@ name = "cairo"
1759scope = "source.cairo"
1849scope = "source.cairo"
1760injection-regex = "cairo"
1850injection-regex = "cairo"
1761file-types = ["cairo"]
1851file-types = ["cairo"]
1762−roots = []
1763comment-token = "//"
1852comment-token = "//"
1764indent = { tab-width = 4, unit = " " }
1853indent = { tab-width = 4, unit = " " }
1765# auto-format = true
1854# auto-format = true
@@ -1771,7 +1860,6 @@ name = "cpon"
1771scope = "scope.cpon"
1860scope = "scope.cpon"
1772injection-regex = "cpon"
1861injection-regex = "cpon"
1773file-types = ["cpon", "cp"]
1862file-types = ["cpon", "cp"]
1774−roots = []
1775auto-format = true
1863auto-format = true
1776comment-token = "//"
1864comment-token = "//"
1777indent = { tab-width = 2, unit = " " }
1865indent = { tab-width = 2, unit = " " }
@@ -1798,8 +1886,7 @@ source = { git = "https://github.com/ap29600/tree-sitter-odin", rev = "b219207e4
1798name = "meson"
1886name = "meson"
1799scope = "source.meson"
1887scope = "source.meson"
1800injection-regex = "meson"
1888injection-regex = "meson"
1801−file-types = ["meson.build"]
1889+file-types = ["meson.build", "meson_options.txt"]
1802−roots = []
1803comment-token = "#"
1890comment-token = "#"
1804indent = { tab-width = 2, unit = " " }
1891indent = { tab-width = 2, unit = " " }
1805
1892
@@ -1811,7 +1898,6 @@ source = { git = "https://github.com/staysail/tree-sitter-meson", rev = "32a83e8
1811name = "sshclientconfig"
1898name = "sshclientconfig"
1812scope = "source.sshclientconfig"
1899scope = "source.sshclientconfig"
1813file-types = [{ suffix = ".ssh/config" }, { suffix = "/etc/ssh/ssh_config" }]
1900file-types = [{ suffix = ".ssh/config" }, { suffix = "/etc/ssh/ssh_config" }]
1814−roots = []
1815comment-token = "#"
1901comment-token = "#"
1816
1902
1817[[grammar]]
1903[[grammar]]
@@ -1824,7 +1910,6 @@ scope = "source.scheme"
1824injection-regex = "scheme"
1910injection-regex = "scheme"
1825file-types = ["ss", "scm"]
1911file-types = ["ss", "scm"]
1826shebangs = ["scheme", "guile", "chicken"]
1912shebangs = ["scheme", "guile", "chicken"]
1827−roots = []
1828comment-token = ";"
1913comment-token = ";"
1829indent = { tab-width = 2, unit = " " }
1914indent = { tab-width = 2, unit = " " }
1830
1915
@@ -1851,7 +1936,6 @@ source = {git = "https://github.com/v-analyzer/v-analyzer", subpath = "tree_sitt
1851name = "verilog"
1936name = "verilog"
1852scope = "source.verilog"
1937scope = "source.verilog"
1853file-types = ["v", "vh", "sv", "svh"]
1938file-types = ["v", "vh", "sv", "svh"]
1854−roots = []
1855comment-token = "//"
1939comment-token = "//"
1856language-servers = [ "svlangserver" ]
1940language-servers = [ "svlangserver" ]
1857indent = { tab-width = 2, unit = " " }
1941indent = { tab-width = 2, unit = " " }
@@ -1866,7 +1950,6 @@ name = "edoc"
1866scope = "source.edoc"
1950scope = "source.edoc"
1867file-types = ["edoc", "edoc.in"]
1951file-types = ["edoc", "edoc.in"]
1868injection-regex = "edoc"
1952injection-regex = "edoc"
1869−roots = []
1870indent = { tab-width = 4, unit = " " }
1953indent = { tab-width = 4, unit = " " }
1871
1954
1872[[grammar]]
1955[[grammar]]
@@ -1878,7 +1961,6 @@ name = "jsdoc"
1878scope = "source.jsdoc"
1961scope = "source.jsdoc"
1879injection-regex = "jsdoc"
1962injection-regex = "jsdoc"
1880file-types = ["jsdoc"]
1963file-types = ["jsdoc"]
1881−roots = []
1882indent = { tab-width = 2, unit = " " }
1964indent = { tab-width = 2, unit = " " }
1883
1965
1884[[grammar]]
1966[[grammar]]
@@ -1890,7 +1972,6 @@ name = "openscad"
1890scope = "source.openscad"
1972scope = "source.openscad"
1891injection-regex = "openscad"
1973injection-regex = "openscad"
1892file-types = ["scad"]
1974file-types = ["scad"]
1893−roots = []
1894comment-token = "//"
1975comment-token = "//"
1895language-servers = [ "openscad-lsp" ]
1976language-servers = [ "openscad-lsp" ]
1896indent = { tab-width = 2, unit = "\t" }
1977indent = { tab-width = 2, unit = "\t" }
@@ -1932,7 +2013,6 @@ name = "starlark"
1932scope = "source.starlark"
2013scope = "source.starlark"
1933injection-regex = "(starlark|bzl|bazel)"
2014injection-regex = "(starlark|bzl|bazel)"
1934file-types = ["bzl", "bazel", "BUILD", "star"]
2015file-types = ["bzl", "bazel", "BUILD", "star"]
1935−roots = []
1936comment-token = "#"
2016comment-token = "#"
1937indent = { tab-width = 4, unit = " " }
2017indent = { tab-width = 4, unit = " " }
1938grammar = "python"
2018grammar = "python"
@@ -1941,7 +2021,6 @@ grammar = "python"
1941name = "elvish"
2021name = "elvish"
1942scope = "source.elvish"
2022scope = "source.elvish"
1943file-types = ["elv"]
2023file-types = ["elv"]
1944−roots = []
1945comment-token = "#"
2024comment-token = "#"
1946indent = { tab-width = 2, unit = " " }
2025indent = { tab-width = 2, unit = " " }
1947language-servers = [ "elvish" ]
2026language-servers = [ "elvish" ]
@@ -1957,7 +2036,6 @@ scope = "source.idr"
1957injection-regex = "idr"
2036injection-regex = "idr"
1958file-types = ["idr"]
2037file-types = ["idr"]
1959shebangs = []
2038shebangs = []
1960−roots = []
1961comment-token = "--"
2039comment-token = "--"
1962indent = { tab-width = 2, unit = " " }
2040indent = { tab-width = 2, unit = " " }
1963language-servers = [ "idris2-lsp" ]
2041language-servers = [ "idris2-lsp" ]
@@ -1981,20 +2059,18 @@ name = "ungrammar"
1981scope = "source.ungrammar"
2059scope = "source.ungrammar"
1982injection-regex = "ungrammar"
2060injection-regex = "ungrammar"
1983file-types = ["ungram", "ungrammar"]
2061file-types = ["ungram", "ungrammar"]
1984−roots = []
1985comment-token = "//"
2062comment-token = "//"
1986indent = { tab-width = 2, unit = " " }
2063indent = { tab-width = 2, unit = " " }
1987
2064
1988[[grammar]]
2065[[grammar]]
1989name = "ungrammar"
2066name = "ungrammar"
1990−source = { git = "https://github.com/Philipp-M/tree-sitter-ungrammar", rev = "0113de880a58ea14f2a75802e9b99fcc25003d9c" }
2067+source = { git = "https://github.com/Philipp-M/tree-sitter-ungrammar", rev = "a7e104629cff5a8b7367187610631e8f5eb7c6ea" }
1991
2068
1992[[language]]
2069[[language]]
1993name = "dot"
2070name = "dot"
1994scope = "source.dot"
2071scope = "source.dot"
1995injection-regex = "dot"
2072injection-regex = "dot"
1996file-types = ["dot"]
2073file-types = ["dot"]
1997−roots = []
1998comment-token = "//"
2074comment-token = "//"
1999indent = { tab-width = 4, unit = " " }
2075indent = { tab-width = 4, unit = " " }
2000language-servers = [ "dot-language-server" ]
2076language-servers = [ "dot-language-server" ]
@@ -2024,7 +2100,6 @@ name = "slint"
2024scope = "source.slint"
2100scope = "source.slint"
2025injection-regex = "slint"
2101injection-regex = "slint"
2026file-types = ["slint"]
2102file-types = ["slint"]
2027−roots = []
2028comment-token = "//"
2103comment-token = "//"
2029indent = { tab-width = 4, unit = " " }
2104indent = { tab-width = 4, unit = " " }
2030language-servers = [ "slint-lsp" ]
2105language-servers = [ "slint-lsp" ]
@@ -2038,7 +2113,6 @@ name = "task"
2038scope = "source.task"
2113scope = "source.task"
2039injection-regex = "task"
2114injection-regex = "task"
2040file-types = ["task"]
2115file-types = ["task"]
2041−roots = []
2042comment-token = "#"
2116comment-token = "#"
2043indent = { tab-width = 2, unit = " " }
2117indent = { tab-width = 2, unit = " " }
2044
2118
@@ -2051,7 +2125,6 @@ name = "xit"
2051scope = "source.xit"
2125scope = "source.xit"
2052injection-regex = "xit"
2126injection-regex = "xit"
2053file-types = ["xit"]
2127file-types = ["xit"]
2054−roots = []
2055indent = { tab-width = 4, unit = " " }
2128indent = { tab-width = 4, unit = " " }
2056
2129
2057[[grammar]]
2130[[grammar]]
@@ -2076,7 +2149,6 @@ name = "pascal"
2076scope = "source.pascal"
2149scope = "source.pascal"
2077injection-regex = "pascal"
2150injection-regex = "pascal"
2078file-types = ["pas", "pp", "inc", "lpr", "lfm"]
2151file-types = ["pas", "pp", "inc", "lpr", "lfm"]
2079−roots = []
2080comment-token = "//"
2152comment-token = "//"
2081indent = { tab-width = 2, unit = " " }
2153indent = { tab-width = 2, unit = " " }
2082language-servers = [ "pasls" ]
2154language-servers = [ "pasls" ]
@@ -2091,7 +2163,6 @@ scope = "source.sml"
2091injection-regex = "sml"
2163injection-regex = "sml"
2092file-types = ["sml"]
2164file-types = ["sml"]
2093comment-token = "(*"
2165comment-token = "(*"
2094−roots = []
2095
2166
2096[[grammar]]
2167[[grammar]]
2097name = "sml"
2168name = "sml"
@@ -2115,19 +2186,17 @@ name = "astro"
2115scope = "source.astro"
2186scope = "source.astro"
2116injection-regex = "astro"
2187injection-regex = "astro"
2117file-types = ["astro"]
2188file-types = ["astro"]
2118−roots = []
2119indent = { tab-width = 2, unit = " " }
2189indent = { tab-width = 2, unit = " " }
2120
2190
2121[[grammar]]
2191[[grammar]]
2122name = "astro"
2192name = "astro"
2123−source = { git = "https://github.com/virchau13/tree-sitter-astro", rev = "5f5c3e73c45967df9aa42f861fad2d77cd4e0900" }
2193+source = { git = "https://github.com/virchau13/tree-sitter-astro", rev = "947e93089e60c66e681eba22283f4037841451e7" }
2124
2194
2125[[language]]
2195[[language]]
2126name = "bass"
2196name = "bass"
2127scope = "source.bass"
2197scope = "source.bass"
2128injection-regex = "bass"
2198injection-regex = "bass"
2129file-types = ["bass"]
2199file-types = ["bass"]
2130−roots = []
2131comment-token = ";"
2200comment-token = ";"
2132indent = { tab-width = 2, unit = " " }
2201indent = { tab-width = 2, unit = " " }
2133language-servers = [ "bass" ]
2202language-servers = [ "bass" ]
@@ -2141,7 +2210,6 @@ name = "wat"
2141scope = "source.wat"
2210scope = "source.wat"
2142comment-token = ";;"
2211comment-token = ";;"
2143file-types = ["wat"]
2212file-types = ["wat"]
2144−roots = []
2145
2213
2146[[grammar]]
2214[[grammar]]
2147name = "wat"
2215name = "wat"
@@ -2152,7 +2220,6 @@ name = "wast"
2152scope = "source.wast"
2220scope = "source.wast"
2153comment-token = ";;"
2221comment-token = ";;"
2154file-types = ["wast"]
2222file-types = ["wast"]
2155−roots = []
2156
2223
2157[[grammar]]
2224[[grammar]]
2158name = "wast"
2225name = "wast"
@@ -2162,7 +2229,6 @@ source = { git = "https://github.com/wasm-lsp/tree-sitter-wasm", rev = "2ca28a9f
2162name = "d"
2229name = "d"
2163scope = "source.d"
2230scope = "source.d"
2164file-types = [ "d", "dd" ]
2231file-types = [ "d", "dd" ]
2165−roots = []
2166comment-token = "//"
2232comment-token = "//"
2167injection-regex = "d"
2233injection-regex = "d"
2168indent = { tab-width = 4, unit = " "}
2234indent = { tab-width = 4, unit = " "}
@@ -2171,13 +2237,12 @@ formatter = { command = "dfmt" }
2171
2237
2172[[grammar]]
2238[[grammar]]
2173name = "d"
2239name = "d"
2174−source = { git = "https://github.com/gdamore/tree-sitter-d", rev="601c4a1e8310fb2f3c43fa8a923d0d27497f3c04" }
2240+source = { git = "https://github.com/gdamore/tree-sitter-d", rev = "5566f8ce8fc24186fad06170bbb3c8d97c935d74" }
2175
2241
2176[[language]]
2242[[language]]
2177name = "vhs"
2243name = "vhs"
2178scope = "source.vhs"
2244scope = "source.vhs"
2179file-types = ["tape"]
2245file-types = ["tape"]
2180−roots = []
2181comment-token = "#"
2246comment-token = "#"
2182indent = { tab-width = 2, unit = " " }
2247indent = { tab-width = 2, unit = " " }
2183grammar = "vhs"
2248grammar = "vhs"
@@ -2190,21 +2255,76 @@ source = { git = "https://github.com/charmbracelet/tree-sitter-vhs", rev = "c6d8
2190name = "kdl"
2255name = "kdl"
2191scope = "source.kdl"
2256scope = "source.kdl"
2192file-types = ["kdl"]
2257file-types = ["kdl"]
2193−roots = []
2194comment-token = "//"
2258comment-token = "//"
2195injection-regex = "kdl"
2259injection-regex = "kdl"
2196
2260
2197[[grammar]]
2261[[grammar]]
2198name = "kdl"
2262name = "kdl"
2199−source = { git = "https://github.com/Unoqwy/tree-sitter-kdl", rev = "e1cd292c6d15df6610484e1d4b5c987ecad52373" }
2263+source = { git = "https://github.com/amaanq/tree-sitter-kdl", rev = "3ca569b9f9af43593c24f9e7a21f02f43a13bb88" }
2200
2264
2201[[language]]
2265[[language]]
2202name = "xml"
2266name = "xml"
2203scope = "source.xml"
2267scope = "source.xml"
2204injection-regex = "xml"
2268injection-regex = "xml"
2205−file-types = ["xml", "mobileconfig", "plist", "xib", "storyboard", "svg", "xsd", "gml", "xaml", "gir", "rss", "atom", "opml"]
2269+file-types = [
2270+ "xml",
2271+ "mobileconfig",
2272+ "plist",
2273+ "xib",
2274+ "storyboard",
2275+ "svg",
2276+ "xsd",
2277+ "gml",
2278+ "xaml",
2279+ "gir",
2280+ "rss",
2281+ "atom",
2282+ "opml",
2283+ "policy",
2284+ "ascx",
2285+ "axml",
2286+ "axaml",
2287+ "bpmn",
2288+ "cpt",
2289+ "csl",
2290+ "csproj.user",
2291+ "dita",
2292+ "ditamap",
2293+ "dtml",
2294+ "fxml",
2295+ "iml",
2296+ "isml",
2297+ "jmx",
2298+ "launch",
2299+ "menu",
2300+ "mxml",
2301+ "nuspec",
2302+ "pt",
2303+ "publishsettings",
2304+ "pubxml",
2305+ "pubxml.user",
2306+ "rbxlx",
2307+ "rbxmx",
2308+ "rng",
2309+ "shproj",
2310+ "tld",
2311+ "tmx",
2312+ "vbproj.user",
2313+ "vcxproj",
2314+ "vcxproj.filters",
2315+ "wsdl",
2316+ "wxi",
2317+ "wxs",
2318+ "xbl",
2319+ "xlf",
2320+ "xliff",
2321+ "xpdl",
2322+ "xul",
2323+ "xoml",
2324+ "musicxml",
2325+ "glif"
2326+]
2206indent = { tab-width = 2, unit = " " }
2327indent = { tab-width = 2, unit = " " }
2207−roots = []
2208
2328
2209[language.auto-pairs]
2329[language.auto-pairs]
2210'(' = ')'
2330'(' = ')'
@@ -2225,7 +2345,6 @@ scope = "source.dtd"
2225injection-regex = "dtd"
2345injection-regex = "dtd"
2226file-types = ["dtd", "ent"]
2346file-types = ["dtd", "ent"]
2227indent = {tab-width = 2, unit = " "}
2347indent = {tab-width = 2, unit = " "}
2228−roots = []
2229
2348
2230[language.auto-pairs]
2349[language.auto-pairs]
2231'(' = ')'
2350'(' = ')'
@@ -2243,7 +2362,6 @@ name = "wit"
2243scope = "source.wit"
2362scope = "source.wit"
2244injection-regex = "wit"
2363injection-regex = "wit"
2245file-types = ["wit"]
2364file-types = ["wit"]
2246−roots = []
2247comment-token = "//"
2365comment-token = "//"
2248indent = { tab-width = 2, unit = " " }
2366indent = { tab-width = 2, unit = " " }
2249
2367
@@ -2262,11 +2380,10 @@ source = { git = "https://github.com/hh9527/tree-sitter-wit", rev = "c917790ab9a
2262[[language]]
2380[[language]]
2263name = "env"
2381name = "env"
2264scope = "source.env"
2382scope = "source.env"
2265−file-types = [".env", ".env.local", ".env.development", ".env.production", ".env.dist", ".envrc"]
2383+file-types = [".env", ".env.local", ".env.development", ".env.production", ".env.dist", ".envrc", ".envrc.local", ".envrc.private"]
2266injection-regex = "env"
2384injection-regex = "env"
2267comment-token = "#"
2385comment-token = "#"
2268indent = { tab-width = 4, unit = "\t" }
2386indent = { tab-width = 4, unit = "\t" }
2269−roots = []
2270grammar = "bash"
2387grammar = "bash"
2271
2388
2272[[language]]
2389[[language]]
@@ -2290,12 +2407,15 @@ file-types = [
2290 "container",
2407 "container",
2291 "volume",
2408 "volume",
2292 "kube",
2409 "kube",
2293− "network"
2410+ "network",
2411+ ".editorconfig",
2412+ "properties",
2413+ "cfg",
2414+ "directory"
2294]
2415]
2295injection-regex = "ini"
2416injection-regex = "ini"
2296comment-token = "#"
2417comment-token = "#"
2297indent = { tab-width = 4, unit = "\t" }
2418indent = { tab-width = 4, unit = "\t" }
2298−roots = []
2299
2419
2300[[grammar]]
2420[[grammar]]
2301name = "ini"
2421name = "ini"
@@ -2305,7 +2425,6 @@ source = { git = "https://github.com/justinmk/tree-sitter-ini", rev = "4d247fb87
2305name = "bicep"
2425name = "bicep"
2306scope = "source.bicep"
2426scope = "source.bicep"
2307file-types = ["bicep"]
2427file-types = ["bicep"]
2308−roots = []
2309auto-format = true
2428auto-format = true
2310comment-token = "//"
2429comment-token = "//"
2311indent = { tab-width = 2, unit = " "}
2430indent = { tab-width = 2, unit = " "}
@@ -2319,7 +2438,6 @@ source = { git = "https://github.com/the-mikedavis/tree-sitter-bicep", rev = "d8
2319name = "qml"
2438name = "qml"
2320scope = "source.qml"
2439scope = "source.qml"
2321file-types = ["qml"]
2440file-types = ["qml"]
2322−roots = []
2323language-servers = [ "qmlls" ]
2441language-servers = [ "qmlls" ]
2324indent = { tab-width = 4, unit = " " }
2442indent = { tab-width = 4, unit = " " }
2325grammar = "qmljs"
2443grammar = "qmljs"
@@ -2333,7 +2451,6 @@ name = "mermaid"
2333scope = "source.mermaid"
2451scope = "source.mermaid"
2334injection-regex = "mermaid"
2452injection-regex = "mermaid"
2335file-types = ["mermaid"]
2453file-types = ["mermaid"]
2336−roots = []
2337comment-token = "%%"
2454comment-token = "%%"
2338indent = { tab-width = 4, unit = " " }
2455indent = { tab-width = 4, unit = " " }
2339
2456
@@ -2347,7 +2464,6 @@ scope = "source.m"
2347file-types = ["m"]
2464file-types = ["m"]
2348comment-token = "%"
2465comment-token = "%"
2349shebangs = ["octave-cli", "matlab"]
2466shebangs = ["octave-cli", "matlab"]
2350−roots = []
2351indent = { tab-width = 2, unit = " " }
2467indent = { tab-width = 2, unit = " " }
2352
2468
2353[[grammar]]
2469[[grammar]]
@@ -2372,7 +2488,6 @@ name = "dhall"
2372scope = "source.dhall"
2488scope = "source.dhall"
2373injection-regex = "dhall"
2489injection-regex = "dhall"
2374file-types = ["dhall"]
2490file-types = ["dhall"]
2375−roots = []
2376comment-token = "--"
2491comment-token = "--"
2377indent = { tab-width = 2, unit = " " }
2492indent = { tab-width = 2, unit = " " }
2378language-servers = [ "dhall-lsp-server" ]
2493language-servers = [ "dhall-lsp-server" ]
@@ -2387,7 +2502,6 @@ name = "sage"
2387scope = "source.sage"
2502scope = "source.sage"
2388file-types = ["sage"]
2503file-types = ["sage"]
2389injection-regex = "sage"
2504injection-regex = "sage"
2390−roots = []
2391comment-token = "#"
2505comment-token = "#"
2392indent = { tab-width = 4, unit = " " }
2506indent = { tab-width = 4, unit = " " }
2393grammar = "python"
2507grammar = "python"
@@ -2398,7 +2512,6 @@ scope = "source.msbuild"
2398injection-regex = "msbuild"
2512injection-regex = "msbuild"
2399file-types = ["proj", "vbproj", "csproj", "fsproj", "targets", "props"]
2513file-types = ["proj", "vbproj", "csproj", "fsproj", "targets", "props"]
2400indent = { tab-width = 2, unit = " " }
2514indent = { tab-width = 2, unit = " " }
2401−roots = []
2402grammar = "xml"
2515grammar = "xml"
2403
2516
2404[language.auto-pairs]
2517[language.auto-pairs]
@@ -2414,7 +2527,6 @@ name = "pem"
2414scope = "source.pem"
2527scope = "source.pem"
2415file-types = ["pem", "cert", "crt"]
2528file-types = ["pem", "cert", "crt"]
2416injection-regex = "pem"
2529injection-regex = "pem"
2417−roots = []
2418grammar = "pem"
2530grammar = "pem"
2419
2531
2420[[grammar]]
2532[[grammar]]
@@ -2425,7 +2537,6 @@ source = { git = "https://github.com/mtoohey31/tree-sitter-pem", rev = "be67a433
2425name = "passwd"
2537name = "passwd"
2426scope = "source.passwd"
2538scope = "source.passwd"
2427file-types = ["passwd"]
2539file-types = ["passwd"]
2428−roots = []
2429
2540
2430[[grammar]]
2541[[grammar]]
2431name = "passwd"
2542name = "passwd"
@@ -2435,7 +2546,6 @@ source = { git = "https://github.com/ath3/tree-sitter-passwd", rev = "20239395ea
2435name = "hosts"
2546name = "hosts"
2436scope = "source.hosts"
2547scope = "source.hosts"
2437file-types = ["hosts"]
2548file-types = ["hosts"]
2438−roots = []
2439comment-token = "#"
2549comment-token = "#"
2440
2550
2441[[grammar]]
2551[[grammar]]
@@ -2447,20 +2557,18 @@ name = "uxntal"
2447scope = "source.tal"
2557scope = "source.tal"
2448injection-regex = "tal"
2558injection-regex = "tal"
2449file-types = ["tal"]
2559file-types = ["tal"]
2450−roots = []
2451auto-format = false
2560auto-format = false
2452comment-token = "("
2561comment-token = "("
2453
2562
2454[[grammar]]
2563[[grammar]]
2455name = "uxntal"
2564name = "uxntal"
2456−source = { git = "https://github.com/Jummit/tree-sitter-uxntal", rev = "9297e95ef74380b0ad84c4fd98f91e9f6e4319e6" }
2565+source = { git = "https://github.com/Jummit/tree-sitter-uxntal", rev = "d68406066648cd6db4c6a2f11ec305af02079884" }
2457
2566
2458[[language]]
2567[[language]]
2459name = "yuck"
2568name = "yuck"
2460scope = "source.yuck"
2569scope = "source.yuck"
2461injection-regex = "yuck"
2570injection-regex = "yuck"
2462file-types = ["yuck"]
2571file-types = ["yuck"]
2463−roots = []
2464comment-token = ";"
2572comment-token = ";"
2465indent = { tab-width = 2, unit = " " }
2573indent = { tab-width = 2, unit = " " }
2466
2574
@@ -2473,7 +2581,6 @@ name = "prql"
2473scope = "source.prql"
2581scope = "source.prql"
2474injection-regex = "prql"
2582injection-regex = "prql"
2475file-types = ["prql"]
2583file-types = ["prql"]
2476−roots = []
2477comment-token = "#"
2584comment-token = "#"
2478indent = { tab-width = 4, unit = " " }
2585indent = { tab-width = 4, unit = " " }
2479
2586
@@ -2485,7 +2592,6 @@ source = { git = "https://github.com/PRQL/tree-sitter-prql", rev = "09e158cd3650
2485name = "po"
2592name = "po"
2486scope = "source.po"
2593scope = "source.po"
2487file-types = ["po", "pot"]
2594file-types = ["po", "pot"]
2488−roots = []
2489comment-token = "#"
2595comment-token = "#"
2490
2596
2491[[grammar]]
2597[[grammar]]
@@ -2497,7 +2603,6 @@ name = "nasm"
2497scope = "source.nasm"
2603scope = "source.nasm"
2498file-types = ["asm", "S", "nasm"]
2604file-types = ["asm", "S", "nasm"]
2499injection-regex = "n?asm"
2605injection-regex = "n?asm"
2500−roots = []
2501comment-token = ";"
2606comment-token = ";"
2502indent = { tab-width = 8, unit = " " }
2607indent = { tab-width = 8, unit = " " }
2503
2608
@@ -2510,7 +2615,6 @@ name = "gas"
2510scope = "source.gas"
2615scope = "source.gas"
2511file-types = ["s"]
2616file-types = ["s"]
2512injection-regex = "gas"
2617injection-regex = "gas"
2513−roots = []
2514comment-token = "#"
2618comment-token = "#"
2515indent = { tab-width = 8, unit = " " }
2619indent = { tab-width = 8, unit = " " }
2516
2620
@@ -2523,7 +2627,6 @@ name = "rst"
2523scope = "source.rst"
2627scope = "source.rst"
2524comment-token = ".."
2628comment-token = ".."
2525file-types = ["rst"]
2629file-types = ["rst"]
2526−roots = []
2527
2630
2528[[grammar]]
2631[[grammar]]
2529name = "rst"
2632name = "rst"
@@ -2534,7 +2637,6 @@ name = "capnp"
2534scope = "source.capnp"
2637scope = "source.capnp"
2535injection-regex = "capnp"
2638injection-regex = "capnp"
2536file-types = ["capnp"]
2639file-types = ["capnp"]
2537−roots = []
2538comment-token = "#"
2640comment-token = "#"
2539indent = { tab-width = 2, unit = " " }
2641indent = { tab-width = 2, unit = " " }
2540
2642
@@ -2560,7 +2662,6 @@ source = { git = "https://github.com/indoorvivants/tree-sitter-smithy", rev = "c
2560name = "vhdl"
2662name = "vhdl"
2561scope = "source.vhdl"
2663scope = "source.vhdl"
2562file-types = ["vhd", "vhdl"]
2664file-types = ["vhd", "vhdl"]
2563−roots = []
2564comment-token = "--"
2665comment-token = "--"
2565language-servers = [ "vhdl_ls" ]
2666language-servers = [ "vhdl_ls" ]
2566indent = { tab-width = 2, unit = " " }
2667indent = { tab-width = 2, unit = " " }
@@ -2572,7 +2673,6 @@ source = { git = "https://github.com/teburd/tree-sitter-vhdl", rev = "c57313adee
2572
2673
2573[[language]]
2674[[language]]
2574name = "rego"
2675name = "rego"
2575−roots = []
2576scope = "source.rego"
2676scope = "source.rego"
2577injection-regex = "rego"
2677injection-regex = "rego"
2578file-types = ["rego"]
2678file-types = ["rego"]
@@ -2583,7 +2683,7 @@ grammar = "rego"
2583
2683
2584[[grammar]]
2684[[grammar]]
2585name = "rego"
2685name = "rego"
2586−source = { git = "https://github.com/FallenAngel97/tree-sitter-rego", rev = "b2667c975f07b33be3ceb83bea5cfbad88095866" }
2686+source = { git = "https://github.com/FallenAngel97/tree-sitter-rego", rev = "9ac75e71b2d791e0aadeef68098319d86a2a14cf" }
2587
2687
2588[[language]]
2688[[language]]
2589name = "nim"
2689name = "nim"
@@ -2591,7 +2691,6 @@ scope = "source.nim"
2591injection-regex = "nim"
2691injection-regex = "nim"
2592file-types = ["nim", "nims", "nimble"]
2692file-types = ["nim", "nims", "nimble"]
2593shebangs = []
2693shebangs = []
2594−roots = []
2595comment-token = "#"
2694comment-token = "#"
2596indent = { tab-width = 2, unit = " " }
2695indent = { tab-width = 2, unit = " " }
2597language-servers = [ "nimlangserver" ]
2696language-servers = [ "nimlangserver" ]
@@ -2615,13 +2714,13 @@ file-types = [ "cabal" ]
2615roots = ["cabal.project", "Setup.hs"]
2714roots = ["cabal.project", "Setup.hs"]
2616indent = { tab-width = 2, unit = " " }
2715indent = { tab-width = 2, unit = " " }
2617comment-token = "--"
2716comment-token = "--"
2717+language-servers = [ "haskell-language-server" ]
2618
2718
2619[[language]]
2719[[language]]
2620name = "hurl"
2720name = "hurl"
2621scope = "source.hurl"
2721scope = "source.hurl"
2622injection-regex = "hurl"
2722injection-regex = "hurl"
2623file-types = ["hurl"]
2723file-types = ["hurl"]
2624−roots = []
2625comment-token = "#"
2724comment-token = "#"
2626indent = { tab-width = 2, unit = " " }
2725indent = { tab-width = 2, unit = " " }
2627
2726
@@ -2632,7 +2731,6 @@ source = { git = "https://github.com/pfeiferj/tree-sitter-hurl", rev = "264c4206
2632[[language]]
2731[[language]]
2633name = "markdoc"
2732name = "markdoc"
2634scope = "text.markdoc"
2733scope = "text.markdoc"
2635−roots = []
2636file-types = ["mdoc"]
2734file-types = ["mdoc"]
2637language-servers = [ "markdoc-ls" ]
2735language-servers = [ "markdoc-ls" ]
2638
2736
@@ -2645,7 +2743,6 @@ name = "opencl"
2645scope = "source.cl"
2743scope = "source.cl"
2646injection-regex = "(cl|opencl)"
2744injection-regex = "(cl|opencl)"
2647file-types = ["cl"]
2745file-types = ["cl"]
2648−roots = []
2649comment-token = "//"
2746comment-token = "//"
2650language-servers = [ "clangd" ]
2747language-servers = [ "clangd" ]
2651
2748
@@ -2658,7 +2755,6 @@ name = "just"
2658scope = "source.just"
2755scope = "source.just"
2659file-types = ["justfile", "Justfile", ".justfile", ".Justfile"]
2756file-types = ["justfile", "Justfile", ".justfile", ".Justfile"]
2660injection-regex = "just"
2757injection-regex = "just"
2661−roots = []
2662comment-token = "#"
2758comment-token = "#"
2663indent = { tab-width = 4, unit = "\t" }
2759indent = { tab-width = 4, unit = "\t" }
2664
2760
@@ -2666,12 +2762,25 @@ indent = { tab-width = 4, unit = "\t" }
2666name = "just"
2762name = "just"
2667source = { git = "https://github.com/IndianBoy42/tree-sitter-just", rev = "8af0aab79854aaf25b620a52c39485849922f766" }
2763source = { git = "https://github.com/IndianBoy42/tree-sitter-just", rev = "8af0aab79854aaf25b620a52c39485849922f766" }
2668
2764
2765+[[language]]
2766+name = "gn"
2767+scope = "source.gn"
2768+injection-regex = "gn"
2769+file-types = ["gn", "gni"]
2770+roots = []
2771+comment-token = "#"
2772+indent = { tab-width = 2, unit = " " }
2773+formatter = { command = "gn", args = ["format", "--stdin"] }
2774+
2775+[[grammar]]
2776+name = "gn"
2777+source = { git = "https://github.com/willcassella/tree-sitter-gn", rev = "e18d6e36a79b20dafb58f19d407bd38b0e60260e" }
2778+
2669[[language]]
2779[[language]]
2670name = "blueprint"
2780name = "blueprint"
2671scope = "source.blueprint"
2781scope = "source.blueprint"
2672injection-regex = "blueprint"
2782injection-regex = "blueprint"
2673file-types = ["blp"]
2783file-types = ["blp"]
2674−roots = []
2675comment-token = "//"
2784comment-token = "//"
2676language-servers = [ "blueprint-compiler" ]
2785language-servers = [ "blueprint-compiler" ]
2677indent = { tab-width = 4, unit = " " }
2786indent = { tab-width = 4, unit = " " }
@@ -2685,21 +2794,20 @@ name = "forth"
2685scope = "source.forth"
2794scope = "source.forth"
2686injection-regex = "forth"
2795injection-regex = "forth"
2687file-types = ["fs", "forth", "fth", "4th"]
2796file-types = ["fs", "forth", "fth", "4th"]
2688−roots = []
2689comment-token = "\\"
2797comment-token = "\\"
2690language-servers = [ "forth-lsp" ]
2798language-servers = [ "forth-lsp" ]
2691indent = { tab-width = 3, unit = " " }
2799indent = { tab-width = 3, unit = " " }
2692
2800
2693[[grammar]]
2801[[grammar]]
2694name = "forth"
2802name = "forth"
2695−source = { git = "https://github.com/alexanderbrevig/tree-sitter-forth", rev = "304ed77beb113e37af38b20ff14e3c37bf350d10" }
2803+source = { git = "https://github.com/alexanderbrevig/tree-sitter-forth", rev = "90189238385cf636b9ee99ce548b9e5b5e569d48" }
2696
2804
2697[[language]]
2805[[language]]
2698name = "fsharp"
2806name = "fsharp"
2699scope = "source.fs"
2807scope = "source.fs"
2700roots = ["sln", "fsproj"]
2808roots = ["sln", "fsproj"]
2701injection-regex = "fsharp"
2809injection-regex = "fsharp"
2702−file-types = ["fs", "fsx"]
2810+file-types = ["fs", "fsx", "fsi", "fsscript"]
2703comment-token = "//"
2811comment-token = "//"
2704indent = { tab-width = 4, unit = " " }
2812indent = { tab-width = 4, unit = " " }
2705auto-format = true
2813auto-format = true
@@ -2714,7 +2822,6 @@ name = "t32"
2714scope = "source.t32"
2822scope = "source.t32"
2715injection-regex = "t32"
2823injection-regex = "t32"
2716file-types = ["cmm", "t32"]
2824file-types = ["cmm", "t32"]
2717−roots = []
2718comment-token = ";"
2825comment-token = ";"
2719indent = { tab-width = 2, unit = " " }
2826indent = { tab-width = 2, unit = " " }
2720
2827
@@ -2727,16 +2834,34 @@ name = "webc"
2727scope = "text.html.webc"
2834scope = "text.html.webc"
2728injection-regex = "webc"
2835injection-regex = "webc"
2729file-types = ["webc"]
2836file-types = ["webc"]
2730−roots = []
2731indent = { tab-width = 2, unit = " " }
2837indent = { tab-width = 2, unit = " " }
2732grammar = "html"
2838grammar = "html"
2733
2839
2840+[[language]]
2841+name = "typst"
2842+scope = "source.typst"
2843+injection-regex = "typst"
2844+file-types = ["typst", "typ"]
2845+comment-token = "//"
2846+language-servers = ["typst-lsp"]
2847+indent = { tab-width = 2, unit = " " }
2848+
2849+[language.auto-pairs]
2850+'(' = ')'
2851+'{' = '}'
2852+'[' = ']'
2853+'$' = '$'
2854+'"' = '"'
2855+
2856+[[grammar]]
2857+name = "typst"
2858+source = { git = "https://github.com/uben0/tree-sitter-typst", rev = "e35aa22395fdde82bbc4b5700c324ce346dfc9e5" }
2859+
2734[[language]]
2860[[language]]
2735name = "nunjucks"
2861name = "nunjucks"
2736scope = "text.html.nunjucks"
2862scope = "text.html.nunjucks"
2737injection-regex = "nunjucks"
2863injection-regex = "nunjucks"
2738file-types = ["njk"]
2864file-types = ["njk"]
2739−roots = []
2740indent = { tab-width = 2, unit = " " }
2865indent = { tab-width = 2, unit = " " }
2741grammar = "jinja2"
2866grammar = "jinja2"
2742
2867
@@ -2745,7 +2870,6 @@ name = "jinja"
2745scope = "text.html.jinja"
2870scope = "text.html.jinja"
2746injection-regex = "jinja"
2871injection-regex = "jinja"
2747file-types = ["jinja", "jinja2", "j2"]
2872file-types = ["jinja", "jinja2", "j2"]
2748−roots = []
2749indent = { tab-width = 2, unit = " " }
2873indent = { tab-width = 2, unit = " " }
2750grammar = "jinja2"
2874grammar = "jinja2"
2751
2875
@@ -2762,7 +2886,6 @@ name = "wren"
2762scope = "source.wren"
2886scope = "source.wren"
2763injection-regex = "wren"
2887injection-regex = "wren"
2764file-types = ["wren"]
2888file-types = ["wren"]
2765−roots = []
2766indent = { tab-width = 2, unit = " "}
2889indent = { tab-width = 2, unit = " "}
2767
2890
2768[[language]]
2891[[language]]
@@ -2771,7 +2894,6 @@ scope = "source.unison"
2771injection-regex = "unison"
2894injection-regex = "unison"
2772file-types = ["u"]
2895file-types = ["u"]
2773shebangs = []
2896shebangs = []
2774−roots = []
2775auto-format = false
2897auto-format = false
2776comment-token = "--"
2898comment-token = "--"
2777indent = { tab-width = 4, unit = " " }
2899indent = { tab-width = 4, unit = " " }
@@ -2791,7 +2913,6 @@ source = { git = "https://github.com/kylegoetz/tree-sitter-unison", rev = "98c4e
2791name = "todotxt"
2913name = "todotxt"
2792scope = "text.todotxt"
2914scope = "text.todotxt"
2793file-types = [{ suffix = ".todo.txt" }, "todotxt"]
2915file-types = [{ suffix = ".todo.txt" }, "todotxt"]
2794−roots = []
2795formatter = { command = "sort" }
2916formatter = { command = "sort" }
2796auto-format = true
2917auto-format = true
2797
2918
@@ -2803,7 +2924,6 @@ source = { git = "https://github.com/arnarg/tree-sitter-todotxt", rev = "0207f6a
2803name = "strace"
2924name = "strace"
2804scope = "source.strace"
2925scope = "source.strace"
2805file-types = ["strace"]
2926file-types = ["strace"]
2806−roots = []
2807
2927
2808[[grammar]]
2928[[grammar]]
2809name = "strace"
2929name = "strace"
@@ -2813,8 +2933,76 @@ source = { git = "https://github.com/sigmaSd/tree-sitter-strace", rev = "2b18fdf
2813name = "gemini"
2933name = "gemini"
2814scope = "source.gmi"
2934scope = "source.gmi"
2815file-types = ["gmi"]
2935file-types = ["gmi"]
2816−roots = []
2817
2936
2818[[grammar]]
2937[[grammar]]
2819name = "gemini"
2938name = "gemini"
2820−source = { git = "https://git.sr.ht/~sfr/tree-sitter-gemini", rev = "3cc5e4bdf572d5df4277fc2e54d6299bd59a54b3" }
2939+source = { git = "https://git.sr.ht/~nbsp/tree-sitter-gemini", rev = "3cc5e4bdf572d5df4277fc2e54d6299bd59a54b3" }
2940+
2941+[[language]]
2942+name = "agda"
2943+scope = "source.agda"
2944+injection-regex = "agda"
2945+file-types = ["agda"]
2946+roots = []
2947+comment-token = "--"
2948+# language-servers = [ "als" ]
2949+# the agda language server is of questionable functionality.
2950+auto-format = false
2951+indent = { tab-width = 2, unit = " " }
2952+
2953+[language.auto-pairs]
2954+'"' = '"'
2955+"'" = "'"
2956+'{' = '}'
2957+'(' = ')'
2958+'[' = ']'
2959+
2960+# [language.debugger]
2961+# ?? can this be used for proof assistant support? explore
2962+
2963+[[grammar]]
2964+name = "agda"
2965+source = { git = "https://github.com/tree-sitter/tree-sitter-agda", rev = "c21c3a0f996363ed17b8ac99d827fe5a4821f217" }
2966+
2967+[[language]]
2968+name = "templ"
2969+scope = "source.templ"
2970+file-types = ["templ"]
2971+roots = ["go.work", "go.mod"]
2972+comment-token = "//"
2973+indent = { tab-width = 2, unit = " " }
2974+language-servers = [ "templ" ]
2975+
2976+[[grammar]]
2977+name = "templ"
2978+source = { git = "https://github.com/vrischmann/tree-sitter-templ", rev = "ea56ac0655243490a4929a988f4eaa91dfccc995" }
2979+
2980+[[language]]
2981+name = "dbml"
2982+scope = "source.dbml"
2983+injection-regex = "dbml"
2984+file-types = ["dbml"]
2985+comment-token = ";"
2986+indent = { tab-width = 2, unit = " " }
2987+
2988+[[grammar]]
2989+name = "dbml"
2990+source = { git = "https://github.com/dynamotn/tree-sitter-dbml", rev = "2e2fa5640268c33c3d3f27f7e676f631a9c68fd9" }
2991+
2992+[[language]]
2993+name = "log"
2994+scope = "source.log"
2995+file-types = ["log"]
2996+
2997+[[grammar]]
2998+name = "log"
2999+source = { git = "https://github.com/Tudyx/tree-sitter-log", rev = "62cfe307e942af3417171243b599cc7deac5eab9" }
3000+
3001+[[language]]
3002+name = "janet"
3003+scope = "source.janet"
3004+injection-regex = "janet"
3005+file-types = ["janet"]
3006+comment-token = "#"
3007+indent = { tab-width = 2, unit = " " }
3008+grammar = "clojure"
logo.svg+1−1
@@ -1 +1 @@
1−<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" viewBox="663.38 37.57 575.35 903.75"> <g transform="matrix(1,0,0,1,-31352.7,-1817.25)"> <g transform="matrix(1,0,0,1,31062.7,-20.8972)"> <g transform="matrix(1,0,0,1,-130.173,0.00185558)"> <path d="M1083.58,1875.72L1635.06,2194.12C1649.8,2202.63 1658.88,2218.37 1658.88,2235.39C1658.88,2264.98 1658.88,2311.74 1658.88,2341.33C1658.88,2349.84 1656.61,2358.03 1652.5,2365.16C1652.5,2365.16 1214.7,2112.4 1107.2,2050.33C1092.58,2041.89 1083.58,2026.29 1083.58,2009.41C1083.58,1963.5 1083.58,1875.72 1083.58,1875.72Z" style="fill:#706bc8;"></path> </g> <g transform="matrix(1,0,0,1,-130.173,0.00185558)"> <path d="M1635.26,2604.84C1649.88,2613.28 1658.88,2628.87 1658.88,2645.75C1658.88,2691.67 1658.88,2779.44 1658.88,2779.44L1107.41,2461.05C1092.66,2452.53 1083.58,2436.8 1083.58,2419.78C1083.58,2390.19 1083.58,2343.42 1083.58,2313.84C1083.58,2305.32 1085.85,2297.13 1089.96,2290.01C1089.96,2290.01 1527.76,2542.77 1635.26,2604.84Z" style="fill:#55c5e4;"></path> </g> <g transform="matrix(1,0,0,1,216.062,984.098)"> <path d="M790.407,1432.56C785.214,1435.55 780.717,1439.9 777.509,1445.46C767.862,1462.16 773.473,1483.76 790.004,1493.59L789.998,1493.59L761.173,1476.95C746.427,1468.44 737.344,1452.71 737.344,1435.68C737.344,1406.09 737.344,1359.33 737.344,1329.74C737.344,1312.71 746.427,1296.98 761.173,1288.47L1259.59,1000.74L1259.83,1000.6C1264.92,997.617 1269.33,993.314 1272.48,987.844C1282.13,971.136 1276.52,949.544 1259.99,939.707L1260,939.707L1288.82,956.349C1303.57,964.862 1312.65,980.595 1312.65,997.622C1312.65,1027.21 1312.65,1073.97 1312.65,1103.56C1312.65,1120.59 1303.57,1136.32 1288.82,1144.83L1259.19,1161.94L1259.59,1161.68L790.407,1432.56Z" style="fill:#84ddea;"></path> </g> <g transform="matrix(1,0,0,1,216.062,984.098)"> <path d="M790.407,1686.24C785.214,1689.23 780.717,1693.58 777.509,1699.13C767.862,1715.84 773.473,1737.43 790.004,1747.27L789.998,1747.27L761.173,1730.63C746.427,1722.12 737.344,1706.38 737.344,1689.36C737.344,1659.77 737.344,1613.01 737.344,1583.42C737.344,1566.39 746.427,1550.66 761.173,1542.15L1259.59,1254.42L1259.83,1254.28C1264.92,1251.29 1269.33,1246.99 1272.48,1241.52C1282.13,1224.81 1276.52,1203.22 1259.99,1193.38L1260,1193.38L1288.82,1210.03C1303.57,1218.54 1312.65,1234.27 1312.65,1251.3C1312.65,1280.89 1312.65,1327.65 1312.65,1357.24C1312.65,1374.26 1303.57,1390 1288.82,1398.51L1259.19,1415.61L1259.59,1415.36L790.407,1686.24Z" style="fill:#997bc8;"></path></g></g></g> </svg>
1+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" viewBox="663.38 37.57 575.35 903.75"><g transform="matrix(1,0,0,1,-31352.7,-1817.25)"><g transform="matrix(1,0,0,1,31062.7,-20.8972)"><g transform="matrix(1,0,0,1,-130.173,0.00185558)"><path style="fill:#706bc8;" d="M1083.58,1875.72L1635.06,2194.12C1649.8,2202.63 1658.88,2218.37 1658.88,2235.39C1658.88,2264.98 1658.88,2311.74 1658.88,2341.33C1658.88,2349.84 1656.61,2358.03 1652.5,2365.16C1652.5,2365.16 1214.7,2112.4 1107.2,2050.33C1092.58,2041.89 1083.58,2026.29 1083.58,2009.41C1083.58,1963.5 1083.58,1875.72 1083.58,1875.72Z"></path></g><g transform="matrix(1,0,0,1,-130.173,0.00185558)"><path style="fill:#55c5e4;" d="M1635.26,2604.84C1649.88,2613.28 1658.88,2628.87 1658.88,2645.75C1658.88,2691.67 1658.88,2779.44 1658.88,2779.44L1107.41,2461.05C1092.66,2452.53 1083.58,2436.8 1083.58,2419.78C1083.58,2390.19 1083.58,2343.42 1083.58,2313.84C1083.58,2305.32 1085.85,2297.13 1089.96,2290.01C1089.96,2290.01 1527.76,2542.77 1635.26,2604.84Z"></path></g><g transform="matrix(1,0,0,1,216.062,984.098)"><path style="fill:#84ddea;" d="M790.407,1432.56C785.214,1435.55 780.717,1439.9 777.509,1445.46C767.862,1462.16 773.473,1483.76 790.004,1493.59L789.998,1493.59L761.173,1476.95C746.427,1468.44 737.344,1452.71 737.344,1435.68C737.344,1406.09 737.344,1359.33 737.344,1329.74C737.344,1312.71 746.427,1296.98 761.173,1288.47L1259.59,1000.74L1259.83,1000.6C1264.92,997.617 1269.33,993.314 1272.48,987.844C1282.13,971.136 1276.52,949.544 1259.99,939.707L1260,939.707L1288.82,956.349C1303.57,964.862 1312.65,980.595 1312.65,997.622C1312.65,1027.21 1312.65,1073.97 1312.65,1103.56C1312.65,1120.59 1303.57,1136.32 1288.82,1144.83L1259.19,1161.94L1259.59,1161.68L790.407,1432.56Z"></path></g><g transform="matrix(1,0,0,1,216.062,984.098)"><path style="fill:#997bc8;" d="M790.407,1686.24C785.214,1689.23 780.717,1693.58 777.509,1699.13C767.862,1715.84 773.473,1737.43 790.004,1747.27L789.998,1747.27L761.173,1730.63C746.427,1722.12 737.344,1706.38 737.344,1689.36C737.344,1659.77 737.344,1613.01 737.344,1583.42C737.344,1566.39 746.427,1550.66 761.173,1542.15L1259.59,1254.42L1259.83,1254.28C1264.92,1251.29 1269.33,1246.99 1272.48,1241.52C1282.13,1224.81 1276.52,1203.22 1259.99,1193.38L1260,1193.38L1288.82,1210.03C1303.57,1218.54 1312.65,1234.27 1312.65,1251.3C1312.65,1280.89 1312.65,1327.65 1312.65,1357.24C1312.65,1374.26 1303.57,1390 1288.82,1398.51L1259.19,1415.61L1259.59,1415.36L790.407,1686.24Z"></path></g></g></g></svg>
runtime/queries/_typescript/highlights.scm+5−3
@@ -39,11 +39,11 @@
39 (identifier) @variable.parameter))
39 (identifier) @variable.parameter))
40
40
41; (p?: t)
41; (p?: t)
42−; (p?: t = 1) // Invalid but still posible to hihglight.
42+; (p?: t = 1) // Invalid but still possible to highlight.
43(optional_parameter
43(optional_parameter
44 (identifier) @variable.parameter)
44 (identifier) @variable.parameter)
45
45
46−; (...p?: t) // Invalid but still posible to hihglight.
46+; (...p?: t) // Invalid but still possible to highlight.
47(optional_parameter
47(optional_parameter
48 (rest_pattern
48 (rest_pattern
49 (identifier) @variable.parameter))
49 (identifier) @variable.parameter))
@@ -59,7 +59,7 @@
59 (pair_pattern
59 (pair_pattern
60 value: (identifier) @variable.parameter)))
60 value: (identifier) @variable.parameter)))
61
61
62−; ([ p ]?: t[]) // Invalid but still posible to hihglight.
62+; ([ p ]?: t[]) // Invalid but still possible to highlight.
63(optional_parameter
63(optional_parameter
64 (array_pattern
64 (array_pattern
65 (identifier) @variable.parameter))
65 (identifier) @variable.parameter))
@@ -107,6 +107,8 @@
107; Types
107; Types
108; -----
108; -----
109
109
110+(type_parameter
111+ name: (type_identifier) @type.parameter)
110(type_identifier) @type
112(type_identifier) @type
111(predefined_type) @type.builtin
113(predefined_type) @type.builtin
112
114
runtime/queries/_typescript/locals.scm+17
@@ -1,6 +1,18 @@
1+; Scopes
2+;-------
3+
4+[
5+ (type_alias_declaration)
6+ (class_declaration)
7+ (interface_declaration)
8+] @local.scope
9+
1; Definitions
10; Definitions
2;------------
11;------------
3
12
13+(type_parameter
14+ name: (type_identifier) @local.definition)
15+
4; Javascript and Typescript Treesitter grammars deviate when defining the
16; Javascript and Typescript Treesitter grammars deviate when defining the
5; tree structure for parameters, so we need to address them in each specific
17; tree structure for parameters, so we need to address them in each specific
6; language instead of ecma.
18; language instead of ecma.
@@ -14,3 +26,8 @@
14; (i?: t = 1) // Invalid but still posible to hihglight.
26; (i?: t = 1) // Invalid but still posible to hihglight.
15(optional_parameter
27(optional_parameter
16 (identifier) @local.definition)
28 (identifier) @local.definition)
29+
30+; References
31+;-----------
32+
33+(type_identifier) @local.reference
runtime/queries/agda/highlights.scmnew file+124
@@ -0,0 +1,124 @@
1+;; Punctuation
2+[ "." ";" ":"] @punctuation.delimiter
3+[ "(" ")" "{" "}" ] @punctuation.bracket
4+
5+;; Constants
6+(integer) @constant.numeric.integer
7+; (float) @constant.numeric.float
8+(literal) @string
9+
10+;; Pragmas and comments
11+(comment) @comment
12+(pragma) @attribute
13+(macro) @function.macro
14+
15+;; Imports
16+(module_name) @namespace
17+(import_directive (id) @namespace)
18+[(module) (import) (open)] @keyword.control.import
19+
20+;; Types
21+(typed_binding (expr) @type)
22+(record (expr) @type)
23+(data (expr) @type)
24+(signature (expr) @type)
25+(function (rhs (expr) @type))
26+; todo: these are too general. ideally, any nested (atom)
27+; https://github.com/tree-sitter/tree-sitter/issues/880
28+
29+;; Variables
30+(untyped_binding (atom) @variable)
31+(typed_binding (atom) @variable)
32+(field_name) @variable.other.member
33+
34+;; Functions
35+(function_name) @function
36+;(function (lhs
37+; . (atom) @function
38+; (atom) @variable.parameter))
39+; todo: currently fails to parse, upstream tree-sitter bug
40+
41+;; Data
42+[(data_name) (record_name)] @constructor
43+((atom) @constant.builtin.boolean
44+ (#any-of? @constant.builtin.boolean "true" "false" "True" "False"))
45+
46+"Set" @type.builtin
47+
48+; postulate
49+; type_signature
50+; pattern
51+; id
52+; bid
53+; typed_binding
54+; primitive
55+; private
56+; record_signature
57+; record_assignments
58+; field_assignment
59+; module_assignment
60+; renaming
61+; import_directive
62+; lambda
63+; let
64+; instance
65+; generalize
66+; record
67+; fields
68+; syntax
69+; hole_name
70+; data_signature
71+
72+;; Keywords
73+[
74+ "where"
75+ "data"
76+ "rewrite"
77+ "postulate"
78+ "public"
79+ "private"
80+ "tactic"
81+ "Prop"
82+ "quote"
83+ "renaming"
84+ "in"
85+ "hiding"
86+ "constructor"
87+ "abstract"
88+ "let"
89+ "field"
90+ "mutual"
91+ "infix"
92+ "infixl"
93+ "infixr"
94+ "record"
95+ "overlap"
96+ "instance"
97+ "do"
98+] @keyword
99+
100+[
101+ "="
102+] @operator
103+
104+; = | -> : ? \ .. ... λ ∀ →
105+; (_LAMBDA) (_FORALL) (_ARROW)
106+; "coinductive"
107+; "eta-equality"
108+; "field"
109+; "inductive"
110+; "interleaved"
111+; "macro"
112+; "no-eta-equality"
113+; "pattern"
114+; "primitive"
115+; "quoteTerm"
116+; "rewrite"
117+; "syntax"
118+; "unquote"
119+; "unquoteDecl"
120+; "unquoteDef"
121+; "using"
122+; "variable"
123+; "with"
124+
runtime/queries/bash/indents.scm+1
@@ -2,6 +2,7 @@
2 (function_definition)
2 (function_definition)
3 (if_statement)
3 (if_statement)
4 (for_statement)
4 (for_statement)
5+ (while_statement)
5 (case_statement)
6 (case_statement)
6 (pipeline)
7 (pipeline)
7] @indent
8] @indent
runtime/queries/c/indents.scm+13
@@ -36,3 +36,16 @@
36(parameter_list
36(parameter_list
37 . (parameter_declaration) @anchor
37 . (parameter_declaration) @anchor
38 (#set! "scope" "tail")) @align
38 (#set! "scope" "tail")) @align
39+(argument_list
40+ . (_) @anchor
41+ (#set! "scope" "tail")) @align
42+; These are a bit opinionated since some people just indent binary/ternary expressions spanning multiple lines.
43+; Since they are only triggered when a newline is inserted into an already complete binary/ternary expression,
44+; this should happen rarely, so it is not a big deal either way.
45+; Additionally, adding these queries has the advantage of preventing such continuation lines from being used
46+; as the baseline when the `hybrid` indent heuristic is used (which is desirable since their indentation is so inconsistent).
47+(binary_expression
48+ (#set! "scope" "tail")) @anchor @align
49+(conditional_expression
50+ "?" @anchor
51+ (#set! "scope" "tail")) @align
runtime/queries/comment/highlights.scm+8−8
@@ -7,31 +7,31 @@
7
7
8; Hint level tags
8; Hint level tags
9((tag (name) @hint)
9((tag (name) @hint)
10− (#match? @hint "^(HINT|MARK)$"))
10+ (#match? @hint "^(HINT|MARK|PASSED|STUB|MOCK)$"))
11
11
12("text" @hint
12("text" @hint
13− (#match? @hint "^(HINT|MARK)$"))
13+ (#match? @hint "^(HINT|MARK|PASSED|STUB|MOCK)$"))
14
14
15; Info level tags
15; Info level tags
16((tag (name) @info)
16((tag (name) @info)
17− (#match? @info "^(INFO|NOTE|TODO)$"))
17+ (#match? @info "^(INFO|NOTE|TODO|PERF|OPTIMIZE|PERFORMANCE|QUESTION|ASK)$"))
18
18
19("text" @info
19("text" @info
20− (#match? @info "^(INFO|NOTE|TODO)$"))
20+ (#match? @info "^(INFO|NOTE|TODO|PERF|OPTIMIZE|PERFORMANCE|QUESTION|ASK)$"))
21
21
22; Warning level tags
22; Warning level tags
23((tag (name) @warning)
23((tag (name) @warning)
24− (#match? @warning "^(HACK|WARN|WARNING)$"))
24+ (#match? @warning "^(HACK|WARN|WARNING|TEST|TEMP)$"))
25
25
26("text" @warning
26("text" @warning
27− (#match? @warning "^(HACK|WARN|WARNING)$"))
27+ (#match? @warning "^(HACK|WARN|WARNING|TEST|TEMP)$"))
28
28
29; Error level tags
29; Error level tags
30((tag (name) @error)
30((tag (name) @error)
31− (#match? @error "^(BUG|FIXME|ISSUE|XXX)$"))
31+ (#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG)$"))
32
32
33("text" @error
33("text" @error
34− (#match? @error "^(BUG|FIXME|ISSUE|XXX)$"))
34+ (#match? @error "^(BUG|FIXME|ISSUE|XXX|FIX|SAFETY|FIXIT|FAILED|DEBUG)$"))
35
35
36(tag
36(tag
37 (name) @ui.text
37 (name) @ui.text
runtime/queries/common-lisp/indents.scmnew file+1
@@ -0,0 +1 @@
1+; inherits: scheme
runtime/queries/dbml/highlights.scmnew file+44
@@ -0,0 +1,44 @@
1+
2+; comments highlighting
3+(comment) @comment
4+
5+; keyword highlighting
6+(keyword_def) @keyword
7+(keyword_enum) @keyword
8+(keyword_ref) @keyword
9+
10+; identify blocks and definitions
11+(definition) @function
12+
13+; for identifiers
14+(identifier) @variable
15+(type) @keyword
16+
17+; Highlight special types for database/data types
18+("Project" ) @type
19+("Table" ) @type
20+("TableGroup" ) @type
21+("database_type" ) @variable
22+
23+; string and number constants
24+("'''") @constant.character.escape
25+(string) @string
26+(number) @constant.numeric
27+
28+; brackets
29+[
30+ "("
31+ ")"
32+ "{"
33+ "}"
34+ "["
35+ "]"
36+] @punctuation.bracket
37+
38+; brackets
39+[
40+ ":"
41+ "."
42+ ","
43+] @punctuation.delimiter
44+
runtime/queries/gleam/highlights.scm+16−5
@@ -21,6 +21,8 @@
21
21
22; Functions
22; Functions
23(unqualified_import (identifier) @function)
23(unqualified_import (identifier) @function)
24+(unqualified_import "type" (type_identifier) @type)
25+(unqualified_import (type_identifier) @constructor)
24(function
26(function
25 name: (identifier) @function)
27 name: (identifier) @function)
26(external_function
28(external_function
@@ -43,6 +45,13 @@
43(tuple_access
45(tuple_access
44 index: (integer) @variable.other.member)
46 index: (integer) @variable.other.member)
45
47
48+; Attributes
49+(attribute
50+ "@" @attribute
51+ name: (identifier) @attribute)
52+
53+(attribute_value (identifier) @constant)
54+
46; Type names
55; Type names
47(remote_type_identifier) @type
56(remote_type_identifier) @type
48(type_identifier) @type
57(type_identifier) @type
@@ -60,10 +69,6 @@
60(identifier) @variable
69(identifier) @variable
61(discard) @comment.unused
70(discard) @comment.unused
62
71
63−; Operators
64−(binary_expression
65− operator: _ @operator)
66−
67; Keywords
72; Keywords
68[
73[
69 (visibility_modifier) ; "pub"
74 (visibility_modifier) ; "pub"
@@ -72,6 +77,7 @@
72 "assert"
77 "assert"
73 "case"
78 "case"
74 "const"
79 "const"
80+ ; DEPRECATED: 'external' was removed in v0.30.
75 "external"
81 "external"
76 "fn"
82 "fn"
77 "if"
83 "if"
@@ -79,11 +85,16 @@
79 "let"
85 "let"
80 "panic"
86 "panic"
81 "todo"
87 "todo"
82− "try"
83 "type"
88 "type"
84 "use"
89 "use"
85] @keyword
90] @keyword
86
91
92+; Operators
93+(binary_expression
94+ operator: _ @operator)
95+(boolean_negation "!" @operator)
96+(integer_negation "-" @operator)
97+
87; Punctuation
98; Punctuation
88[
99[
89 "("
100 "("
runtime/queries/gn/highlights.scmnew file+42
@@ -0,0 +1,42 @@
1+; Copyright (C) 2021 Will Cassella (github@willcassella.com)
2+;
3+; Licensed under the Apache License, Version 2.0 (the "License");
4+; you may not use this file except in compliance with the License.
5+; You may obtain a copy of the License at
6+;
7+; http://www.apache.org/licenses/LICENSE-2.0
8+;
9+; Unless required by applicable law or agreed to in writing, software
10+; distributed under the License is distributed on an "AS IS" BASIS,
11+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+; See the License for the specific language governing permissions and
13+; limitations under the License.
14+
15+(identifier) @variable.builtin
16+
17+(scope_access field: (_) @variable.other.member)
18+
19+(call target: (_) @function)
20+
21+[ "if" "else" ] @keyword.control.conditional
22+
23+[
24+ (assign_op)
25+ (arithmetic_binary_op)
26+ (comparison_binary_op)
27+ (equivalence_binary_op)
28+ (logical_and_binary_op)
29+ (logical_or_binary_op)
30+ (negation_unary_op)
31+] @operator
32+
33+[ "(" ")" "[" "]" "{" "}" ] @punctuation.bracket
34+[ "." "," ] @punctuation.delimiter
35+
36+(string) @string
37+(string_escape) @constant.character.escape
38+(string_expansion [ "$" "${" "}" ] @constant.character.escape)
39+[ (integer) (hex) ] @constant.numeric
40+(boolean) @constant.builtin.boolean
41+
42+(comment) @comment
runtime/queries/gn/injections.scmnew file+15
@@ -0,0 +1,15 @@
1+; Copyright (C) 2021 Will Cassella (github@willcassella.com)
2+;
3+; Licensed under the Apache License, Version 2.0 (the "License");
4+; you may not use this file except in compliance with the License.
5+; You may obtain a copy of the License at
6+;
7+; http://www.apache.org/licenses/LICENSE-2.0
8+;
9+; Unless required by applicable law or agreed to in writing, software
10+; distributed under the License is distributed on an "AS IS" BASIS,
11+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+; See the License for the specific language governing permissions and
13+; limitations under the License.
14+
15+((comment) @injection.content (#set! injection.language "comment"))
runtime/queries/gn/locals.scmnew file+16
@@ -0,0 +1,16 @@
1+; Copyright (C) 2021 Will Cassella (github@willcassella.com)
2+;
3+; Licensed under the Apache License, Version 2.0 (the "License");
4+; you may not use this file except in compliance with the License.
5+; You may obtain a copy of the License at
6+;
7+; http://www.apache.org/licenses/LICENSE-2.0
8+;
9+; Unless required by applicable law or agreed to in writing, software
10+; distributed under the License is distributed on an "AS IS" BASIS,
11+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+; See the License for the specific language governing permissions and
13+; limitations under the License.
14+
15+(source_file) @local.scope
16+(assignment target: (identifier) @local.definition)
runtime/queries/go/highlights.scm+13−5
@@ -11,6 +11,18 @@
11 function: (selector_expression
11 function: (selector_expression
12 field: (field_identifier) @function.method))
12 field: (field_identifier) @function.method))
13
13
14+
15+; Types
16+
17+(type_parameter_list
18+ (parameter_declaration
19+ name: (identifier) @type.parameter))
20+
21+((type_identifier) @type.builtin
22+ (match? @type.builtin "^(any|bool|byte|comparable|complex128|complex64|error|float32|float64|int|int16|int32|int64|int8|rune|string|uint|uint16|uint32|uint64|uint8|uintptr)$"))
23+
24+(type_identifier) @type
25+
14; Function definitions
26; Function definitions
15
27
16(function_declaration
28(function_declaration
@@ -24,20 +36,16 @@
24
36
25; Identifiers
37; Identifiers
26
38
27−((identifier) @constant (match? @constant "^[A-Z][A-Z\\d_]+$"))
28(const_spec
39(const_spec
29 name: (identifier) @constant)
40 name: (identifier) @constant)
30
41
31(parameter_declaration (identifier) @variable.parameter)
42(parameter_declaration (identifier) @variable.parameter)
32(variadic_parameter_declaration (identifier) @variable.parameter)
43(variadic_parameter_declaration (identifier) @variable.parameter)
33
44
34−((type_identifier) @type.builtin
35− (match? @type.builtin "^(any|bool|byte|comparable|complex128|complex64|error|float32|float64|int|int16|int32|int64|int8|rune|string|uint|uint16|uint32|uint64|uint8|uintptr)$"))
36−
37−(type_identifier) @type
38(type_spec
45(type_spec
39 name: (type_identifier) @constructor)
46 name: (type_identifier) @constructor)
40(field_identifier) @variable.other.member
47(field_identifier) @variable.other.member
48+(keyed_element (literal_element (identifier) @variable.other.member))
41(identifier) @variable
49(identifier) @variable
42(package_identifier) @namespace
50(package_identifier) @namespace
43
51
runtime/queries/go/locals.scm+10−2
@@ -1,9 +1,17 @@
1; Scopes
1; Scopes
2
2
3+[
4+ (function_declaration)
5+ (type_declaration)
6+ (block)
3−(block) @local.scope
7+] @local.scope
4
8
5; Definitions
9; Definitions
6
10
11+(type_parameter_list
12+ (parameter_declaration
13+ name: (identifier) @local.definition))
14+
7(parameter_declaration (identifier) @local.definition)
15(parameter_declaration (identifier) @local.definition)
8(variadic_parameter_declaration (identifier) @local.definition)
16(variadic_parameter_declaration (identifier) @local.definition)
9
17
@@ -27,4 +35,4 @@
27
35
28(identifier) @local.reference
36(identifier) @local.reference
29(field_identifier) @local.reference
37(field_identifier) @local.reference
30−
38+(type_identifier) @local.reference
runtime/queries/haskell/highlights.scm+24−11
@@ -33,6 +33,11 @@
33;; ----------------------------------------------------------------------------
33;; ----------------------------------------------------------------------------
34;; Keywords, operators, includes
34;; Keywords, operators, includes
35
35
36+[
37+ "forall"
38+ "∀"
39+] @keyword.control.repeat
40+
36(pragma) @constant.macro
41(pragma) @constant.macro
37
42
38[
43[
@@ -68,10 +73,7 @@
68 "@"
73 "@"
69] @operator
74] @operator
70
75
71−(qualified_module (module) @constructor)
72−(qualified_type (module) @namespace)
76+(module) @namespace
73−(qualified_variable (module) @namespace)
74−(import (module) @namespace)
75
77
76[
78[
77 (where)
79 (where)
@@ -92,8 +94,6 @@
92 "do"
94 "do"
93 "mdo"
95 "mdo"
94 "rec"
96 "rec"
95− "forall"
96− "∀"
97 "infix"
97 "infix"
98 "infixl"
98 "infixl"
99 "infixr"
99 "infixr"
@@ -104,22 +104,35 @@
104;; Functions and variables
104;; Functions and variables
105
105
106(signature name: (variable) @type)
106(signature name: (variable) @type)
107+(function
107−(function name: (variable) @function)
108+ name: (variable) @function
108−
109+ patterns: (patterns))
109−(variable) @variable
110+((signature (fun)) . (function (variable) @function))
110−"_" @variable.builtin
111+((signature (context (fun))) . (function (variable) @function))
112+((signature (forall (context (fun)))) . (function (variable) @function))
111
113
112(exp_infix (variable) @operator) ; consider infix functions as operators
114(exp_infix (variable) @operator) ; consider infix functions as operators
113
115
114−("@" @namespace) ; "as" pattern operator, e.g. x@Constructor
116+(exp_infix (exp_name) @function)
117+(exp_apply . (exp_name (variable) @function))
118+(exp_apply . (exp_name (qualified_variable (variable) @function)))
115
119
120+(variable) @variable
121+(pat_wildcard) @variable
116
122
117;; ----------------------------------------------------------------------------
123;; ----------------------------------------------------------------------------
118;; Types
124;; Types
119
125
120(type) @type
126(type) @type
127+(type_variable) @type.parameter
121
128
122(constructor) @constructor
129(constructor) @constructor
123
130
124; True or False
131; True or False
125((constructor) @_bool (#match? @_bool "(True|False)")) @constant.builtin.boolean
132((constructor) @_bool (#match? @_bool "(True|False)")) @constant.builtin.boolean
133+
134+;; ----------------------------------------------------------------------------
135+;; Quasi-quotes
136+
137+(quoter) @function
138+; Highlighting of quasiquote_body is handled by injections.scm
runtime/queries/janet/highlights.scmnew file+1
@@ -0,0 +1 @@
1+; inherits: clojure
runtime/queries/json5/highlights.scmnew file+11
@@ -0,0 +1,11 @@
1+(string) @string
2+
3+(identifier) @constant
4+
5+(number) @constant.numeric
6+
7+(null) @constant.builtin
8+
9+[(true) (false)] @constant.builtin.boolean
10+
11+(comment) @comment
runtime/queries/kdl/highlights.scm+4−4
@@ -1,12 +1,12 @@
1−(comment) @comment
2(single_line_comment) @comment
1(single_line_comment) @comment
2+(multi_line_comment) @comment
3
3
4(node
4(node
5− name: (identifier) @function)
5+ (identifier) @variable)
6+
6(prop (identifier) @attribute)
7(prop (identifier) @attribute)
7−(type) @type
8
8
9−(bare_identifier) @variable.other.member
9+(type (_) @type) @punctuation.bracket
10
10
11(keyword) @keyword
11(keyword) @keyword
12
12
runtime/queries/kdl/indents.scmnew file+3
@@ -0,0 +1,3 @@
1+(node_children) @indent
2+
3+ "}" @outdent
runtime/queries/kdl/textobjects.scmnew file+27
@@ -0,0 +1,27 @@
1+(type (_) @test.inside) @test.around
2+
3+(node
4+ children: (node_children)? @class.inside) @class.around
5+
6+(node
7+ children: (node_children)? @function.inside) @function.around
8+
9+(node (identifier) @function.movement)
10+
11+[
12+ (single_line_comment)
13+ (multi_line_comment)
14+] @comment.inside
15+
16+[
17+ (single_line_comment)+
18+ (multi_line_comment)+
19+] @comment.around
20+
21+[
22+ (prop)
23+ (value)
24+] @parameter.inside
25+
26+(value (type) ? (_) @parameter.inside @parameter.movement . ) @parameter.around
27+
runtime/queries/kotlin/highlights.scm+4−1
@@ -244,7 +244,10 @@
244 . (identifier)) @namespace
244 . (identifier)) @namespace
245
245
246((type_identifier) @type.builtin
246((type_identifier) @type.builtin
247− (#match? @function.builtin "^(Byte|Short|Int|Long|UByte|UShort|UInt|ULong|Float|Double|Boolean|Char|String|Array|ByteArray|ShortArray|IntArray|LongArray|UByteArray|UShortArray|UIntArray|ULongArray|FloatArray|DoubleArray|BooleanArray|CharArray|Map|Set|List|EmptyMap|EmptySet|EmptyList|MutableMap|MutableSet|MutableList)$"))
247+ (#match? @type.builtin "^(Byte|Short|Int|Long|UByte|UShort|UInt|ULong|Float|Double|Boolean|Char|String|Array|ByteArray|ShortArray|IntArray|LongArray|UByteArray|UShortArray|UIntArray|ULongArray|FloatArray|DoubleArray|BooleanArray|CharArray|Map|Set|List|EmptyMap|EmptySet|EmptyList|MutableMap|MutableSet|MutableList)$"))
248+
249+(type_parameter
250+ (type_identifier) @type.parameter)
248
251
249(type_identifier) @type
252(type_identifier) @type
250
253
runtime/queries/kotlin/locals.scmnew file+15
@@ -0,0 +1,15 @@
1+; Scopes
2+
3+[
4+ (class_declaration)
5+ (function_declaration)
6+] @local.scope
7+
8+; Definitions
9+
10+(type_parameter
11+ (type_identifier) @local.definition)
12+
13+; References
14+
15+(type_identifier) @local.reference
runtime/queries/log/highlights.scmnew file+10
@@ -0,0 +1,10 @@
1+(trace) @comment
2+(debug) @hint
3+(info) @info
4+(warn) @warning
5+(error) @error
6+(year_month_day) @keyword
7+(time) @constant
8+(string_literal) @string
9+(number) @constant.numeric
10+(constant) @constant.builtin
runtime/queries/lpf/highlights.scmnew file+19
@@ -0,0 +1,19 @@
1+[
2+ "SYSCONFIG"
3+ "BLOCK"
4+ "LOCATE"
5+ "COMP"
6+ "FREQUENCY"
7+ "PORT"
8+ "IOBUF"
9+] @keyword
10+
11+["SITE"] @keyword.storage
12+
13+["="] @operator
14+
15+((number) @constant.numeric)
16+
17+((string) @string)
18+((line_comment) @comment)
19+
runtime/queries/nix/injections.scm+14
@@ -5,6 +5,20 @@
5((((comment) @injection.language) .
5((((comment) @injection.language) .
6 (indented_string_expression (string_fragment) @injection.content))
6 (indented_string_expression (string_fragment) @injection.content))
7 (#set! injection.combined))
7 (#set! injection.combined))
8+((binding
9+ (comment) @injection.language
10+ expression: (indented_string_expression (string_fragment) @injection.content))
11+ (#set! injection.combined))
12+
13+; Common attribute keys corresponding to Python scripts,
14+; such as those for NixOS VM tests in nixpkgs/nixos/tests.
15+((binding
16+ attrpath: (attrpath (identifier) @_path)
17+ expression: (indented_string_expression
18+ (string_fragment) @injection.content))
19+ (#match? @_path "(^|\\.)testScript$")
20+ (#set! injection.language "python")
21+ (#set! injection.combined))
8
22
9; Common attribute keys corresponding to scripts,
23; Common attribute keys corresponding to scripts,
10; such as those of stdenv.mkDerivation.
24; such as those of stdenv.mkDerivation.
runtime/queries/ocaml/highlights.scm+2
@@ -8,6 +8,8 @@
8
8
9[(class_name) (class_type_name) (type_constructor)] @type
9[(class_name) (class_type_name) (type_constructor)] @type
10
10
11+(type_variable) @type.parameter
12+
11[(constructor_name) (tag)] @constructor
13[(constructor_name) (tag)] @constructor
12
14
13; Functions
15; Functions
runtime/queries/purescript/highlights.scm+164−1
@@ -1 +1,164 @@
1−; inherits: haskell
1+; ----------------------------------------------------------------------------
2+; Record fields would need to come before literal strings in order to be captured correctly
3+
4+ (record_accessor
5+ field: [ (variable)
6+ (string)
7+ (triple_quote_string)
8+ ] @variable.other.member)
9+
10+ (exp_record_access
11+ field: [ (variable)
12+ (string)
13+ (triple_quote_string)
14+ ] @variable.other.member)
15+
16+
17+; ----------------------------------------------------------------------------
18+; Literals and comments
19+
20+ (integer) @constant.numeric.integer
21+ (exp_negation) @constant.numeric.integer
22+ (exp_literal (number)) @constant.numeric.float
23+ (char) @constant.character
24+ [
25+ (string)
26+ (triple_quote_string)
27+ ] @string
28+
29+ (comment) @comment
30+
31+
32+; ----------------------------------------------------------------------------
33+; Punctuation
34+
35+ [
36+ "("
37+ ")"
38+ "{"
39+ "}"
40+ "["
41+ "]"
42+ ] @punctuation.bracket
43+
44+ [
45+ (comma)
46+ ";"
47+ ] @punctuation.delimiter
48+
49+
50+; ----------------------------------------------------------------------------
51+; Keywords, operators, includes
52+
53+ ; This needs to come before the other "else" in
54+ ; order to be highlighted correctly
55+ (class_instance "else" @keyword)
56+
57+ [
58+ "if"
59+ "then"
60+ "else"
61+ "case"
62+ "of"
63+ ] @keyword.control.conditional
64+
65+ [
66+ "import"
67+ "module"
68+ ] @keyword.control.import
69+
70+ [
71+ (operator)
72+ (constructor_operator)
73+ (type_operator)
74+ (qualified_module) ; grabs the `.` (dot), ex: import System.IO
75+ (all_names)
76+
77+ ; `_` wildcards in if-then-else and case-of expressions,
78+ ; as well as record updates and operator sections
79+ (wildcard)
80+ "="
81+ "|"
82+ "::"
83+ "∷"
84+ "=>"
85+ "⇒"
86+ "<="
87+ "⇐"
88+ "->"
89+ "→"
90+ "<-"
91+ "←"
92+ "\\"
93+ "`"
94+ "@"
95+ ] @operator
96+
97+ (qualified_module (module) @constructor)
98+ (module) @namespace
99+ (qualified_type (module) @namespace)
100+ (qualified_variable (module) @namespace)
101+ (import (module) @namespace)
102+
103+ [
104+ (where)
105+ "let"
106+ "in"
107+ "class"
108+ "instance"
109+ "derive"
110+ "foreign"
111+ "data"
112+ "newtype"
113+ "type"
114+ "as"
115+ "hiding"
116+ "do"
117+ "ado"
118+ "forall"
119+ "∀"
120+ "infix"
121+ "infixl"
122+ "infixr"
123+ ] @keyword
124+
125+ (type_role_declaration
126+ "role" @keyword
127+ role: (type_role) @keyword)
128+
129+ (hole) @label
130+
131+; ----------------------------------------------------------------------------
132+; Functions and variables
133+
134+ (row_field (field_name) @variable.other.member)
135+ (record_field (field_name) @variable.other.member)
136+ (record_field (field_pun) @variable.other.member)
137+
138+ (signature name: (variable) @type)
139+ (function name: (variable) @function)
140+ (class_instance (instance_name) @function)
141+ (derive_declaration (instance_name) @function)
142+
143+ ; true or false
144+ ((variable) @constant.builtin.boolean
145+ (#match? @constant.builtin.boolean "^(true|false)$"))
146+
147+ ; The former one works for `tree-sitter highlight` but not in Helix/Kakoune.
148+ ; The latter two work in Helix (but not Kakoune) and are a good compromise between not highlighting anything at all
149+ ; as an operator and leaving it to the child nodes, and highlighting everything as an operator.
150+ (exp_ticked (_) @operator)
151+ (exp_ticked (exp_name (variable) @operator))
152+ (exp_ticked (exp_name (qualified_variable (variable) @operator)))
153+
154+ (variable) @variable
155+
156+ ("@" @namespace) ; "as" pattern operator, e.g. x@Constructor
157+
158+; ----------------------------------------------------------------------------
159+; Types
160+
161+ (type) @type
162+
163+ (constructor) @constructor
164+
runtime/queries/purescript/injections.scm+2−1
@@ -1 +1,2 @@
1−; inherits: haskell
1+((comment) @injection.content
2+ (#set! injection.language "comment"))
runtime/queries/purescript/locals.scm+4−1
@@ -1 +1,4 @@
1−; inherits: haskell
1+(signature name: (variable)) @local.definition
2+(function name: (variable)) @local.definition
3+(pat_name (variable)) @local.definition
4+(exp_name (variable)) @local.reference
runtime/queries/purescript/textobjects.scmnew file+13
@@ -0,0 +1,13 @@
1+(comment) @comment.inside
2+
3+[
4+ (data)
5+ (type)
6+ (newtype)
7+] @class.around
8+
9+((signature)? (function rhs:(_) @function.inside)) @function.around
10+(exp_lambda) @function.around
11+
12+(data (type_variable) @parameter.inside)
13+(patterns (_) @parameter.inside)
runtime/queries/python/highlights.scm+6
@@ -134,14 +134,17 @@
134 "//="
134 "//="
135 "/="
135 "/="
136 "&"
136 "&"
137+ "&="
137 "%"
138 "%"
138 "%="
139 "%="
139 "^"
140 "^"
141+ "^="
140 "+"
142 "+"
141 "->"
143 "->"
142 "+="
144 "+="
143 "<"
145 "<"
144 "<<"
146 "<<"
147+ "<<="
145 "<="
148 "<="
146 "<>"
149 "<>"
147 "="
150 "="
@@ -150,8 +153,11 @@
150 ">"
153 ">"
151 ">="
154 ">="
152 ">>"
155 ">>"
156+ ">>="
153 "|"
157 "|"
158+ "|="
154 "~"
159 "~"
160+ "@="
155] @operator
161] @operator
156
162
157[
163[
runtime/queries/racket/indents.scmnew file+1
@@ -0,0 +1 @@
1+; inherits: scheme
runtime/queries/ron/highlights.scm+43−1
@@ -1 +1,43 @@
1−; inherits: rust
1+; Literals
2+;------------
3+
4+(string) @string
5+(boolean) @constant.builtin.boolean
6+(integer) @constant.numeric.integer
7+(float) @constant.numeric.float
8+(char) @constant.character
9+
10+; Structs
11+;------------
12+
13+(enum_variant) @type.enum.variant
14+(struct_entry (_) @variable.other.member ":")
15+(struct_name (identifier)) @type
16+
17+
18+
19+
20+; Comments
21+;------------
22+
23+(line_comment) @comment.line
24+(block_comment) @comment.block
25+
26+
27+; Punctuation
28+;------------
29+
30+"," @punctuation.delimiter
31+":" @punctuation.delimiter
32+
33+"(" @punctuation.bracket
34+")" @punctuation.bracket
35+"[" @punctuation.bracket
36+"]" @punctuation.bracket
37+"{" @punctuation.bracket
38+"}" @punctuation.bracket
39+
40+
41+; Special
42+;------------
43+(escape_sequence) @constant.character.escape
runtime/queries/ron/indents.scm+12−1
@@ -1 +1,12 @@
1−; inherits: rust
1+[
2+ (array)
3+ (map)
4+ (tuple)
5+ (struct)
6+] @indent
7+
8+[
9+ "}"
10+ "]"
11+ ")"
12+] @outdent
runtime/queries/ron/injections.scm+2−1
@@ -1 +1,2 @@
1−; inherits: rust
1+([(line_comment) (block_comment)] @injection.content
2+ (#set! injection.language "comment"))
runtime/queries/rust/highlights.scm+7
@@ -9,6 +9,13 @@
9; Types
9; Types
10; -------
10; -------
11
11
12+(type_parameters
13+ (type_identifier) @type.parameter)
14+(constrained_type_parameter
15+ left: (type_identifier) @type.parameter)
16+(optional_type_parameter
17+ name: (type_identifier) @type.parameter)
18+
12; ---
19; ---
13; Primitives
20; Primitives
14; ---
21; ---
runtime/queries/rust/injections.scm+6
@@ -1,6 +1,12 @@
1([(line_comment) (block_comment)] @injection.content
1([(line_comment) (block_comment)] @injection.content
2 (#set! injection.language "comment"))
2 (#set! injection.language "comment"))
3
3
4+((macro_invocation
5+ macro: (identifier) @_html (#eq? @_html "html")
6+ (token_tree) @injection.content)
7+ (#set! injection.language "html")
8+ (#set! injection.include-children))
9+
4((macro_invocation
10((macro_invocation
5 (token_tree) @injection.content)
11 (token_tree) @injection.content)
6 (#set! injection.language "rust")
12 (#set! injection.language "rust")
runtime/queries/rust/locals.scm+14−1
@@ -2,6 +2,12 @@
2
2
3[
3[
4 (function_item)
4 (function_item)
5+ (struct_item)
6+ (enum_item)
7+ (union_item)
8+ (type_item)
9+ (trait_item)
10+ (impl_item)
5 (closure_expression)
11 (closure_expression)
6 (block)
12 (block)
7] @local.scope
13] @local.scope
@@ -11,8 +17,15 @@
11(parameter
17(parameter
12 (identifier) @local.definition)
18 (identifier) @local.definition)
13
19
20+(type_parameters
21+ (type_identifier) @local.definition)
22+(constrained_type_parameter
23+ left: (type_identifier) @local.definition)
24+(optional_type_parameter
25+ name: (type_identifier) @local.definition)
26+
14(closure_parameters (identifier) @local.definition)
27(closure_parameters (identifier) @local.definition)
15
28
16; References
29; References
17(identifier) @local.reference
30(identifier) @local.reference
18−
31+(type_identifier) @local.reference
runtime/queries/scheme/indents.scmnew file+43
@@ -0,0 +1,43 @@
1+; This roughly follows the description at: https://github.com/ds26gte/scmindent#how-subforms-are-indented
2+
3+; Exclude literals in the first patterns, since different rules apply for them.
4+; Similarly, exclude certain keywords (detected by a regular expression).
5+; If a list has 2 elements on the first line, it is aligned to the second element.
6+(list . (_) @first . (_) @anchor
7+ (#same-line? @first @anchor)
8+ (#set! "scope" "tail")
9+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
10+ (#not-match? @first "def.*|let.*|set!")) @align
11+; If the first element in a list is also a list and on a line by itself, the outer list is aligned to it
12+(list . (list) @anchor .
13+ (#set! "scope" "tail")
14+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")) @align
15+(list . (list) @anchor . (_) @second
16+ (#not-same-line? @anchor @second)
17+ (#set! "scope" "tail")
18+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
19+ (#not-match? @first "def.*|let.*|set!")) @align
20+; If the first element in a list is not a list and on a line by itself, the outer list is aligned to
21+; it plus 1 additional space. This cannot currently be modelled exactly by our indent queries,
22+; but the following is equivalent, assuming that:
23+; - the indent width is 2 (the default for scheme)
24+; - There is no space between the opening parenthesis of the list and the first element
25+(list . (_) @first .
26+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
27+ (#not-match? @first "def.*|let.*|set!")) @indent
28+(list . (_) @first . (_) @second
29+ (#not-same-line? @first @second)
30+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
31+ (#not-match? @first "def.*|let.*|set!")) @indent
32+
33+; If the first element in a list is a literal, align the list to it
34+(list . [(boolean) (character) (string) (number)] @anchor
35+ (#set! "scope" "tail")) @align
36+
37+; If the first element is among a set of predefined keywords, align the list to this element
38+; plus 1 space (using the same workaround as above for now). This is a simplification since actually
39+; the second line of the list should be indented by 2 spaces more in some cases. Supporting this would
40+; be possible but require significantly more patterns.
41+(list . (symbol) @first
42+ (#match? @first "def.*|let.*|set!")) @indent
43+
runtime/queries/smali/folds.scmnew file+12
@@ -0,0 +1,12 @@
1+[
2+ (annotation_directive)
3+ (array_data_directive)
4+ (field_definition)
5+ (method_definition)
6+ (packed_switch_directive)
7+ (param_directive)
8+ (parameter_directive)
9+ (sparse_switch_directive)
10+ (subannotation_directive)
11+ (list)
12+] @fold
runtime/queries/smali/highlights.scmnew file+216
@@ -0,0 +1,216 @@
1+; Types
2+
3+(class_identifier
4+ (identifier) @type)
5+
6+(primitive_type) @type.builtin
7+
8+((class_identifier
9+ . (identifier) @_first @type.builtin
10+ (identifier) @type.builtin)
11+ (#match? @_first "^(android|dalvik|java|kotlinx)$"))
12+
13+((class_identifier
14+ . (identifier) @_first @type.builtin
15+ . (identifier) @_second @type.builtin
16+ (identifier) @type.builtin)
17+ (#eq? @_first "com")
18+ (#match? @_second "^(android|google)$"))
19+
20+; Methods
21+
22+(method_definition
23+ (method_signature (method_identifier) @function.method))
24+
25+(expression
26+ (opcode) @_invoke
27+ (body
28+ (full_method_signature
29+ (method_signature (method_identifier) @function.method)))
30+ (#match? @_invoke "^invoke"))
31+
32+(expression
33+ (opcode) @_field_access
34+ (body
35+ (field_identifier) @variable.other.member)
36+ (#match? @_field_access "^[is](get|put)-"))
37+
38+(method_handle
39+ (full_method_signature
40+ (method_signature (method_identifier) @function.method)))
41+
42+(custom_invoke
43+ . (identifier) @function.method
44+ (method_signature (method_identifier) @function.method))
45+
46+(annotation_value
47+ (body
48+ (method_signature (method_identifier) @function.method)))
49+
50+(annotation_value
51+ (body
52+ (full_method_signature
53+ (method_signature (method_identifier) @function.method))))
54+
55+(field_definition
56+ (body
57+ (method_signature (method_identifier) @function.method)))
58+
59+(field_definition
60+ (body
61+ (full_method_signature
62+ (method_signature (method_identifier) @function.method))))
63+
64+((method_identifier) @constructor
65+ (#match? @constructor "^(<init>|<clinit>)$"))
66+
67+"constructor" @constructor
68+
69+; Fields
70+
71+[
72+ (field_identifier)
73+ (annotation_key)
74+] @variable.other.member
75+
76+((field_identifier) @constant
77+ (#match? @constant "^[%u_]*$"))
78+
79+; Variables
80+
81+(variable) @variable.builtin
82+
83+(local_directive
84+ (identifier) @variable)
85+
86+; Parameters
87+
88+(parameter) @variable.parameter
89+(param_identifier) @variable.parameter
90+
91+; Labels
92+
93+[
94+ (label)
95+ (jmp_label)
96+] @label
97+
98+; Operators
99+
100+; (opcode) @keyword.operator
101+
102+((opcode) @keyword.control.return
103+ (#match? @keyword.control.return "^return"))
104+
105+((opcode) @keyword.control.conditional
106+ (#match? @keyword.control.conditional "^if"))
107+
108+((opcode) @keyword.control.conditional
109+ (#match? @keyword.control.conditional "^cmp"))
110+
111+((opcode) @keyword.control.exception
112+ (#match? @keyword.control.exception "^throw"))
113+
114+[
115+ "="
116+ ".."
117+] @operator
118+
119+; Keywords
120+
121+[
122+ ".class"
123+ ".super"
124+ ".implements"
125+ ".field"
126+ ".end field"
127+ ".annotation"
128+ ".end annotation"
129+ ".subannotation"
130+ ".end subannotation"
131+ ".param"
132+ ".end param"
133+ ".parameter"
134+ ".end parameter"
135+ ".local"
136+ ".end local"
137+ ".restart local"
138+ ".registers"
139+ ".packed-switch"
140+ ".end packed-switch"
141+ ".sparse-switch"
142+ ".end sparse-switch"
143+ ".array-data"
144+ ".end array-data"
145+ ".enum"
146+ (prologue_directive)
147+ (epilogue_directive)
148+] @keyword
149+
150+[
151+ ".source"
152+] @keyword.directive
153+
154+[
155+ ".method"
156+ ".end method"
157+] @keyword.function
158+
159+[
160+ ".catch"
161+ ".catchall"
162+] @keyword.control.exception
163+
164+; Literals
165+
166+(string) @string
167+(source_directive (string "\"" _ @string.special.url "\""))
168+(escape_sequence) @constant.character.escape
169+
170+(character) @constant.character
171+
172+"L" @punctuation
173+
174+(line_directive (number) @comment) @comment
175+(".locals" (number) @comment) @comment
176+
177+(number) @constant.numeric.integer
178+
179+[
180+ (float)
181+ (NaN)
182+ (Infinity)
183+] @constant.numeric.float
184+
185+(boolean) @constant.builtin.boolean
186+
187+(null) @constant.builtin
188+
189+; Misc
190+
191+(annotation_visibility) @keyword.storage.modifier
192+
193+(access_modifier) @keyword.storage.type
194+
195+(array_type
196+ "[" @punctuation.special)
197+
198+["{" "}"] @punctuation.bracket
199+
200+["(" ")"] @punctuation.bracket
201+
202+[
203+ "->"
204+ ","
205+ ":"
206+ ";"
207+ "@"
208+ "/"
209+] @punctuation.delimiter
210+
211+; Comments
212+
213+(comment) @comment
214+
215+(class_definition
216+ (comment) @comment.block.documentation)
runtime/queries/smali/indents.scmnew file+31
@@ -0,0 +1,31 @@
1+[
2+ (annotation_directive)
3+ (array_data_directive)
4+ (field_definition)
5+ (method_definition)
6+ (packed_switch_directive)
7+ (param_directive)
8+ (parameter_directive)
9+ (sparse_switch_directive)
10+ (subannotation_directive)
11+ (list)
12+ "\{"
13+] @indent
14+
15+[
16+ ".end annotation"
17+ ".end array-data"
18+ ".end field"
19+ ".end method"
20+ ".end packed-switch"
21+ ".end param"
22+ ".end parameter"
23+ ".end sparse-switch"
24+ ".end subannotation"
25+ "\}"
26+] @outdent
27+
28+[
29+ (ERROR)
30+ (comment)
31+] @indent.always
runtime/queries/smali/injections.scmnew file+2
@@ -0,0 +1,2 @@
1+((comment) @injection.content
2+ (#set! injection.language "comment"))
runtime/queries/smali/locals.scmnew file+42
@@ -0,0 +1,42 @@
1+[
2+ (class_directive)
3+ (expression)
4+ (annotation_directive)
5+ (array_data_directive)
6+ (method_definition)
7+ (packed_switch_directive)
8+ (sparse_switch_directive)
9+ (subannotation_directive)
10+] @local.scope
11+
12+[
13+ (identifier)
14+ (class_identifier)
15+ (label)
16+ (jmp_label)
17+] @local.reference
18+
19+(enum_reference
20+ (field_identifier) @local.definition)
21+
22+((field_definition
23+ (access_modifiers) @_mod
24+ (field_identifier) @local.definition)
25+ (#eq? @_mod "enum"))
26+
27+(field_definition
28+ (field_identifier) @local.definition
29+ (field_type) @local.definition)
30+
31+(annotation_key) @local.definition
32+
33+(method_definition
34+ (method_signature (method_identifier) @local.definition))
35+
36+(param_identifier) @local.definition
37+
38+(annotation_directive
39+ (class_identifier) @local.definition)
40+
41+(class_directive
42+ (class_identifier) @local.definition)
runtime/queries/sql/highlights.scm+317−231
@@ -1,134 +1,169 @@
1+(invocation
2+ (object_reference
3+ name: (identifier) @function.method))
1
4
2[
5[
6+ (keyword_gist)
3 (keyword_btree)
7 (keyword_btree)
4 (keyword_hash)
8 (keyword_hash)
5− (keyword_gist)
6 (keyword_spgist)
9 (keyword_spgist)
7 (keyword_gin)
10 (keyword_gin)
8 (keyword_brin)
11 (keyword_brin)
9−
12+ (keyword_array)
10− (cast)
11− (group_concat)
12− (invocation)
13] @function.builtin
13] @function.builtin
14−
15−(table_reference
16− name: (identifier) @namespace)
17
14
18−(relation
15+(object_reference
19− table_alias: (identifier) @variable.parameter)
20−
21−(field
22 name: (identifier) @variable.other.member)
16 name: (identifier) @variable.other.member)
23−
17+
18+(relation
19+ alias: (identifier) @variable.parameter)
20+
24(field
21(field
25− table_alias: (identifier) @variable.parameter
26 name: (identifier) @variable.other.member)
22 name: (identifier) @variable.other.member)
27
23
28−(comment) @comment
24+(term
25+ alias: (identifier) @variable.parameter)
29
26
30−[
27+(term
31− "("
28+ value: (cast
32− ")"
29+ name: (keyword_cast) @function.builtin
33−] @punctuation.bracket
30+ parameter: [(literal)]?))
34
31
35−[
32+(literal) @string
36− ";"
33+(comment) @comment.line
37− ","
34+(marginalia) @comment.block
38− "."
39−] @punctuation.delimiter
40
35
41−(binary_expression
36+((literal) @constant.numeric.integer
42− operator: _ @operator)
37+ (#match? @constant.numeric.integer "^-?\\d+$"))
43
38
44−(unary_expression
39+((literal) @constant.numeric.float
45− operator: _ @operator)
40+ (#match? @constant.numeric.float "^-?\\d*\\.\\d*$"))
46
41
47−(all_fields) @special
42+(parameter) @variable.parameter
48
43
49[
44[
50− (keyword_null)
51− (keyword_true)
45+ (keyword_true)
52− (keyword_false)
46+ (keyword_false)
53−] @constant.builtin
47+] @constant.builtin.boolean
54
48
55−((literal) @constant.numeric
49+[
56− (#match? @constant.numeric "^-?\\d*\\.?\\d*$"))
50+ (keyword_asc)
51+ (keyword_desc)
52+ (keyword_terminated)
53+ (keyword_escaped)
54+ (keyword_unsigned)
55+ (keyword_nulls)
56+ (keyword_last)
57+ (keyword_delimited)
58+ (keyword_replication)
59+ (keyword_auto_increment)
60+ (keyword_default)
61+ (keyword_collate)
62+ (keyword_concurrently)
63+ (keyword_engine)
64+ (keyword_always)
65+ (keyword_generated)
66+ (keyword_preceding)
67+ (keyword_following)
68+ (keyword_first)
69+ (keyword_current_timestamp)
70+ (keyword_immutable)
71+ (keyword_atomic)
72+ (keyword_parallel)
73+ (keyword_leakproof)
74+ (keyword_safe)
75+ (keyword_cost)
76+ (keyword_strict)
77+] @attribute
57
78
58−(literal) @string
79+[
80+ (keyword_materialized)
81+ (keyword_recursive)
82+ (keyword_temp)
83+ (keyword_temporary)
84+ (keyword_unlogged)
85+ (keyword_external)
86+ (keyword_parquet)
87+ (keyword_csv)
88+ (keyword_rcfile)
89+ (keyword_textfile)
90+ (keyword_orc)
91+ (keyword_avro)
92+ (keyword_jsonfile)
93+ (keyword_sequencefile)
94+ (keyword_volatile)
95+] @keyword.storage.type
96+
97+[
98+ (keyword_case)
99+ (keyword_when)
100+ (keyword_then)
101+ (keyword_else)
102+] @keyword.control.conditional
59
103
60[
104[
61 (keyword_select)
105 (keyword_select)
106+ (keyword_from)
107+ (keyword_where)
108+ (keyword_index)
109+ (keyword_join)
110+ (keyword_primary)
62 (keyword_delete)
111 (keyword_delete)
112+ (keyword_create)
63 (keyword_insert)
113 (keyword_insert)
114+ (keyword_merge)
115+ (keyword_distinct)
64 (keyword_replace)
116 (keyword_replace)
65 (keyword_update)
117 (keyword_update)
66 (keyword_into)
118 (keyword_into)
67 (keyword_overwrite)
119 (keyword_overwrite)
120+ (keyword_matched)
68 (keyword_values)
121 (keyword_values)
122+ (keyword_value)
123+ (keyword_attribute)
69 (keyword_set)
124 (keyword_set)
70− (keyword_from)
71 (keyword_left)
125 (keyword_left)
72 (keyword_right)
126 (keyword_right)
127+ (keyword_outer)
73 (keyword_inner)
128 (keyword_inner)
74 (keyword_full)
129 (keyword_full)
75− (keyword_outer)
76− (keyword_cross)
77− (keyword_join)
78− (keyword_lateral)
79− (keyword_on)
80− (keyword_not)
81 (keyword_order)
130 (keyword_order)
82− (keyword_group)
83 (keyword_partition)
131 (keyword_partition)
84− (keyword_by)
132+ (keyword_group)
133+ (keyword_with)
134+ (keyword_without)
135+ (keyword_as)
85 (keyword_having)
136 (keyword_having)
86− (keyword_desc)
87− (keyword_asc)
88 (keyword_limit)
137 (keyword_limit)
89 (keyword_offset)
138 (keyword_offset)
90− (keyword_primary)
91− (keyword_create)
92− (keyword_alter)
93− (keyword_change)
94− (keyword_analyze)
95− (keyword_modify)
96− (keyword_drop)
97− (keyword_add)
98 (keyword_table)
139 (keyword_table)
99 (keyword_tables)
140 (keyword_tables)
100− (keyword_view)
101− (keyword_materialized)
102− (keyword_column)
103 (keyword_key)
141 (keyword_key)
104− (keyword_as)
142+ (keyword_references)
105− (keyword_distinct)
143+ (keyword_foreign)
106 (keyword_constraint)
144 (keyword_constraint)
107− ; (keyword_cast)
108− ; (keyword_group_concat)
109− (keyword_separator)
110− (keyword_max)
111− (keyword_min)
112− (keyword_avg)
113− (keyword_end)
114 (keyword_force)
145 (keyword_force)
115− (keyword_ignore)
116− (keyword_using)
117 (keyword_use)
146 (keyword_use)
118− (keyword_index)
119 (keyword_for)
147 (keyword_for)
120 (keyword_if)
148 (keyword_if)
121 (keyword_exists)
149 (keyword_exists)
122− (keyword_auto_increment)
150+ (keyword_max)
123− (keyword_generated)
151+ (keyword_min)
124− (keyword_always)
152+ (keyword_avg)
125− (keyword_collate)
153+ (keyword_column)
126− (keyword_character)
154+ (keyword_columns)
127− (keyword_engine)
155+ (keyword_cross)
128− (keyword_default)
156+ (keyword_lateral)
129− (keyword_cascade)
157+ (keyword_natural)
130− (keyword_restrict)
158+ (keyword_alter)
131− (keyword_with)
159+ (keyword_drop)
160+ (keyword_add)
161+ (keyword_view)
162+ (keyword_end)
163+ (keyword_is)
164+ (keyword_using)
165+ (keyword_between)
166+ (keyword_window)
132 (keyword_no)
167 (keyword_no)
133 (keyword_data)
168 (keyword_data)
134 (keyword_type)
169 (keyword_type)
@@ -136,208 +171,259 @@
136 (keyword_to)
171 (keyword_to)
137 (keyword_schema)
172 (keyword_schema)
138 (keyword_owner)
173 (keyword_owner)
139− (keyword_temp)
174+ (keyword_authorization)
140− (keyword_temporary)
141− (keyword_unlogged)
142− (keyword_union)
143 (keyword_all)
175 (keyword_all)
144 (keyword_any)
176 (keyword_any)
145 (keyword_some)
177 (keyword_some)
146− (keyword_except)
147− (keyword_intersect)
148 (keyword_returning)
178 (keyword_returning)
149 (keyword_begin)
179 (keyword_begin)
150 (keyword_commit)
180 (keyword_commit)
151 (keyword_rollback)
181 (keyword_rollback)
152 (keyword_transaction)
182 (keyword_transaction)
183+ (keyword_only)
184+ (keyword_like)
185+ (keyword_similar)
153 (keyword_over)
186 (keyword_over)
154− (keyword_nulls)
187+ (keyword_change)
155− (keyword_first)
188+ (keyword_modify)
156 (keyword_after)
189 (keyword_after)
157− (keyword_last)
190+ (keyword_before)
158− (keyword_window)
159 (keyword_range)
191 (keyword_range)
160 (keyword_rows)
192 (keyword_rows)
161 (keyword_groups)
193 (keyword_groups)
162− (keyword_between)
163− (keyword_unbounded)
164− (keyword_preceding)
165− (keyword_following)
166 (keyword_exclude)
194 (keyword_exclude)
167 (keyword_current)
195 (keyword_current)
168− (keyword_row)
169 (keyword_ties)
196 (keyword_ties)
170 (keyword_others)
197 (keyword_others)
171− (keyword_only)
172− (keyword_unique)
173− (keyword_foreign)
174− (keyword_references)
175− (keyword_concurrently)
176− ; (keyword_btree)
177− ; (keyword_hash)
178− ; (keyword_gist)
179− ; (keyword_spgist)
180− ; (keyword_gin)
181− ; (keyword_brin)
182− (keyword_like)
183− (keyword_similar)
184 (keyword_preserve)
198 (keyword_preserve)
185− (keyword_unsigned)
186 (keyword_zerofill)
199 (keyword_zerofill)
187− (keyword_conflict)
200+ (keyword_format)
188− (keyword_do)
201+ (keyword_fields)
189− (keyword_nothing)
202+ (keyword_row)
190− (keyword_high_priority)
203+ (keyword_sort)
191− (keyword_low_priority)
204+ (keyword_compute)
192− (keyword_delayed)
205+ (keyword_comment)
193− (keyword_recursive)
206+ (keyword_location)
194− (keyword_cascaded)
207+ (keyword_cached)
195− (keyword_local)
208+ (keyword_uncached)
196− (keyword_current_timestamp)
209+ (keyword_lines)
197− (keyword_check)
210+ (keyword_stored)
198− (keyword_option)
211+ (keyword_virtual)
212+ (keyword_partitioned)
213+ (keyword_analyze)
214+ (keyword_explain)
215+ (keyword_verbose)
216+ (keyword_truncate)
217+ (keyword_rewrite)
218+ (keyword_optimize)
199 (keyword_vacuum)
219 (keyword_vacuum)
200− (keyword_wait)
220+ (keyword_cache)
201− (keyword_nowait)
202−
203− (keyword_trigger)
204− (keyword_function)
205− (keyword_returns)
206− (keyword_return)
207− (keyword_setof)
208− (keyword_atomic)
209− (keyword_declare)
210− ; (keyword_language)
221+ (keyword_language)
211 (keyword_sql)
222 (keyword_sql)
223+ (keyword_called)
224+ (keyword_conflict)
225+ (keyword_declare)
226+ (keyword_filter)
227+ (keyword_function)
228+ (keyword_input)
229+ (keyword_name)
230+ (keyword_oid)
231+ (keyword_oids)
232+ (keyword_options)
212 (keyword_plpgsql)
233 (keyword_plpgsql)
213− (keyword_immutable)
234+ (keyword_precision)
214− (keyword_stable)
235+ (keyword_regclass)
215− (keyword_volatile)
236+ (keyword_regnamespace)
216− (keyword_leakproof)
237+ (keyword_regproc)
217− (keyword_parallel)
238+ (keyword_regtype)
218− (keyword_safe)
219− (keyword_unsafe)
220 (keyword_restricted)
239 (keyword_restricted)
221− (keyword_called)
240+ (keyword_return)
222 (keyword_returns)
241 (keyword_returns)
223− (keyword_input)
242+ (keyword_separator)
224− (keyword_strict)
243+ (keyword_setof)
225− (keyword_cost)
244+ (keyword_stable)
226− (keyword_rows)
227 (keyword_support)
245 (keyword_support)
228−
229− (keyword_external)
230− (keyword_stored)
231− (keyword_cached)
232− (keyword_uncached)
233− (keyword_replication)
234 (keyword_tblproperties)
246 (keyword_tblproperties)
235− (keyword_options)
247+ (keyword_trigger)
236− (keyword_compute)
248+ (keyword_unsafe)
237− (keyword_stats)
249+ (keyword_admin)
238− (keyword_statistics)
250+ (keyword_connection)
239− (keyword_optimize)
251+ (keyword_cycle)
240− (keyword_rewrite)
252+ (keyword_database)
241− (keyword_bin_pack)
253+ (keyword_encrypted)
242− (keyword_incremental)
254+ (keyword_increment)
243− (keyword_location)
255+ (keyword_logged)
244− (keyword_partitioned)
256+ (keyword_none)
245− (keyword_comment)
257+ (keyword_owned)
246− (keyword_sort)
258+ (keyword_password)
247− (keyword_format)
259+ (keyword_reset)
248− (keyword_delimited)
260+ (keyword_role)
249− (keyword_fields)
261+ (keyword_sequence)
250− (keyword_terminated)
262+ (keyword_start)
251− (keyword_escaped)
263+ (keyword_restart)
252− (keyword_lines)
264+ (keyword_tablespace)
253− (keyword_cache)
265+ (keyword_until)
254− (keyword_metadata)
266+ (keyword_user)
255− (keyword_noscan)
267+ (keyword_valid)
256−
268+ (keyword_action)
257− (keyword_parquet)
269+ (keyword_definer)
258− (keyword_rcfile)
270+ (keyword_invoker)
259− (keyword_csv)
271+ (keyword_security)
260− (keyword_textfile)
272+ (keyword_extension)
261− (keyword_avro)
273+ (keyword_version)
262− (keyword_sequencefile)
274+ (keyword_out)
263− (keyword_orc)
275+ (keyword_inout)
264− (keyword_avro)
276+ (keyword_variadic)
265− (keyword_jsonfile)
277+ (keyword_session)
266−
278+ (keyword_isolation)
267− (keyword_precision)
279+ (keyword_level)
268− (keyword_inet)
280+ (keyword_serializable)
281+ (keyword_repeatable)
282+ (keyword_read)
283+ (keyword_write)
284+ (keyword_committed)
285+ (keyword_uncommitted)
286+ (keyword_deferrable)
287+ (keyword_names)
288+ (keyword_zone)
289+ (keyword_immediate)
290+ (keyword_deferred)
291+ (keyword_constraints)
292+ (keyword_snapshot)
293+ (keyword_characteristics)
294+ (keyword_off)
295+ (keyword_follows)
296+ (keyword_precedes)
297+ (keyword_each)
298+ (keyword_instead)
299+ (keyword_of)
300+ (keyword_initially)
301+ (keyword_old)
302+ (keyword_new)
303+ (keyword_referencing)
304+ (keyword_statement)
305+ (keyword_execute)
306+ (keyword_procedure)
269] @keyword
307] @keyword
270
308
271[
309[
272− (keyword_case)
310+ (keyword_restrict)
273− (keyword_when)
311+ (keyword_unbounded)
274− (keyword_then)
312+ (keyword_unique)
275− (keyword_else)
313+ (keyword_cascade)
276− (keyword_where)
314+ (keyword_delayed)
277−] @keyword.control.conditional
315+ (keyword_high_priority)
278−
316+ (keyword_low_priority)
279−[
317+ (keyword_ignore)
280− (keyword_in)
318+ (keyword_nothing)
281− (keyword_and)
319+ (keyword_check)
282− (keyword_or)
320+ (keyword_option)
283− (keyword_is)
321+ (keyword_local)
322+ (keyword_cascaded)
323+ (keyword_wait)
324+ (keyword_nowait)
325+ (keyword_metadata)
326+ (keyword_incremental)
327+ (keyword_bin_pack)
328+ (keyword_noscan)
329+ (keyword_stats)
330+ (keyword_statistics)
331+ (keyword_maxvalue)
332+ (keyword_minvalue)
284−] @keyword.operator
333+] @keyword
285
334
286[
335[
336+ (keyword_int)
337+ (keyword_null)
287 (keyword_boolean)
338 (keyword_boolean)
288− (bit)
289 (keyword_binary)
339 (keyword_binary)
290−
340+ (keyword_varbinary)
341+ (keyword_image)
342+ (keyword_bit)
343+ (keyword_inet)
344+ (keyword_character)
291 (keyword_smallserial)
345 (keyword_smallserial)
292 (keyword_serial)
346 (keyword_serial)
293 (keyword_bigserial)
347 (keyword_bigserial)
294−
348+ (keyword_smallint)
295− (tinyint)
349+ (keyword_mediumint)
296− (smallint)
350+ (keyword_bigint)
297− (mediumint)
351+ (keyword_tinyint)
298− (int)
352+ (keyword_decimal)
299− (bigint)
353+ (keyword_float)
300− (decimal)
354+ (keyword_double)
301− (numeric)
355+ (keyword_numeric)
302 (keyword_real)
356 (keyword_real)
303 (double)
357 (double)
304− (float)
305−
306 (keyword_money)
358 (keyword_money)
307−
359+ (keyword_smallmoney)
308− (char)
360+ (keyword_char)
309− (varchar)
361+ (keyword_nchar)
310− (numeric)
362+ (keyword_varchar)
311− (keyword_string)
363+ (keyword_nvarchar)
364+ (keyword_varying)
312 (keyword_text)
365 (keyword_text)
313−
366+ (keyword_string)
314 (keyword_uuid)
367 (keyword_uuid)
315−
316 (keyword_json)
368 (keyword_json)
317 (keyword_jsonb)
369 (keyword_jsonb)
318 (keyword_xml)
370 (keyword_xml)
319−
320 (keyword_bytea)
371 (keyword_bytea)
321− (keyword_inet)
372+ (keyword_enum)
322−
323− (enum)
324−
325 (keyword_date)
373 (keyword_date)
326 (keyword_datetime)
374 (keyword_datetime)
375+ (keyword_time)
376+ (keyword_datetime2)
377+ (keyword_datetimeoffset)
378+ (keyword_smalldatetime)
327 (keyword_timestamp)
379 (keyword_timestamp)
328 (keyword_timestamptz)
380 (keyword_timestamptz)
329−
330− (keyword_interval)
331−
332 (keyword_geometry)
381 (keyword_geometry)
333 (keyword_geography)
382 (keyword_geography)
334 (keyword_box2d)
383 (keyword_box2d)
335 (keyword_box3d)
384 (keyword_box3d)
336−
385+ (keyword_interval)
337− (keyword_oid)
338− (keyword_name)
339− (keyword_regclass)
340− (keyword_regnamespace)
341− (keyword_regproc)
342− (keyword_regtype)
343] @type.builtin
386] @type.builtin
387+
388+[
389+ (keyword_in)
390+ (keyword_and)
391+ (keyword_or)
392+ (keyword_not)
393+ (keyword_by)
394+ (keyword_on)
395+ (keyword_do)
396+ (keyword_union)
397+ (keyword_except)
398+ (keyword_intersect)
399+] @keyword.operator
400+
401+[
402+ "+"
403+ "-"
404+ "*"
405+ "/"
406+ "%"
407+ "^"
408+ ":="
409+ "="
410+ "<"
411+ "<="
412+ "!="
413+ ">="
414+ ">"
415+ "<>"
416+ (op_other)
417+ (op_unary_other)
418+] @operator
419+
420+[
421+ "("
422+ ")"
423+] @punctuation.bracket
424+
425+[
426+ ";"
427+ ","
428+ "."
429+] @punctuation.delimiter
runtime/queries/templ/highlights.scmnew file+99
@@ -0,0 +1,99 @@
1+(package_identifier) @namespace
2+
3+(parameter_declaration (identifier) @variable.parameter)
4+(variadic_parameter_declaration (identifier) @variable.parameter)
5+
6+(function_declaration
7+ name: (identifier) @function)
8+
9+(type_spec name: (type_identifier) @type)
10+(type_identifier) @type
11+(field_identifier) @variable.other.member
12+(identifier) @variable
13+
14+; Function calls
15+
16+(call_expression
17+ function: (identifier) @function)
18+
19+(call_expression
20+ function: (selector_expression
21+ field: (field_identifier) @function))
22+
23+;
24+; These are Templ specific
25+;
26+
27+(component_declaration
28+ name: (component_identifier) @function)
29+
30+(tag_start) @tag
31+(tag_end) @tag
32+(self_closing_tag) @tag
33+(style_element) @tag
34+
35+(attribute
36+ name: (attribute_name) @attribute)
37+(attribute
38+ value: (quoted_attribute_value) @string)
39+
40+(element_text) @string.special
41+(style_element_text) @string.special
42+
43+(css_property
44+ name: (css_property_name) @attribute)
45+
46+(expression) @function.method
47+(dynamic_class_attribute_value) @function.method
48+
49+(component_import
50+ name: (component_identifier) @function)
51+
52+(component_render) @function
53+
54+[
55+ "@"
56+] @operator
57+
58+[
59+ "func"
60+ "var"
61+ "const"
62+ "templ"
63+ "css"
64+ "type"
65+ "struct"
66+ "range"
67+ "script"
68+] @keyword.storage.type
69+
70+[
71+ "return"
72+] @keyword.control.return
73+
74+[
75+ "import"
76+ "package"
77+] @keyword.control.import
78+
79+[
80+ "else"
81+ "case"
82+ "switch"
83+ "if"
84+ "default"
85+] @keyword.control.conditional
86+
87+"for" @keyword.control.repeat
88+
89+[
90+ (interpreted_string_literal)
91+ (raw_string_literal)
92+ (rune_literal)
93+] @string
94+
95+; Comments
96+
97+(comment) @comment
98+
99+(element_comment) @comment
runtime/queries/templ/injections.scmnew file+4
@@ -0,0 +1,4 @@
1+((script_block_text) @injection.content (#set! injection.language "javascript"))
2+((script_element_text) @injection.content (#set! injection.language "javascript"))
3+
4+((style_element_text) @injection.content (#set! injection.language "css"))
runtime/queries/typst/highlights.scmnew file+77
@@ -0,0 +1,77 @@
1+(call
2+ item: (ident) @function)
3+(call
4+ item: (field field: (ident) @function.method))
5+(tagged field: (ident) @tag)
6+(field field: (ident) @tag)
7+(comment) @comment
8+
9+; CONTROL
10+(let "let" @keyword.storage.type)
11+(branch ["if" "else"] @keyword.control.conditional)
12+(while "while" @keyword.control.repeat)
13+(for ["for" "in"] @keyword.control.repeat)
14+(import "import" @keyword.control.import)
15+(as "as" @keyword.operator)
16+(include "include" @keyword.control.import)
17+(show "show" @keyword.control)
18+(set "set" @keyword.control)
19+(return "return" @keyword.control)
20+(flow ["break" "continue"] @keyword.control)
21+
22+; OPERATOR
23+(in ["in" "not"] @keyword.operator)
24+(and "and" @keyword.operator)
25+(or "or" @keyword.operator)
26+(not "not" @keyword.operator)
27+(sign ["+" "-"] @operator)
28+(add "+" @operator)
29+(sub "-" @operator)
30+(mul "*" @operator)
31+(div "/" @operator)
32+(cmp ["==" "<=" ">=" "!=" "<" ">"] @operator)
33+(fraction "/" @operator)
34+(fac "!" @operator)
35+(attach ["^" "_"] @operator)
36+(wildcard) @operator
37+
38+; VALUE
39+(raw_blck "```" @operator) @markup.raw.block
40+(raw_span "`" @operator) @markup.raw.block
41+(raw_blck lang: (ident) @tag)
42+(label) @tag
43+(ref) @tag
44+(number) @constant.numeric
45+(string) @string
46+(content ["[" "]"] @operator)
47+(bool) @constant.builtin.boolean
48+(builtin) @constant.builtin
49+(none) @constant.builtin
50+(auto) @constant.builtin
51+(ident) @variable
52+(call
53+ item: (builtin) @function.builtin)
54+
55+; MARKUP
56+(item "-" @markup.list)
57+(term ["/" ":"] @markup.list)
58+(heading ["=" "==" "===" "====" "====="] @markup.heading.marker) @markup.heading
59+(url) @tag
60+(emph) @markup.italic
61+(strong) @markup.bold
62+(symbol) @constant.character
63+(shorthand) @constant.builtin
64+(quote) @markup.quote
65+(align) @operator
66+(letter) @constant.character
67+(linebreak) @constant.builtin
68+
69+(math "$" @operator)
70+"#" @operator
71+"end" @operator
72+
73+(escape) @constant.character.escape
74+["(" ")" "{" "}"] @punctuation.bracket
75+["," ";" ".." ":" "sep"] @punctuation.delimiter
76+"assign" @punctuation
77+(field "." @punctuation)
runtime/queries/typst/injections.scmnew file+6
@@ -0,0 +1,6 @@
1+(raw_blck
2+ (blob) @injection.shebang @injection.content)
3+
4+(raw_blck
5+ lang: (ident) @injection.language
6+ (blob) @injection.content)
runtime/queries/unison/highlights.scm+21−6
@@ -10,14 +10,18 @@
10[
10[
11 (kw_forall)
11 (kw_forall)
12 (unique_kw)
12 (unique_kw)
13+ (structural_kw)
13 (type_kw)
14 (type_kw)
14 (kw_equals)
15 (kw_equals)
15 (do)
16 (do)
17+ (ability)
18+ (where)
16] @keyword
19] @keyword
17
20
18(kw_let) @keyword.function
21(kw_let) @keyword.function
19(type_kw) @keyword.storage.type
22(type_kw) @keyword.storage.type
20(unique) @keyword.storage.modifier
23(unique) @keyword.storage.modifier
24+(structural) @keyword.storage.modifier
21("use") @keyword.control.import
25("use") @keyword.control.import
22
26
23
27
@@ -31,6 +35,7 @@
31 (arrow_symbol)
35 (arrow_symbol)
32 (">")
36 (">")
33 (or)
37 (or)
38+ (and)
34 (bang)
39 (bang)
35] @operator
40] @operator
36
41
@@ -47,13 +52,22 @@
47
52
48;; Types
53;; Types
49(record_field name: (wordy_id) @variable.other.member type: (wordy_id) @type)
54(record_field name: (wordy_id) @variable.other.member type: (wordy_id) @type)
50−[
55+(type_constructor (type_name (wordy_id) @constructor))
51− (type_name)
56+(ability_declaration type_name: (wordy_id) @type type_arg: (wordy_id) @variable.parameter)
52− (type_signature)
57+(effect (wordy_id) @special) ;; NOTE: an effect is just like a type, but in signature we special case it
53− (effect)
58+
54−] @type
59+;; Namespaces
60+(path) @namespace
61+(namespace) @namespace
62+
63+;; Terms
64+(type_signature term_name: (path)? @variable term_name: (wordy_id) @variable)
65+(type_signature (wordy_id) @type)
66+(type_signature (delayed (wordy_id)) @type)
67+
68+(term_definition param: (wordy_id) @variable.parameter)
55
69
56−(term_definition) @variable
70+(function_application function_name: (path)? function_name: (wordy_id) @function)
57
71
58;; Punctuation
72;; Punctuation
59[
73[
@@ -70,3 +84,4 @@
70 "]"
84 "]"
71] @punctuation.bracket
85] @punctuation.bracket
72
86
87+(test_watch_expression (wordy_id) @keyword.directive)
runtime/queries/yuck/highlights.scm+1−1
@@ -101,7 +101,7 @@
101(list
101(list
102 (symbol) @tag)
102 (symbol) @tag)
103
103
104−; Other stuff that has not been catched by the previous queries yet
104+; Other stuff that has not been caught by the previous queries yet
105
105
106(ident) @variable
106(ident) @variable
107(index) @variable
107(index) @variable
runtime/themes/README.md+8
@@ -6,4 +6,12 @@ If you submit a theme, please include a comment at the top with your name and em
6# Author : Name <email@my.domain>
6# Author : Name <email@my.domain>
7```
7```
8
8
9+If you are submitting a theme that is already published somewhere, then please
10+add the corresponding license file for it under `licenses/` with the following
11+name `theme_name.license` and add a comment at the top of the theme file:
12+
13+```toml
14+# License: <License specification>
15+```
16+
9We have a preview page for themes on our [wiki](https://github.com/helix-editor/helix/wiki/Themes)!
17We have a preview page for themes on our [wiki](https://github.com/helix-editor/helix/wiki/Themes)!
runtime/themes/cyan_light.toml+9−6
@@ -57,9 +57,12 @@
57"markup.raw.inline" = "green"
57"markup.raw.inline" = "green"
58"markup.raw.block" = "green"
58"markup.raw.block" = "green"
59
59
60−"diff.plus" = "diff_green"
60+"diff.plus" = "green"
61+"diff.plus.gutter" = "gutter_green"
62+"diff.minus" = "red"
61−"diff.minus" = "diff_red"
63+"diff.minus.gutter" = "gutter_red"
64+"diff.delta" = "blue"
62−"diff.delta" = "diff_blue"
65+"diff.delta.gutter" = "gutter_blue"
63
66
64# ui specific
67# ui specific
65"ui.background" = { bg = "shade00" }
68"ui.background" = { bg = "shade00" }
@@ -121,7 +124,7 @@ foreground = "#25293c"
121
124
122comment_gray = "#808080"
125comment_gray = "#808080"
123
126
124−diff_blue = "#C3D6E8"
127+gutter_blue = "#C3D6E8"
125faint_blue = "#E8Eef1"
128faint_blue = "#E8Eef1"
126lighter_blue = "#d0eaff"
129lighter_blue = "#d0eaff"
127light_blue = "#99ccff"
130light_blue = "#99ccff"
@@ -134,7 +137,7 @@ darker_blue = "#000080"
134purple = "#660E7A"
137purple = "#660E7A"
135light_purple = "#ED9CFF"
138light_purple = "#ED9CFF"
136
139
137−diff_green = "#C9DEC1"
140+gutter_green = "#C9DEC1"
138green = "#00733B"
141green = "#00733B"
139light_green = "#5DCE87"
142light_green = "#5DCE87"
140green_blue = "#458383"
143green_blue = "#458383"
@@ -146,6 +149,6 @@ dark_yellow = "#7A7A43"
146light_orange = "#f9c881"
149light_orange = "#f9c881"
147orange = "#F49810"
150orange = "#F49810"
148
151
149−diff_red = "#EBBCBC"
152+gutter_red = "#EBBCBC"
150red = "#d90016"
153red = "#d90016"
151dark_red = "#7F0000"
154dark_red = "#7F0000"
runtime/themes/darcula-solid.toml+1−4
@@ -4,9 +4,8 @@ inherits = "darcula"
4
4
5"ui.background.separator" = { bg = "grey01" }
5"ui.background.separator" = { bg = "grey01" }
6"ui.menu.scroll" = { fg = "grey02", bg = "grey00" }
6"ui.menu.scroll" = { fg = "grey02", bg = "grey00" }
7−"ui.popup" = { fg = "grey03", bg = "grey02" }
7+"ui.popup" = { fg = "grey05", bg = "grey00" }
8"ui.window" = { bg = "grey00" }
8"ui.window" = { bg = "grey00" }
9−"ui.selection" = { bg = "blue" }
10"ui.cursorline.secondary" = { bg = "grey03" }
9"ui.cursorline.secondary" = { bg = "grey03" }
11
10
12[palette]
11[palette]
@@ -15,5 +14,3 @@ grey01 = "#1f1f1f"
15grey02 = "#323232"
14grey02 = "#323232"
16grey03 = "#555555"
15grey03 = "#555555"
17grey04 = "#a8a8a8"
16grey04 = "#a8a8a8"
18−
19−blue = "#104158"
runtime/themes/darcula.toml+10−4
@@ -8,13 +8,14 @@
8"ui.gutter" = { bg = "grey01" }
8"ui.gutter" = { bg = "grey01" }
9"ui.popup" = { fg = "grey05", bg = "grey00" }
9"ui.popup" = { fg = "grey05", bg = "grey00" }
10"ui.window" = { bg = "grey01" }
10"ui.window" = { bg = "grey01" }
11−"ui.selection" = { bg = "grey03" }
11+"ui.selection" = { bg = "grey02" }
12+"ui.selection.primary" = { bg = "blue" }
12"ui.statusline" = { fg = "grey04", bg = "grey02" }
13"ui.statusline" = { fg = "grey04", bg = "grey02" }
13"ui.statusline.insert" = { bg = "white", fg = "grey01" }
14"ui.statusline.insert" = { bg = "white", fg = "grey01" }
14"ui.statusline.select" = { bg = "orange", fg = "grey01" }
15"ui.statusline.select" = { bg = "orange", fg = "grey01" }
15"ui.help" = { fg = "grey04", bg = "grey01" }
16"ui.help" = { fg = "grey04", bg = "grey01" }
16"ui.cursor" = { fg = "grey04", modifiers = ["reversed"] }
17"ui.cursor" = { fg = "grey04", modifiers = ["reversed"] }
17−"ui.cursor.primary" = { fg = "grey05", modifiers = ["reversed"] }
18+"ui.cursor.primary" = { fg = "grey02", bg = "grey05" }
18"ui.cursor.match" = { fg = "white", modifiers = ["underlined"] }
19"ui.cursor.match" = { fg = "white", modifiers = ["underlined"] }
19"ui.cursorline.primary" = { bg = "grey02" }
20"ui.cursorline.primary" = { bg = "grey02" }
20"ui.cursorline.secondary" = { bg = "grey02" }
21"ui.cursorline.secondary" = { bg = "grey02" }
@@ -34,7 +35,11 @@
34"constant.numeric" = "lightblue"
35"constant.numeric" = "lightblue"
35"constant.character.escape" = "white"
36"constant.character.escape" = "white"
36"attribute" = "yellow"
37"attribute" = "yellow"
37−"type" = "orange"
38+"type" = "white"
39+"type.builtin" = "orange"
40+"type.parameter" = { fg = "white", modifiers = ["bold"] }
41+"type.enum" = "white"
42+"type.enum.variant" = "orange"
38"string" = "darkgreen"
43"string" = "darkgreen"
39"function" = "yellow"
44"function" = "yellow"
40"function.macro" = "green"
45"function.macro" = "green"
@@ -61,7 +66,7 @@
61"markup.link.url" = { fg = "lightblue", modifiers = ["underlined"] }
66"markup.link.url" = { fg = "lightblue", modifiers = ["underlined"] }
62"markup.link.text" = "white"
67"markup.link.text" = "white"
63"markup.quote" = "darkgreen"
68"markup.quote" = "darkgreen"
64−"markup.raw" = "white"
69+"markup.raw" = "purple"
65
70
66"diff.plus" = "green"
71"diff.plus" = "green"
67"diff.delta" = "grey"
72"diff.delta" = "grey"
@@ -97,3 +102,4 @@ green = "#32cd32"
97grey = "#808080"
102grey = "#808080"
98darkgreen = "#629755"
103darkgreen = "#629755"
99lightblue = "#6897bb"
104lightblue = "#6897bb"
105+blue = "#104158"
runtime/themes/everblush.toml+1
@@ -68,6 +68,7 @@
68"ui.virtual.whitespace" = { fg = "comment" }
68"ui.virtual.whitespace" = { fg = "comment" }
69"ui.virtual.wrap" = { fg = "comment" }
69"ui.virtual.wrap" = { fg = "comment" }
70"ui.virtual.indent-guide" = { fg = "comment" }
70"ui.virtual.indent-guide" = { fg = "comment" }
71+"ui.virtual.inlay-hint" = { fg = "comment" }
71"ui.window" = { fg = "black" }
72"ui.window" = { fg = "black" }
72
73
73"error" = { fg = "red" }
74"error" = { fg = "red" }
runtime/themes/gruber-darker.tomlnew file+114
@@ -0,0 +1,114 @@
1+# Author : Mehedi Hasan <mehedi.r137@gmail.com>
2+# Based on : https://github.com/rexim/gruber-darker-theme
3+
4+"attribute" = "fg0"
5+"keyword" = { fg = "yellow0", modifiers = ["bold"] }
6+"keyword.directive" = "quartz"
7+"namespace" = "quartz"
8+"punctuation" = "fg0"
9+"punctuation.delimiter" = "fg0"
10+"operator" = "fg0"
11+"special" = { fg = "yellow0", modifiers = ["bold"] }
12+"variable" = "fg0"
13+"variable.builtin" = { fg = "yellow0", modifiers = ["bold"] }
14+"variable.parameter" = "fg0"
15+"type" = "quartz"
16+"type.builtin" = "yellow0"
17+"constructor" = { fg = "quartz" }
18+"function" = "niagara0"
19+"function.builtin" = "yellow0"
20+"tag" = "niagara0"
21+"comment" = { fg = "brown0" }
22+"constant.character" = { fg = "green0" }
23+"constant.character.escape" = { fg = "yellow0" }
24+"constant.builtin" = { fg = "yellow0", modifiers = ["bold"] }
25+"string" = "green0"
26+"constant.numeric" = "wisteria"
27+"label" = "fg0"
28+"module" = "aqua1"
29+
30+"diff.plus" = "green1"
31+"diff.delta" = "orange1"
32+"diff.minus" = "red0"
33+
34+"warning" = { fg = "orange1", modifiers = ["bold"] }
35+"error" = { fg = "red0", modifiers = ["bold"] }
36+"info" = { fg = "aqua1", modifiers = ["bold"] }
37+"hint" = { fg = "blue0", modifiers = ["bold"] }
38+
39+"ui.background" = { bg = "bg0" }
40+"ui.linenr" = { fg = "bg4" }
41+"ui.linenr.selected" = { fg = "yellow0" }
42+"ui.cursorline" = { bg = "bg1" }
43+
44+"ui.statusline" = { fg = "fg0", bg = "bg1" }
45+"ui.statusline.normal" = { fg = "bg1", bg = "yellow0", modifiers = ["bold"] }
46+"ui.statusline.insert" = { fg = "bg1", bg = "blue0", modifiers = ["bold"] }
47+"ui.statusline.select" = { fg = "bg1", bg = "wisteria", modifiers = ["bold"] }
48+"ui.statusline.inactive" = { fg = "fg3", bg = "bg1" }
49+
50+"ui.bufferline" = { fg = "fg3", bg = "bg6" }
51+"ui.bufferline.active" = { fg = "fg0", bg = "bg7" }
52+
53+"ui.popup" = { bg = "bg6" }
54+"ui.window" = { fg = "bg1" }
55+"ui.help" = { bg = "bg1", fg = "fg0" }
56+"ui.text" = { fg = "fg0" }
57+"ui.text.focus" = { bg = "bg5", modifiers = ["bold"] }
58+"ui.selection" = { bg = "bg2" }
59+"ui.selection.primary" = { bg = "bg5" }
60+"ui.cursor.primary" = { bg = "fg0", fg = "niagara1" }
61+"ui.cursor.match" = { bg = "yellow1" }
62+"ui.menu" = { fg = "fg0", bg = "bg6" }
63+"ui.menu.selected" = { fg = "fg0", bg = "bg5", modifiers = ["bold"] }
64+
65+"ui.virtual.whitespace" = "bg8"
66+"ui.virtual.indent-guide" = "bg8"
67+"ui.virtual.ruler" = { bg = "bg1" }
68+"ui.virtual.inlay-hint" = { fg = "bg7" }
69+"ui.virtual.wrap" = { fg = "bg2" }
70+
71+"diagnostic.warning" = { underline = { color = "orange1", style = "dashed" } }
72+"diagnostic.error" = { underline = { color = "red3", style = "dashed" } }
73+"diagnostic.info" = { underline = { color = "aqua1", style = "dashed" } }
74+"diagnostic.hint" = { underline = { color = "blue0", style = "dashed" } }
75+
76+"markup.heading" = { fg = "aqua1", modifiers = ["bold"] }
77+"markup.bold" = { modifiers = ["bold"] }
78+"markup.italic" = { modifiers = ["italic"] }
79+"markup.strikethrough" = { modifiers = ["crossed_out"] }
80+"markup.link.url" = { fg = "green1", modifiers = ["underlined"] }
81+"markup.link.text" = "red3"
82+"markup.raw" = { fg = "fg0", bg = "bg8", modifiers = ["bold"] }
83+
84+[palette]
85+fg0 = "#e4e4ef"
86+fg1 = "#f4f4ff"
87+fg2 = "#f5f5f5"
88+fg3 = "#a89984"
89+bg0 = "#181818"
90+bg1 = "#282828"
91+bg2 = "#453d41"
92+bg4 = "#52494e"
93+bg5 = "#404040"
94+bg6 = "#232323"
95+bg7 = "#3f3f3f"
96+bg8 = "#2c2c2c"
97+red0 = "#f43841"
98+red1 = "#ff4f58"
99+red2 = "#2B0A0B"
100+red3 = "#fb4934"
101+green0 = "#73c936"
102+green1 = "#b8bb26"
103+yellow0 = "#ffdd33"
104+yellow1 = "#655814"
105+blue0 = "#5292c8"
106+orange0 = "#d65d0e"
107+orange1 = "#fe8019"
108+brown0 = "#cc8c3c"
109+quartz = "#95a99f"
110+niagara0 = "#96a6c8"
111+niagara1 = "#303540"
112+wisteria = "#9e95c7"
113+aqua1 = "#8ec07c"
114+
runtime/themes/horizon-dark.tomlnew file+80
@@ -0,0 +1,80 @@
1+# Syntax
2+string = "orange"
3+constant = "purple"
4+"constant.numeric" = "orange"
5+"constant.builtin" = "orange"
6+variable = "red"
7+comment = "light-gray"
8+special = "purple"
9+"punctuation.bracket" = "purple"
10+keyword = "purple"
11+function = "blue"
12+label = "orange"
13+type = "orange"
14+namespace = "orange"
15+
16+# User Interface
17+"ui.background" = { bg = "bg", fg = "gray" }
18+"ui.background.separator" = "light-gray"
19+"ui.text" = "white"
20+"ui.text.focus" = "green"
21+"ui.text.inactive" = "selection"
22+"ui.text.info" = "orange"
23+"ui.cursor" = { modifiers = ["reversed"] }
24+"ui.cursor.primary" = { modifiers = ["reversed"] }
25+"ui.cursor.match" = { bg = "selection" }
26+"ui.gutter" = "gray"
27+"ui.gutter.selected" = "light-gray"
28+"ui.selection" = { bg = "selection" }
29+"ui.virtual.indent-guide" = { fg = "gray"}
30+"ui.virtual.whitespace" = { fg = "light-gray"}
31+"ui.statusline" = { bg = "dark-bg", fg = "light-gray" }
32+"ui.popup" = { bg = "dark-bg", fg = "orange" }
33+"ui.help" = { bg = "dark-bg", fg = "orange" }
34+"ui.menu" = { bg = "dark-bg", fg = "light-gray" }
35+"ui.menu.selected" = { bg = "selection", fg = "orange" }
36+"ui.window" = "selection"
37+"ui.bufferline" = { bg = "dark-bg", fg = "light-gray" }
38+"ui.bufferline.active" = { bg = "dark-bg", fg = "orange" }
39+
40+# Diagnostics
41+"diagnostic" = { underline = { style = "curl" } }
42+"diagnostic.hint" = { underline = { color = "green", style = "curl" } }
43+"diagnostic.info" = { underline = { color = "blue", style = "curl" } }
44+"diagnostics.error" = { underline = { color = "red", style = "curl"} }
45+"diagnostics.warning" = { underline = { color = "orange", style = "curl"} }
46+
47+warning = { fg = "orange", modifiers = ["bold"] }
48+error = { fg = "red", modifiers = ["bold"] }
49+info = { fg = "blue", modifiers = ["bold"] }
50+hint = { fg = "green", modifiers = ["bold"] }
51+
52+# Markup
53+"markup.heading" = "pink"
54+"markup.list" = "light-gray"
55+"markup.list.checked" = "green"
56+"markup.list.unchecked" = "light-gray"
57+"markup.bold" = { modifiers = ["bold"] }
58+"markup.italic" = { modifiers = ["italic"] }
59+"markup.strikethrough" = { modifiers = ["crossed_out"] }
60+"markup.link" = "blue"
61+"markup.quote" = "orange"
62+"markup.raw" = "orange"
63+
64+"diff.plus" = "green"
65+"diff.minus" = "red"
66+"diff.delta" = "orange"
67+
68+[palette]
69+white = "#D5D8DA"
70+gray = "#2E303E"
71+light-gray = "#6C6F93"
72+bg = "#1C1E26"
73+dark-bg = "#16161C"
74+pink = "#EE64AE"
75+selection = "#353747"
76+green = "#27D796"
77+orange = "#FAB795"
78+purple = "#B877DB"
79+red = "#E95678"
80+blue = "#25B2BC"
runtime/themes/licenses/everforest.LICENSEnew file+21
@@ -0,0 +1,21 @@
1+MIT License
2+
3+Copyright (c) 2019 sainnhe
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
runtime/themes/licenses/modus_vivendi.LICENSEnew file+5
@@ -0,0 +1,5 @@
1+Copyright (C) 2020-2023 Free Software Foundation, Inc.
2+
3+Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”
4+
5+(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.”
runtime/themes/licenses/modus_vivendi_deuteranopia.LICENSEnew file+5
@@ -0,0 +1,5 @@
1+Copyright (C) 2020-2023 Free Software Foundation, Inc.
2+
3+Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”
4+
5+(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.”
runtime/themes/licenses/modus_vivendi_tinted.LICENSEnew file+5
@@ -0,0 +1,5 @@
1+Copyright (C) 2020-2023 Free Software Foundation, Inc.
2+
3+Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”
4+
5+(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.”
runtime/themes/licenses/modus_vivendi_tritanopia.LICENSEnew file+5
@@ -0,0 +1,5 @@
1+Copyright (C) 2020-2023 Free Software Foundation, Inc.
2+
3+Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”
4+
5+(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.”
runtime/themes/licenses/poimandres.LICENSEnew file+21
@@ -0,0 +1,21 @@
1+MIT License
2+
3+Copyright (c) 2023 drcmda
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
runtime/themes/licenses/serika-syntax.LICENSEnew file+21
@@ -0,0 +1,21 @@
1+MIT License
2+
3+Copyright (c) 2018 arturoalviar
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
runtime/themes/licenses/sonokai.LICENSEnew file+21
@@ -0,0 +1,21 @@
1+MIT License
2+
3+Copyright (c) 2020 sainnhe
4+
5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+
12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+
15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
runtime/themes/licenses/starlight.LICENSEnew file+24
@@ -0,0 +1,24 @@
1+This is free and unencumbered software released into the public domain.
2+
3+Anyone is free to copy, modify, publish, use, compile, sell, or
4+distribute this software, either in source code form or as a compiled
5+binary, for any purpose, commercial or non-commercial, and by any
6+means.
7+
8+In jurisdictions that recognize copyright laws, the author or authors
9+of this software dedicate any and all copyright interest in the
10+software to the public domain. We make this dedication for the benefit
11+of the public at large and to the detriment of our heirs and
12+successors. We intend this dedication to be an overt act of
13+relinquishment in perpetuity of all present and future rights to this
14+software under copyright law.
15+
16+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+OTHER DEALINGS IN THE SOFTWARE.
23+
24+For more information, please refer to <https://unlicense.org>
runtime/themes/modus_operandi.tomlnew file+194
@@ -0,0 +1,194 @@
1+# Author: Alexis Mousset <contact@amousset.me>
2+# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
3+# Version 4.3.0
4+#
5+
6+# Syntax highlighting
7+# -------------------
8+"type" = "cyan-cooler"
9+"constructor" = "cyan-cooler"
10+
11+"constant" = "blue-cooler"
12+"constant.character.escape" = "magenta"
13+
14+"string" = "blue-warmer"
15+"string.regexp" = "magenta-faint"
16+"string.special" = "blue-faint" # used for colors in CSS
17+
18+"comment" = "fg-dim"
19+
20+"variable.parameter" = "cyan"
21+"variable.builtin" = "magenta-cooler"
22+"label" = "fg-dim" # used for language in markdown code blocks
23+"keyword" = "magenta-cooler"
24+"keyword.directive" = "red-cooler"
25+"function" = "magenta"
26+"function.macro" = "magenta-warmer"
27+
28+punctuation = "fg-dim"
29+"tag" = "magenta"
30+"attribute" = "cyan-cooler"
31+"namespace" = "blue-cooler"
32+"special" = "red-cooler"
33+
34+"markup.heading.marker" = "fg-dim"
35+"markup.heading.1" = { fg = "fg-main", modifiers = ["bold"] }
36+"markup.heading.2" = { fg = "yellow-faint", modifiers = ["bold"] }
37+"markup.heading.3" = { fg = "fg-alt", modifiers = ["bold"] }
38+"markup.heading.4" = { fg = "magenta", modifiers = ["bold"] }
39+"markup.heading.5" = { fg = "green-faint", modifiers = ["bold"] }
40+"markup.heading.6" = { fg = "red-faint", modifiers = ["bold"] }
41+"markup.list" = "fg-dim"
42+"markup.list.checked" = { fg = "yellow-warmer" }
43+"markup.list.unchecked" = { fg = "yellow-warmer" }
44+"markup.bold" = { modifiers = ["bold"] }
45+"markup.italic" = { modifiers = ["italic"] }
46+"markup.strikethrough" = { modifiers = ["crossed_out"] }
47+"markup.link.url" = { fg = "cyan" }
48+"markup.link.text" = { fg = "blue-warmer", modifiers = ["underlined"] }
49+"markup.raw.block" = { bg = "bg-dim" }
50+"markup.raw.inline" = { fg = "green-cooler" }
51+
52+"diff.plus" = { fg = "fg-added", bg = "bg-added" }
53+"diff.plus.gutter" = "green-intense"
54+"diff.minus" = { fg = "fg-removed", bg = "bg-removed" }
55+"diff.minus.gutter" = "red-intense"
56+"diff.delta" = { fg = "fg-changed", bg = "bg-changed" }
57+"diff.delta.gutter" = "yellow-intense"
58+
59+# User Interface
60+# --------------
61+
62+"ui.background" = { bg = "bg-main" }
63+
64+"ui.linenr" = { fg = "fg-dim", bg = "bg-dim" }
65+"ui.linenr.selected" = { fg = "fg-main", bg = "bg-active" }
66+
67+"ui.statusline" = { fg = "fg-mode-line-active", bg = "bg-mode-line-active" }
68+"ui.statusline.inactive" = { fg = "fg-mode-line-inactive", bg = "bg-mode-line-inactive" }
69+"ui.statusline.normal" = { fg = "blue-warmer" }
70+"ui.statusline.insert" = { fg = "green-warmer" }
71+"ui.statusline.select" = { fg = "magenta-warmer" }
72+
73+"ui.popup" = { fg = "fg-main", bg = "bg-dim" }
74+"ui.window" = { fg = "fg-dim" }
75+"ui.help" = { fg = "fg-main", bg = "bg-dim" }
76+"ui.gutter" = { bg = "bg-dim" }
77+"ui.text" = "fg-main"
78+"ui.text.focus" = { fg = "fg-main", bg = "bg-completion", modifiers = ["bold"] }
79+"ui.text.inactive" = { fg = "fg-dim" }
80+"ui.virtual" = "bg-active"
81+"ui.virtual.ruler" = { bg = "bg-dim" }
82+"ui.virtual.inlay-hint" = { fg = "fg-dim", modifiers = ["italic"] }
83+
84+"ui.selection" = { fg = "fg-main", bg = "bg-inactive" }
85+"ui.selection.primary" = { fg = "fg-main", bg = "bg-active" }
86+
87+"ui.cursor" = { fg = "bg-main", bg = "fg-main" }
88+"ui.cursor.primary" = { fg = "bg-main", bg = "fg-dim" }
89+"ui.cursor.match" = { bg = "bg-paren-match" }
90+"ui.cursorline.primary" = { bg = "bg-hl-line" }
91+
92+"ui.highlight" = { bg = "bg-hl-line" }
93+
94+"ui.menu" = { fg = "fg-main", bg = "bg-dim" }
95+"ui.menu.selected" = { fg = "fg-main", bg = "bg-completion", modifiers = ["bold"] }
96+"ui.menu.scroll" = { fg = "fg-dim", bg = "bg-cyan-intense" }
97+
98+"diagnostic.error" = { underline = { color = "red-intense", style = "curl" } }
99+"diagnostic.warning" = { underline = { color = "yellow-intense", style = "curl" } }
100+"diagnostic.info" = { underline = { color = "cyan-intense", style = "curl" } }
101+"diagnostic.hint" = { underline = { color = "blue-intense", style = "curl" } }
102+
103+error = "red"
104+warning = "yellow-warmer"
105+info = "cyan-cooler"
106+hint = "blue-cooler"
107+
108+[palette]
109+# Basic values
110+bg-main = "#ffffff"
111+bg-dim = "#f2f2f2"
112+fg-main = "#000000"
113+fg-dim = "#595959"
114+fg-alt = "#193668"
115+bg-active = "#c4c4c4"
116+bg-inactive = "#e0e0e0"
117+
118+# Common accent foregrounds
119+red = "#a60000"
120+red-warmer = "#972500"
121+red-cooler = "#a0132f"
122+red-faint = "#7f0000"
123+red-intense = "#d00000"
124+green = "#006800"
125+green-warmer = "#316500"
126+green-cooler = "#00663f"
127+green-faint = "#2a5045"
128+green-intense = "#008900"
129+yellow = "#6f5500"
130+yellow-warmer = "#884900"
131+yellow-cooler = "#7a4f2f"
132+yellow-faint = "#624416"
133+yellow-intense = "#808000"
134+blue = "#0031a9"
135+blue-warmer = "#354fcf"
136+blue-cooler = "#0000b0"
137+blue-faint = "#003497"
138+blue-intense = "#0000ff"
139+magenta = "#721045"
140+magenta-warmer = "#8f0075"
141+magenta-cooler = "#531ab6"
142+magenta-faint = "#7c318f"
143+magenta-intense = "#dd22dd"
144+cyan = "#005e8b"
145+cyan-warmer = "#3f578f"
146+cyan-cooler = "#005f5f"
147+cyan-faint = "#005077"
148+cyan-intense = "#008899"
149+
150+# Common accent backgrounds
151+bg-red-intense = "#ff8f88"
152+bg-green-intense = "#8adf80"
153+bg-yellow-intense = "#f3d000"
154+bg-blue-intense = "#bfc9ff"
155+bg-magenta-intense = "#dfa0f0"
156+bg-cyan-intense = "#a4d5f9"
157+
158+bg-red-subtle = "#ffcfbf"
159+bg-green-subtle = "#b3fabf"
160+bg-yellow-subtle = "#fff576"
161+bg-blue-subtle = "#ccdfff"
162+bg-magenta-subtle = "#ffddff"
163+bg-cyan-subtle = "#bfefff"
164+
165+bg-red-nuanced = "#fff1f0"
166+bg-green-nuanced = "#ecf7ed"
167+bg-yellow-nuanced = "#fff3da"
168+bg-blue-nuanced = "#f3f3ff"
169+bg-magenta-nuanced = "#fdf0ff"
170+bg-cyan-nuanced = "#ebf6fa"
171+
172+# Special purpose
173+bg-completion = "#c0deff"
174+bg-hl-line = "#dae5ec"
175+
176+bg-mode-line-active = "#c8c8c8"
177+fg-mode-line-active = "#000000"
178+bg-mode-line-inactive = "#e6e6e6"
179+fg-mode-line-inactive = "#585858"
180+
181+modeline-err = "#7f0000"
182+modeline-warning = "#5f0070"
183+modeline-info = "#002580"
184+
185+# Diffs
186+bg-added = "#c1f2d1"
187+fg-added = "#005000"
188+bg-changed = "#ffdfa9"
189+fg-changed = "#553d00"
190+bg-removed = "#ffd8d5"
191+fg-removed = "#8f1313"
192+
193+# Paren match
194+bg-paren-match = "#5fcfff"
runtime/themes/modus_operandi_deuteranopia.tomlnew file+46
@@ -0,0 +1,46 @@
1+# Author: Alexis Mousset <contact@amousset.me>
2+# modus_operandi.toml variant
3+#
4+# This variant is optimized for users with red-green color deficiency (deuteranopia)
5+
6+inherits = "modus_operandi"
7+
8+"constant.character.escape" = "magenta"
9+"comment" = "yellow-cooler"
10+"function" = "magenta"
11+"tag" = "magenta"
12+
13+"ui.cursor" = { fg = "bg-main", bg = "blue-intense" }
14+"ui.cursor.primary.normal" = { fg = "bg-main", bg = "blue-intense" }
15+
16+"diagnostic.error" = { underline = { color = "yellow-intense", style = "curl" } }
17+"diagnostic.warning" = { underline = { color = "magenta-faint", style = "curl" } }
18+"diagnostic.info" = { underline = { color = "cyan", style = "curl" } }
19+"diagnostic.hint" = { underline = { color = "blue", style = "curl" } }
20+
21+error = "yellow-intense"
22+warning = "magenta-faint"
23+info = "cyan"
24+hint = "blue"
25+
26+[palette]
27+
28+yellow = "#695500"
29+yellow-warmer = "#973300"
30+yellow-cooler = "#77492f"
31+
32+bg-mode-line-active = "#d0d6ff"
33+fg-mode-line-active = "#0f0f0f"
34+border-mode-line-active = "#4f4f74"
35+
36+modeline-err = "#603a00"
37+modeline-warning = "#454500"
38+modeline-info = "#023d92"
39+
40+# Diffs
41+bg-added = "#d5d7ff"
42+fg-added = "#303099"
43+bg-changed = "#eecfdf"
44+fg-changed = "#6f1343"
45+bg-removed = "#f4f099"
46+fg-removed = "#553d00"
runtime/themes/modus_operandi_tinted.tomlnew file+45
@@ -0,0 +1,45 @@
1+# Author: Alexis Mousset <contact@amousset.me>
2+# modus_operandi.toml variant
3+
4+inherits = "modus_operandi"
5+
6+"comment" = "red-faint"
7+
8+"ui.cursor.primary" = { fg = "bg-main", bg = "red" }
9+
10+[palette]
11+# Basic values
12+bg-main = "#fbf7f0"
13+bg-dim = "#efe9dd"
14+bg-active = "#c9b9b0"
15+bg-inactive = "#dfd5cf"
16+border = "#9f9690"
17+
18+# Common accent backgrounds
19+bg-red-nuanced = "#ffe8f0"
20+bg-green-nuanced = "#e0f5e0"
21+bg-yellow-nuanced = "#f9ead0"
22+bg-blue-nuanced = "#ebebff"
23+bg-magenta-nuanced = "#f6e7ff"
24+bg-cyan-nuanced = "#e1f3fc"
25+
26+# Special purpose
27+bg-completion = "#f0c1cf"
28+bg-hl-line = "#f1d5d0"
29+bg-region = "#c2bcb5"
30+
31+bg-mode-line-active = "#cab9b2"
32+border-mode-line-active = "#545454"
33+bg-mode-line-inactive = "#dfd9cf"
34+border-mode-line-inactive = "#a59a94"
35+
36+bg-tab-bar = "#e0d4ce"
37+bg-tab-current = "#fbf7f0"
38+bg-tab-other = "#c8b8b2"
39+
40+# Diffs
41+bg-added = "#c3ebc1"
42+bg-removed = "#f4d0cf"
43+
44+# Paren match
45+bg-paren-match = "#7fdfcf"
runtime/themes/modus_operandi_tritanopia.tomlnew file+73
@@ -0,0 +1,73 @@
1+# Author: Alexis Mousset <contact@amousset.me>
2+# modus_operandi.toml variant
3+#
4+# This variant is optimized for users with blue-yellow color deficiency (tritanopia)
5+
6+inherits = "modus_operandi"
7+
8+"type" = "blue-warmer"
9+"constructor" = "blue-warmer"
10+"constant" = "green-cooler"
11+"constant.character.escape" = "red-cooler"
12+"string" = "cyan"
13+"comment" = "red-faint"
14+"variable.parameter" = "cyan-cooler"
15+"keyword" = "red-cooler"
16+"keyword.directive" = "red-warmer"
17+"function" = "cyan-warmer"
18+"function.macro" = "magenta"
19+"tag" = "red-cooler"
20+
21+"markup.heading.2" = { fg = "red-faint", modifiers = ["bold"] }
22+"markup.heading.3" = { fg = "cyan-faint", modifiers = ["bold"] }
23+"markup.heading.6" = { fg = "magenta-faint", modifiers = ["bold"] }
24+"markup.link.url" = { fg = "cyan-cooler" }
25+"markup.link.text" = { fg = "cyan", modifiers = ["underlined"] }
26+
27+"ui.cursor" = { fg = "bg-main", bg = "red-intense" }
28+"ui.cursor.primary.normal" = { fg = "bg-main", bg = "red-intense" }
29+
30+"diagnostic.error" = { underline = { color = "red-warmer", style = "curl" } }
31+"diagnostic.warning" = { underline = { color = "magenta", style = "curl" } }
32+"diagnostic.info" = { underline = { color = "cyan", style = "curl" } }
33+"diagnostic.hint" = { underline = { color = "blue", style = "curl" } }
34+
35+error = "red-warmer"
36+warning = "magenta"
37+info = "cyan"
38+hint = "blue"
39+
40+[palette]
41+
42+# Common accent foregrounds
43+red-warmer = "#b21100"
44+red-faint = "#702000"
45+yellow = "#695500"
46+yellow-warmer = "#973300"
47+yellow-cooler = "#77492f"
48+magenta-intense = "#cd22bd"
49+cyan-faint = "#004f5f"
50+
51+# Special purpose
52+bg-completion = "#afdfef"
53+bg-hover = "#ffafbc"
54+bg-hover-secondary = "#9fdfff"
55+bg-hl-line = "#dfeaec"
56+
57+bg-char-0 = "#ff908f"
58+bg-char-1 = "#bfbfff"
59+bg-char-2 = "#5fcfdf"
60+
61+bg-mode-line-active = "#afe0f2"
62+fg-mode-line-active = "#0f0f0f"
63+border-mode-line-active = "#2f4f44"
64+
65+modeline-err = "#8f0000"
66+modeline-warning = "#6f306f"
67+modeline-info = "#00445f"
68+
69+# Diffs
70+bg-added = "#b5e7ff"
71+fg-added = "#005079"
72+bg-changed = "#eecfdf"
73+fg-changed = "#6f1343"
runtime/themes/modus_vivendi.tomlnew file+242
@@ -0,0 +1,242 @@
1+# Author: Matous Dzivjak <matousdzivjak@gmail.com>
2+# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
3+# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-theme.el
4+# Version 4.3.0
5+
6+# Syntax highlighting
7+# -------------------
8+"type" = "cyan-cooler"
9+"constructor" = "cyan-cooler"
10+
11+"constant" = "blue-cooler"
12+"constant.character.escape" = "magenta"
13+
14+"string" = "blue-warmer"
15+"string.regexp" = "magenta-faint"
16+"string.special" = "blue-faint" # used for colors in CSS
17+
18+"comment" = "fg-dim"
19+
20+"variable.parameter" = "cyan"
21+"variable.builtin" = "magenta-cooler"
22+"label" = "fg-dim" # used for language in markdown code blocks
23+"keyword" = "magenta-cooler"
24+"keyword.directive" = "red-cooler"
25+"function" = "magenta"
26+"function.macro" = "magenta-warmer"
27+
28+punctuation = "fg-dim"
29+"tag" = "magenta"
30+"attribute" = "cyan-cooler"
31+"namespace" = "blue-cooler"
32+"special" = "red-cooler"
33+
34+"markup.heading.marker" = "fg-dim"
35+"markup.heading.1" = { fg = "fg-main", modifiers = ["bold"] }
36+"markup.heading.2" = { fg = "yellow-faint", modifiers = ["bold"] }
37+"markup.heading.3" = { fg = "fg-alt", modifiers = ["bold"] }
38+"markup.heading.4" = { fg = "magenta", modifiers = ["bold"] }
39+"markup.heading.5" = { fg = "green-faint", modifiers = ["bold"] }
40+"markup.heading.6" = { fg = "red-faint", modifiers = ["bold"] }
41+"markup.list" = "fg-dim"
42+"markup.list.checked" = { fg = "yellow-warmer" }
43+"markup.list.unchecked" = { fg = "yellow-warmer" }
44+"markup.bold" = { modifiers = ["bold"] }
45+"markup.italic" = { modifiers = ["italic"] }
46+"markup.strikethrough" = { modifiers = ["crossed_out"] }
47+"markup.link.url" = { fg = "cyan" }
48+"markup.link.text" = { fg = "blue-warmer", modifiers = ["underlined"] }
49+"markup.raw.block" = { bg = "bg-dim" }
50+"markup.raw.inline" = { fg = "green-cooler" }
51+
52+"diff.plus" = { fg = "fg-added", bg = "bg-added" }
53+"diff.plus.gutter" = "green-intense"
54+"diff.minus" = { fg = "fg-removed", bg = "bg-removed" }
55+"diff.minus.gutter" = "red-intense"
56+"diff.delta" = { fg = "fg-changed", bg = "bg-changed" }
57+"diff.delta.gutter" = "yellow-intense"
58+
59+# User Interface
60+# --------------
61+
62+"ui.background" = { bg = "bg-main" }
63+
64+"ui.linenr" = { fg = "fg-dim", bg = "bg-dim" }
65+"ui.linenr.selected" = { fg = "fg-main", bg = "bg-active" }
66+
67+"ui.statusline" = { fg = "fg-mode-line-active", bg = "bg-mode-line-active" }
68+"ui.statusline.inactive" = { fg = "fg-mode-line-inactive", bg = "bg-mode-line-inactive" }
69+"ui.statusline.normal" = { fg = "blue-warmer" }
70+"ui.statusline.insert" = { fg = "green-warmer" }
71+"ui.statusline.select" = { fg = "magenta-warmer" }
72+
73+"ui.bufferline" = { bg = "bg-tab-bar" }
74+"ui.bufferline.active" = { bg = "bg-tab-current", fg = "fg-mode-line-active" }
75+
76+"ui.popup" = { fg = "fg-main", bg = "bg-dim" }
77+"ui.window" = { fg = "fg-dim" }
78+"ui.help" = { fg = "fg-main", bg = "bg-dim" }
79+"ui.gutter" = { bg = "bg-dim" }
80+"ui.text" = "fg-main"
81+"ui.text.focus" = { fg = "fg-main", bg = "bg-completion", modifiers = ["bold"] }
82+"ui.text.inactive" = { fg = "fg-dim" }
83+"ui.virtual" = "bg-active"
84+"ui.virtual.ruler" = { bg = "bg-dim" }
85+"ui.virtual.inlay-hint" = { fg = "fg-dim", modifiers = ["italic"] }
86+
87+"ui.selection" = { fg = "fg-main", bg = "bg-inactive" }
88+"ui.selection.primary" = { fg = "fg-main", bg = "bg-active" }
89+
90+"ui.cursor" = { fg = "bg-main", bg = "fg-main" }
91+"ui.cursor.primary" = { fg = "bg-main", bg = "fg-dim" }
92+"ui.cursor.match" = { bg = "bg-paren-match" }
93+"ui.cursorline.primary" = { bg = "bg-hl-line" }
94+
95+"ui.highlight" = { bg = "bg-hl-line" }
96+
97+"ui.menu" = { fg = "fg-main", bg = "bg-dim" }
98+"ui.menu.selected" = { fg = "fg-main", bg = "bg-completion", modifiers = ["bold"] }
99+"ui.menu.scroll" = { fg = "fg-dim", bg = "bg-cyan-intense" }
100+
101+"diagnostic.error" = { underline = { color = "red-intense", style = "curl" } }
102+"diagnostic.warning" = { underline = { color = "yellow-intense", style = "curl" } }
103+"diagnostic.info" = { underline = { color = "cyan-intense", style = "curl" } }
104+"diagnostic.hint" = { underline = { color = "blue-intense", style = "curl" } }
105+
106+error = "red"
107+warning = "yellow-warmer"
108+info = "cyan-cooler"
109+hint = "blue-cooler"
110+
111+[palette]
112+# Basic values
113+bg-main = "#000000"
114+bg-dim = "#1e1e1e"
115+fg-main = "#ffffff"
116+fg-dim = "#989898"
117+fg-alt = "#c6daff"
118+bg-active = "#535353"
119+bg-inactive = "#303030"
120+
121+# Common accent foregrounds
122+red = "#ff5f59"
123+red-warmer = "#ff6b55"
124+red-cooler = "#ff7f9f"
125+red-faint = "#ff9580"
126+red-intense = "#ff5f5f"
127+green = "#44bc44"
128+green-warmer = "#70b900"
129+green-cooler = "#00c06f"
130+green-faint = "#88ca9f"
131+green-intense = "#44df44"
132+yellow = "#d0bc00"
133+yellow-warmer = "#fec43f"
134+yellow-cooler = "#dfaf7a"
135+yellow-faint = "#d2b580"
136+yellow-intense = "#efef00"
137+blue = "#2fafff"
138+blue-warmer = "#79a8ff"
139+blue-cooler = "#00bcff"
140+blue-faint = "#82b0ec"
141+blue-intense = "#338fff"
142+magenta = "#feacd0"
143+magenta-warmer = "#f78fe7"
144+magenta-cooler = "#b6a0ff"
145+magenta-faint = "#caa6df"
146+magenta-intense = "#ff66ff"
147+cyan = "#00d3d0"
148+cyan-warmer = "#4ae2f0"
149+cyan-cooler = "#6ae4b9"
150+cyan-faint = "#9ac8e0"
151+cyan-intense = "#00eff0"
152+
153+# Uncommon accent foregrounds
154+rust = "#db7b5f"
155+gold = "#c0965b"
156+olive = "#9cbd6f"
157+slate = "#76afbf"
158+indigo = "#9099d9"
159+maroon = "#cf7fa7"
160+pink = "#d09dc0"
161+
162+# Common accent backgrounds
163+bg-red-intense = "#9d1f1f"
164+bg-green-intense = "#2f822f"
165+bg-yellow-intense = "#7a6100"
166+bg-blue-intense = "#1640b0"
167+bg-magenta-intense = "#7030af"
168+bg-cyan-intense = "#2266ae"
169+
170+bg-red-subtle = "#620f2a"
171+bg-green-subtle = "#00422a"
172+bg-yellow-subtle = "#4a4000"
173+bg-blue-subtle = "#242679"
174+bg-magenta-subtle = "#552f5f"
175+bg-cyan-subtle = "#004065"
176+
177+bg-red-nuanced = "#2c0614"
178+bg-green-nuanced = "#001904"
179+bg-yellow-nuanced = "#221000"
180+bg-blue-nuanced = "#0f0e39"
181+bg-magenta-nuanced = "#230631"
182+bg-cyan-nuanced = "#041529"
183+
184+# Uncommon accent backgrounds
185+bg-ochre = "#442c2f"
186+bg-lavender = "#38325c"
187+bg-sage = "#0f3d30"
188+
189+# Special purpose
190+bg-completion = "#2f447f"
191+bg-hover = "#45605e"
192+bg-hover-secondary = "#654a39"
193+bg-hl-line = "#2f3849"
194+bg-region = "#5a5a5a"
195+fg-region = "#ffffff"
196+
197+bg-char-0 = "#0050af"
198+bg-char-1 = "#7f1f7f"
199+bg-char-2 = "#625a00"
200+
201+bg-mode-line-active = "#505050"
202+fg-mode-line-active = "#ffffff"
203+border-mode-line-active = "#959595"
204+bg-mode-line-inactive = "#2d2d2d"
205+fg-mode-line-inactive = "#969696"
206+border-mode-line-inactive = "#606060"
207+
208+modeline-err = "#ffa9bf"
209+modeline-warning = "#dfcf43"
210+modeline-info = "#9fefff"
211+
212+bg-tab-bar = "#313131"
213+bg-tab-current = "#000000"
214+bg-tab-other = "#545454"
215+
216+# Diffs
217+bg-added = "#00381f"
218+bg-added-faint = "#002910"
219+bg-added-refine = "#034f2f"
220+bg-added-fringe = "#237f3f"
221+fg-added = "#a0e0a0"
222+fg-added-intense = "#80e080"
223+
224+bg-changed = "#363300"
225+bg-changed-faint = "#2a1f00"
226+bg-changed-refine = "#4a4a00"
227+bg-changed-fringe = "#8a7a00"
228+fg-changed = "#efef80"
229+fg-changed-intense = "#c0b05f"
230+
231+bg-removed = "#4f1119"
232+bg-removed-faint = "#380a0f"
233+bg-removed-refine = "#781a1f"
234+bg-removed-fringe = "#b81a1f"
235+fg-removed = "#ffbfbf"
236+fg-removed-intense = "#ff9095"
237+
238+bg-diff-context = "#1a1a1a"
239+
240+# Paren match
241+bg-paren-match = "#2f7f9f"
242+tg-paren-expression = "#453040"
runtime/themes/modus_vivendi_deuteranopia.tomlnew file+158
@@ -0,0 +1,158 @@
1+# Author: Matous Dzivjak <matousdzivjak@gmail.com>
2+# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
3+# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-deuteranopia-theme.el
4+# Version 4.3.0
5+
6+inherits = "modus_vivendi"
7+
8+"constant.character.escape" = "magenta"
9+"comment" = "yellow-cooler"
10+"function" = "magenta"
11+"tag" = "magenta"
12+
13+"ui.cursor" = { fg = "bg-main", bg = "blue-intense" }
14+"ui.cursor.primary.normal" = { fg = "bg-main", bg = "blue-intense" }
15+
16+"diagnostic.error" = { underline = { color = "yellow-intense", style = "curl" } }
17+"diagnostic.warning" = { underline = { color = "magenta-faint", style = "curl" } }
18+"diagnostic.info" = { underline = { color = "cyan", style = "curl" } }
19+"diagnostic.hint" = { underline = { color = "blue", style = "curl" } }
20+
21+error = "yellow-intense"
22+warning = "magenta-faint"
23+info = "cyan"
24+hint = "blue"
25+
26+[palette]
27+# Basic values
28+bg-main = "#000000"
29+bg-dim = "#1e1e1e"
30+fg-main = "#ffffff"
31+fg-dim = "#989898"
32+fg-alt = "#c6daff"
33+bg-active = "#535353"
34+bg-inactive = "#303030"
35+border = "#646464"
36+
37+# Common accent foregrounds
38+red = "#ff5f59"
39+red-warmer = "#ff6b55"
40+red-cooler = "#ff7f9f"
41+red-faint = "#ff9580"
42+red-intense = "#ff5f5f"
43+green = "#44bc44"
44+green-warmer = "#70b900"
45+green-cooler = "#00c06f"
46+green-faint = "#88ca9f"
47+green-intense = "#44df44"
48+yellow = "#cabf00"
49+yellow-warmer = "#ffa00f"
50+yellow-cooler = "#d8af7a"
51+yellow-faint = "#d2b580"
52+yellow-intense = "#efef00"
53+blue = "#2fafff"
54+blue-warmer = "#79a8ff"
55+blue-cooler = "#00bcff"
56+blue-faint = "#82b0ec"
57+blue-intense = "#338fff"
58+magenta = "#feacd0"
59+magenta-warmer = "#f78fe7"
60+magenta-cooler = "#b6a0ff"
61+magenta-faint = "#caa6df"
62+magenta-intense = "#ff66ff"
63+cyan = "#00d3d0"
64+cyan-warmer = "#4ae2f0"
65+cyan-cooler = "#6ae4b9"
66+cyan-faint = "#9ac8e0"
67+cyan-intense = "#00eff0"
68+
69+# Uncommon accent foregrounds
70+rust = "#db7b5f"
71+gold = "#c0965b"
72+olive = "#9cbd6f"
73+slate = "#76afbf"
74+indigo = "#9099d9"
75+maroon = "#cf7fa7"
76+pink = "#d09dc0"
77+
78+# Common accent backgrounds
79+bg-red-intense = "#9d1f1f"
80+bg-green-intense = "#2f822f"
81+bg-yellow-intense = "#7a6100"
82+bg-blue-intense = "#1640b0"
83+bg-magenta-intense = "#7030af"
84+bg-cyan-intense = "#2266ae"
85+
86+bg-red-subtle = "#620f2a"
87+bg-green-subtle = "#00422a"
88+bg-yellow-subtle = "#4a4000"
89+bg-blue-subtle = "#242679"
90+bg-magenta-subtle = "#552f5f"
91+bg-cyan-subtle = "#004065"
92+
93+bg-red-nuanced = "#2c0614"
94+bg-green-nuanced = "#001904"
95+bg-yellow-nuanced = "#221000"
96+bg-blue-nuanced = "#0f0e39"
97+bg-magenta-nuanced = "#230631"
98+bg-cyan-nuanced = "#041529"
99+
100+# Uncommon accent backgrounds
101+bg-ochre = "#442c2f"
102+bg-lavender = "#38325c"
103+bg-sage = "#0f3d30"
104+
105+# Special purpose
106+bg-completion = "#2f447f"
107+bg-hover = "#45605e"
108+bg-hover-secondary = "#654a39"
109+bg-hl-line = "#2f3849"
110+bg-region = "#5a5a5a"
111+fg-region = "#ffffff"
112+
113+bg-char-0 = "#0050af"
114+bg-char-1 = "#7f1f7f"
115+bg-char-2 = "#625a00"
116+
117+bg-mode-line-active = "#2a2a6a"
118+fg-mode-line-active = "#f0f0f0"
119+border-mode-line-active = "#8080a7"
120+bg-mode-line-inactive = "#2d2d2d"
121+fg-mode-line-inactive = "#969696"
122+border-mode-line-inactive = "#606060"
123+
124+modeline-err = "#e5bf00"
125+modeline-warning = "#c0cf35"
126+modeline-info = "#abeadf"
127+
128+bg-tab-bar = "#313131"
129+bg-tab-current = "#000000"
130+bg-tab-other = "#545454"
131+
132+# Diffs
133+bg-added = "#003066"
134+bg-added-faint = "#001a4f"
135+bg-added-refine = "#0f4a77"
136+bg-added-fringe = "#006fff"
137+fg-added = "#c4d5ff"
138+fg-added-intense = "#8080ff"
139+
140+bg-changed = "#2f123f"
141+bg-changed-faint = "#1f022f"
142+bg-changed-refine = "#3f325f"
143+bg-changed-fringe = "#7f55a0"
144+fg-changed = "#e3cfff"
145+fg-changed-intense = "#cf9fe2"
146+
147+bg-removed = "#3d3d00"
148+bg-removed-faint = "#281f00"
149+bg-removed-refine = "#555500"
150+bg-removed-fringe = "#d0c03f"
151+fg-removed = "#d4d48f"
152+fg-removed-intense = "#d0b05f"
153+
154+bg-diff-context = "#1a1a1a"
155+
156+# Paren match
157+bg-paren-match = "#2f7f9f"
158+bg-paren-expression = "#453040"
runtime/themes/modus_vivendi_tinted.tomlnew file+144
@@ -0,0 +1,144 @@
1+# Author: Matous Dzivjak <matousdzivjak@gmail.com>
2+# Adapted from: https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
3+# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tinted-theme.el
4+# Version 4.3.0
5+
6+inherits = "modus_vivendi"
7+
8+"comment" = "red-faint"
9+
10+"ui.cursor.primary" = { fg = "bg-main", bg = "red" }
11+
12+[palette]
13+# Basic values
14+bg-main = "#0d0e1c"
15+bg-dim = "#1d2235"
16+fg-main = "#ffffff"
17+fg-dim = "#989898"
18+fg-alt = "#c6daff"
19+bg-active = "#4a4f69"
20+bg-inactive = "#2b3045"
21+border = "#61647a"
22+
23+# Common accent foregrounds
24+red = "#ff5f59"
25+red-warmer = "#ff6b55"
26+red-cooler = "#ff7f9f"
27+red-faint = "#ff9f80"
28+red-intense = "#ff5f5f"
29+green = "#44bc44"
30+green-warmer = "#70b900"
31+green-cooler = "#00c06f"
32+green-faint = "#88ca9f"
33+green-intense = "#44df44"
34+yellow = "#d0bc00"
35+yellow-warmer = "#fec43f"
36+yellow-cooler = "#dfaf7a"
37+yellow-faint = "#d2b580"
38+yellow-intense = "#efef00"
39+blue = "#2fafff"
40+blue-warmer = "#79a8ff"
41+blue-cooler = "#00bcff"
42+blue-faint = "#82b0ec"
43+blue-intense = "#338fff"
44+magenta = "#feacd0"
45+magenta-warmer = "#f78fe7"
46+magenta-cooler = "#b6a0ff"
47+magenta-faint = "#caa6df"
48+magenta-intense = "#ff66ff"
49+cyan = "#00d3d0"
50+cyan-warmer = "#4ae2f0"
51+cyan-cooler = "#6ae4b9"
52+cyan-faint = "#9ac8e0"
53+cyan-intense = "#00eff0"
54+
55+# Uncommon accent foregrounds
56+rust = "#db7b5f"
57+gold = "#c0965b"
58+olive = "#9cbd6f"
59+slate = "#76afbf"
60+indigo = "#9099d9"
61+maroon = "#cf7fa7"
62+pink = "#d09dc0"
63+
64+# Common accent backgrounds
65+bg-red-intense = "#9d1f1f"
66+bg-green-intense = "#2f822f"
67+bg-yellow-intense = "#7a6100"
68+bg-blue-intense = "#1640b0"
69+bg-magenta-intense = "#7030af"
70+bg-cyan-intense = "#2266ae"
71+
72+bg-red-subtle = "#620f2a"
73+bg-green-subtle = "#00422a"
74+bg-yellow-subtle = "#4a4000"
75+bg-blue-subtle = "#242679"
76+bg-magenta-subtle = "#552f5f"
77+bg-cyan-subtle = "#004065"
78+
79+bg-red-nuanced = "#350f14"
80+bg-green-nuanced = "#002718"
81+bg-yellow-nuanced = "#2c1f00"
82+bg-blue-nuanced = "#131c4d"
83+bg-magenta-nuanced = "#2f133f"
84+bg-cyan-nuanced = "#04253f"
85+
86+# Special purpose
87+bg-completion = "#483d8a"
88+bg-hover = "#45605e"
89+bg-hover-secondary = "#654a39"
90+bg-hl-line = "#303a6f"
91+bg-region = "#555a66"
92+fg-region = "#ffffff"
93+
94+bg-char-0 = "#0050af"
95+bg-char-1 = "#7f1f7f"
96+bg-char-2 = "#625a00"
97+
98+bg-mode-line-active = "#484d67"
99+fg-mode-line-active = "#ffffff"
100+border-mode-line-active = "#979797"
101+bg-mode-line-inactive = "#292d48"
102+fg-mode-line-inactive = "#969696"
103+border-mode-line-inactive = "#606270"
104+
105+modeline-err = "#ffa9bf"
106+modeline-warning = "#dfcf43"
107+modeline-info = "#9fefff"
108+
109+bg-tab-bar = "#2c3045"
110+bg-tab-current = "#0d0e1c"
111+bg-tab-other = "#4a4f6a"
112+
113+# Diffs
114+bg-added = "#003a2f"
115+bg-added-faint = "#002922"
116+bg-added-refine = "#035542"
117+bg-added-fringe = "#23884f"
118+fg-added = "#a0e0a0"
119+fg-added-intense = "#80e080"
120+
121+bg-changed = "#363300"
122+bg-changed-faint = "#2a1f00"
123+bg-changed-refine = "#4a4a00"
124+bg-changed-fringe = "#8f7a30"
125+fg-changed = "#efef80"
126+fg-changed-intense = "#c0b05f"
127+
128+bg-removed = "#4f1127"
129+bg-removed-faint = "#380a19"
130+bg-removed-refine = "#781a3a"
131+bg-removed-fringe = "#b81a26"
132+fg-removed = "#ffbfbf"
133+fg-removed-intense = "#ff9095"
134+
135+bg-diff-context = "#1a1f30"
136+
137+# Uncommon accent backgrounds
138+bg-ochre = "#442c2f"
139+bg-lavender = "#38325c"
140+bg-sage = "#0f3d30"
141+
142+# Paren match
143+bg-paren-match = "#2f7f9f"
144+bg-paren-expression = "#453040"
runtime/themes/modus_vivendi_tritanopia.tomlnew file+186
@@ -0,0 +1,186 @@
1+# Author: Matous Dzivjak <matousdzivjak@gmail.com>
2+# Adapted from https://protesilaos.com/emacs/modus-themes, by Protesilaos Stavrou
3+# Source: https://github.com/protesilaos/modus-themes/blob/main/modus-vivendi-tritanopia-theme.el
4+# Version 4.3.0
5+
6+inherits = "modus_vivendi"
7+
8+"type" = "blue-warmer"
9+"constructor" = "blue-warmer"
10+"constant" = "green-cooler"
11+"constant.character.escape" = "red-cooler"
12+"string" = "cyan"
13+"comment" = "red-faint"
14+"variable.parameter" = "cyan-cooler"
15+"keyword" = "red-cooler"
16+"keyword.directive" = "red-warmer"
17+"function" = "cyan-warmer"
18+"function.macro" = "magenta"
19+"tag" = "red-cooler"
20+
21+"markup.heading.2" = { fg = "red-faint", modifiers = ["bold"] }
22+"markup.heading.3" = { fg = "cyan-faint", modifiers = ["bold"] }
23+"markup.heading.6" = { fg = "magenta-faint", modifiers = ["bold"] }
24+"markup.link.url" = { fg = "cyan-cooler" }
25+"markup.link.text" = { fg = "cyan", modifiers = ["underlined"] }
26+
27+"ui.cursor" = { fg = "bg-main", bg = "red-intense" }
28+"ui.cursor.primary.normal" = { fg = "bg-main", bg = "red-intense" }
29+
30+"diagnostic.error" = { underline = { color = "red-warmer", style = "curl" } }
31+"diagnostic.warning" = { underline = { color = "magenta", style = "curl" } }
32+"diagnostic.info" = { underline = { color = "cyan", style = "curl" } }
33+"diagnostic.hint" = { underline = { color = "blue", style = "curl" } }
34+
35+error = "red-warmer"
36+warning = "magenta"
37+info = "cyan"
38+hint = "blue"
39+
40+[palette]
41+# Basic values
42+bg-main = "#000000"
43+bg-dim = "#1e1e1e"
44+fg-main = "#ffffff"
45+fg-dim = "#989898"
46+fg-alt = "#c6daff"
47+bg-active = "#535353"
48+bg-inactive = "#303030"
49+border = "#646464"
50+
51+# Common accent foregrounds
52+red = "#ff5f59"
53+red-warmer = "#ff6740"
54+red-cooler = "#ff6f9f"
55+red-faint = "#ff9070"
56+red-intense = "#ff5f5f"
57+green = "#44bc44"
58+green-warmer = "#70b900"
59+green-cooler = "#00c06f"
60+green-faint = "#88ca9f"
61+green-intense = "#44df44"
62+yellow = "#cabf00"
63+yellow-warmer = "#ffa00f"
64+yellow-cooler = "#d8af7a"
65+yellow-faint = "#d2b580"
66+yellow-intense = "#efef00"
67+blue = "#2fafff"
68+blue-warmer = "#79a8ff"
69+blue-cooler = "#00bcff"
70+blue-faint = "#82b0ec"
71+blue-intense = "#338fff"
72+magenta = "#feacd0"
73+magenta-warmer = "#f78fe7"
74+magenta-cooler = "#b6a0ff"
75+magenta-faint = "#caa6df"
76+magenta-intense = "#ef7fff"
77+cyan = "#00d3d0"
78+cyan-warmer = "#4ae2ff"
79+cyan-cooler = "#6ae4b9"
80+cyan-faint = "#7fdbdf"
81+cyan-intense = "#00eff0"
82+
83+# Uncommon accent foregrounds
84+rust = "#db7b5f"
85+gold = "#c0965b"
86+olive = "#9cbd6f"
87+slate = "#76afbf"
88+indigo = "#9099d9"
89+maroon = "#cf7fa7"
90+pink = "#d09dc0"
91+
92+# Common accent backgrounds
93+bg-red-intense = "#9d1f1f"
94+bg-green-intense = "#2f822f"
95+bg-yellow-intense = "#7a6100"
96+bg-blue-intense = "#1640b0"
97+bg-magenta-intense = "#7030af"
98+bg-cyan-intense = "#2266ae"
99+
100+bg-red-subtle = "#620f2a"
101+bg-green-subtle = "#00422a"
102+bg-yellow-subtle = "#4a4000"
103+bg-blue-subtle = "#242679"
104+bg-magenta-subtle = "#552f5f"
105+bg-cyan-subtle = "#004065"
106+
107+bg-red-nuanced = "#2c0614"
108+bg-green-nuanced = "#001904"
109+bg-yellow-nuanced = "#221000"
110+bg-blue-nuanced = "#0f0e39"
111+bg-magenta-nuanced = "#230631"
112+bg-cyan-nuanced = "#041529"
113+
114+# Uncommon accent backgrounds
115+bg-ochre = "#442c2f"
116+bg-lavender = "#38325c"
117+bg-sage = "#0f3d30"
118+
119+# Graphs
120+bg-graph-red-0 = "#b52c2c"
121+bg-graph-red-1 = "#702020"
122+bg-graph-green-0 = "#afd1c0"
123+bg-graph-green-1 = "#607a8f"
124+bg-graph-yellow-0 = "#facfd6"
125+bg-graph-yellow-1 = "#b57b85"
126+bg-graph-blue-0 = "#4f9fdf"
127+bg-graph-blue-1 = "#004559"
128+bg-graph-magenta-0 = "#b6427f"
129+bg-graph-magenta-1 = "#7f506f"
130+bg-graph-cyan-0 = "#57dfea"
131+bg-graph-cyan-1 = "#00808f"
132+
133+# Special purpose
134+bg-completion = "#004253"
135+bg-hover = "#8e3e3b"
136+bg-hover-secondary = "#00405f"
137+bg-hl-line = "#2f3849"
138+bg-region = "#5a5a5a"
139+fg-region = "#ffffff"
140+
141+bg-char-0 = "#922a00"
142+bg-char-1 = "#00709f"
143+bg-char-2 = "#5f3faf"
144+
145+bg-mode-line-active = "#003c52"
146+fg-mode-line-active = "#f0f0f0"
147+border-mode-line-active = "#5f8fb4"
148+bg-mode-line-inactive = "#2d2d2d"
149+fg-mode-line-inactive = "#969696"
150+border-mode-line-inactive = "#606060"
151+
152+modeline-err = "#ff7fbf"
153+modeline-warning = "#df9f93"
154+modeline-info = "#4fcfef"
155+
156+bg-tab-bar = "#313131"
157+bg-tab-current = "#000000"
158+bg-tab-other = "#545454"
159+
160+# Diffs
161+bg-added = "#004254"
162+bg-added-faint = "#003042"
163+bg-added-refine = "#004f7f"
164+bg-added-fringe = "#008fcf"
165+fg-added = "#9fdfdf"
166+fg-added-intense = "#50c0ef"
167+
168+bg-changed = "#2f123f"
169+bg-changed-faint = "#1f022f"
170+bg-changed-refine = "#3f325f"
171+bg-changed-fringe = "#7f55a0"
172+fg-changed = "#e3cfff"
173+fg-changed-intense = "#cf9fe2"
174+
175+bg-removed = "#4f1119"
176+bg-removed-faint = "#380a0f"
177+bg-removed-refine = "#781a1f"
178+bg-removed-fringe = "#b81a1f"
179+fg-removed = "#ffbfbf"
180+fg-removed-intense = "#ff9095"
181+
182+bg-diff-context = "#1a1a1a"
183+
184+# Paren match
185+bg-paren-match = "#2f7f9f"
186+bg-paren-expression = "#453040"
runtime/themes/naysayer.toml+2−2
@@ -20,13 +20,13 @@
20"ui.help" = { fg = "text", bg = "bg" }
20"ui.help" = { fg = "text", bg = "bg" }
21"ui.popup" = { fg = "text", bg = "bg" }
21"ui.popup" = { fg = "text", bg = "bg" }
22"ui.menu" = { fg = "text", bg = "bg" }
22"ui.menu" = { fg = "text", bg = "bg" }
23−"ui.menu.selected" = { fg = "text", bg = "bg" }
23+"ui.menu.selected" = { fg = "text", bg = "bg", modifiers = ['underlined'] }
24"ui.window" = { bg = "bg" }
24"ui.window" = { bg = "bg" }
25"diagnostic.error" = { bg = "error", fg = "text", modifiers = ["bold"] }
25"diagnostic.error" = { bg = "error", fg = "text", modifiers = ["bold"] }
26"diagnostic.warning" = { bg = "warning", fg = "text", modifiers = ["bold"] }
26"diagnostic.warning" = { bg = "warning", fg = "text", modifiers = ["bold"] }
27"diagnostic.hint" = { bg = "cyan", modifiers = ["bold"] }
27"diagnostic.hint" = { bg = "cyan", modifiers = ["bold"] }
28"ui.bufferline" = { fg = "text", bg = "bg" }
28"ui.bufferline" = { fg = "text", bg = "bg" }
29−"ui.bufferline.active" = { fg = "text", bg = "bg" }
29+"ui.bufferline.active" = { fg = "text", bg = "bg", modifiers = ['underlined'] }
30"ui.gutter.selected" = { bg = "highlight-line", modifiers = ["bold"] }
30"ui.gutter.selected" = { bg = "highlight-line", modifiers = ["bold"] }
31"ui.highlight" = { bg = "highlight-line" }
31"ui.highlight" = { bg = "highlight-line" }
32
32
runtime/themes/noctis.toml+25−25
@@ -7,8 +7,8 @@
7
7
8'property' = { fg = "red" } # Regex group names.
8'property' = { fg = "red" } # Regex group names.
9"warning" = { fg ="yellow", modifiers = ["bold"] } # Editor warnings.
9"warning" = { fg ="yellow", modifiers = ["bold"] } # Editor warnings.
10−"error" = { bg = "mid-green", fg = "red", modifiers = ["bold"] } # Editor errors, like mis-typing a command.
10+"error" = { fg = "red", modifiers = ["bold"] } # Editor errors, like mis-typing a command.
11−"info" = { fg = "mid-blue", bg = "mid-green" } # Code diagnostic info in gutter (LSP).
11+"info" = { fg = "mid-blue" } # Code diagnostic info in gutter (LSP).
12# ? Difference between info and hint ?
12# ? Difference between info and hint ?
13"hint" = { fg = "light-green", modifiers = ["bold"] } # Code diagnostics hint in gutter (LSP).
13"hint" = { fg = "light-green", modifiers = ["bold"] } # Code diagnostics hint in gutter (LSP).
14
14
@@ -21,14 +21,14 @@
21# UI ==============================
21# UI ==============================
22# For styling helix itself.
22# For styling helix itself.
23
23
24−'ui.background' = { bg = "dark-green"} # Default background color.
24+'ui.background' = { fg = "autocomp-green", bg = "dark-green" } # Default background color.
25'ui.window' = { fg = "mid-green" } # Window border between splits.
25'ui.window' = { fg = "mid-green" } # Window border between splits.
26
26
27'ui.gutter' = { } # Left gutter for diagnostics and breakpoints.
27'ui.gutter' = { } # Left gutter for diagnostics and breakpoints.
28
28
29'ui.text' = { fg = "white" } # Default text color.
29'ui.text' = { fg = "white" } # Default text color.
30'ui.text.focus' = { fg = "white", bg = "mid-green", modifiers = ["bold"] } # Selection highlight in buffer-picker or file-picker.
30'ui.text.focus' = { fg = "white", bg = "mid-green", modifiers = ["bold"] } # Selection highlight in buffer-picker or file-picker.
31−'ui.text.info' = { } # Info popup contents (space mode menu).
31+'ui.text.info' = { fg = "white" } # Info popup contents (space mode menu).
32
32
33'ui.cursor' = { fg = "dark-green", bg = "white" } # Fallback cursor colour, non-primary cursors when there are multiple (shift-c).
33'ui.cursor' = { fg = "dark-green", bg = "white" } # Fallback cursor colour, non-primary cursors when there are multiple (shift-c).
34'ui.cursor.primary' = { fg = "dark-green", bg = "light-blue" } # The primary cursor when there are multiple (shift-c).
34'ui.cursor.primary' = { fg = "dark-green", bg = "light-blue" } # The primary cursor when there are multiple (shift-c).
@@ -40,8 +40,8 @@
40'ui.selection.primary' = { bg = "autocomp-green" } # The primary selection when there are multiple.
40'ui.selection.primary' = { bg = "autocomp-green" } # The primary selection when there are multiple.
41'ui.cursorline.primary' = { bg = 'mid-green' }
41'ui.cursorline.primary' = { bg = 'mid-green' }
42
42
43−'ui.linenr' = { bg = "dark-green", fg = "gray" } # Line numbers.
43+'ui.linenr' = { fg = "gray" } # Line numbers.
44−'ui.linenr.selected' = { bg = "mid-green", fg = "light-green", modifiers = [ "bold" ] } # Current line number.
44+'ui.linenr.selected' = { fg = "light-green", modifiers = [ "bold" ] } # Current line number.
45
45
46'ui.virtual' = { fg = "mid-green" } # Namespace for additions to the editing area.
46'ui.virtual' = { fg = "mid-green" } # Namespace for additions to the editing area.
47'ui.virtual.ruler' = { bg = "mid-green" } # Vertical rulers (colored columns in editing area).
47'ui.virtual.ruler' = { bg = "mid-green" } # Vertical rulers (colored columns in editing area).
@@ -75,9 +75,9 @@
75#'type.builtin' = { } # Primitive types of the language (string, int, float).
75#'type.builtin' = { } # Primitive types of the language (string, int, float).
76#'type.enum.variant' = { } # A variant of an enum.
76#'type.enum.variant' = { } # A variant of an enum.
77
77
78−'constructor' = { fg = "mid-blue", modifiers = ["bold"]} # Constructor method for a class or struct. And in some cases applies to module names
78+'constructor' = { fg = "light-blue", modifiers = ["bold"]} # Constructor method for a class or struct. And in some cases applies to module names
79
79
80−'constant' = { fg = "light-blue" } # Constant value
80+'constant' = { fg = "light-blue", modifiers = ["bold"] } # Constant value
81'constant.builtin' = { fg = "mid-blue", modifiers = ["bold"] } # Special constants like `true`, `false`, `none`, etc.
81'constant.builtin' = { fg = "mid-blue", modifiers = ["bold"] } # Special constants like `true`, `false`, `none`, etc.
82'constant.builtin.boolean' = { } # True or False.
82'constant.builtin.boolean' = { } # True or False.
83'constant.character' = { fg = "light-green"} # Constant of character type.
83'constant.character' = { fg = "light-green"} # Constant of character type.
@@ -88,21 +88,20 @@
88
88
89'string' = { fg = "light-green" } # String literal.
89'string' = { fg = "light-green" } # String literal.
90'string.regexp' = { } # Regular expression literal.
90'string.regexp' = { } # Regular expression literal.
91−'string.special' = { fg = "light-blue" } # Strings containing a path, URL, etc.
91+'string.special' = { fg = "red" } # Strings containing a path, URL, etc.
92−'string.special.path' = { } # String containing a file path.
92+# 'string.special.path' = { } # String containing a file path.
93−'string.special.url' = { } # String containing a web URL.
93+# 'string.special.url' = { } # String containing a web URL.
94−'string.special.symbol' = { } # Erlang/Elixir atoms, Ruby symbols, Clojure keywords.
94+# 'string.special.symbol' = { } # Erlang/Elixir atoms, Ruby symbols, Clojure keywords.
95
95
96'comment' = { fg = "gray", modifiers = ["italic"] } # This is a comment.
96'comment' = { fg = "gray", modifiers = ["italic"] } # This is a comment.
97'comment.line' = { } # Line comments, like this.
97'comment.line' = { } # Line comments, like this.
98'comment.block' = { } # Block comments, like /* this */ in some languages.
98'comment.block' = { } # Block comments, like /* this */ in some languages.
99'comment.block.documentation' = { } # Doc comments, e.g '///' in rust.
99'comment.block.documentation' = { } # Doc comments, e.g '///' in rust.
100
100
101−'variable' = { fg = "white" } # Variable names.
101+'variable' = { fg = "light-orange" } # Variable names.
102−'variable.builtin' = { } # Language reserved variables: `this`, `self`, `super`, etc.
102+# 'variable.builtin' = { } # Language reserved variables: `this`, `self`, `super`, etc.
103−'variable.parameter' = { } # Function parameters.
103+# 'variable.parameter' = { } # Function parameters.
104−'variable.other.member' = { } # Fields of composite data types (e.g. structs, unions).
104+'variable.other.member' = { fg = "orange" } # Fields of composite data types (e.g. structs, unions).
105−'variable.function' = { } # ?
106
105
107'label' = { fg = "purple" } # Loop labels in rust.
106'label' = { fg = "purple" } # Loop labels in rust.
108
107
@@ -113,17 +112,17 @@
113'keyword' = { fg = "pink", modifiers = ["bold"] } # Language reserved keywords.
112'keyword' = { fg = "pink", modifiers = ["bold"] } # Language reserved keywords.
114'keyword.control' = { fg = "pink", modifiers = ["bold"] } # Control keywords.
113'keyword.control' = { fg = "pink", modifiers = ["bold"] } # Control keywords.
115'keyword.control.conditional' = { fg = "pink", modifiers = ["bold"] } # 'if', 'else', 'elif'.
114'keyword.control.conditional' = { fg = "pink", modifiers = ["bold"] } # 'if', 'else', 'elif'.
116−'keyword.control.repeat' = { } # 'for', 'while', 'loop'.
115+# 'keyword.control.repeat' = { } # 'for', 'while', 'loop'.
117'keyword.control.import' = { fg = "pink", modifiers = ["italic"] } # 'import', 'export' ('use'?).
116'keyword.control.import' = { fg = "pink", modifiers = ["italic"] } # 'import', 'export' ('use'?).
118−'keyword.control.return' = { } # 'return' in most languages.
117+# 'keyword.control.return' = { } # 'return' in most languages.
119'keyword.control.exception' = {fg = "pink", modifiers = ["bold"] } # 'raise' in python.
118'keyword.control.exception' = {fg = "pink", modifiers = ["bold"] } # 'raise' in python.
120−'keyword.operator' = { } # 'or', 'and', 'in'.
119+'keyword.operator' = { fg = "pink" } # 'or', 'and', 'in'.
121'keyword.directive' = { fg = "purple" } # Preprocessor directives (#if in C).
120'keyword.directive' = { fg = "purple" } # Preprocessor directives (#if in C).
122−'keyword.function' = { } # The keyword to define a function: 'def', 'fun', 'fn'.
121+'keyword.function' = { fg= "red" } # The keyword to define a function: 'def', 'fun', 'fn'.
123
122
124'operator' = { fg = "pink", modifiers = ["bold"] } # Logical (&&, ||) and - I assume - Mathematical (+, %) operators
123'operator' = { fg = "pink", modifiers = ["bold"] } # Logical (&&, ||) and - I assume - Mathematical (+, %) operators
125
124
126−'function' = { fg = "dark-blue"}
125+'function' = { fg = "mid-blue"}
127'function.builtin' = { fg = "dark-blue" }
126'function.builtin' = { fg = "dark-blue" }
128'function.method' = { fg = "dark-blue" } # Class / Struct methods.
127'function.method' = { fg = "dark-blue" } # Class / Struct methods.
129'function.macro' = { fg = "purple" } # Like macros in rust.
128'function.macro' = { fg = "purple" } # Like macros in rust.
@@ -181,8 +180,8 @@
181# Version control changes.
180# Version control changes.
182
181
183'diff.plus' = "light-green" # { } # Additions.
182'diff.plus' = "light-green" # { } # Additions.
184−'diff.minus' = "yellow" # { } # Deletions.
183+'diff.minus' = "red" # { } # Deletions.
185−'diff.delta' = "red" # { } # Modifications.
184+'diff.delta' = "yellow" # { } # Modifications.
186# 'diff.delta.moved' = { } # Renamed or moved files / changes.
185# 'diff.delta.moved' = { } # Renamed or moved files / changes.
187
186
188
187
@@ -197,8 +196,9 @@ yellow = "#ffd800"
197purple = "#918cff"
196purple = "#918cff"
198white = "#b1cace"
197white = "#b1cace"
199orange = "#ffa864"
198orange = "#ffa864"
199+light-orange = "#fff2c5"
200gray = "#5b858b" # mainly for comments/background text
200gray = "#5b858b" # mainly for comments/background text
201−light-gray = "#354e51" # used when whitespace rendering is enabled and for indent-guides
201+light-gray = "#2a3c41" # used when whitespace rendering is enabled and for indent-guides
202red = "#e34e1b"
202red = "#e34e1b"
203
203
204dark-blue = "#19a2b7"
204dark-blue = "#19a2b7"
runtime/themes/nord-night.tomlnew file+23
@@ -0,0 +1,23 @@
1+# Nord Night
2+#
3+# Based on the Nord theme, with minor modifications.
4+# The Background and the Primary Text color have been slightly darkened.
5+# The Aurora color palette has been used more generously.
6+
7+inherits = 'nord'
8+
9+'constant' = 'nord13'
10+'constant.builtin.boolean' = 'nord13'
11+'constant.numeric' = 'nord13'
12+
13+'keyword.control' = 'nord11'
14+'keyword.control.conditional' = 'nord11'
15+'keyword.control.exception' = 'nord11'
16+'keyword.control.repeat' = 'nord11'
17+'keyword.control.return' = 'nord11'
18+
19+'variable.parameter' = 'nord15'
20+
21+[palette]
22+nord0 = '#252933'
23+nord4 = '#C0C5CF'
runtime/themes/nord.toml+16−7
@@ -50,7 +50,7 @@
50"keyword.operator" = "nord9"
50"keyword.operator" = "nord9"
51"keyword.return" = "nord9"
51"keyword.return" = "nord9"
52"keyword.storage.modifier" = "nord9"
52"keyword.storage.modifier" = "nord9"
53−"keyword.storage.type" = "nord7"
53+"keyword.storage.type" = "nord9"
54
54
55# Punctuation
55# Punctuation
56"punctuation" = "nord6"
56"punctuation" = "nord6"
@@ -65,22 +65,22 @@
65"string.special" = "nord13"
65"string.special" = "nord13"
66
66
67# Types
67# Types
68−"type" = "nord4"
68+"type" = "nord7"
69"type.builtin" = "nord7"
69"type.builtin" = "nord7"
70
70
71# Variables
71# Variables
72"variable" = "nord4"
72"variable" = "nord4"
73−"variable.builint" = "nord9"
73+"variable.builtin" = "nord9"
74"variable.other.member" = "nord4"
74"variable.other.member" = "nord4"
75"variable.parameter" = "nord8"
75"variable.parameter" = "nord8"
76−"attribute" = "nord4"
76+"attribute" = "nord9"
77
77
78# Misc.
78# Misc.
79"label" = "nord7"
79"label" = "nord7"
80"namespace" = "nord4"
80"namespace" = "nord4"
81"operator" = "nord9"
81"operator" = "nord9"
82−"special" = "nord4"
82+"special" = "nord9"
83−"tag" = "nord4"
83+"tag" = "nord7"
84"comment" = { fg = "nord3_bright", modifiers = ["italic"] }
84"comment" = { fg = "nord3_bright", modifiers = ["italic"] }
85
85
86## EDITOR UI COLORS
86## EDITOR UI COLORS
@@ -134,6 +134,15 @@
134"ui.bufferline" = { fg = "nord5", bg = "nord1" }
134"ui.bufferline" = { fg = "nord5", bg = "nord1" }
135"ui.bufferline.active" = { fg = "nord6", bg = "nord2", underline = { color = "nord8", style = "line" }, modifiers = [ "italic" ] }
135"ui.bufferline.active" = { fg = "nord6", bg = "nord2", underline = { color = "nord8", style = "line" }, modifiers = [ "italic" ] }
136
136
137+# Markup
138+"markup.heading" = "nord8"
139+"markup.list" = "nord9"
140+"markup.bold" = { modifiers = ["bold"] }
141+"markup.italic" = { modifiers = ["italic"] }
142+"markup.strikethrough" = { modifiers = ["crossed_out"] }
143+"markup.link.text" = "nord8"
144+"markup.raw" = "nord7"
145+
137[palette]
146[palette]
138# Polar Night is made up of four darker colors that are commonly used for base elements like backgrounds or text color in bright ambiance designs.
147# Polar Night is made up of four darker colors that are commonly used for base elements like backgrounds or text color in bright ambiance designs.
139#
148#
@@ -165,7 +174,7 @@ nord8 = "#88C0D0"
165# A more darkened and less saturated color reminiscent of arctic waters
174# A more darkened and less saturated color reminiscent of arctic waters
166nord9 = "#81A1C1"
175nord9 = "#81A1C1"
167# A dark and intensive color reminiscent of the deep arctic ocean
176# A dark and intensive color reminiscent of the deep arctic ocean
168− nord10 = "#5E81AC"
177+nord10 = "#5E81AC"
169
178
170# Aurora consists of five colorful components reminiscent of the "Aurora borealis", sometimes referred to as polar lights or northern lights.
179# Aurora consists of five colorful components reminiscent of the "Aurora borealis", sometimes referred to as polar lights or northern lights.
171#
180#
runtime/themes/onedark.toml+1
@@ -1,5 +1,6 @@
1# Author : Gokul Soumya <gokulps15@gmail.com>
1# Author : Gokul Soumya <gokulps15@gmail.com>
2
2
3+"tag" = { fg = "red" }
3"attribute" = { fg = "yellow" }
4"attribute" = { fg = "yellow" }
4"comment" = { fg = "light-gray", modifiers = ["italic"] }
5"comment" = { fg = "light-gray", modifiers = ["italic"] }
5"constant" = { fg = "cyan" }
6"constant" = { fg = "cyan" }
runtime/themes/papercolor-light.toml+4
@@ -26,6 +26,9 @@
26"ui.virtual.whitespace" = { fg = "regular5" }
26"ui.virtual.whitespace" = { fg = "regular5" }
27"ui.virtual.indent-guide" = { fg = "bright0" }
27"ui.virtual.indent-guide" = { fg = "bright0" }
28"ui.virtual.ruler" = { bg = "cursorline_secondary_bg", fg = "regular4" }
28"ui.virtual.ruler" = { bg = "cursorline_secondary_bg", fg = "regular4" }
29+"ui.virtual.inlay-hint" = { fg = "regular5", modifiers = ["italic"] }
30+"ui.virtual.inlay-hint.parameter" = { fg = "regular5", modifiers = ["italic"] }
31+"ui.virtual.inlay-hint.type" = { fg = "regular5", modifiers = ["bold", "italic"] }
29"ui.cursor.match" = { bg = "matchparen_bg", fg = "matchparen_fg" }
32"ui.cursor.match" = { bg = "matchparen_bg", fg = "matchparen_fg" }
30"ui.cursor" = { bg = "regular5", fg = "background" }
33"ui.cursor" = { bg = "regular5", fg = "background" }
31"ui.cursor.primary" = { bg = "foreground", fg = "background" }
34"ui.cursor.primary" = { bg = "foreground", fg = "background" }
@@ -52,6 +55,7 @@
52
55
53"type" = { fg = "bright2", modifiers = ["bold"] }
56"type" = { fg = "bright2", modifiers = ["bold"] }
54"type.builtin" = { fg = "bright2", modifiers = ["bold"] }
57"type.builtin" = { fg = "bright2", modifiers = ["bold"] }
58+"type.parameter" = { fg = "foreground" }
55"type.enum" = { fg = "foreground" }
59"type.enum" = { fg = "foreground" }
56"type.enum.variant" = { fg = "foreground" }
60"type.enum.variant" = { fg = "foreground" }
57
61
runtime/themes/poimandres.tomlnew file+113
@@ -0,0 +1,113 @@
1+# Author: Ambuj Kumar <ambujs89@gmail.com>
2+# Ported from: https://github.com/drcmda/poimandres-theme
3+
4+attribute = { fg = "desaturatedBlue", modifiers = ["italic"] }
5+keyword = "brightMint"
6+"keyword.directive" = "gray"
7+"keyword.storage.type" = "desaturatedBlue"
8+"keyword.storage.modifier" = "lowerMint"
9+"keyword.other" = "brightMint"
10+"keyword.operator" = "desaturatedBlue"
11+namespace = "lightBlue"
12+punctuation = "gray"
13+"punctuation.bracket" = "desaturatedBlue"
14+operator = "desaturatedBlue"
15+special = "desaturatedBlue"
16+variable = "offWhite"
17+"variable.parameter" = { fg = "offWhite" }
18+"variable.builtin" = { fg = "lightBlue", modifiers = ["italic"] }
19+"variable.other" = "offWhite"
20+type = { fg = "gray.c0" }
21+"type.builtin" = { fg = "desaturatedBlue" }
22+constructor = "lightBlue"
23+function = "lightBlue"
24+"function.method" = { fg = "lightBlue" }
25+tag = "brightMint"
26+comment = { fg = "darkerGray.b0", modifiers = ["italic"] }
27+constant = "brightMint"
28+"constant.character.escape" = { fg = "offWhite" }
29+"constant.numeric" = { fg = "brightMint" }
30+"constant.builtin" = { fg = "hotRed" }
31+label = { fg = "gray.c0" }
32+string = { fg = "brightMint" }
33+
34+# Markup
35+"markup.heading" = { fg = "brightMint" }
36+"markup.bold" = { fg = "bluishGrayBrighter", modifiers = ["bold"] }
37+"markup.italic" = { fg = "bluishGrayBrighter", modifiers = ["italic"] }
38+"markup.strikethrough" = { modifiers = ["italic", "crossed_out"] }
39+
40+# UI
41+"markup.link.url" = { fg = "lightBlue", modifiers = ["underlined"] }
42+"markup.link.text" = { fg = "lightBlue", modifiers = ["underlined"] }
43+"markup.raw" = { fg = "lightBlue" }
44+
45+"ui.background" = { bg = "bg" }
46+"ui.background.separator" = { fg = "darkerGray" }
47+"ui.linenr" = "darkerGray.50"
48+"ui.linenr.selected" = "offWhite"
49+"ui.cursor" = { bg = "gray", fg = "bg" }
50+"ui.cursor.match" = { bg = "focus" }
51+"ui.cursorline" = { bg = "#242837" }
52+
53+"ui.popup" = { bg = "#20232d" }
54+"ui.window" = "gray"
55+
56+"ui.text" = "gray"
57+"ui.text.focus" = { fg = "offWhite", bg = "focus", modifiers = ["bold"] }
58+"ui.text.inactive" = "darkerGray"
59+"ui.virtual" = { fg = "darkerGray.b0" }
60+"ui.virtual.indent-guide" = "#303442"
61+
62+"ui.selection" = { bg = "focus" }
63+"ui.selection.primary" = { bg = "selection" }
64+
65+"ui.menu" = { fg = "offWhite", bg = "bg" }
66+"ui.menu.selected" = { fg = "bg", bg = "gray" }
67+"ui.menu.scroll" = { fg = "gray", bg = "bg" }
68+
69+"ui.statusline" = { fg = "offWhite", bg = "selection" }
70+"ui.statusline.inactive" = { fg = "lightBlue", bg = "bg" }
71+"ui.statusline.normal" = { bg = "lightBlue", fg = "bg", modifiers = ["bold"] }
72+"ui.statusline.insert" = { bg = "brightMint", fg = "bg", modifiers = ["bold"] }
73+"ui.statusline.select" = { bg = "hotRed", fg = "bg", modifiers = ["bold"] }
74+
75+"diagnostic.hint" = { underline = { color = "lowerMint", style = "curl" } }
76+"diagnostic.info" = { underline = { color = "lightBlue", style = "curl" } }
77+"diagnostic.warning" = { underline = { color = "brightYellow", style = "curl" } }
78+"diagnostic.error" = { underline = { color = "hotRed", style = "curl" } }
79+
80+hint = "lowerMint"
81+info = "lightBlue"
82+warning = "brightYellow"
83+error = "hotRed"
84+
85+# Version Control
86+"diff.plus" = "lowerMint"
87+"diff.minus" = "hotRed"
88+"diff.delta" = "lightBlue"
89+
90+[palette]
91+brightYellow = "#fffac2"
92+brightMint = "#5DE4c7"
93+lowerMint = "#5fb3a1"
94+blueishGreen = "#42675A"
95+lowerBlue = "#89ddff"
96+lightBlue = "#ADD7FF"
97+desaturatedBlue = "#91B4D5"
98+bluishGrayBrighter = "#7390AA"
99+hotRed = "#d0679d"
100+pink = "#f087bd"
101+gray = "#a6accd"
102+"gray.c0" = "#98a0c2"
103+darkerGray = "#767c9d"
104+"darkerGray.50" = "#404559"
105+"darkerGray.b0" = "#6c7494"
106+bluishGray = "#506477"
107+focus = "#303340"
108+bg = "#1b1e28"
109+offWhite = "#e4f0fb"
110+selection = "#30354a"
111+white = "#ffffff"
112+black = "#000000"
113+transparent = "#00000000"
runtime/themes/poimandres_storm.tomlnew file+19
@@ -0,0 +1,19 @@
1+# Author: Ambuj Kumar <ambujs89@gmail.com>
2+# Ported from: https://github.com/drcmda/poimandres-theme
3+
4+inherits = "poimandres"
5+
6+"ui.cursorline" = { bg = "#303747" }
7+"ui.popup" = { bg = "#2a303c" }
8+"ui.virtual.indent-guide" = "#3a4151"
9+
10+[palette]
11+"gray.c0" = "#98a2c4"
12+darkerGray = "#868cad"
13+"darkerGray.50" = "#4f576d"
14+"darkerGray.b0" = "#818cae"
15+bluishGray = "#607487"
16+focus = "#404350"
17+bg = "#252b37"
18+selection = "#3d455c"
19+black = "#101010"
runtime/themes/rose_pine.toml+30−28
@@ -10,7 +10,7 @@
10"ui.cursor" = { fg = "text", bg = "highlight_high" }
10"ui.cursor" = { fg = "text", bg = "highlight_high" }
11# "ui.cursor.select" = {}
11# "ui.cursor.select" = {}
12"ui.cursor.match" = { fg = "text", bg = "highlight_med" }
12"ui.cursor.match" = { fg = "text", bg = "highlight_med" }
13−"ui.cursor.primary" = { fg = "text", bg = "muted"}
13+"ui.cursor.primary" = { fg = "text", bg = "muted" }
14
14
15# "ui.gutter" = {}
15# "ui.gutter" = {}
16# "ui.gutter.selected" = {}
16# "ui.gutter.selected" = {}
@@ -18,6 +18,8 @@
18"ui.linenr" = { fg = "muted" }
18"ui.linenr" = { fg = "muted" }
19"ui.linenr.selected" = { fg = "text" }
19"ui.linenr.selected" = { fg = "text" }
20
20
21+"ui.bufferline" = { fg = "muted", bg = "base" }
22+"ui.bufferline.active" = { fg = "text", bg = "overlay" }
21"ui.statusline" = { fg = "subtle", bg = "surface" }
23"ui.statusline" = { fg = "subtle", bg = "surface" }
22"ui.statusline.inactive" = { fg = "muted", bg = "surface" }
24"ui.statusline.inactive" = { fg = "muted", bg = "surface" }
23"ui.statusline.normal" = { fg = "rose", bg = "rose_10" }
25"ui.statusline.normal" = { fg = "rose", bg = "rose_10" }
@@ -71,8 +73,8 @@
71"constructor" = "foam"
73"constructor" = "foam"
72
74
73"constant" = "foam"
75"constant" = "foam"
74−"constant.builtin" = "rose"
76+"constant.builtin" = "love"
75−# "constant.builtin.boolean" = ""
77+"constant.builtin.boolean" = "rose"
76"constant.character" = "gold"
78"constant.character" = "gold"
77"constant.character.escape" = "pine"
79"constant.character.escape" = "pine"
78"constant.numeric" = "gold"
80"constant.numeric" = "gold"
@@ -86,7 +88,7 @@
86# "string.special.url" = ""
88# "string.special.url" = ""
87# "string.special.symbol" = ""
89# "string.special.symbol" = ""
88
90
89−"comment" = { fg = "muted", modifiers = ["italic"]}
91+"comment" = { fg = "muted", modifiers = ["italic"] }
90# "comment.line" = ""
92# "comment.line" = ""
91# "comment.block" = ""
93# "comment.block" = ""
92# "comment.block.documentation" = ""
94# "comment.block.documentation" = ""
@@ -95,7 +97,7 @@
95"variable.builtin" = "love"
97"variable.builtin" = "love"
96"variable.parameter" = "iris"
98"variable.parameter" = "iris"
97# "variable.other" = ""
99# "variable.other" = ""
98−# "variable.other.member" = ""
100+"variable.other.member" = "foam"
99
101
100"label" = "foam"
102"label" = "foam"
101
103
@@ -120,7 +122,7 @@
120
122
121"operator" = "subtle"
123"operator" = "subtle"
122
124
123−"function" = "rose" # maybe pine
125+"function" = "rose" # maybe pine
124"function.builtin" = "love"
126"function.builtin" = "love"
125# "function.method" = ""
127# "function.method" = ""
126# "function.macro" = ""
128# "function.macro" = ""
@@ -128,7 +130,7 @@
128
130
129"tag" = "foam"
131"tag" = "foam"
130
132
131−"namespace" = "iris"
133+"namespace" = "text"
132
134
133"markup.heading.marker" = "muted"
135"markup.heading.marker" = "muted"
134"markup.heading" = { fg = "iris", modifiers = ["bold"] }
136"markup.heading" = { fg = "iris", modifiers = ["bold"] }
@@ -147,7 +149,7 @@
147"markup.italic" = { modifiers = ["italic"] }
149"markup.italic" = { modifiers = ["italic"] }
148"markup.strikethrough" = { modifiers = ["crossed_out"] }
150"markup.strikethrough" = { modifiers = ["crossed_out"] }
149"markup.link" = "iris"
151"markup.link" = "iris"
150−"markup.link.url" = { fg = "iris", underline = { color = "iris", style = "line" } }
152+"markup.link.url" = { fg = "iris", underline = { color = "iris", style = "line" } }
151"markup.link.label" = "subtle"
153"markup.link.label" = "subtle"
152"markup.link.text" = "text"
154"markup.link.text" = "text"
153"markup.quote" = "subtle"
155"markup.quote" = "subtle"
@@ -167,24 +169,24 @@
167# "diff.delta.moved" = ""
169# "diff.delta.moved" = ""
168
170
169[palette]
171[palette]
170−base = "#191724"
172+base = "#191724"
171−surface = "#1f1d2e"
173+surface = "#1f1d2e"
172−overlay = "#26233a"
174+overlay = "#26233a"
173−muted = "#6e6a86"
175+muted = "#6e6a86"
174−subtle = "#908caa"
176+subtle = "#908caa"
175−text = "#e0def4"
177+text = "#e0def4"
176−love = "#eb6f92"
178+love = "#eb6f92"
177−love_10 = "#311f30"
179+love_10 = "#311f30"
178−gold = "#f6c177"
180+gold = "#f6c177"
179−gold_10 = "#30282c"
181+gold_10 = "#30282c"
180−rose = "#ebbcba"
182+rose = "#ebbcba"
181−rose_10 = "#2f2834"
183+rose_10 = "#2f2834"
182−pine = "#31748f"
184+pine = "#31748f"
183−pine_10 = "#1a2030"
185+pine_10 = "#1a2030"
184−foam = "#9ccfd8"
186+foam = "#9ccfd8"
185−foam_10 = "#252937"
187+foam_10 = "#252937"
186−iris = "#c4a7e7"
188+iris = "#c4a7e7"
187−iris_10 = "#2b2539"
189+iris_10 = "#2b2539"
188−highlight_low = "#21202e"
190+highlight_low = "#21202e"
189−highlight_med = "#403d52"
191+highlight_med = "#403d52"
190highlight_high = "#524f67"
192highlight_high = "#524f67"
runtime/themes/starlight.tomlnew file+113
@@ -0,0 +1,113 @@
1+# Author : eemilhaa <eemil.haapanen@gmail.com>
2+# Palette from : https://github.com/CosmicToast/starlight
3+
4+# Syntax
5+"function" = "green"
6+"constructor" = "green"
7+
8+"type" = "cyan"
9+"string.special" = "cyan"
10+"string.regexp" = "cyan"
11+"constant" = "cyan"
12+"punctuation.special" = "cyan"
13+
14+"namespace" = "white"
15+"module" = "white"
16+"variable" = "white"
17+
18+"attribute" = "magenta"
19+"variable.parameter" = "magenta"
20+"variable.other.member" = "magenta"
21+"type.parameter" = "magenta"
22+
23+"keyword" = "blue"
24+"variable.builtin" = "blue"
25+"label" = "blue"
26+"tag" = "blue"
27+"operator" = "blue"
28+"special" = "blue"
29+
30+"string" = "yellow"
31+
32+"punctuation" = "punct"
33+
34+"comment" = "dark-fg"
35+
36+# Markup
37+"markup.heading.marker" = { fg = "blue", modifiers = ["bold"] }
38+"markup.heading" = { fg = "white", modifiers = ["bold"] }
39+"markup.list" = "blue"
40+"markup.bold" = { fg = "magenta", modifiers = ["bold"] }
41+"markup.italic" = { fg = "magenta", modifiers = ["italic"] }
42+"markup.strikethrough" = "red"
43+"markup.link" = "cyan"
44+"markup.link.text" = "yellow"
45+"markup.quote" = "magenta"
46+"markup.raw" = "green"
47+
48+# UI
49+"diff.plus" = "green"
50+"diff.minus" = "red"
51+"diff.delta" = "blue"
52+
53+"ui.background" = { fg = "dark-fg", bg = "dark-bg" }
54+"ui.cursor" = { fg = "black", bg = "light-fg" }
55+"ui.cursor.primary" = { fg = "black", bg = "yellow" }
56+"ui.cursor.match" = { fg = "black", bg = "dark-blue", modifiers = ["bold"] }
57+"ui.linenr" = "dark-fg"
58+"ui.linenr.selected" = "yellow"
59+"ui.statusline" = { fg = "light-fg", bg = "light-bg" }
60+"ui.statusline.inactive" = { fg = "dark-fg", bg = "light-bg" }
61+"ui.statusline.insert" = { fg = "black", bg = "green" }
62+"ui.statusline.select" = { fg = "black", bg = "magenta" }
63+"ui.statusline.normal" = { fg = "black", bg = "blue" }
64+"ui.popup" = { fg = "dark-fg", bg = "light-bg" }
65+"ui.window" = { fg = "light-bg", bg = "dark-bg" }
66+"ui.help" = { fg = "light-fg", bg = "light-bg" }
67+"ui.text" = "light-fg"
68+"ui.text.focus" = { fg = "white", bg = "light-bg", modifiers = ["bold"] }
69+"ui.virtual" = "dark-fg"
70+"ui.virtual.ruler" = { bg = "medium-bg" }
71+"ui.virtual.indent-guide" = "indent"
72+"ui.virtual.whitespace" = "indent"
73+"ui.menu" = { fg = "light-fg", bg = "light-bg" }
74+"ui.menu.selected" = { fg = "white", bg = "dark-fg", modifiers = ["bold"] }
75+"ui.selection" = { fg = "light-fg", bg = "dark-fg" }
76+"ui.selection.primary" = { fg = "white", bg = "dark-blue" }
77+"ui.highlight" = { bg = "light-bg" }
78+"ui.cursorline.primary" = { bg = "black" }
79+"ui.cursorcolumn.primary" = { bg = "black" }
80+"ui.bufferline.background" = { bg = "dark-bg" }
81+"ui.bufferline" = { fg = "light-fg", bg = "light-bg" }
82+"ui.bufferline.active" = { fg = "white", bg = "dark-fg" }
83+
84+"diagnostic.error" = { underline = { color = "red", style = "curl" } }
85+"diagnostic.warning" = { underline = { color = "yellow", style = "curl" } }
86+"diagnostic.info" = { underline = { color = "blue", style = "curl" } }
87+"diagnostic.hint" = { underline = { color = "blue", style = "curl" } }
88+
89+"info" = "blue"
90+"hint" = "blue"
91+"warning" = "yellow"
92+"error" = "red"
93+
94+[palette]
95+# Colors
96+red = "#FF4D51"
97+green = "#35D450"
98+yellow = "#E9E836"
99+blue = "#5DC5F8"
100+dark-blue = "#24ACD4"
101+magenta = "#FEABF2"
102+cyan = "#24DFC4"
103+white = "#ffffff"
104+punct = "#C9C9C9"
105+
106+# Grays
107+black = "#1e1e1e"
108+dark-bg = "#242424"
109+medium-bg = "#2D2D2D"
110+light-bg = "#353535"
111+indent = "#616161"
112+dark-fg = "#929292"
113+light-fg = "#E6E6E6"
runtime/tutor+157−3
@@ -794,11 +794,11 @@ lines.
794= 7.3 INDENTING LINES =
794= 7.3 INDENTING LINES =
795=================================================================
795=================================================================
796
796
797− Type > to indent a line and < to outdent it.
797+ Type > to indent a line and < to unindent it.
798
798
799 1. Move the cursor to the line marked '-->' below.
799 1. Move the cursor to the line marked '-->' below.
800 2. Move down to the second line and type > to indent it.
800 2. Move down to the second line and type > to indent it.
801− 3. Move to the third line and type < to outdent it.
801+ 3. Move to the third line and type < to unindent it.
802
802
803 --> These lines
803 --> These lines
804 are indented
804 are indented
@@ -842,7 +842,7 @@ lines.
842
842
843 * Type J to join lines in selection.
843 * Type J to join lines in selection.
844
844
845− * Type < and > to indent / outdent lines.
845+ * Type > and < to indent / unindent lines.
846
846
847 * Press Ctrl-a to increment the selected number.
847 * Press Ctrl-a to increment the selected number.
848 * Press Ctrl-x to decrement the selected number.
848 * Press Ctrl-x to decrement the selected number.
@@ -1186,6 +1186,160 @@ multiple cursors, they won't be uncommented but commented again.
1186
1186
1187
1187
1188
1188
1189+=================================================================
1190+= 12.1 USING MATCH MODE JUMP =
1191+=================================================================
1192+
1193+To switch to match mode from normal mode, type m. This feature
1194+is particularly useful for handling bracket pairs and their
1195+contents.
1196+
1197+There are several actions that can be performed in match mode,
1198+as indicated by the help pop-up. To jump to a matching bracket pair,
1199+simply press mm. For example on the lines below (starting with
1200+-->), move the cursor in normal mode to (, and then press mm to jump
1201+to the matching ). You can do the same on the line below: for example
1202+move to ], and press mm to jump to [ .
1203+
1204+--> you can (jump between matching parenthesis)
1205+--> or between matching [ square brackets ]
1206+--> now { you know the drill: this works with brackets too }
1207+
1208+
1209+
1210+
1211+=================================================================
1212+= 12.2 USING MATCH MODE SELECT INSIDE =
1213+=================================================================
1214+
1215+Match mode also lets you select the "inside" content between a
1216+pair of brackets or other delimiters. In the lines below:
1217+
1218+- move to the --> line, put your cursor in normal mode at any
1219+location between the parenthesis, for example at 'x', and press
1220+mi( or mi) to select the whole content inside the parenthesis
1221+(parenthesis excluded). As usual, you can then do anything you want
1222+with the selection (for example, press c to change it)
1223+
1224+--> outside and (inside x parenthesis) - and outside again
1225+
1226+Test below that you can do the same with [], or {}, or with
1227+nested combinations of these (this will act on the immediately
1228+surrounding matching pair). This also works with "" and similar
1229+
1230+--> test [ with square brackets ] !
1231+--> try ( with nested [ pairs of ( parenthesis) and "brackets" ])
1232+
1233+=================================================================
1234+= 12.3 USING MATCH MODE SELECT AROUND =
1235+=================================================================
1236+
1237+You can also select the "around" content, i.e. both the inside
1238+content and the delimiters themselves, by using the ma select.
1239+For example, move to the line under, move your cursor in normal
1240+mode to any position between the (), and select the content of
1241+the (), including the surrounding (), by typing ma( or ma). As
1242+usual, you can do anything you want with the selection, for
1243+example delete it all with ma(d .
1244+
1245+--> you ( select x around ) to include delimiters in the select
1246+
1247+This naturally works with other delimiters too:
1248+
1249+--> try [ with 'square' brackets ] too!
1250+
1251+
1252+
1253+
1254+
1255+=================================================================
1256+= 12.4 USING MATCH MODE SURROUND =
1257+=================================================================
1258+
1259+The match mode can also be used to add surrounding around the
1260+current selection. For example, move to the line below, then:
1261+ * i) select the "select all of this" line segment (for example,
1262+move in normal mode the cursor to the start of select, then enter
1263+selection mode with v , then select the 4 next words with 4e ),
1264+ * ii) press ms( or ms) to surround the selection with a pair of
1265+parenthesis.
1266+
1267+--> so, select all of this, and surround it with ()
1268+
1269+You can do the same with other delimiters: for example, ms' on
1270+WORD below to surround it with a pair of ''. You can try also
1271+with adding a surrounding pair of "", or {}, or [].
1272+
1273+--> surround this WORD !
1274+
1275+
1276+
1277+=================================================================
1278+= 12.5 USING MATCH MODE DELETE SURROUND =
1279+=================================================================
1280+
1281+You can delete surrounding pair of delimiters with the md
1282+command. On the line below, move the cursor anywhere
1283+within the pair of (), for example to the 'x', then from there,
1284+in normal mode, press md( or md) to delete the surrounding
1285+pair of parenthesis.
1286+
1287+--> delete (the x pair of parenthesis) from within!
1288+
1289+You can naturally delete other kinds of surroundings:
1290+
1291+--> delete (nested [delimiters]): "this" will delete the nearest
1292+matching surrounding pair.
1293+--> delete "layers "of" quote marks" too: this will delete the
1294+nearest previous and following quote marks
1295+
1296+Trying to delete unexisting surrounding delimiters print an error
1297+at the bottom bar and does nothing.
1298+
1299+=================================================================
1300+= 12.6 USING MATCH MODE REPLACE SURROUND =
1301+=================================================================
1302+
1303+You can replace surrounding pairs of delimiters with the mr
1304+command. On the line below, move the cursor to
1305+anywhere within the pair of (), for example on the 'x', then in
1306+normal mode, press mr([ to replace the pair of () with a pair
1307+of [].
1308+
1309+--> replace the (pair from x within), with something else
1310+
1311+This command will act on the closest enclosing pair, so you
1312+can try replacing different surrounding in the following:
1313+
1314+--> some (nested surroundings [can be replaced])
1315+--> this "works with 'other surroundings' too"
1316+
1317+You can try to replace a non existing pair: this will show
1318+an error warning at the bottom bar and do nothing.
1319+
1320+
1321+=================================================================
1322+= CHAPTER 12 RECAP =
1323+=================================================================
1324+
1325+You can enter the match mode with the m key; this will show the
1326+actions available in a popup. This will allow you to:
1327+ * jump to matching pair of delimiters with mm (you must have a
1328+ delimiter belonging to a pair under your cursor)
1329+ * select inside a pair of delimiters surrounding your cursor
1330+ (i.e. select the content but not the delimiters) with mi(
1331+ and similar
1332+ * select around a pair of delimiters surrounding your cursor
1333+ (i.e. select the content and the delimiters) with ma( and
1334+ similar
1335+ * delete surrounding delimiters with md( and similar
1336+ * add surrounding delimiters around the selection with ms(
1337+ * replace a pair of delimiters surrounding your selection with
1338+ mr([ to replace for example surrounding () with []
1339+
1340+
1341+
1342+
1189=================================================================
1343=================================================================
1190 This tutorial is still a work-in-progress.
1344 This tutorial is still a work-in-progress.
1191 More sections are planned.
1345 More sections are planned.
rust-toolchain.toml+2−2
@@ -1,3 +1,3 @@
1[toolchain]
1[toolchain]
2−channel = "1.65.0"
2+channel = "1.70.0"
3−components = ["rustfmt", "rust-src"]
3+components = ["rustfmt", "rust-src", "clippy"]
xtask/Cargo.toml+12−6
@@ -1,13 +1,19 @@
1[package]
1[package]
2name = "xtask"
2name = "xtask"
3−version = "0.6.0"
3+version.workspace = true
4+authors.workspace = true
4−edition = "2021"
5+edition.workspace = true
6+license.workspace = true
7+rust-version.workspace = true
8+categories.workspace = true
9+repository.workspace = true
10+homepage.workspace = true
5
11
6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
12# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
13
8[dependencies]
14[dependencies]
9−helix-term = { version = "0.6", path = "../helix-term" }
15+helix-term = { path = "../helix-term" }
10−helix-core = { version = "0.6", path = "../helix-core" }
16+helix-core = { path = "../helix-core" }
11−helix-view = { version = "0.6", path = "../helix-view" }
17+helix-view = { path = "../helix-view" }
12−helix-loader = { version = "0.6", path = "../helix-loader" }
18+helix-loader = { path = "../helix-loader" }
13toml = "0.7"
19toml = "0.7"