Compare commits

...

26 Commits

Author SHA1 Message Date
Michael Davis
a05c151bb6 Release 25.07.1 2025-07-18 10:31:37 -04:00
RoloEdits
3c230c9b4a build: lower ubuntu version from 24.04 to 22.04
(cherry picked from commit fd8aacc1a4)
2025-07-18 10:19:33 -04:00
Michael Davis
5cda70e866 Add changelog notes for 25.07 (#13939) 2025-07-15 13:26:52 -05:00
Meiram Shunshalin
c67c3faa78 feat(themes): add soft-wrap style for nightfox (#13957) 2025-07-15 08:42:41 -05:00
Michael Davis
6fd1efd1c2 Gracefully handle highlighter bugs in the markdown component
Since tree-house is young and we've seen a few bugs that make it go
backwards, we should handle this case gracefully and just give up on
syntax highlighting with an error log.
2025-07-13 13:12:14 -04:00
Michael Davis
86f10ae24c Add a language to fix Rust highlights in format-args macros
This is a bit hacky. Injections cannot stack on each other like
highlights because layers can have their own injections. So this new
language `rust-format-args-macro` emulates that. It unconditionally
injects `rust-format-args` into all strings. Rust injects this new
language into known format-args macros like `println!`.

The downside is that this can cause false-positive highlights within
these macros for strings which happen to contain format-args syntax

    println!("Hello, {}!", "{}");
    //               ^ format args syntax
    //                      ^ not format args syntax, but highlighted
    //                        as if it were :(

This false-positive case is expected to be rare.

Injecting this fake language fixes regular non-string highlights in
macro invocations: macro invocations need to inject the entire token
tree and use `injection.include-children` for proper highlighting.
2025-07-13 12:01:18 -04:00
Michael Davis
d2f37b1559 deps: Update tree-house-bindings to v0.2.1 2025-07-12 18:21:28 -04:00
Nik Revenco
e844a4365d fix: bitwise representation for RGB highlight (#13188)
Co-authored-by: Nik Revenco <154856872+NikitaRevenco@users.noreply.github.com>
2025-07-12 11:11:31 -04:00
CalebLarsen
ca7479ca88 Add docs to helix-stdx, helix-tui, helix-vcs (#13765) 2025-07-12 09:48:00 -04:00
Matthew Toohey
7e1fbb05fd feat: add :buffer-close-others --skip-visible flag (#5393) 2025-07-11 11:17:50 -05:00
Michael Davis
2f560914fb Add a '--no-format' flag for :write commands 2025-07-11 12:00:41 -04:00
spentbliss
636cbe58e3 feat(theme): add doom-one theme (#13933)
Co-authored-by: spentbliss <spentbliss@users.noreply.github.com>
2025-07-11 10:34:45 -04:00
Maikel Martens
43187f2ed3 Add Django language support (#13935) 2025-07-11 10:33:44 -04:00
Michael Davis
532f241287 Allow symlinks in shell program completions
Co-authored-by: thort <thort@compass-vm>
2025-07-11 10:30:58 -04:00
Gabriel Lopes Rodrigues
ba04f53830 languages: consider compose.yaml/.yml as docker compose language (#13930) 2025-07-10 20:14:45 -05:00
StratusFearMe21
242353b2ba Add ability to configure atomic saving (#13656)
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
2025-07-10 19:12:59 -04:00
belowm
de898460b8 Allow :move command to accept directories as target (#13922)
Co-authored-by: Martin Below <martin@below.cologne>
2025-07-10 14:28:53 -05:00
Kristoffer Plagborg Bak Sørensen
8e0f326ebb languages: create dedicated language for json-ld (#13925) 2025-07-10 08:49:33 -05:00
connnnal
16d06643a4 queries: Odin or_break+or_continue keywords, struct indents
from https://github.com/tree-sitter-grammars/tree-sitter-odin/pull/25
2025-07-08 19:05:48 -04:00
connnnal
9447a9cc93 chore: Bump Odin grammar 2025-07-08 19:05:48 -04:00
Jonas Köhnen
febc3d03b3 queries/gomod: add "tool", "toolchain" to keywords (#13913) 2025-07-08 08:19:11 -05:00
dependabot[bot]
06047808eb build(deps): bump the rust-dependencies group with 2 updates (#13909)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-08 08:18:37 -05:00
Andrew Davis
02fe437622 Fix off by one error when opening multiple new lines with CRLF line endings (#13905) 2025-07-07 17:41:16 -05:00
Daniel Fortes
e88e48f41c Rose pine theme: improve contrast of selected menu item (#13908) 2025-07-07 16:09:16 -05:00
Val Packett
fc53af9f4e Add systemd-lsp and dts-lsp (#13907) 2025-07-07 15:55:19 -05:00
Kristoffer Plagborg Bak Sørensen
3e5bb392fa languages: add comment tokens for DTD language (#13904) 2025-07-07 14:02:26 -04:00
54 changed files with 994 additions and 154 deletions

View File

@@ -61,12 +61,15 @@ jobs:
build: [x86_64-linux, aarch64-linux, x86_64-macos, x86_64-windows] #, x86_64-win-gnu, win32-msvc
include:
- build: x86_64-linux
os: ubuntu-24.04
# WARN: When changing this to a newer version, make sure that the GLIBC isnt too new, as this can cause issues
# with portablity on older systems that dont follow ubuntus more rapid release cadence.
os: ubuntu-22.04
rust: stable
target: x86_64-unknown-linux-gnu
cross: false
- build: aarch64-linux
os: ubuntu-24.04-arm
# Version should be kept in lockstep with the x86_64 version
os: ubuntu-22.04-arm
rust: stable
target: aarch64-unknown-linux-gnu
cross: false
@@ -291,7 +294,7 @@ jobs:
file_glob: true
tag: ${{ github.ref_name }}
overwrite: true
- name: Upload binaries as artifact
uses: actions/upload-artifact@v4
if: env.preview == 'true'

View File

@@ -20,6 +20,306 @@ Updated languages and queries:
Packaging:
-->
# 25.07.1 (2025-07-18)
This is a patch release which lowers the GLIBC requirements of the release artifacts published to GitHub ([#13983](https://github.com/helix-editor/helix/pull/13983))
# 25.07 (2025-07-15)
As always, a big thank you to all of the contributors! This release saw changes from 195 contributors.
Breaking changes:
* The parsing of the command line has been rewritten and now supports flags and expansions ([#12527](https://github.com/helix-editor/helix/pull/12527), [#13018](https://github.com/helix-editor/helix/pull/13018), [9574e55](https://github.com/helix-editor/helix/commit/9574e55), [2d4c2a1](https://github.com/helix-editor/helix/commit/2d4c2a1), [#13192](https://github.com/helix-editor/helix/pull/13192), [67f1fe2](https://github.com/helix-editor/helix/commit/67f1fe2), [#13466](https://github.com/helix-editor/helix/pull/13466), [#13467](https://github.com/helix-editor/helix/pull/13467), [#13840](https://github.com/helix-editor/helix/pull/13840))
* Quoting and spaces are now handled differently. This can break existing keymaps which use typable commands, in particular `:sh`, `:set-option` or `:toggle-option`.
* The `:rsort` command has been removed. Use the reverse flag instead: `:sort --reverse`
Features:
* Add a picker which explores directories ([#11285](https://github.com/helix-editor/helix/pull/11285), [d4aed40](https://github.com/helix-editor/helix/commit/d4aed40))
* Allow cycling through multiple LSP Hover responses with `A-n`/`A-p` ([#10122](https://github.com/helix-editor/helix/pull/10122), [2367b20](https://github.com/helix-editor/helix/commit/2367b20))
* Add support for incomplete LSP completions ([5c1f3f8](https://github.com/helix-editor/helix/commit/5c1f3f8))
* Add support for EditorConfig ([#13056](https://github.com/helix-editor/helix/pull/13056), [#13443](https://github.com/helix-editor/helix/pull/13443))
* Add support for LSP document colors ([#12308](https://github.com/helix-editor/helix/pull/12308), [d43de14](https://github.com/helix-editor/helix/commit/d43de14), [47cdd23](https://github.com/helix-editor/helix/commit/47cdd23), [ba54b6a](https://github.com/helix-editor/helix/commit/ba54b6a), [#13188](https://github.com/helix-editor/helix/pull/13188))
* Support expansions in external formatter arguments ([#13429](https://github.com/helix-editor/helix/pull/13429))
* Switch out the highlighter for the `tree-house` crate ([#12972](https://github.com/helix-editor/helix/pull/12972), [09bc67a](https://github.com/helix-editor/helix/commit/09bc67a), [a7c3a43](https://github.com/helix-editor/helix/commit/a7c3a43), [3ceae88](https://github.com/helix-editor/helix/commit/3ceae88), [05ae617](https://github.com/helix-editor/helix/commit/05ae617), [5a1dcc2](https://github.com/helix-editor/helix/commit/5a1dcc2), [ebf96bd](https://github.com/helix-editor/helix/commit/ebf96bd), [#13644](https://github.com/helix-editor/helix/pull/13644), [b1f4717](https://github.com/helix-editor/helix/commit/b1f4717), [7410fe3](https://github.com/helix-editor/helix/commit/7410fe3), [633c5fb](https://github.com/helix-editor/helix/commit/633c5fb), [362e97e](https://github.com/helix-editor/helix/commit/362e97e), [#13828](https://github.com/helix-editor/helix/pull/13828), [6fd1efd](https://github.com/helix-editor/helix/commit/6fd1efd))
* This fixes a number of highlighter bugs.
* Locals like parameter highlights are now highlighted even when the definition is not in view.
* Markdown is now injected into rust doc comments (`///` and `//!`).
* Add support for the DAP `startDebugging` reverse request ([#13403](https://github.com/helix-editor/helix/pull/13403))
Commands:
* Add `copy_between_registers` for interactive copying between two registers ([066e938](https://github.com/helix-editor/helix/commit/066e938))
* Add `extend_to_file_{start,end}`, select-mode variants of `goto_file_{start,end}` ([#11767](https://github.com/helix-editor/helix/pull/11767))
* Add `:!` alias for `:sh` and `:|` for `:pipe` ([#13263](https://github.com/helix-editor/helix/pull/13263))
* Add `goto_column` and `extend_to_column` ([#13440](https://github.com/helix-editor/helix/pull/13440))
* Add an `--insensitive`/`-i` flag to the `:sort` command ([#13560](https://github.com/helix-editor/helix/pull/13560))
* Add `rotate_selections_first` and `rotate_selections_last` ([#13615](https://github.com/helix-editor/helix/pull/13615))
* Add a `--no-format` flag for all `:write` commands ([2f56091](https://github.com/helix-editor/helix/commit/2f56091))
* Add a `--skip-visible` flag for `:buffer-close-others` and `:buffer-close-others!` ([#5393](https://github.com/helix-editor/helix/pull/5393))
Usability improvements:
* Replace current file using `A-ret` in pickers rather than loading it in the background ([#12605](https://github.com/helix-editor/helix/pull/12605))
* Set multiple selections when passing a file with multiple locations to `hx` ([#12192](https://github.com/helix-editor/helix/pull/12192))
* Add path completion for multiple cursors ([#12550](https://github.com/helix-editor/helix/pull/12550), [c9dc940](https://github.com/helix-editor/helix/commit/c9dc940))
* Truncate long prompt lines with "…" ([#12036](https://github.com/helix-editor/helix/pull/12036), [9d6ea77](https://github.com/helix-editor/helix/commit/9d6ea77), [0b9701e](https://github.com/helix-editor/helix/commit/0b9701e), [d3fb8fc](https://github.com/helix-editor/helix/commit/d3fb8fc))
* Allow specifying languages in `:lsp-stop` and `:lsp-restart` ([#12578](https://github.com/helix-editor/helix/pull/12578), [3d7e273](https://github.com/helix-editor/helix/commit/3d7e273))
* Add `m` (nearest matching pair) to infobox popups for `md` and `mr` ([#12650](https://github.com/helix-editor/helix/pull/12650))
* Add a hint message in the statusline when using `:sort` on a single selection ([#12585](https://github.com/helix-editor/helix/pull/12585))
* Avoid wrapping around in `goto_{next,prev}_diag` ([#12704](https://github.com/helix-editor/helix/pull/12704))
* Support responses from multiple language servers for LSP goto-definition (and declaration, type definition and implementation) and goto-references ([f7394d5](https://github.com/helix-editor/helix/commit/f7394d5), [1a821ac](https://github.com/helix-editor/helix/commit/1a821ac), [d285a8a](https://github.com/helix-editor/helix/commit/d285a8a))
* Show formatter errors in `:format` ([47f84d0](https://github.com/helix-editor/helix/commit/47f84d0))
* Show typable command docs in keybinding infobox popups when the command takes no arguments ([e9c16b7](https://github.com/helix-editor/helix/commit/e9c16b7))
* Add per-command titles to register selection infobox popups for `select_register`, `insert_register` and `copy_between_registers` ([e0da129](https://github.com/helix-editor/helix/commit/e0da129))
* Add container name column to the LSP symbol picker ([#12930](https://github.com/helix-editor/helix/pull/12930))
* Add a theme key for highlighting directories in completions and picker items ([#12855](https://github.com/helix-editor/helix/pull/12855), [7bebe0a](https://github.com/helix-editor/helix/commit/7bebe0a))
* Add `editor.trim-final-newlines` and `editor.trim-trailing-whitespace` config options ([aa20eb8](https://github.com/helix-editor/helix/commit/aa20eb8))
* Warn when the configured theme is unusable because true-color is not available ([#13058](https://github.com/helix-editor/helix/pull/13058))
* Allow configuring `[workspace-]diagnostic` statusline element severities ([#13288](https://github.com/helix-editor/helix/pull/13288), [b0528bb](https://github.com/helix-editor/helix/commit/b0528bb))
* Improve completion for shell commands ([#12883](https://github.com/helix-editor/helix/pull/12883), [532f241](https://github.com/helix-editor/helix/commit/532f241))
* Show the primary selection index in the `selections` statusline element when there are multiple selections ([#12326](https://github.com/helix-editor/helix/pull/12326))
* Use configured language server names when possible in `--health` output ([#13573](https://github.com/helix-editor/helix/pull/13573))
* Add a statusline element for indentation style ([#13632](https://github.com/helix-editor/helix/pull/13632))
* Set the working directory of language server commands to the workspace root ([#13691](https://github.com/helix-editor/helix/pull/13691))
* Avoid jumpiness in the picker preview for languages with non-default tab widths ([#13761](https://github.com/helix-editor/helix/pull/13761))
* Add a config option for limiting LSP inlay hint length ([#13742](https://github.com/helix-editor/helix/pull/13742))
* Improve heuristics used in the diff gutter ([#13722](https://github.com/helix-editor/helix/pull/13722))
* Allow moving a file with `:move` when its old path does not exist ([#13748](https://github.com/helix-editor/helix/pull/13748))
* Allow moving a file into a directory with `:move` ([#13922](https://github.com/helix-editor/helix/pull/13922))
* Show human-readable file sizes in the statusline message for file writes ([#13627](https://github.com/helix-editor/helix/pull/13627))
* Add diagnostic source to the diagnosics pickers ([#13758](https://github.com/helix-editor/helix/pull/13758))
* Show all active scopes under the cursor in `:tree-sitter-highlight-name` ([4a85171](https://github.com/helix-editor/helix/commit/4a85171))
* Auto-close the LSP code-actions popup ([#13832](https://github.com/helix-editor/helix/pull/13832))
* Add a configuration option for controlling atomic writes to disk ([#13656](https://github.com/helix-editor/helix/pull/13656))
Fixes:
* Fix panic from using `search_selection_detect_word_boundaries` (`*`) at the end of the file ([#12611](https://github.com/helix-editor/helix/pull/12611))
* Discard placeholder text for zero tabstop `${0:placeholder}` ([#12647](https://github.com/helix-editor/helix/pull/12647))
* Fix panic in `goto_file` (`gf`) on file names with non-ASCII characters ([#12673](https://github.com/helix-editor/helix/pull/12673))
* Only accept unmodified characters in `goto_word` (`gw`) ([f5f9f49](https://github.com/helix-editor/helix/commit/f5f9f49), [0364521](https://github.com/helix-editor/helix/commit/0364521))
* Skip recording keys pressed by macros while recording a macro ([#12733](https://github.com/helix-editor/helix/pull/12733))
* Deny unknown fields in `editor.smart-tab` config ([28047fe](https://github.com/helix-editor/helix/commit/28047fe))
* Fix soft-wrap word boundary detection for Unicode combining accent characters ([#12483](https://github.com/helix-editor/helix/pull/12483))
* Fix clearing of infobox popups in `select_register` and `insert_register` commands ([e882a75](https://github.com/helix-editor/helix/commit/e882a75))
* Fix handling of `stderr` of DAP child processes ([d0d1693](https://github.com/helix-editor/helix/commit/d0d1693))
* Cancel all pending requests when a DAP session terminates ([26db541](https://github.com/helix-editor/helix/commit/26db541))
* Properly discard out-of-date diagnostics ([313a647](https://github.com/helix-editor/helix/commit/313a647))
* Fix display of multiple language servers in `hx --health` ([#12841](https://github.com/helix-editor/helix/pull/12841))
* Respect `editor.default-yank-register` in `:yank-joined` ([#12890](https://github.com/helix-editor/helix/pull/12890))
* Escape percent character when pasting the history register into the picker ([#12886](https://github.com/helix-editor/helix/pull/12886))
* Render rulers before the cursor ([2d3b75a](https://github.com/helix-editor/helix/commit/2d3b75a))
* Avoid inserting final newlines in empty files ([67879a1](https://github.com/helix-editor/helix/commit/67879a1))
* Gracefully handle partial failure in multi-language-server requests ([#13156](https://github.com/helix-editor/helix/pull/13156), [14cab4b](https://github.com/helix-editor/helix/commit/14cab4b))
* Improve LSP progress message display in the statusline ([#13180](https://github.com/helix-editor/helix/pull/13180))
* Fix behavior of `<esc>` removing added indentation in documents with CRLF line endings ([702a961](https://github.com/helix-editor/helix/commit/702a961))
* Append changes to document history before pushing jumplist jumps ([#13619](https://github.com/helix-editor/helix/pull/13619))
* Fix overflow in the display of large chunks of text in the signature-help component ([#13566](https://github.com/helix-editor/helix/pull/13566))
* Fix panic from clearing whitespace when changing multiple selections on one line ([#13673](https://github.com/helix-editor/helix/pull/13673))
* Include formatting options in LSP range formatting request ([#13734](https://github.com/helix-editor/helix/pull/13734))
* Consistently set statusline errors when LSP features are not available ([#12577](https://github.com/helix-editor/helix/pull/12577))
* Fix `goto_file` on Windows ([#13770](https://github.com/helix-editor/helix/pull/13770))
* Fix crash in `goto_word` (`gw`) when `editor.jump-label-alphabet` is configured to be empty ([#13863](https://github.com/helix-editor/helix/pull/13863))
* Fix `open_above` / `open_below` (`o` / `O`) when using a count on a document with CRLF line-endings ([#13905](https://github.com/helix-editor/helix/pull/13905))
Themes:
* Update `modus` themes ([#12670](https://github.com/helix-editor/helix/pull/12670))
* Update `snazzy` ([#11089](https://github.com/helix-editor/helix/pull/11089))
* Update `gruber-darker` ([#12797](https://github.com/helix-editor/helix/pull/12797))
* Update `cyan_light` ([#12864](https://github.com/helix-editor/helix/pull/12864), [#12891](https://github.com/helix-editor/helix/pull/12891))
* Update `onedarker` ([#12833](https://github.com/helix-editor/helix/pull/12833))
* Update `github_light` ([#12907](https://github.com/helix-editor/helix/pull/12907))
* Update `kanagawa` ([#12895](https://github.com/helix-editor/helix/pull/12895))
* Add `beans` ([#12963](https://github.com/helix-editor/helix/pull/12963))
* Update `base16_transparent` ([#13080](https://github.com/helix-editor/helix/pull/13080))
* Update `sunset` ([#13086](https://github.com/helix-editor/helix/pull/13086))
* Add `carbon` ([#13067](https://github.com/helix-editor/helix/pull/13067))
* Update `soralized` ([#13121](https://github.com/helix-editor/helix/pull/13121))
* Add `focus_nova` ([#13144](https://github.com/helix-editor/helix/pull/13144))
* Update `onedark` ([#13166](https://github.com/helix-editor/helix/pull/13166))
* Update `adwaita-light` ([#13174](https://github.com/helix-editor/helix/pull/13174))
* Add `earl_grey` ([#13203](https://github.com/helix-editor/helix/pull/13203))
* Update `spacebones` ([#13213](https://github.com/helix-editor/helix/pull/13213))
* Add `peachpuff` ([#13225](https://github.com/helix-editor/helix/pull/13225))
* Update catppuccin themes ([#13262](https://github.com/helix-editor/helix/pull/13262))
* Update gruvbox themes ([#13315](https://github.com/helix-editor/helix/pull/13315))
* Update serika themes ([#13341](https://github.com/helix-editor/helix/pull/13341))
* Add `gruvbox-material` ([#13311](https://github.com/helix-editor/helix/pull/13311))
* Add `ashen` ([#13366](https://github.com/helix-editor/helix/pull/13366))
* Update Zed themes ([#13370](https://github.com/helix-editor/helix/pull/13370))
* Update Tokyonight themes ([#13375](https://github.com/helix-editor/helix/pull/13375))
* Update `onelight` ([#13413](https://github.com/helix-editor/helix/pull/13413))
* Add `ataraxia` ([#13390](https://github.com/helix-editor/helix/pull/13390))
* Add `vesper` ([#13394](https://github.com/helix-editor/helix/pull/13394))
* Add `kinda_nvim` and `kinda_nvim_light` ([#13406](https://github.com/helix-editor/helix/pull/13406))
* Update `sonokai` ([#13410](https://github.com/helix-editor/helix/pull/13410))
* Add `nyxvamp` themes ([#12185](https://github.com/helix-editor/helix/pull/12185))
* Update nord themes ([#13574](https://github.com/helix-editor/helix/pull/13574))
* Add `lapis_aquamarine` ([#13726](https://github.com/helix-editor/helix/pull/13726))
* Add `sidra` ([#13575](https://github.com/helix-editor/helix/pull/13575))
* Add `dark-synthwave` ([#13857](https://github.com/helix-editor/helix/pull/13857))
* Update `rose_pine` ([#13908](https://github.com/helix-editor/helix/pull/13908))
* Add `doom-one` ([#13933](https://github.com/helix-editor/helix/pull/13933))
* Update `nightfox` ([#13957](https://github.com/helix-editor/helix/pull/13957))
New languages:
* Ghostty config ([#12703](https://github.com/helix-editor/helix/pull/12703))
* Tera ([#12756](https://github.com/helix-editor/helix/pull/12756))
* FGA ([#12763](https://github.com/helix-editor/helix/pull/12763))
* CSV ([#11973](https://github.com/helix-editor/helix/pull/11973))
* Yara ([#12753](https://github.com/helix-editor/helix/pull/12753))
* Djot ([#12562](https://github.com/helix-editor/helix/pull/12562))
* Ink ([#12773](https://github.com/helix-editor/helix/pull/12773))
* Mail ([#12945](https://github.com/helix-editor/helix/pull/12945))
* SourcePawn ([#13028](https://github.com/helix-editor/helix/pull/13028))
* TLA+ ([#13081](https://github.com/helix-editor/helix/pull/13081))
* Werk ([#13136](https://github.com/helix-editor/helix/pull/13136))
* Debian control file ([#13245](https://github.com/helix-editor/helix/pull/13245))
* WESL ([#13267](https://github.com/helix-editor/helix/pull/13267))
* Fennel ([#13260](https://github.com/helix-editor/helix/pull/13260), [6081a5d](https://github.com/helix-editor/helix/commit/6081a5d))
* Quarto ([#13339](https://github.com/helix-editor/helix/pull/13339))
* Pug ([#13435](https://github.com/helix-editor/helix/pull/13435))
* Slang ([#13449](https://github.com/helix-editor/helix/pull/13449))
* Dunst config ([#13458](https://github.com/helix-editor/helix/pull/13458))
* Luau ([#13702](https://github.com/helix-editor/helix/pull/13702))
* Caddyfile ([#13859](https://github.com/helix-editor/helix/pull/13859))
* Java properties ([#13874](https://github.com/helix-editor/helix/pull/13874))
* Git notes ([#13885](https://github.com/helix-editor/helix/pull/13885))
* systemd (split from INI) ([#13907](https://github.com/helix-editor/helix/pull/13907))
* JSON-LD (split from JSON) ([#13925](https://github.com/helix-editor/helix/pull/13925))
* Django HTML ([#13935](https://github.com/helix-editor/helix/pull/13935))
Updated languages and queries:
* Add `ruby-lsp` for Ruby ([#12511](https://github.com/helix-editor/helix/pull/12511))
* Add `wat_server` for Wat ([#12581](https://github.com/helix-editor/helix/pull/12581))
* Recognize `bun.lock` as JSONC ([fcf981b](https://github.com/helix-editor/helix/commit/fcf981b))
* Update tree-sitter-rust ([#12607](https://github.com/helix-editor/helix/pull/12607), [1afa63d](https://github.com/helix-editor/helix/commit/1afa63d))
* Fix configuration of `cs-lsp` ([#12615](https://github.com/helix-editor/helix/pull/12615))
* Add `beancount-language-server` for Beancount ([#12610](https://github.com/helix-editor/helix/pull/12610))
* Update tree-sitter-fish ([#12456](https://github.com/helix-editor/helix/pull/12456))
* Add `fish-lsp` for Fish ([#12456](https://github.com/helix-editor/helix/pull/12456))
* Update tree-sitter-ini ([#12456](https://github.com/helix-editor/helix/pull/12456), [#13088](https://github.com/helix-editor/helix/pull/13088))
* Recognize `hgrc` as INI ([#12456](https://github.com/helix-editor/helix/pull/12456))
* Restrict tagged template injection languages for ECMA languages ([#12217](https://github.com/helix-editor/helix/pull/12217))
* Update tree-sitter-zig ([#11980](https://github.com/helix-editor/helix/pull/11980), [#12708](https://github.com/helix-editor/helix/pull/12708))
* Update tree-sitter-elixir ([8bf9adf](https://github.com/helix-editor/helix/commit/8bf9adf))
* Add `asm-lsp` for Assembly dialects ([#12684](https://github.com/helix-editor/helix/pull/12684))
* Update tree-sitter-just ([#12692](https://github.com/helix-editor/helix/pull/12692), #)
* Update tree-sitter-cairo ([#12712](https://github.com/helix-editor/helix/pull/12712))
* Configure a comment token for Svelte ([#12743](https://github.com/helix-editor/helix/pull/12743))
* Recognize `.sublime-*` files ([#12750](https://github.com/helix-editor/helix/pull/12750))
* Highlight `$` tagged templates as shell commands in ECMA languages ([#12751](https://github.com/helix-editor/helix/pull/12751))
* Add `#'` comment token for R ([#12748](https://github.com/helix-editor/helix/pull/12748))
* Fix module/namespace highlight in Unison ([93fa990](https://github.com/helix-editor/helix/commit/93fa990))
* Add missing `#not-eq?` and `#not-match?` highlights in TSQ ([3824010](https://github.com/helix-editor/helix/commit/3824010))
* Reverse the precedence order of highlight queries ([#9458](https://github.com/helix-editor/helix/pull/9458), [#12777](https://github.com/helix-editor/helix/pull/12777), [#12795](https://github.com/helix-editor/helix/pull/12795), [144a4f4](https://github.com/helix-editor/helix/commit/144a4f4), [e1c26eb](https://github.com/helix-editor/helix/commit/e1c26eb), [e1060a2](https://github.com/helix-editor/helix/commit/e1060a2), [7f41670](https://github.com/helix-editor/helix/commit/7f41670), [#13293](https://github.com/helix-editor/helix/pull/13293))
* Update Rust highlights ([b8bfc44](https://github.com/helix-editor/helix/commit/b8bfc44), [#12871](https://github.com/helix-editor/helix/pull/12871), [#13664](https://github.com/helix-editor/helix/pull/13664))
* Add block comment configuration for PHP ([0ab403d](https://github.com/helix-editor/helix/commit/0ab403d))
* Update Gren highlights ([#12769](https://github.com/helix-editor/helix/pull/12769))
* Remove `ERROR` node highlighting from all highlight queries ([16ff063](https://github.com/helix-editor/helix/commit/16ff063))
* Update tree-sitter-erlang and highlights ([18b9eb9](https://github.com/helix-editor/helix/commit/18b9eb9), [9f3b193](https://github.com/helix-editor/helix/commit/9f3b193), [12139a4](https://github.com/helix-editor/helix/commit/12139a4))
* Update Nix injections ([#12776](https://github.com/helix-editor/helix/pull/12776), [#12774](https://github.com/helix-editor/helix/pull/12774), [#13851](https://github.com/helix-editor/helix/pull/13851))
* Add indent queries for Nix ([#12829](https://github.com/helix-editor/helix/pull/12829))
* Update Markdown highlights ([#12696](https://github.com/helix-editor/helix/pull/12696))
* Recognize `xsl` as XML ([#12834](https://github.com/helix-editor/helix/pull/12834))
* Remove deprecated `typst-lsp` config ([5a66270](https://github.com/helix-editor/helix/commit/5a66270))
* Replace `pkgbuild-language-server` with `termux-language-server` ([c3c9a0d](https://github.com/helix-editor/helix/commit/c3c9a0d))
* Update SQL highlights ([#12837](https://github.com/helix-editor/helix/pull/12837))
* Recognize `mpd` and `smil` as XML ([#12916](https://github.com/helix-editor/helix/pull/12916))
* Add indents and textojbects for Kotlin ([#12925](https://github.com/helix-editor/helix/pull/12925))
* Fix module highlights in Koto ([7e87a36](https://github.com/helix-editor/helix/commit/7e87a36))
* Update language servers for Protobuf ([#12936](https://github.com/helix-editor/helix/pull/12936))
* Add `astro-ls` for Astro ([#12939](https://github.com/helix-editor/helix/pull/12939))
* Fix recognition of "scons*" files as Python ([#12943](https://github.com/helix-editor/helix/pull/12943))
* Update C# queries ([#12948](https://github.com/helix-editor/helix/pull/12948))
* Add comment textojbect to TOML ([#12952](https://github.com/helix-editor/helix/pull/12952))
* Add `starpls` as Starlark language server ([#12958](https://github.com/helix-editor/helix/pull/12958))
* Add `pkl-lsp` for PKL ([#12962](https://github.com/helix-editor/helix/pull/12962))
* Add `kdlfmt` formatter for KDL ([#12967](https://github.com/helix-editor/helix/pull/12967))
* Update CSS highlights ([#12497](https://github.com/helix-editor/helix/pull/12497), [fed3edc](https://github.com/helix-editor/helix/commit/fed3edc))
* Add `harper-ls` ([#13029](https://github.com/helix-editor/helix/pull/13029))
* Change `wgsl_analyzer` to `wgsl-analyzer` ([#13063](https://github.com/helix-editor/helix/pull/13063))
* Update tree-sitter-vhdl ([#13091](https://github.com/helix-editor/helix/pull/13091))
* Update tree-sitter-openscad ([#13033](https://github.com/helix-editor/helix/pull/13033))
* Update Rust injections ([694b615](https://github.com/helix-editor/helix/commit/694b615), [1bd7a39](https://github.com/helix-editor/helix/commit/1bd7a39))
* Update Ruby highlights ([#13055](https://github.com/helix-editor/helix/pull/13055))
* Recognize `gitconfig` as an extension ([#13115](https://github.com/helix-editor/helix/pull/13115))
* Add `///` comment token for Amber ([#13122](https://github.com/helix-editor/helix/pull/13122))
* Add indent queries for Starlark ([#13126](https://github.com/helix-editor/helix/pull/13126))
* Recognize more systemd file types as INI ([#13139](https://github.com/helix-editor/helix/pull/13139))
* Update scheme queries ([#13143](https://github.com/helix-editor/helix/pull/13143))
* Recognize `tmTheme` as XML ([#13202](https://github.com/helix-editor/helix/pull/13202))
* Update `golangci-lint` command for v2 ([#13204](https://github.com/helix-editor/helix/pull/13204))
* Add `just-lsp` for Just ([#13276](https://github.com/helix-editor/helix/pull/13276))
* Add a tree-sitter-prolog grammar ([#11611](https://github.com/helix-editor/helix/pull/11611))
* Fix typos in Ada queries ([#13251](https://github.com/helix-editor/helix/pull/13251))
* Update mint language server args ([#13248](https://github.com/helix-editor/helix/pull/13248))
* Update typescript highlights ([#13250](https://github.com/helix-editor/helix/pull/13250))
* Update tree-sitter-jjdescription ([#13329](https://github.com/helix-editor/helix/pull/13329))
* Add injection queries for Quint ([#13322](https://github.com/helix-editor/helix/pull/13322))
* Update tree-sitter-scss and highlights ([#13414](https://github.com/helix-editor/helix/pull/13414))
* Update tree-sitter-go-mod ([#13395](https://github.com/helix-editor/helix/pull/13395))
* Update tree-sitter-svelte ([#13423](https://github.com/helix-editor/helix/pull/13423))
* Update Lua highlights ([#13401](https://github.com/helix-editor/helix/pull/13401))
* Update Go highlights ([#13425](https://github.com/helix-editor/helix/pull/13425), [25b299a](https://github.com/helix-editor/helix/commit/25b299a), [#13825](https://github.com/helix-editor/helix/pull/13825))
* Recognize `.git-blame-ignore-revs` as gitignore ([#13460](https://github.com/helix-editor/helix/pull/13460))
* Update Verilog highlights ([#13473](https://github.com/helix-editor/helix/pull/13473), [#13493](https://github.com/helix-editor/helix/pull/13493))
* Update tree-sitter-v ([#13469](https://github.com/helix-editor/helix/pull/13469))
* Update WGSL highlights ([#13479](https://github.com/helix-editor/helix/pull/13479))
* Update Bash highlights ([#13477](https://github.com/helix-editor/helix/pull/13477))
* Update tree-sitter-cpp ([#13504](https://github.com/helix-editor/helix/pull/13504))
* Update rust-analyzer config to use server-side file watching ([#13432](https://github.com/helix-editor/helix/pull/13432))
* Update Vue injections ([#13511](https://github.com/helix-editor/helix/pull/13511))
* Recognize `sld` as Scheme ([#13528](https://github.com/helix-editor/helix/pull/13528))
* Recognize more files as git-attributes ([#13540](https://github.com/helix-editor/helix/pull/13540))
* Update tree-sitter-haskell and queries ([#13475](https://github.com/helix-editor/helix/pull/13475))
* Align INI highlights with TOML ([#13589](https://github.com/helix-editor/helix/pull/13589))
* Add tree-sitter-rust-format-args for `format_args!` injections in Rust ([#13533](https://github.com/helix-editor/helix/pull/13533), [#13657](https://github.com/helix-editor/helix/pull/13657), [4dd4ba7](https://github.com/helix-editor/helix/commit/4dd4ba7), [86f10ae](https://github.com/helix-editor/helix/commit/86f10ae))
* Update Ungrammar highlights ([8d58f6c](https://github.com/helix-editor/helix/commit/8d58f6c))
* Add `ty` language server for Python ([#13643](https://github.com/helix-editor/helix/pull/13643))
* Add `clarinet` language server for Clarity ([#13647](https://github.com/helix-editor/helix/pull/13647))
* Update prisma config to avoid a crash in the language server ([f6878f6](https://github.com/helix-editor/helix/commit/f6878f6))
* Add `pyrefly` for Python ([#13713](https://github.com/helix-editor/helix/pull/13713))
* Update Python highlights ([#13715](https://github.com/helix-editor/helix/pull/13715))
* Update Mojo language server and formatter to `pixi` ([#13648](https://github.com/helix-editor/helix/pull/13648))
* Add `tombi` for TOML ([#13723](https://github.com/helix-editor/helix/pull/13723))
* Add `neocmakelsp` for CMake ([#13740](https://github.com/helix-editor/helix/pull/13740))
* Update C and C++ highlights ([#13747](https://github.com/helix-editor/helix/pull/13747), [#13772](https://github.com/helix-editor/helix/pull/13772))
* Highlight escape sequences in ECMA languages ([#13762](https://github.com/helix-editor/helix/pull/13762))
* Add an external formatter config for Crystal ([#13759](https://github.com/helix-editor/helix/pull/13759))
* Add `amber-lsp` for Amber ([#13763](https://github.com/helix-editor/helix/pull/13763))
* Update HTML highlights ([#13753](https://github.com/helix-editor/helix/pull/13753))
* Update tree-sitter-purescript and highlights ([#13782](https://github.com/helix-editor/helix/pull/13782))
* Update tree-sitter-gleam and highlights ([#13793](https://github.com/helix-editor/helix/pull/13793), [#13807](https://github.com/helix-editor/helix/pull/13807), [#13813](https://github.com/helix-editor/helix/pull/13813))
* Recognize Buck files as Starlark ([#13810](https://github.com/helix-editor/helix/pull/13810))
* Use tree-sitter-crystal instead of tree-sitter-ruby for Crystal and add custom queries ([#13805](https://github.com/helix-editor/helix/pull/13805))
* Update tree-sitter-twig ([#13689](https://github.com/helix-editor/helix/pull/13689))
* Recognize `jsconfig.json` as JSONC, use as JavaScript and JSX roots ([#13822](https://github.com/helix-editor/helix/pull/13822))
* Recognize `.gem/credentials` as YAML ([#13843](https://github.com/helix-editor/helix/pull/13843))
* Update Dockerfile injections ([#13845](https://github.com/helix-editor/helix/pull/13845), 13852)
* Change tree-sitter parser for Git commit message files ([44293df](https://github.com/helix-editor/helix/commit/44293df))
* Recognize `mimeapps.list` as INI ([#13850](https://github.com/helix-editor/helix/pull/13850))
* Update tree-sitter-odin, highlights and indents ([#13877](https://github.com/helix-editor/helix/pull/13877), [#13917](https://github.com/helix-editor/helix/pull/13917))
* Add locals queries for C, improve parameter highlighting ([#13876](https://github.com/helix-editor/helix/pull/13876))
* Add textobjects for QML ([#13855](https://github.com/helix-editor/helix/pull/13855))
* Add comment tokens for DTD ([#13904](https://github.com/helix-editor/helix/pull/13904))
* Add `dts-lsp` for DeviceTree ([#13907](https://github.com/helix-editor/helix/pull/13907))
* Update gomod highlights ([#13913](https://github.com/helix-editor/helix/pull/13913))
* Recognize `compose.yaml` and `compose.yml` as Docker Compose ([#13930](https://github.com/helix-editor/helix/pull/13930))
Packaging:
* Fix handling of spaces in Bash completion ([#12828](https://github.com/helix-editor/helix/pull/12828))
* Refactor Nix flake ([#12831](https://github.com/helix-editor/helix/pull/12831), [#13024](https://github.com/helix-editor/helix/pull/13024), [cb1ecc9](https://github.com/helix-editor/helix/commit/cb1ecc9), [#13305](https://github.com/helix-editor/helix/pull/13305))
* Add `ConsoleOnly` to `Helix.desktop` categories ([#13236](https://github.com/helix-editor/helix/pull/13236))
* Drop Nix flake dependency on flake-utils ([60a03a3](https://github.com/helix-editor/helix/commit/60a03a3))
* Increase the MSRV to 1.82 ([#13275](https://github.com/helix-editor/helix/pull/13275))
# 25.01.1 (2025-01-19)
25.01.1 is a patch release focusing on fixing bugs and panics from changes in 25.01.

51
Cargo.lock generated
View File

@@ -150,9 +150,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cc"
version = "1.2.27"
version = "1.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
dependencies = [
"shlex",
]
@@ -1397,7 +1397,7 @@ dependencies = [
[[package]]
name = "helix-core"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"arc-swap",
@@ -1435,7 +1435,7 @@ dependencies = [
[[package]]
name = "helix-dap"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"fern",
@@ -1454,7 +1454,7 @@ dependencies = [
[[package]]
name = "helix-event"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"foldhash",
@@ -1468,7 +1468,7 @@ dependencies = [
[[package]]
name = "helix-loader"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"cc",
@@ -1485,7 +1485,7 @@ dependencies = [
[[package]]
name = "helix-lsp"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"arc-swap",
@@ -1518,11 +1518,11 @@ dependencies = [
[[package]]
name = "helix-parsec"
version = "25.1.1"
version = "25.7.1"
[[package]]
name = "helix-stdx"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"bitflags",
"dunce",
@@ -1540,7 +1540,7 @@ dependencies = [
[[package]]
name = "helix-term"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"arc-swap",
@@ -1586,7 +1586,7 @@ dependencies = [
[[package]]
name = "helix-tui"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"bitflags",
"cassowary",
@@ -1601,7 +1601,7 @@ dependencies = [
[[package]]
name = "helix-vcs"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"arc-swap",
@@ -1617,7 +1617,7 @@ dependencies = [
[[package]]
name = "helix-view"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"anyhow",
"arc-swap",
@@ -1878,6 +1878,17 @@ version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
[[package]]
name = "io-uring"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
dependencies = [
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "is-docker"
version = "0.2.0"
@@ -1975,7 +1986,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
dependencies = [
"cfg-if",
"windows-targets 0.53.2",
"windows-targets 0.52.6",
]
[[package]]
@@ -2733,17 +2744,19 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.45.1"
version = "1.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
dependencies = [
"backtrace",
"bytes",
"io-uring",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"slab",
"socket2",
"tokio-macros",
"windows-sys 0.52.0",
@@ -2831,9 +2844,9 @@ dependencies = [
[[package]]
name = "tree-house-bindings"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "690809022f44e3d2329882649724b6e0027ade3fada65e4631d303e744dc32b4"
checksum = "3f1646788fe0afdbf8e191b5d0f558df7333d8857665a67053c532ec811e6086"
dependencies = [
"cc",
"libloading",
@@ -3268,7 +3281,7 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "xtask"
version = "25.1.1"
version = "25.7.1"
dependencies = [
"helix-core",
"helix-loader",

View File

@@ -52,7 +52,7 @@ futures-util = { version = "0.3", features = ["std", "async-await"], default-fea
tokio-stream = "0.1.17"
[workspace.package]
version = "25.1.1"
version = "25.7.1"
edition = "2021"
authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
categories = ["editor"]

View File

@@ -53,6 +53,7 @@
| `workspace-lsp-roots` | Directories relative to the workspace root that are treated as LSP roots. Should only be set in `.helix/config.toml` | `[]` |
| `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` |
| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
| `atomic-save` | Whether to use atomic operations to write documents to disk. This prevents data loss if the editor is interrupted while writing the file, but may confuse some file watching/hot reloading programs. | `true` |
| `trim-final-newlines` | Whether to automatically remove line-endings after the final one on write | `false` |
| `trim-trailing-whitespace` | Whether to automatically remove whitespace preceding line endings on write | `false` |
| `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` |

View File

@@ -40,7 +40,7 @@
| dart | ✓ | ✓ | ✓ | `dart` |
| dbml | ✓ | | | |
| debian | ✓ | | | |
| devicetree | ✓ | | | |
| devicetree | ✓ | | | `dts-lsp` |
| dhall | ✓ | ✓ | | `dhall-lsp-server` |
| diff | ✓ | | | |
| djot | ✓ | | | |
@@ -105,6 +105,7 @@
| hoon | ✓ | | | |
| hosts | ✓ | | | |
| html | ✓ | | | `vscode-html-language-server`, `superhtml` |
| htmldjango | ✓ | | | `djlsp`, `vscode-html-language-server`, `superhtml` |
| hurl | ✓ | ✓ | ✓ | |
| hyprlang | ✓ | | ✓ | `hyprls` |
| idris | | | | `idris2-lsp` |
@@ -120,6 +121,7 @@
| jq | ✓ | ✓ | | `jq-lsp` |
| jsdoc | ✓ | | | |
| json | ✓ | ✓ | ✓ | `vscode-json-language-server` |
| json-ld | ✓ | ✓ | ✓ | `vscode-json-language-server` |
| json5 | ✓ | | | |
| jsonc | ✓ | | ✓ | `vscode-json-language-server` |
| jsonnet | ✓ | | | `jsonnet-language-server` |
@@ -206,6 +208,7 @@
| ruby | ✓ | ✓ | ✓ | `ruby-lsp`, `solargraph` |
| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
| rust-format-args | ✓ | | | |
| rust-format-args-macro | ✓ | ✓ | ✓ | |
| sage | ✓ | ✓ | | |
| scala | ✓ | ✓ | ✓ | `metals` |
| scheme | ✓ | | ✓ | |
@@ -228,6 +231,7 @@
| svelte | ✓ | | ✓ | `svelteserver` |
| sway | ✓ | ✓ | ✓ | `forc` |
| swift | ✓ | ✓ | | `sourcekit-lsp` |
| systemd | ✓ | | | `systemd-lsp` |
| t32 | ✓ | | | |
| tablegen | ✓ | ✓ | ✓ | |
| tact | ✓ | ✓ | ✓ | |

View File

@@ -47,6 +47,12 @@
<content_rating type="oars-1.1" />
<releases>
<release version="25.07.1" date="2025-07-18">
<url>https://github.com/helix-editor/helix/releases/tag/25.07.1</url>
</release>
<release version="25.07" date="2025-07-15">
<url>https://helix-editor.com/news/release-25-07-highlights/</url>
</release>
<release version="25.01.1" date="2025-01-19">
<url>https://github.com/helix-editor/helix/releases/tag/25.01.1</url>
</release>

View File

@@ -25,7 +25,7 @@ globset = "0.4.16"
log = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1.45", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] }
tokio = { version = "1.46", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] }
tokio-stream.workspace = true
parking_lot.workspace = true
arc-swap = "1"

View File

@@ -1,3 +1,4 @@
//! Functions for working with the host environment.
use std::{
borrow::Cow,
ffi::{OsStr, OsString},
@@ -10,9 +11,9 @@ use once_cell::sync::Lazy;
// We keep the CWD as a static so that we can access it in places where we don't have access to the Editor
static CWD: RwLock<Option<PathBuf>> = RwLock::new(None);
// Get the current working directory.
// This information is managed internally as the call to std::env::current_dir
// might fail if the cwd has been deleted.
/// Get the current working directory.
/// This information is managed internally as the call to std::env::current_dir
/// might fail if the cwd has been deleted.
pub fn current_working_dir() -> PathBuf {
if let Some(path) = &*CWD.read().unwrap() {
return path.clone();
@@ -37,6 +38,7 @@ pub fn current_working_dir() -> PathBuf {
cwd
}
/// Update the current working directory.
pub fn set_current_working_dir(path: impl AsRef<Path>) -> std::io::Result<Option<PathBuf>> {
let path = crate::path::canonicalize(path);
std::env::set_current_dir(&path)?;
@@ -45,14 +47,17 @@ pub fn set_current_working_dir(path: impl AsRef<Path>) -> std::io::Result<Option
Ok(cwd.replace(path))
}
/// Checks if the given environment variable is set.
pub fn env_var_is_set(env_var_name: &str) -> bool {
std::env::var_os(env_var_name).is_some()
}
/// Checks if a binary with the given name exists.
pub fn binary_exists<T: AsRef<OsStr>>(binary_name: T) -> bool {
which::which(binary_name).is_ok()
}
/// Attempts to find a binary of the given name. See [which](https://linux.die.net/man/1/which).
pub fn which<T: AsRef<OsStr>>(
binary_name: T,
) -> Result<std::path::PathBuf, ExecutableNotFoundError> {

View File

@@ -1,3 +1,4 @@
//! Functions for managine file metadata.
//! From <https://github.com/Freaky/faccess>
use std::io;

View File

@@ -1,3 +1,6 @@
//! Extensions to the standard library. A collection of helper functions
//! used throughout helix.
pub mod env;
pub mod faccess;
pub mod path;

View File

@@ -1,3 +1,5 @@
//! Functions for working with [Path].
pub use etcetera::home_dir;
use once_cell::sync::Lazy;
use regex_cursor::{engines::meta::Regex, Input};
@@ -140,6 +142,7 @@ pub fn canonicalize(path: impl AsRef<Path>) -> PathBuf {
normalize(path)
}
/// Convert path into a relative path
pub fn get_relative_path<'a, P>(path: P) -> Cow<'a, Path>
where
P: Into<Cow<'a, Path>>,

View File

@@ -1,3 +1,5 @@
//! Provides [Range] type expanding on [RangeBounds].
use std::ops::{self, RangeBounds};
/// A range of `char`s within the text.
@@ -66,6 +68,7 @@ pub fn is_subset<const ALLOW_EMPTY: bool>(
}
}
/// Similar to is_subset but requires each element of `super_set` to be matched
pub fn is_exact_subset(
mut super_set: impl Iterator<Item = Range>,
mut sub_set: impl Iterator<Item = Range>,

View File

@@ -1,3 +1,4 @@
//! Functions and types for working with [RopeSlice]
use std::fmt;
use std::ops::{Bound, RangeBounds};
@@ -8,6 +9,7 @@ use ropey::iter::Chunks;
use ropey::RopeSlice;
use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};
/// Additional utility functions for [RopeSlice]
pub trait RopeSliceExt<'a>: Sized {
fn ends_with(self, text: &str) -> bool;
fn starts_with(self, text: &str) -> bool;

View File

@@ -3726,11 +3726,13 @@ fn open(cx: &mut Context, open: Open, comment_continuation: CommentContinuation)
.map(|token| token.len() + 1) // `+ 1` for the extra space added
.unwrap_or_default();
for i in 0..count {
// pos -> beginning of reference line,
// + (i * (1+indent_len + comment_len)) -> beginning of i'th line from pos (possibly including comment token)
// pos -> beginning of reference line,
// + (i * (line_ending_len + indent_len + comment_len)) -> beginning of i'th line from pos (possibly including comment token)
// + indent_len + comment_len -> -> indent for i'th line
ranges.push(Range::point(
pos + (i * (1 + indent_len + comment_len)) + indent_len + comment_len,
pos + (i * (doc.line_ending.len_chars() + indent_len + comment_len))
+ indent_len
+ comment_len,
));
}

View File

@@ -230,38 +230,51 @@ fn force_buffer_close(
buffer_close_by_ids_impl(cx, &document_ids, true)
}
fn buffer_gather_others_impl(editor: &mut Editor) -> Vec<DocumentId> {
let current_document = &doc!(editor).id();
editor
.documents()
.map(|doc| doc.id())
.filter(|doc_id| doc_id != current_document)
.collect()
fn buffer_gather_others_impl(editor: &mut Editor, skip_visible: bool) -> Vec<DocumentId> {
if skip_visible {
let visible_document_ids = editor
.tree
.views()
.map(|view| &view.0.doc)
.collect::<HashSet<_>>();
editor
.documents()
.map(|doc| doc.id())
.filter(|doc_id| !visible_document_ids.contains(doc_id))
.collect()
} else {
let current_document = &doc!(editor).id();
editor
.documents()
.map(|doc| doc.id())
.filter(|doc_id| doc_id != current_document)
.collect()
}
}
fn buffer_close_others(
cx: &mut compositor::Context,
_args: Args,
args: Args,
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
let document_ids = buffer_gather_others_impl(cx.editor);
let document_ids = buffer_gather_others_impl(cx.editor, args.has_flag("skip-visible"));
buffer_close_by_ids_impl(cx, &document_ids, false)
}
fn force_buffer_close_others(
cx: &mut compositor::Context,
_args: Args,
args: Args,
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
let document_ids = buffer_gather_others_impl(cx.editor);
let document_ids = buffer_gather_others_impl(cx.editor, args.has_flag("skip-visible"));
buffer_close_by_ids_impl(cx, &document_ids, true)
}
@@ -321,7 +334,11 @@ fn buffer_previous(
Ok(())
}
fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) -> anyhow::Result<()> {
fn write_impl(
cx: &mut compositor::Context,
path: Option<&str>,
options: WriteOptions,
) -> anyhow::Result<()> {
let config = cx.editor.config();
let jobs = &mut cx.jobs;
let (view, doc) = current!(cx.editor);
@@ -340,14 +357,14 @@ fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) ->
doc.append_changes_to_history(view);
let (view, doc) = current_ref!(cx.editor);
let fmt = if config.auto_format {
let fmt = if config.auto_format && options.auto_format {
doc.auto_format(cx.editor).map(|fmt| {
let callback = make_format_callback(
doc.id(),
doc.version(),
view.id,
fmt,
Some((path.map(Into::into), force)),
Some((path.map(Into::into), options.force)),
);
jobs.add(Job::with_callback(callback).wait_before_exiting());
@@ -358,7 +375,7 @@ fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) ->
if fmt.is_none() {
let id = doc.id();
cx.editor.save(id, path, force)?;
cx.editor.save(id, path, options.force)?;
}
Ok(())
@@ -423,12 +440,25 @@ fn insert_final_newline(doc: &mut Document, view_id: ViewId) {
}
}
#[derive(Debug, Clone, Copy)]
pub struct WriteOptions {
pub force: bool,
pub auto_format: bool,
}
fn write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
write_impl(cx, args.first(), false)
write_impl(
cx,
args.first(),
WriteOptions {
force: false,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)
}
fn force_write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {
@@ -436,7 +466,14 @@ fn force_write(cx: &mut compositor::Context, args: Args, event: PromptEvent) ->
return Ok(());
}
write_impl(cx, args.first(), true)
write_impl(
cx,
args.first(),
WriteOptions {
force: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)
}
fn write_buffer_close(
@@ -448,7 +485,14 @@ fn write_buffer_close(
return Ok(());
}
write_impl(cx, args.first(), false)?;
write_impl(
cx,
args.first(),
WriteOptions {
force: false,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)?;
let document_ids = buffer_gather_paths_impl(cx.editor, args);
buffer_close_by_ids_impl(cx, &document_ids, false)
@@ -463,7 +507,14 @@ fn force_write_buffer_close(
return Ok(());
}
write_impl(cx, args.first(), true)?;
write_impl(
cx,
args.first(),
WriteOptions {
force: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)?;
let document_ids = buffer_gather_paths_impl(cx.editor, args);
buffer_close_by_ids_impl(cx, &document_ids, false)
@@ -644,7 +695,14 @@ fn write_quit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> a
return Ok(());
}
write_impl(cx, args.first(), false)?;
write_impl(
cx,
args.first(),
WriteOptions {
force: false,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)?;
cx.block_try_flush_writes()?;
quit(cx, Args::default(), event)
}
@@ -658,7 +716,14 @@ fn force_write_quit(
return Ok(());
}
write_impl(cx, args.first(), true)?;
write_impl(
cx,
args.first(),
WriteOptions {
force: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)?;
cx.block_try_flush_writes()?;
force_quit(cx, Args::default(), event)
}
@@ -780,7 +845,7 @@ pub fn write_all_impl(
Ok(())
}
fn write_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> {
fn write_all(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
@@ -790,14 +855,14 @@ fn write_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> a
WriteAllOptions {
force: false,
write_scratch: true,
auto_format: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)
}
fn force_write_all(
cx: &mut compositor::Context,
_args: Args,
args: Args,
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
@@ -809,14 +874,14 @@ fn force_write_all(
WriteAllOptions {
force: true,
write_scratch: true,
auto_format: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)
}
fn write_all_quit(
cx: &mut compositor::Context,
_args: Args,
args: Args,
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
@@ -827,7 +892,7 @@ fn write_all_quit(
WriteAllOptions {
force: false,
write_scratch: true,
auto_format: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
)?;
quit_all_impl(cx, false)
@@ -835,7 +900,7 @@ fn write_all_quit(
fn force_write_all_quit(
cx: &mut compositor::Context,
_args: Args,
args: Args,
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
@@ -846,7 +911,7 @@ fn force_write_all_quit(
WriteAllOptions {
force: true,
write_scratch: true,
auto_format: true,
auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name),
},
);
quit_all_impl(cx, true)
@@ -2463,7 +2528,16 @@ fn move_buffer(cx: &mut compositor::Context, args: Args, event: PromptEvent) ->
.path()
.context("Scratch buffer cannot be moved. Use :write instead")?
.clone();
let new_path = args.first().unwrap().to_string();
let new_path: PathBuf = args.first().unwrap().into();
// if new_path is a directory, append the original file name
// to move the file into that directory.
let new_path = old_path
.file_name()
.filter(|_| new_path.is_dir())
.map(|old_file_name| new_path.join(old_file_name))
.unwrap_or(new_path);
if let Err(err) = cx.editor.move_path(&old_path, new_path.as_ref()) {
bail!("Could not move file: {err}");
}
@@ -2562,6 +2636,18 @@ fn noop(_cx: &mut compositor::Context, _args: Args, _event: PromptEvent) -> anyh
Ok(())
}
/// This command accepts a single boolean --skip-visible flag and no positionals.
const BUFFER_CLOSE_OTHERS_SIGNATURE: Signature = Signature {
positionals: (0, Some(0)),
flags: &[Flag {
name: "skip-visible",
alias: Some('s'),
doc: "don't close buffers that are visible",
..Flag::DEFAULT
}],
..Signature::DEFAULT
};
// TODO: SHELL_SIGNATURE should specify var args for arguments, so that just completers::filename can be used,
// but Signature does not yet allow for var args.
@@ -2579,6 +2665,12 @@ const SHELL_COMPLETER: CommandCompleter = CommandCompleter::positional(&[
completers::repeating_filenames,
]);
const WRITE_NO_FORMAT_FLAG: Flag = Flag {
name: "no-format",
doc: "skip auto-formatting",
..Flag::DEFAULT
};
pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
TypableCommand {
name: "quit",
@@ -2641,10 +2733,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
doc: "Close all buffers but the currently focused one.",
fun: buffer_close_others,
completer: CommandCompleter::none(),
signature: Signature {
positionals: (0, Some(0)),
..Signature::DEFAULT
},
signature: BUFFER_CLOSE_OTHERS_SIGNATURE,
},
TypableCommand {
name: "buffer-close-others!",
@@ -2652,10 +2741,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
doc: "Force close all buffers but the currently focused one.",
fun: force_buffer_close_others,
completer: CommandCompleter::none(),
signature: Signature {
positionals: (0, Some(0)),
..Signature::DEFAULT
},
signature: BUFFER_CLOSE_OTHERS_SIGNATURE,
},
TypableCommand {
name: "buffer-close-all",
@@ -2709,6 +2795,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::positional(&[completers::filename]),
signature: Signature {
positionals: (0, Some(1)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2720,6 +2807,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::positional(&[completers::filename]),
signature: Signature {
positionals: (0, Some(1)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2731,6 +2819,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::positional(&[completers::filename]),
signature: Signature {
positionals: (0, Some(1)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2742,6 +2831,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::positional(&[completers::filename]),
signature: Signature {
positionals: (0, Some(1)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2822,6 +2912,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::positional(&[completers::filename]),
signature: Signature {
positionals: (0, Some(1)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2833,6 +2924,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::positional(&[completers::filename]),
signature: Signature {
positionals: (0, Some(1)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2844,6 +2936,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::none(),
signature: Signature {
positionals: (0, Some(0)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2855,6 +2948,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::none(),
signature: Signature {
positionals: (0, Some(0)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2866,6 +2960,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::none(),
signature: Signature {
positionals: (0, Some(0)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},
@@ -2877,6 +2972,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[
completer: CommandCompleter::none(),
signature: Signature {
positionals: (0, Some(0)),
flags: &[WRITE_NO_FORMAT_FLAG],
..Signature::DEFAULT
},
},

View File

@@ -90,7 +90,13 @@ pub fn highlighted_code_block<'a>(
if pos == start {
continue;
}
assert!(pos > start);
// The highlighter should always move forward.
// If the highlighter malfunctions, bail on syntax highlighting and log an error.
debug_assert!(pos > start);
if pos < start {
log::error!("Failed to highlight '{language}': {text:?}");
return styled_multiline_text(text, code_style);
}
let style = syntax_highlight_stack
.iter()

View File

@@ -692,7 +692,8 @@ pub mod completers {
.flatten()
.filter_map(|res| {
let entry = res.ok()?;
if entry.metadata().ok()?.is_file() {
let metadata = entry.metadata().ok()?;
if metadata.is_file() || metadata.is_symlink() {
entry.file_name().into_string().ok()
} else {
None

View File

@@ -772,3 +772,70 @@ async fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> {
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_move_file_when_given_dir_and_filename() -> anyhow::Result<()> {
let dir = tempfile::tempdir()?;
let source_file = tempfile::NamedTempFile::new_in(&dir)?;
let target_file = dir.path().join("new_name.ext");
let mut app = helpers::AppBuilder::new()
.with_file(source_file.path(), None)
.build()?;
test_key_sequence(
&mut app,
Some(format!(":move {}<ret>", target_file.to_string_lossy()).as_ref()),
None,
false,
)
.await?;
assert!(
target_file.is_file(),
"target file '{}' should have been created",
target_file.display()
);
assert!(
!source_file.path().exists(),
"Source file '{}' should have been removed",
source_file.path().display()
);
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn test_move_file_when_given_dir_only() -> anyhow::Result<()> {
let source_dir = tempfile::tempdir()?;
let target_dir = tempfile::tempdir()?;
let source_file = source_dir.path().join("file.ext");
std::fs::File::create(&source_file)?;
let mut app = helpers::AppBuilder::new()
.with_file(&source_file, None)
.build()?;
test_key_sequence(
&mut app,
Some(format!(":move {}<ret>", target_dir.path().to_string_lossy()).as_ref()),
None,
false,
)
.await?;
let target_file = target_dir.path().join("file.ext");
assert!(
target_file.is_file(),
"target file '{}' should have been created",
target_file.display()
);
assert!(
!source_file.exists(),
"Source file '{}' should have been removed",
source_file.display()
);
Ok(())
}

View File

@@ -95,6 +95,7 @@ impl Capabilities {
}
}
/// Terminal backend supporting a wide variety of terminals
pub struct CrosstermBackend<W: Write> {
buffer: W,
capabilities: Capabilities,

View File

@@ -1,3 +1,5 @@
//! Provides interface for controlling the terminal
use std::io;
use crate::{buffer::Cell, terminal::Config};
@@ -12,19 +14,32 @@ pub use self::crossterm::CrosstermBackend;
mod test;
pub use self::test::TestBackend;
/// Representation of a terminal backend.
pub trait Backend {
/// Claims the terminal for TUI use.
fn claim(&mut self, config: Config) -> Result<(), io::Error>;
/// Update terminal configuration.
fn reconfigure(&mut self, config: Config) -> Result<(), io::Error>;
/// Restores the terminal to a normal state, undoes `claim`
fn restore(&mut self, config: Config) -> Result<(), io::Error>;
/// Forcibly resets the terminal, ignoring errors and configuration
fn force_restore() -> Result<(), io::Error>;
/// Draws styled text to the terminal
fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>
where
I: Iterator<Item = (u16, u16, &'a Cell)>;
/// Hides the cursor
fn hide_cursor(&mut self) -> Result<(), io::Error>;
/// Sets the cursor to the given shape
fn show_cursor(&mut self, kind: CursorKind) -> Result<(), io::Error>;
/// Gets the current position of the cursor
fn get_cursor(&mut self) -> Result<(u16, u16), io::Error>;
/// Sets the cursor to the given position
fn set_cursor(&mut self, x: u16, y: u16) -> Result<(), io::Error>;
/// Clears the terminal
fn clear(&mut self) -> Result<(), io::Error>;
/// Gets the size of the terminal in cells
fn size(&self) -> Result<Rect, io::Error>;
/// Flushes the terminal buffer
fn flush(&mut self) -> Result<(), io::Error>;
}

View File

@@ -1,3 +1,4 @@
//! Contents of a terminal screen. A [Buffer] is made up of [Cell]s.
use crate::text::{Span, Spans};
use helix_core::unicode::width::UnicodeWidthStr;
use std::cmp::min;
@@ -5,7 +6,7 @@ use unicode_segmentation::UnicodeSegmentation;
use helix_view::graphics::{Color, Modifier, Rect, Style, UnderlineStyle};
/// A buffer cell
/// One cell of the terminal. Contains one stylized grapheme.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Cell {
pub symbol: String,
@@ -17,28 +18,33 @@ pub struct Cell {
}
impl Cell {
/// Set the cell's grapheme
pub fn set_symbol(&mut self, symbol: &str) -> &mut Cell {
self.symbol.clear();
self.symbol.push_str(symbol);
self
}
/// Set the cell's grapheme to a [char]
pub fn set_char(&mut self, ch: char) -> &mut Cell {
self.symbol.clear();
self.symbol.push(ch);
self
}
/// Set the foreground [Color]
pub fn set_fg(&mut self, color: Color) -> &mut Cell {
self.fg = color;
self
}
/// Set the background [Color]
pub fn set_bg(&mut self, color: Color) -> &mut Cell {
self.bg = color;
self
}
/// Set the [Style] of the cell
pub fn set_style(&mut self, style: Style) -> &mut Cell {
if let Some(c) = style.fg {
self.fg = c;
@@ -58,6 +64,7 @@ impl Cell {
self
}
/// Returns the current style of the cell
pub fn style(&self) -> Style {
Style::default()
.fg(self.fg)
@@ -67,6 +74,7 @@ impl Cell {
.add_modifier(self.modifier)
}
/// Resets the cell to a default blank state
pub fn reset(&mut self) {
self.symbol.clear();
self.symbol.push(' ');
@@ -495,6 +503,8 @@ impl Buffer {
(x_offset as u16, y)
}
/// Print at most the first `width` characters of a [Spans] if enough space is available
/// until the end of the line. Appends a `…` at the end of truncated lines.
pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
// prevent panic if out of range
if !self.in_bounds(x, y) || width == 0 {
@@ -536,6 +546,8 @@ impl Buffer {
(x_offset as u16, y)
}
/// Print at most the first `width` characters of a [Spans] if enough space is available
/// until the end of the line
pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
let mut remaining_width = width;
let mut x = x;
@@ -557,6 +569,8 @@ impl Buffer {
(x, y)
}
/// Print at most the first `width` characters of a [Span] if enough space is available
/// until the end of the line
pub fn set_span(&mut self, x: u16, y: u16, span: &Span, width: u16) -> (u16, u16) {
self.set_stringn(x, y, span.content.as_ref(), width as usize, span.style)
}
@@ -573,6 +587,7 @@ impl Buffer {
}
}
/// Set all cells in the [area](Rect) to the given [Style]
pub fn set_style(&mut self, area: Rect, style: Style) {
for y in area.top()..area.bottom() {
for x in area.left()..area.right() {

View File

@@ -1,3 +1,5 @@
//! Layout engine for terminal
use std::cell::RefCell;
use std::collections::HashMap;
@@ -7,6 +9,7 @@ use cassowary::{Constraint as CassowaryConstraint, Expression, Solver, Variable}
use helix_view::graphics::{Margin, Rect};
/// Enum of all corners
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub enum Corner {
TopLeft,
@@ -15,12 +18,14 @@ pub enum Corner {
BottomLeft,
}
/// Direction a [Rect] should be split
#[derive(Debug, Hash, Clone, PartialEq, Eq)]
pub enum Direction {
Horizontal,
Vertical,
}
/// Describes requirements of a [Rect] to be split
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Constraint {
// TODO: enforce range 0 - 100
@@ -46,6 +51,7 @@ impl Constraint {
}
}
/// How content should be aligned
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Alignment {
Left,
@@ -53,6 +59,7 @@ pub enum Alignment {
Right,
}
/// Description of a how a [Rect] should be split
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Layout {
direction: Direction,
@@ -75,6 +82,7 @@ impl Default for Layout {
}
impl Layout {
/// Returns a layout with the given [Constraint]s.
pub fn constraints<C>(mut self, constraints: C) -> Layout
where
C: Into<Vec<Constraint>>,
@@ -83,21 +91,25 @@ impl Layout {
self
}
/// Returns a layout wit the given margins on all sides.
pub const fn margin(mut self, margin: u16) -> Layout {
self.margin = Margin::all(margin);
self
}
/// Returns a layout with the given horizontal margins.
pub const fn horizontal_margin(mut self, horizontal: u16) -> Layout {
self.margin.horizontal = horizontal;
self
}
/// Returns a layout with the given vertical margins.
pub const fn vertical_margin(mut self, vertical: u16) -> Layout {
self.margin.vertical = vertical;
self
}
/// Returns a layout with the given [Direction].
pub const fn direction(mut self, direction: Direction) -> Layout {
self.direction = direction;
self

View File

@@ -1,3 +1,5 @@
//! Common TUI symbols including blocks, bars, braille, lines
pub mod block {
pub const FULL: &str = "";
pub const SEVEN_EIGHTHS: &str = "";

View File

@@ -1,3 +1,6 @@
//! Terminal interface provided through the [Terminal] type.
//! Frontend for [Backend]
use crate::{backend::Backend, buffer::Buffer};
use helix_view::editor::Config as EditorConfig;
use helix_view::graphics::{CursorKind, Rect};
@@ -17,6 +20,7 @@ pub struct Viewport {
resize_behavior: ResizeBehavior,
}
/// Terminal configuration
#[derive(Debug)]
pub struct Config {
pub enable_mouse_capture: bool,
@@ -47,7 +51,7 @@ pub struct TerminalOptions {
pub viewport: Viewport,
}
/// Interface to the terminal backed by Termion
/// Interface to the terminal backed by crossterm
#[derive(Debug)]
pub struct Terminal<B>
where

View File

@@ -331,6 +331,7 @@ impl<'a> Table<'a> {
}
}
/// Track [Table] scroll offset and selection
#[derive(Debug, Default, Clone)]
pub struct TableState {
pub offset: usize,

View File

@@ -9,8 +9,6 @@ categories.workspace = true
repository.workspace = true
homepage.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
helix-core = { path = "../helix-core" }
helix-event = { path = "../helix-event" }

View File

@@ -35,6 +35,7 @@ struct DiffInner {
hunks: Vec<Hunk>,
}
/// Representation of a diff that can be updated.
#[derive(Clone, Debug)]
pub struct DiffHandle {
channel: UnboundedSender<Event>,
@@ -65,10 +66,12 @@ impl DiffHandle {
(differ, handle)
}
/// Switch base and modified texts' roles
pub fn invert(&mut self) {
self.inverted = !self.inverted;
}
/// Load the actual diff
pub fn load(&self) -> Diff {
Diff {
diff: self.diff.read(),
@@ -89,6 +92,7 @@ impl DiffHandle {
self.update_document_impl(doc, self.inverted, Some(RenderLock { lock, timeout }))
}
/// Updates the base text of the diff. Returns if the update was successful.
pub fn update_diff_base(&self, diff_base: Rope) -> bool {
self.update_document_impl(diff_base, !self.inverted, None)
}
@@ -128,6 +132,7 @@ pub struct Diff<'a> {
}
impl Diff<'_> {
/// Returns the base [Rope] of the [Diff]
pub fn diff_base(&self) -> &Rope {
if self.inverted {
&self.diff.doc
@@ -136,6 +141,7 @@ impl Diff<'_> {
}
}
/// Returns the [Rope] being compared against
pub fn doc(&self) -> &Rope {
if self.inverted {
&self.diff.diff_base
@@ -166,6 +172,7 @@ impl Diff<'_> {
self.len() == 0
}
/// Gives the index of the first hunk after the given line, if one exists.
pub fn next_hunk(&self, line: u32) -> Option<u32> {
let hunk_range = if self.inverted {
|hunk: &Hunk| hunk.before.clone()
@@ -192,6 +199,7 @@ impl Diff<'_> {
}
}
/// Gives the index of the first hunk before the given line, if one exists.
pub fn prev_hunk(&self, line: u32) -> Option<u32> {
let hunk_range = if self.inverted {
|hunk: &Hunk| hunk.before.clone()
@@ -235,6 +243,7 @@ impl Diff<'_> {
}
}
/// Returns the index of the hunk containing the given line if it exists.
pub fn hunk_at(&self, line: u32, include_removal: bool) -> Option<u32> {
let hunk_range = if self.inverted {
|hunk: &Hunk| hunk.before.clone()

View File

@@ -1,3 +1,7 @@
//! `helix_vcs` provides types for working with diffs from a Version Control System (VCS).
//! Currently `git` is the only supported provider for diffs, but this architecture allows
//! for other providers to be added in the future.
use anyhow::{anyhow, bail, Result};
use arc_swap::ArcSwap;
use std::{
@@ -16,12 +20,16 @@ mod status;
pub use status::FileChange;
/// Contains all active diff providers. Diff providers are compiled in via features. Currently
/// only `git` is supported.
#[derive(Clone)]
pub struct DiffProviderRegistry {
providers: Vec<DiffProvider>,
}
impl DiffProviderRegistry {
/// Get the given file from the VCS. This provides the unedited document as a "base"
/// for a diff to be created.
pub fn get_diff_base(&self, file: &Path) -> Option<Vec<u8>> {
self.providers
.iter()
@@ -35,6 +43,7 @@ impl DiffProviderRegistry {
})
}
/// Get the current name of the current [HEAD](https://stackoverflow.com/questions/2304087/what-is-head-in-git).
pub fn get_current_head_name(&self, file: &Path) -> Option<Arc<ArcSwap<Box<str>>>> {
self.providers
.iter()
@@ -75,6 +84,7 @@ impl Default for DiffProviderRegistry {
let providers = vec![
#[cfg(feature = "git")]
DiffProvider::Git,
DiffProvider::None,
];
DiffProviderRegistry { providers }
}
@@ -85,7 +95,7 @@ impl Default for DiffProviderRegistry {
///
/// `Copy` is simply to ensure the `clone()` call is the simplest it can be.
#[derive(Copy, Clone)]
pub enum DiffProvider {
enum DiffProvider {
#[cfg(feature = "git")]
Git,
None,

View File

@@ -1,18 +1,16 @@
use std::path::{Path, PathBuf};
/// States for a file having been changed.
pub enum FileChange {
Untracked {
path: PathBuf,
},
Modified {
path: PathBuf,
},
Conflict {
path: PathBuf,
},
Deleted {
path: PathBuf,
},
/// Not tracked by the VCS.
Untracked { path: PathBuf },
/// File has been modified.
Modified { path: PathBuf },
/// File modification is in conflict with a different update.
Conflict { path: PathBuf },
/// File has been deleted.
Deleted { path: PathBuf },
/// File has been renamed.
Renamed {
from_path: PathBuf,
to_path: PathBuf,

View File

@@ -980,6 +980,7 @@ impl Document {
// mark changes up to now as saved
let current_rev = self.get_current_revision();
let doc_id = self.id();
let atomic_save = self.config.load().atomic_save;
let encoding_with_bom_info = (self.encoding, self.has_bom);
let last_saved_time = self.last_saved_time;
@@ -1029,7 +1030,7 @@ impl Document {
// Assume it is a hardlink to prevent data loss if the metadata cant be read (e.g. on certain Windows configurations)
let is_hardlink = helix_stdx::faccess::hardlink_count(&write_path).unwrap_or(2) > 1;
let backup = if path.exists() {
let backup = if path.exists() && atomic_save {
let path_ = write_path.clone();
// hacks: we use tempfile to handle the complex task of creating
// non clobbered temporary path for us we don't want

View File

@@ -345,6 +345,10 @@ pub struct Config {
pub default_line_ending: LineEndingConfig,
/// Whether to automatically insert a trailing line-ending on write if missing. Defaults to `true`.
pub insert_final_newline: bool,
/// Whether to use atomic operations to write documents to disk.
/// This prevents data loss if the editor is interrupted while writing the file, but may
/// confuse some file watching/hot reloading programs. Defaults to `true`.
pub atomic_save: bool,
/// Whether to automatically remove all trailing line-endings after the final one on write.
/// Defaults to `false`.
pub trim_final_newlines: bool,
@@ -1020,6 +1024,7 @@ impl Default for Config {
workspace_lsp_roots: Vec::new(),
default_line_ending: LineEndingConfig::default(),
insert_final_newline: true,
atomic_save: true,
trim_final_newlines: false,
trim_trailing_whitespace: false,
smart_tab: Some(SmartTabConfig::default()),

View File

@@ -300,7 +300,7 @@ impl Theme {
/// Interpret a Highlight with the RGB foreground
fn decode_rgb_highlight(highlight: Highlight) -> Option<(u8, u8, u8)> {
(highlight.get() > Self::RGB_START).then(|| {
let [b, g, r, ..] = (highlight.get() + 1).to_ne_bytes();
let [b, g, r, ..] = (highlight.get() + 1).to_le_bytes();
(r, g, b)
})
}
@@ -309,7 +309,7 @@ impl Theme {
pub fn rgb_highlight(r: u8, g: u8, b: u8) -> Highlight {
// -1 because highlight is "non-max": u32::MAX is reserved for the null pointer
// optimization.
Highlight::new(u32::from_ne_bytes([b, g, r, u8::MAX]) - 1)
Highlight::new(u32::from_le_bytes([b, g, r, u8::MAX]) - 1)
}
#[inline]

View File

@@ -32,9 +32,11 @@ csharp-ls = { command = "csharp-ls" }
cuelsp = { command = "cuelsp" }
dart = { command = "dart", args = ["language-server", "--client-id=helix"] }
dhall-lsp-server = { command = "dhall-lsp-server" }
djlsp = { command = "djlsp" }
docker-langserver = { command = "docker-langserver", args = ["--stdio"] }
docker-compose-langserver = { command = "docker-compose-langserver", args = ["--stdio"]}
dot-language-server = { command = "dot-language-server", args = ["--stdio"] }
dts-lsp = { command = "dts-lsp" }
earthlyls = { command = "earthlyls" }
elixir-ls = { command = "elixir-ls", config = { elixirLS.dialyzerEnabled = false } }
elm-language-server = { command = "elm-language-server" }
@@ -110,6 +112,7 @@ ruby-lsp = { command = "ruby-lsp" }
serve-d = { command = "serve-d" }
slangd = { command = "slangd" }
slint-lsp = { command = "slint-lsp", args = [] }
systemd-lsp = { command = "systemd-lsp" }
solargraph = { command = "solargraph", args = ["stdio"] }
solc = { command = "solc", args = ["--lsp"] }
sourcekit-lsp = { command = "sourcekit-lsp" }
@@ -512,7 +515,6 @@ file-types = [
"css.map",
{ glob = ".jslintrc" },
"jsonl",
"jsonld",
{ glob = ".vuerc" },
{ glob = "composer.lock" },
{ glob = ".watchmanconfig" },
@@ -553,6 +555,17 @@ language-servers = [ "vscode-json-language-server" ]
auto-format = true
indent = { tab-width = 2, unit = " " }
# https://www.w3.org/TR/json-ld/
[[language]]
name = "json-ld"
scope = "source.json-ld"
injection-regex = "json-ld"
grammar = "json"
file-types = ["jsonld"]
language-servers = ["vscode-json-language-server"]
auto-format = true
indent = { tab-width = 2, unit = " " }
[[language]]
name = "json5"
scope = "source.json5"
@@ -944,6 +957,25 @@ indent = { tab-width = 2, unit = " " }
name = "html"
source = { git = "https://github.com/tree-sitter/tree-sitter-html", rev = "cbb91a0ff3621245e890d1c50cc811bffb77a26b" }
[[language]]
name = "htmldjango"
scope = "source.htmldjango"
injection-regex = "htmldjango"
language-servers = ["djlsp", "vscode-html-language-server", "superhtml"]
file-types = []
[language.auto-pairs]
'"' = '"'
'(' = ')'
'[' = ']'
'{' = '}'
'%' = '%'
'<' = '>'
[[grammar]]
name = "htmldjango"
source = { git = "https://github.com/interdependence/tree-sitter-htmldjango", rev = "3a643167ad9afac5d61e092f08ff5b054576fadf" }
[[language]]
name = "python"
scope = "source.python"
@@ -1847,9 +1879,9 @@ source = { git = "https://github.com/camdencheek/tree-sitter-dockerfile", rev =
[[language]]
name = "docker-compose"
scope = "source.yaml.docker-compose"
roots = ["docker-compose.yaml", "docker-compose.yml"]
roots = ["docker-compose.yaml", "docker-compose.yml", "compose.yaml", "compose.yml"]
language-servers = [ "docker-compose-langserver", "yaml-language-server" ]
file-types = [{ glob = "docker-compose.yaml" }, { glob = "docker-compose.yml" }]
file-types = [{ glob = "docker-compose.yaml" }, { glob = "docker-compose.yml" }, { glob = "compose.yaml" }, { glob = "compose.yml" }]
comment-token = "#"
indent = { tab-width = 2, unit = " " }
grammar = "yaml"
@@ -2319,6 +2351,7 @@ file-types = ["dts", "dtsi"]
comment-token = "//"
block-comment-tokens = { start = "/*", end = "*/" }
indent = { tab-width = 4, unit = "\t" }
language-servers = [ "dts-lsp" ]
[[grammar]]
name = "devicetree"
@@ -2388,7 +2421,7 @@ args = { console = "internalConsole", attachCommands = [ "platform select remote
[[grammar]]
name = "odin"
source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-odin", rev = "b5f668ef8918aab13812ce73acd89fe191fb8c5e" }
source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-odin", rev = "6c6b07e354a52f8f2a9bc776cbc262a74e74fd26" }
[[language]]
name = "meson"
@@ -2922,6 +2955,7 @@ scope = "source.dtd"
injection-regex = "dtd"
file-types = ["dtd", "ent"]
indent = {tab-width = 2, unit = " "}
block-comment-tokens = { start = "<!--", end = "-->" }
[language.auto-pairs]
'(' = ')'
@@ -2965,15 +2999,12 @@ indent = { tab-width = 4, unit = "\t" }
grammar = "bash"
[[language]]
name = "ini"
name = "systemd"
scope = "source.ini"
file-types = [
"ini",
# Systemd unit files
"service",
"automount",
"desktop",
{ glob = "mimeapps.list" },
"device",
"mount",
"nspawn",
@@ -2985,6 +3016,19 @@ file-types = [
"target",
"timer",
{ glob = "systemd/**/*.conf" },
]
injection-regex = "systemd"
comment-token = "#"
grammar = "ini"
language-servers = ["systemd-lsp"]
[[language]]
name = "ini"
scope = "source.ini"
file-types = [
"ini",
"desktop",
{ glob = "mimeapps.list" },
# Podman quadlets
"container",
"volume",
@@ -4401,6 +4445,12 @@ injection-regex = "rust-format-args"
name = "rust-format-args"
source = { git = "https://github.com/nik-rev/tree-sitter-rust-format-args", rev = "84ffe550e261cf5ea40a0ec31849ba2443bae99f" }
[[language]]
name = "rust-format-args-macro"
scope = "source.rust-format-args-macro"
file-types = []
grammar = "rust"
[[language]]
name = "clarity"
scope = "source.clar"

View File

@@ -2,6 +2,8 @@
"require"
"replace"
"go"
"toolchain"
"tool"
"exclude"
"retract"
"module"

View File

@@ -0,0 +1,26 @@
[
(unpaired_comment)
(paired_comment)
] @comment
[
"{{"
"}}"
"{%"
"%}"
(end_paired_statement)
] @punctuation.bracket
[
(tag_name)
] @function
(variable_name) @variable
(filter_name) @function
(filter_argument) @variable.parameter
(keyword) @keyword
(operator) @operator
(keyword_operator) @keyword.operator
(number) @constant.numeric
(boolean) @constant.builtin.boolean
(string) @string

View File

@@ -0,0 +1,3 @@
((content) @injection.content
(#set! injection.language "html")
(#set! injection.combined))

View File

@@ -12,4 +12,4 @@
(setting
(setting_name) @variable.other.member
(setting_value) @string)
((setting_value) @string)?)

View File

@@ -0,0 +1,43 @@
; inherits: json
; https://www.w3.org/TR/json-ld/#syntax-tokens-and-keywords
((string (string_content) @keyword)
(#any-of? @keyword
"@base"
"@container"
"@context"
"@direction"
"@graph"
"@id"
"@import"
"@included"
"@index"
"@json"
"@language"
"@list"
"@nest"
"@none"
"@prefix"
"@propagate"
"@protected"
"@reverse"
"@set"
"@type"
"@value"
"@version"
"@vocab"))
((pair
value: (string (string_content) @string.special.url))
(#match? @string.special.url "^https?://"))
((array
(string (string_content) @string.special.url))
(#match? @string.special.url "^https?://"))
; https://www.w3.org/TR/json-ld/#dfn-base-direction
((pair
key: (string (string_content) @keyword)
value: (string (string_content) @type.enum.variant))
(#eq? @keyword "@direction")
(#any-of? @type.enum.variant "ltr" "rtl"))

View File

@@ -0,0 +1 @@
; inherits: json

View File

@@ -0,0 +1 @@
; inherits: json

View File

@@ -57,6 +57,7 @@
"case"
"where"
"break"
"or_break"
(fallthrough_statement)
] @keyword.control.conditional
@@ -73,6 +74,7 @@
"for"
"do"
"continue"
"or_continue"
] @keyword.control.repeat
[

View File

@@ -6,6 +6,7 @@
(struct)
(parameters)
(tuple_type)
(struct_type)
(call_expression)
(switch_case)
] @indent
@@ -21,3 +22,4 @@
(union_declaration "}" @outdent)
(struct_declaration "}" @outdent)
(struct "}" @outdent)
(struct_type "}" @outdent)

View File

@@ -0,0 +1 @@
; inherits: rust

View File

@@ -0,0 +1 @@
; inherits: rust

View File

@@ -0,0 +1,13 @@
; inherits: rust
; HACK: This language is the same as Rust but all strings are injected
; with rust-format-args. Rust injects this into known macros which use
; the format args syntax. This can cause false-positive highlights but
; those are expected to be rare.
([
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
]
(#set! injection.language "rust-format-args")
(#set! injection.include-children))

View File

@@ -0,0 +1 @@
; inherits: rust

View File

@@ -0,0 +1 @@
; inherits: rust

View File

@@ -103,8 +103,6 @@
; the `format_args!` syntax.
;
; This language is injected into a hard-coded set of macros.
; 1st argument is `format_args!`
(
(macro_invocation
macro:
@@ -113,13 +111,11 @@
name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree . [
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
]
)
(token_tree) @injection.content
)
(#any-of? @_macro_name
; 1st argument is `format_args!`
; std
"print" "println" "eprint" "eprintln"
"format" "format_args" "todo" "panic"
@@ -140,63 +136,22 @@
"eyre"
; miette
"miette"
)
(#set! injection.language "rust-format-args")
(#set! injection.include-children)
)
; 2nd argument is `format_args!`
(
(macro_invocation
macro:
[
(scoped_identifier
name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree
. (_)
. [
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
]
)
)
(#any-of? @_macro_name
; 2nd argument is `format_args!`
; std
"write" "writeln" "assert" "debug_assert"
; defmt
"expect" "unwrap"
; ratatui
"span"
)
(#set! injection.language "rust-format-args")
(#set! injection.include-children)
)
; 3rd argument is `format_args!`
(
(macro_invocation
macro:
[
(scoped_identifier
name: (_) @_macro_name)
(identifier) @_macro_name
]
(token_tree
. (_)
. (_)
. [
(string_literal (string_content) @injection.content)
(raw_string_literal (string_content) @injection.content)
]
)
)
(#any-of? @_macro_name
; 3rd argument is `format_args!`
; std
"assert_eq" "debug_assert_eq" "assert_ne" "debug_assert_ne"
)
(#set! injection.language "rust-format-args")
(#set! injection.language "rust-format-args-macro")
(#set! injection.include-children)
)

View File

@@ -0,0 +1 @@
; inherits: ini

View File

@@ -0,0 +1,126 @@
# Author: spentbliss <zyhkekrz.hatbox475@passinbox.com>
# License: MIT (originally by NTBBloodbath)
"ui.background" = { bg = "bg", fg = "fg" }
"ui.text" = "fg"
"ui.text.focus" = { bg = "bg_highlight", fg = "cyan" }
"ui.cursor" = { bg = "cyan", fg = "bg" }
"ui.linenr" = "grey"
"ui.linenr.selected" = "yellow"
"ui.statusline" = { fg = "blue" }
"ui.selection" = { bg = "bg_highlight" }
"ui.selection.primary" = { bg = "bg_highlight" }
"ui.virtual.ruler" = { bg = "bg_highlight" }
# Markdown Highlighting
"markup.raw" = { fg = "blue", bg = "bg" }
"markup.raw.inline" = { fg = "orange" }
"markup.heading.1" = { fg = "#E99BEA", bg = "#4F4258"}
"markup.heading.2" = { fg = "#51AFEF", bg = "#2F4456" }
"markup.heading.3" = { fg = "#A9A1E1", bg = "#3F4153" }
"markup.heading.4" = { fg = "#98BE65", bg = "#3C453D" }
"markup.heading.5" = { fg = "#ECBE7B", bg = "#4B4641" }
"markup.heading.6" = { fg = "#DA8549", bg = "#483C39" }
"markup.list" = { fg = "magenta" }
"markup.bold" = { fg = "orange", modifiers = ["bold"] }
"markup.italic" = { fg = "orange" }
"markup.strikethrough" = { fg = "red", modifiers = ["crossed_out"] }
"markup.link" = { fg = "cyan" }
"markup.quote" = { fg = "fg" }
# Syntax Highlighting for Code
"comment" = { fg = "grey" }
"comment.line" = { fg = "grey" }
"comment.block" = { fg = "grey" }
"comment.documentation" = { fg = "blue" }
"keyword" = "blue"
"keyword.control" = "blue"
"keyword.operator" = "fg"
"keyword.function" = "blue"
"keyword.directive" = "green"
"keyword.storage" = "blue"
"type" = "yellow"
"type.builtin" = "yellow"
"type.enum.variant" = "purple"
"function" = "magenta"
"function.builtin" = "fg"
"function.method" = "fg"
"function.macro" = "purple"
"variable" = "fg"
"variable.builtin" = "red"
"variable.parameter" = "fg"
"string" = "green"
"string.special" = "green"
"constant" = "orange"
"constant.builtin" = "orange"
"constant.numeric" = "orange"
"constant.character" = "orange"
"constant.boolean" = "orange"
"attribute" = "magenta"
"operator" = "blue"
"tag" = { fg = "magenta", modifiers = ["bold"] }
"tag.special" = { fg = "orange", modifiers = ["bold"] }
"namespace" = "blue"
"macro" = "orange"
"label" = "red"
# Interface specific
"ui.cursorline.primary" = { bg = "bg_highlight" }
"ui.cursorline.secondary" = { bg = "bg_alt" }
"ui.cursorcolumn.primary" = { bg = "bg_highlight" }
"ui.cursorcolumn.secondary" = { bg = "bg_alt" }
"ui.statusline.normal" = { fg = "bg", bg = "blue" }
"ui.statusline.insert" = { fg = "bg", bg = "green" }
"ui.statusline.select" = { fg = "bg", bg = "purple" }
# Git changes indicator
"diff.plus" = "green"
"diff.plus.gutter" = "green"
"diff.minus" = "red"
"diff.minus.gutter" = "red"
"diff.delta" = "green"
"diff.delta.gutter" = "green"
"diff.delta.moved" = "orange"
"diff.delta.conflict" = "purple"
# Diagnostic styles
"warning" = { fg = "yellow", modifiers = ["bold"] }
"error" = { fg = "red", modifiers = ["bold"] }
"info" = { fg = "cyan", modifiers = ["bold"] }
"hint" = { fg = "blue", modifiers = ["bold"] }
"diagnostic.error" = { fg = "red" }
"diagnostic.warning" = { fg = "yellow" }
"diagnostic.info" = { fg = "cyan" }
"diagnostic.hint" = { fg = "blue" }
# Popups for documentation or file picker
"ui.popup" = { fg = "fg", bg = "bg" }
"ui.popup.info" = { fg = "fg", bg = "bg" }
"ui.menu" = { fg = "fg", bg = "bg" }
"ui.menu.selected" = { fg = "cyan", bg = "bg_highlight" }
# Additional overrides
"ui.virtual.whitespace" = "grey"
"ui.virtual.indent-guide" = { fg = "grey" }
[palette]
bg = "#282C34"
fg = "#BBC2CF"
grey = "#5B6268"
blue = "#51AFEF"
green = "#98BE65"
cyan = "#46D9FF"
red = "#FF6C6B"
yellow = "#ECBE7B"
purple = "#A8A1E1"
magenta = "#C678DD"
orange = "#DA8548"
bg_alt = "#21242B"
bg_highlight = "#3C4048"

View File

@@ -0,0 +1,23 @@
MIT License
Copyright (c) 2025 NTBBloodbath
This theme has been ported by spentbliss <zyhkekrz.hatbox475@passinbox.com>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -36,6 +36,7 @@
"ui.virtual.indent-guide" = { fg = "black" } # Vertical indent width guides
"ui.virtual.inlay-hint" = { fg = "comment", bg = "bg2" } # Default style for inlay hints of all kinds
"ui.virtual.jump-label" = { fg = "blue", modifiers = ["bold"] } # Style for virtual jump labels
"ui.virtual.wrap" = { fg = "fg3" } # Soft-wrap indicator.
"ui.statusline" = { fg = "fg2", bg = "bg0" } # Status line.
"ui.statusline.inactive" = { fg = "fg3", bg = "bg0" } # Status line in unfocused windows.

View File

@@ -45,7 +45,7 @@
"ui.virtual.inlay-hint" = { fg = "subtle" }
"ui.menu" = { fg = "subtle", bg = "surface" }
"ui.menu.selected" = { fg = "text" }
"ui.menu.selected" = { fg = "text", bg = "overlay" }
"ui.menu.scroll" = { fg = "muted", bg = "highlight_med" }
"ui.selection" = { bg = "overlay" }