Compare commits

...

1686 Commits

Author SHA1 Message Date
Michael Davis
66276ce630 Changelog notes for 22.08.1 (#3639) 2022-09-01 12:07:46 -05:00
A-Walrus
45dbcb6783 Fix closing buffer with custom keymap (#3633)
* Fix closing buffer with custom keymap

* Add comment explaining if
2022-09-02 01:59:39 +09:00
Fanda Vacek
ec28b2b5cc Change MonokaiProSpectrum theme error background from red to magenta. (#3627)
Co-authored-by: Fanda Vacek <fvacek@elektroline.cz>
2022-09-01 07:45:22 -05:00
Charles Hall
04e1cbe33f fix: typo in tutor about searching compared to vim (#3625) 2022-09-01 07:41:15 -05:00
Blaž Hrastnik
5c2b77b41f Make mode editor-wide rather than per-document 2022-09-01 16:14:38 +09:00
Blaž Hrastnik
10d9355b34 Update deps 2022-09-01 16:00:19 +09:00
Saber Haj Rabiee
1cbf552554 fix: prevents storing last prompt if is top of stack (#3609) 2022-09-01 10:29:15 +09:00
Michael Davis
ee94031fc4 Bump VERSION to 22.08 2022-08-31 11:43:51 -05:00
Michael Davis
22c5f2474d Add changelog entries for 22.08 2022-08-31 11:37:17 -05:00
Michael Davis
7c34f20dca Fix Prompt::handle_event compilation 2022-08-31 11:37:17 -05:00
Frojdholm
4c9f144dac fix: Recalculate completion when going through prompt history (#3193)
* fix: Recalculate completion when going through prompt history

* Update completion when the prompt line is changed

It should not be possible to update the line without also updating the
completion since the completion holds an index into the line.

* Fix Prompt::with_line recalculate completion

with_line was the last function where recalculate completion had to be
done manually. This function now also recalculates the completion so
that it's impossible to forget.

* Exit selection when recalculating completion

Keeping the selection index when the completion has been recalculated
doesn't make sense. This clears the selection automatically, removing
most needs to manually clear it.

* Remove &mut on save_filter

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-09-01 01:26:21 +09:00
Gokul Soumya
e3e71fa36b Show clipboard info in --health output (#2947)
* Show clipboard info in --health output

* health: Separate 'languages' category from 'all'

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-09-01 01:23:45 +09:00
Charlie Groves
5c3f43a7f0 Share the restore_term code between panic and normal exits (#3612)
It was starting to diverge as the normal exit code was restoring the prompt but the panic code
wasn't, and the panic code was disabling bracketed paste but the normal code wasn't.

This changes the panic path slightly in that we won't disable raw mode if exiting alternate screen
and disabling bracketed paste fails. If that happens, things are so busted I don't think it matters
anyway.
2022-09-01 01:23:21 +09:00
Michael Davis
93c6a337c4 Avoid command execution hooks on closed docs (#3613)
Fixes a panic with a config like:

    [keys.normal.space]
    x = [":buffer-close"]

by bailing out of the command-execution handling if the document
doesn't exist after handling a command.
2022-09-01 01:20:55 +09:00
Michael Davis
83f177d270 Refactor goto_ts_object_impl as a motion (#3264)
This refactor changes the overall structure of the goto_ts_object_impl
command without removing any functionality from its behavior. The
refactored motion:

* acts on all selections instead of reducing to one selection
* may be repeated with the `repeat_last_motion` (A-.) command
* informs the user when the syntax-tree is not accessible in the current buffer
2022-08-31 17:48:33 +09:00
Michael Davis
7547a961bb Discard LSP publishDiagnostic when LS is not initialized (#3403)
This is invalid according to the [LSP spec]:

> In addition the server is not allowed to send any requests
> or notifications to the client until it has responded with an
> InitializeResult, with the exception that during the initialize
> request the server is allowed to send the notifications
> window/showMessage, window/logMessage and telemetry/event as well
> as the window/showMessageRequest request to the client.

So we should discard the message when the language server is not
yet initialized. This can happen if the server sends
textDocument/publishDiagnostics before responding to the initialize
request. clojure-lsp appears to exhibit this behavior in the wild.

[LSP Spec]: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize
2022-08-31 17:47:18 +09:00
Michael Davis
03f0ef93ac Update tree-sitter-rust to latest
There don't appear to be any regressions from the updates.
Also included is a fix which highlights the "#" as in attributes
as punctuation. This was previously unhighlighted.
2022-08-31 17:46:34 +09:00
Michael Davis
ac669ade05 erlang: Fix highlighting of empty records
For example

    -record(state, {})

Would not highlight `state` as a type since the alternation didn't
allow for an empty tuple. Allowing the inner atom of the tuple to be
optional fixes this case.
2022-08-31 17:46:34 +09:00
Michael Davis
acf3599723 erlang: Use Edoc style auto-pairs
Specifically this changes backtic's right-hand-side pair character
to single-quote which is the syntax for inline and block code in
Edoc.
2022-08-31 17:46:34 +09:00
Michael Davis
00d88e540e Fix missing C highlights
* "const" keyword
* booleans
* <=/>= operators
2022-08-31 17:46:34 +09:00
Michael Davis
d7d9ca37e5 Reword the feature_request issue template as enhancement (#3481) 2022-08-31 17:45:49 +09:00
Michael Davis
e441b1c472 packaging: Point to homebrew-core instead of tap (#3513) 2022-08-31 17:45:38 +09:00
Michael Davis
73d5bd739e Delete invalid indents.scm queries 2022-08-31 17:45:23 +09:00
Michael Davis
4e4c6da3bf Add query-check xtask 2022-08-31 17:45:23 +09:00
Michael Davis
fa1dc7e508 tree-sitter: Prevent panic on loading queries 2022-08-31 17:45:23 +09:00
Michael Davis
4c789cfbda tree-sitter: Refactor lazy query loading
The code for loading queries can be shared between indent and
textobjects queries. In both cases we want to kick an error
message out to the logs.
2022-08-31 17:45:23 +09:00
Blaž Hrastnik
12ddd03d3b fix: Don't translate mouse up events as down 2022-08-31 11:36:18 +09:00
Michael Davis
701cea54d2 jumplist: Add documents to view history (#3593)
This change adds documents to the view's document history Vec.
(This is used by `ga` for example to access the last buffer.)

Previously, a sequence like so would have confusing behavior:

1. Open file A: any document with an active language server
2. Find some definition that lives in another file - file B - with `gd`
3. Jump back in the jumplist with `C-o` to file A
4. Use `ga` intending to switch back to file B

The behavior prior to this change was that `ga` would switch to file
A: you could not use `ga` to switch to file B.
2022-08-31 10:45:47 +09:00
Lucy
404db2ebee Move mode transition logic to handle_keymap_event() (#2634)
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-08-31 10:44:06 +09:00
A-Walrus
78189dd9c1 Fix extra selection with regex anchors (^,$) (#3598)
Also added a bunch of tests to ensure correct behaviour
2022-08-31 10:42:58 +09:00
Michael Davis
9e24f2aa81 Use the original document and view for mode transition hooks (#3508)
When changing focus, the lookup with `current!` may change the
view and end up executing mode transition hooks on the newly
focused view. We should use the same view and document to execute
mode transition hooks so that switching away from a view triggers
history save points.
2022-08-31 10:34:04 +09:00
Alexander Brevig
16525349db Themes update (#3587)
* lint: snazzy

* lint: pop-dark

* lint: penumbra+

* lint: noctis_bordo

* lint: ingrid

* lint: flatwhite

* lint: doom_acario_dark

* lint: dark_plus

* lint: boo_berry

* fix: use 47345E per author instruction

* lint: bogster

* lint: everforest

* lint: acme

* lint: serika

* fix: use nasty_red per author suggestion

* lint: nord

* lint: dracula

* lint: gruvbox

* fix: cursorline gruvbox

* lint: autumn

* fix: no fg for cursorline

* lint: ayu

* lint: rose_pine

* lint: monokai

* lint: solarized

* lint: spacebones

* fix: penumbra bg!=sky

* Update runtime/themes/ayu_light.toml

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* Update runtime/themes/ayu_light.toml

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* fix: fg for ui.help thanks @pickfire

* fix: ingrid with input from @intarga

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2022-08-31 10:27:40 +09:00
dependabot[bot]
86b80e6ce6 build(deps): bump iana-time-zone from 0.1.44 to 0.1.47 (#3611)
Bumps [iana-time-zone](https://github.com/strawlab/iana-time-zone) from 0.1.44 to 0.1.47.
- [Release notes](https://github.com/strawlab/iana-time-zone/releases)
- [Changelog](https://github.com/strawlab/iana-time-zone/blob/main/CHANGELOG.md)
- [Commits](https://github.com/strawlab/iana-time-zone/compare/0.1.44...v0.1.47)

---
updated-dependencies:
- dependency-name: iana-time-zone
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-31 08:47:03 +09:00
Kristoffer Flottorp
1de17a2530 Fix fleetish theme (#3607)
Co-authored-by: krfl <kr.fl@outlook.com>
2022-08-30 08:15:38 -05:00
Blaž Hrastnik
e77b7d147c fix: Recalculate completion after pasting into prompt 2022-08-30 12:27:04 +09:00
Blaž Hrastnik
8a4fbf6daf completion: remove_follow links on filename_impl
We don't need to follow links since we're only scanning the current
directory level (non-recursive).
2022-08-30 12:23:49 +09:00
PiergiorgioZagaria
d2cec25395 Fix process spawning error handling (#3349)
* Fix process spawning error handling

* Log stderr in any case
2022-08-30 11:02:34 +09:00
Michael Davis
5f043dde56 Derive Document language name from languages.toml name key (#3338)
* Derive Document language name from `languages.toml` `name` key

This changes switches from deriving the language name from the
`languages.toml` `scope` key to `name` (`language_id` in the
`LanguageConfiguration` type). For the most part it works to derive the
language name from scope by chopping off `source.` or `rsplit_once` on
`.` but for some languages we have now like html (`text.html.basic`),
it doesn't. This also should be a more accurate fallback for the
`language_id` method which is used in LSP and currently uses the
`rsplit_once` strategy.

Here we expose the language's name as `language_name` on `Document` and
replace ad-hoc calculations of the language name with the new method.

This is most impactful for the `file-type` statusline element which is
using `language_id`.

* Use `Document::language_name` for the `file-type` statusline element

The `file-type` indicator element in the statusline was using
`Document::language_id` which is meant to be used to for telling
Language Servers what language we're using. That works for languages
with `language-server` configurations in `languages.toml` but shows
text otherwise. The new `Document::language_name` method from the
parent commit is a more accurate way to determine the language.
2022-08-30 10:59:45 +09:00
A-Walrus
ae81fbdbf6 Allow less than and greater than in macros (#3556)
* Allow less than and greater than in macros

* Fix failing test
2022-08-30 10:58:51 +09:00
dependabot[bot]
841766ef82 build(deps): bump futures-executor from 0.3.23 to 0.3.24 (#3602)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-29 18:55:26 -05:00
dependabot[bot]
50d5463f90 build(deps): bump futures-util from 0.3.23 to 0.3.24 (#3603)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-29 18:54:58 -05:00
dependabot[bot]
ca4b6eab74 build(deps): bump lsp-types from 0.93.0 to 0.93.1 (#3601)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-29 18:54:24 -05:00
Roman Chumak
ab67788e76 Sonokai (#3595)
Co-authored-by: Roman Chumak <p4ymak@yandex.ru>
2022-08-29 09:00:43 -05:00
Bob
411c5e4871 let extend-line respect range direction (#3046)
* let extend-line respect range direction

* fix extend above logic

* keep `x` existing binding

* Update book/src/keymap.md

Co-authored-by: Ivan Tham <pickfire@riseup.net>

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2022-08-29 10:00:40 +09:00
Charlie Groves
f38ede8631 Add bracketed paste (#3233) 2022-08-29 09:48:49 +09:00
unrelentingtech
51b62230da Add wezterm to get_terminal_provider (#3588)
https://github.com/wez/wezterm is a terminal emulator with its own built-in multiplexer
2022-08-29 09:24:22 +09:00
Kristoffer Flottorp
eeb0a9f504 Add fleetish theme. Based on the unreleased JetBrains Fleet editor (#3591)
Co-authored-by: krfl <kr.fl@outlook.com>
2022-08-29 09:23:54 +09:00
Soc Virnyl S. Estela
abb9f139c5 update colors for papercolor-light (#3585)
* theme: add papercolor light

* fix typo

* add markup highlighting

* theme: added diff colors 

forgot to add it to PaperColor Light

* fix some ui colors

* assign more color for markup headings

* change heading color to bright7
2022-08-29 07:58:05 +08:00
David
db18206795 Fix rust text objects (#3590) 2022-08-28 16:03:39 -05:00
Gustavo Bogarín
e066782782 Add c-sharp textobjects (#3494)
Co-authored-by: Gustavo Bogarín <gbogarin@outlook.com>
Co-authored-by: Gustavo Bogarín <gbogarin@posibillian.tech>
2022-08-27 09:24:47 -05:00
ath3
86a8ea57bb Pascal support (#3542) 2022-08-25 17:59:02 -05:00
Luna
f0fb3407d2 Fixed Doom acario theme (#3533) (#3539)
Changed the `namespace` style to fix the issue (#3533).

I also made the theme look a little closer to how it looks in Emacs, I did however opt to still have it slightly different as I found it easier to read with my port than on the original in Emacs.
I also sorted most keys (mainly from line 8 to 28) for the theme to be in alphabetical order, so it's easier to have a quick glance where they are.
2022-08-25 23:35:43 +08:00
Michael Davis
28c5e2170e Update tree-sitter-ruby (#3527) 2022-08-25 09:15:44 +09:00
ath3
0a22148559 AWK Regex injection (#3535) 2022-08-24 16:14:56 -05:00
ath3
45add73fb1 AWK support (#3528) 2022-08-24 11:58:15 -05:00
Christoph Horn
facde9f18c Julia queries: fix non-consecutive docstring highlight 2022-08-24 11:55:47 -05:00
Christoph Horn
26b2f0a1b5 Julia queries: prevent constructors to be highlighted as functions
Also improves the captures of the remaining identifiers.
2022-08-24 11:55:47 -05:00
Christoph Horn
5806db1e5c Julia queries: limit markdown highlighting to docstrings 2022-08-24 11:55:47 -05:00
Christoph Horn
f5c00b9bc9 Julia queries: major refactoring of highlights.scm, add regex injections, locals 2022-08-24 11:55:47 -05:00
Christoph Horn
77f11bf272 Julia queries: update grammar, fix breaking changes 2022-08-24 11:55:47 -05:00
Jaden
2b16fd43f9 feat(lang): Add esdl grammar (#3526) 2022-08-24 09:51:10 -05:00
seb-bl
ccae718a67 Improve dart indent (#3419) 2022-08-23 21:35:57 -05:00
ChemicalXandco
6b912b8641 add syntax highlights for xit (#3521) 2022-08-23 20:52:01 -05:00
Clay
99b1e8ad89 Fix markdown indented code block rendering (#3503) 2022-08-24 09:12:04 +09:00
Blaž Hrastnik
e4c9d4082a fix: Reset document mode when losing focus
Fixes #3090
2022-08-23 14:07:50 +09:00
Blaž Hrastnik
7b8e4ac95a Editor: remove duplication for view focus/swap commands 2022-08-23 11:44:10 +09:00
Ivan Tham
dd2b9e55a2 Reduce health tick width
Use the same tick as book to reduce margin of whitespace errors.
2022-08-22 19:27:26 -05:00
dependabot[bot]
f32f451b98 build(deps): bump once_cell from 1.13.0 to 1.13.1 (#3511)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-22 19:17:31 -05:00
dependabot[bot]
25f5e8c5d1 build(deps): bump serde_json from 1.0.83 to 1.0.85 (#3510)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-22 19:17:08 -05:00
dependabot[bot]
650cf76d44 build(deps): bump serde from 1.0.142 to 1.0.144 (#3512)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-22 19:16:36 -05:00
dependabot[bot]
f6a1078684 build(deps): bump anyhow from 1.0.61 to 1.0.62 (#3509)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-22 19:15:59 -05:00
Charlie Groves
18909aafe2 Update to crossterm-0.25 (#3390) 2022-08-22 10:29:30 +09:00
Blaž Hrastnik
d993c6349b One more windows fix... 2022-08-22 10:29:11 +09:00
Blaž Hrastnik
e863f6fe27 Fix compilation on windows 2022-08-22 10:18:53 +09:00
Blaž Hrastnik
cb7615e0ed Make external terminal provider configurable
Fixes #1699
2022-08-22 10:11:04 +09:00
ScribblyBirb
7e330697e1 Update tree-sitter-elm to latest commit (#3497) 2022-08-21 15:42:19 -05:00
A-Walrus
ed74e6d5d4 Switch to tabpad configuration option (#3458)
Virtual whitespace tabs are created from the `tab` character padded
with `tabpad` up to  the tab width.
2022-08-21 13:54:02 +09:00
Michael Davis
e61c0b461c Update tree-sitter-org (#3489)
The update fixes a bug that caused the external scanner to hang during
error recovery.

Looking at the diff, there are no structural changes in this update.
There are a few new fields and it looks like some edge-case fixes
but nothing that breaks compatibility with the current queries.
2022-08-21 13:52:52 +09:00
Vince Mutolo
59968d27a4 add penumbra+ theme (#3398)
Co-authored-by: Vince Mutolo <vince@mutolo.org>
2022-08-20 19:26:22 -05:00
Alexander Brevig
aef00a3ab6 feat: add taskwarrior to languages so task N edit is nice (#3468)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-19 19:16:54 -05:00
jdrst
9b0fd51318 removes deprecated stdio flag for omnisharp (#3480) 2022-08-19 08:44:17 -05:00
Saber Haj Rabiee
1577a9d0ab style: fixes unused_parens warnings on nightly builds (#3471) 2022-08-18 18:07:18 -05:00
Soc Virnyl S. Estela
bdd1192a35 add diff colors in PaperColor Light (#3470) 2022-08-18 08:24:54 -05:00
Soc Virnyl S. Estela
c18b54263a theme: add papercolor light (#3426)
* theme: add papercolor light

* fix typo

* add markup highlighting
2022-08-17 22:31:17 +08:00
Daniel S Poulin
7711db3a3a Adjust m textobject description and minor code clarification (#3343)
* Update description of `m` textobject to its actual functionality

Sometime recently the functionality of `m` was changed to match the
nearest pair to the cursor, rather than the former functionality of
matching the pair only if the cursor was on one of the brace characters
directly.

* Rename surround methods to reflect that they work on pairs

The current naming suggests that they may work generally on any
textobject, whereas their implementation really focuses on pairs.

* Change description of m textobject to match actual functionality

The current implementation of `m` no longer merely looks at the pair
character the cursor is on, but actually will search for the pair
(defined in helix-core/src/surround.rs) that encloses the cursor, and
not the entire selection.

* Accept suggested wording change

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>

* Prefix pair surround for consistency

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-17 10:41:59 +09:00
Michael Davis
254d558907 Update tree-sitter-swift (#3461) 2022-08-17 10:40:21 +09:00
A-Walrus
d6e4fd15fc Fix failing test with unicode-lines feature (#3455) 2022-08-17 10:37:34 +09:00
Poliorcetics
6618cf2d68 feat: shorten output for grammar fetching and building (#3396)
New look:

```
Fetching 102 grammars
98 up to date git grammars
4 updated grammars
        bash      now on 275effdfc0edce774acf7d481f9ea195c6c403cd
        beancount now on 4cbd1f09cd07c1f1fabf867c2cf354f9da53cc4c
        c         now on f05e279aedde06a25801c3f2b2cc8ac17fac52ae
        c-sharp   now on 53a65a908167d6556e1fcdb67f1ee62aac101dda
```

```
Building 102 grammars
100 grammars already built
2 grammars built now
        ["bash", "rust"]
```
2022-08-17 10:37:10 +09:00
Yevgnen
956fbab488 Add emacs theme (#3410) 2022-08-16 19:57:28 -05:00
dependabot[bot]
2968756baf build(deps): bump futures-executor from 0.3.21 to 0.3.23 (#3446)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-15 18:29:32 -05:00
dependabot[bot]
941e023e97 build(deps): bump futures-util from 0.3.21 to 0.3.23 (#3448)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-15 18:28:57 -05:00
dependabot[bot]
f9dc1f33ea build(deps): bump chrono from 0.4.19 to 0.4.22 (#3447)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-15 18:23:26 -05:00
dependabot[bot]
52c8de55a0 build(deps): bump anyhow from 1.0.60 to 1.0.61 (#3449)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-15 18:20:33 -05:00
ChrHorn
a7ff39fe3e remove duplicate entries from theme picker (#3439) 2022-08-16 00:18:04 +09:00
Manuel Schmidbauer
8a75795472 Improved file-picker configuration documentation (#3422) 2022-08-14 13:36:08 -05:00
nosa
c5deb30814 Theme Related Fixes (#3412) 2022-08-14 08:35:15 -05:00
n0s4
8deaebde26 Fix typos in ayu themes, also remove trailing space 2022-08-12 10:57:03 -05:00
n0s4
b565fff0f2 Fix Typos in base16_transparent
Fixes #3373.
2022-08-12 10:57:03 -05:00
Erasin
1eeca10675 Fix Markdown Metadata (#3400) 2022-08-12 09:27:50 -05:00
Kyle L. Davis
21f2affa16 Fix conditional setting of stdin handle on Windows (#3379)
* Revert 3121353c6a

* Switch to conditional compilation

* Run formatter

* Switch from conditional compilation to compile-time bool
2022-08-12 11:27:18 +09:00
Vince Mutolo
7559b77d53 highlight closure pipes as brackets (#3397)
Co-authored-by: Vince Mutolo <vince@mutolo.org>
2022-08-11 19:00:03 -05:00
Itay123TheKing
80dde577b0 Fix hyperlink at the bottom of CONTRIBUTING.md (#3392) 2022-08-11 08:57:17 -05:00
notusknot
d773a6e5f2 Update keymap.md to have Tab and Shift-tab listed (#3365)
Co-authored-by: notusknot <notusknot@gmail.com>
2022-08-11 00:21:37 -05:00
Joshua Suskalo
d192d59753 Update Clojure language definition (#3387) 2022-08-10 16:57:23 -05:00
Erasin
921027fb32 Update tree-sitter-latex and highlights (#3370)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-10 07:29:43 -05:00
jdrst
598aa7c424 adds xcopy param to recursively copy runtime folder (#3378) 2022-08-09 20:47:04 -05:00
dependabot[bot]
404defb59b build(deps): bump anyhow from 1.0.59 to 1.0.60 (#3363)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.59 to 1.0.60.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.59...1.0.60)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-09 11:51:20 +09:00
Michael Davis
672ea98b05 Advertise WorkspaceSymbolClientCapabilities support (#3361) 2022-08-09 11:51:10 +09:00
Gokul Soumya
634b6d455f Add custom event type replacing crossterm's Event (#3169)
Ported over from 61365dfbf3 in the `gui` branch. This will allow
adding our own events, most notably an idle timer event (useful
for adding debounced input in [dynamic pickers][1] used by interactive
global search and workspace symbols).

[1]: https://github.com/helix-editor/helix/pull/3110

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-08-09 10:31:26 +09:00
Kyle L. Davis
4ce5a94552 Add language: beancount (#3297)
Co-authored-by: erasin <erasinoo@gmail.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Erasin <erasinoo@gmail.com>
2022-08-08 17:59:55 -05:00
Erasin
d9321134f6 slint indents 2022-08-08 17:57:08 -05:00
Erasin
f09d2bc56b Add slint-ui support
<https://slint-ui.com/>
lsp: <https://github.com/slint-ui/slint/tree/HEAD/tools/lsp>
tree-sitter-slint: <https://github.com/jrmoulton/tree-sitter-slint>
2022-08-08 17:57:08 -05:00
Skyler Hawthorne
3e11017ade revert chrono to 0.4.19
This is causing builds to fail when there is no time zone info, e.g. Alpine,
Android
2022-08-07 12:19:47 -05:00
A-Walrus
6b84344e20 Add completion for nested settings (#3183)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-06 12:16:18 -05:00
Michael Davis
973c51c3e9 Remove C-n and C-p from the insert mode keymap (#3340)
These are read-line-like bindings which we'd like to minimize in
insert mode in general.

In particular these two are troublesome if you have a low
`editor.idle-timeout` config and are using LSP completions: the
behavior of C-n/C-p switches from moving down/up lines to moving
down/up the completion menu, so if you hit C-n too quickly
expecting to be in the completion menu, you'll end up moving down
a line instead. Using C-p moves you back up the line but doesn't
re-trigger the completion menu. This kind of timing related change
to behavior isn't realistically that big of a deal but it can be
annoying.
2022-08-07 01:25:09 +09:00
Matthias Deiml
ea04220874 Use split_parser branch for markdown grammar (#3108) 2022-08-06 10:56:48 -05:00
A-Walrus
c00b8f7ad7 Fix tab highlight when tab is partially visible (#3313)
* Fix tab highlight when tab is partially visible

* Make it style based, and not truncation based

Dealing with truncating is a mess, especially when it comes to wide
unicode graphemes. This way it should work no matter what.

* Inline style calculation into branches
2022-08-07 00:46:50 +09:00
A-Walrus
fdd8bbf16b Fix indent guide styling (#3324)
* Fix incorrect indent guide styling

Before the indent guides on top of whitespace inherited the theme
from them. Now they do not.

* Fix dark_plus theme indent_guides

* Use whitespace style as fallback for indent-guide

* Fix dark_plus theme indent_guides

* Move indent_guide style patching out of loop
2022-08-07 00:46:23 +09:00
Daniel S Poulin
4dd35777f4 Attempt to bring spacebones light up to speed with recent features (#3342) 2022-08-06 09:40:10 -05:00
A. Taha Baki
24f5a47cec Rosé Pine Moon Theme (#3229) 2022-08-06 07:14:13 -05:00
Luna
7176c84844 Add Doom's Acario dark theme. (#3308) 2022-08-06 07:07:14 -05:00
ChrHorn
23f4a40a7a Rust queries: add (function_item) as a local scope (#3345) 2022-08-06 05:58:06 -05:00
Kyle L. Davis
63ec10950f Fix comment (#3334) 2022-08-05 20:13:58 -05:00
Erasin
bf6f7042fe Fix php hightlight (#3317)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-05 07:34:03 -05:00
Dario Oddenino
3121353c6a Avoid setting stdin handle when not necessary (#3248)
* Avoid setting stdin handle when not necessary

Avoid setting the stdin handle in `shell_impl` when the input argument
is None.

This permits to run commands with no stdin with :sh

* refactoring to avoid code duplication

* making clippy happy

* Process variable name fix
2022-08-05 11:15:50 +09:00
Alexander Brevig
c2a6d29ffc fix: add elvish completions (#3331) 2022-08-05 09:50:47 +09:00
A-Walrus
cfa882557e Fix nondeterministic highlighting (#3275)
* Fix nondeterministic highlighting

This is done by prefering matches in the begining, ie for
`keyword.function`, `keyword` is a better match than `function`.

* Use all positions and not just leftmost

Fixes possible edgecase with something like `function.method.builtin`
and the queries `function.builtin` and `function.method`

* Switch to bitmask for slightly better performance

* Make matches from the start of string

Also change comments to match new behaviour
2022-08-05 09:12:14 +09:00
Michael Davis
f32c05db85 Detect indent-style in :set-language (#3330)
Indent style may change when choosing a language with `:set-language`.
Line-endings most likely will not change, but `:set-language` should
have a similar effect as reloading a file (`:reload`), plus the two
are currently grouped in the implementation and line-ending detection
is not particularly expensive.
2022-08-05 09:11:31 +09:00
Blaž Hrastnik
ee1214d6e5 Update dependencies (chrono) 2022-08-05 09:10:07 +09:00
Matthias Deiml
0ee2061102 Avoid copying fragments (#3136)
* Avoid copying fragments

* Add slice / slices method

* Better documentation for fragment and slice methods
2022-08-04 14:44:43 +09:00
Omnikar
afd292e3b9 Resolve clippy lints (#3307) 2022-08-04 14:32:59 +09:00
Michael Davis
5d33dbacac add a CLI flag for specifying config file location (#2666) 2022-08-04 13:05:52 +09:00
PiergiorgioZagaria
219d2c2515 Change default formatter for any language (#2942)
* Change default formatter for any language

* Fix clippy error

* Close stdin for Stdio formatters

* Better indentation and pattern matching

* Return Result<Option<...>> for fn format instead of Option

* Remove unwrap for stdin

* Handle FormatterErrors instead of Result<Option<...>>

* Use Transaction instead of LspFormatting

* Use Transaction directly in Document::format

* Perform stdin type formatting asynchronously

* Rename formatter.type values to kebab-case

* Debug format for displaying io::ErrorKind (msrv fix)

* Solve conflict?

* Use only stdio type formatters

* Remove FormatterType enum

* Remove old comment

* Check if the formatter exited correctly

* Add formatter configuration to the book

* Avoid allocations when writing to stdin and formatting errors

* Remove unused import

Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
2022-08-04 13:01:48 +09:00
Charlie Groves
c5f8a835f5 Add a .ignore file to make ripgrep more useful (#3315)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-03 09:00:39 -05:00
Alexander Brevig
6e7774bb79 Add .gitattributes (#3318) 2022-08-03 08:21:51 -05:00
Charlie Groves
4b6c4ae6ee Fix LF line-endings (#3316) 2022-08-03 07:53:57 -05:00
Matthias Deiml
6b244e2fef Exclude only named children without injection.include-children (#3129)
* Exclude only named children without injection.include-children

* Add injection.include-unnamed-children parameter
2022-08-03 19:18:17 +09:00
Michael Davis
08b442f4cc Inherit javascript/typescript from common 'ecma' queries (#3301)
JavaScript queries now contain a few lines that prevent them from
being used whole-sale in typescript with `; inherits: javascript`.
Here we follow nvim-treesitter's way of using a fake 'ecma' language
as a common base for JavaScript and TypeScript to share as much as
we can.
2022-08-03 14:09:44 +09:00
Kirawi
69f84e2516 theme ui.virtual.indent-guide in dark_plus (#3302) 2022-08-02 10:13:22 -05:00
yvt
aa4394ce12 chore(ci): match *-macos by checking suffix
Simplifies a conditional expression in the CI workflow configuration.

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-08-02 12:04:09 +09:00
yvt
6d16d2cbc9 feat: support grammar cross-compilation 2022-08-02 12:04:09 +09:00
yvt
f6f054ae5b fix(loader): pass cc::Tool::args()
Certain targets, such as `aarch64-apple-*`, require additional compiler
flags to cross-compile for the intended target.
2022-08-02 12:04:09 +09:00
yvt
4461090c3d chore(ci): build binary for aarch64-macos
The tests are conditionally disabled for this target because the x86_64 CI
host is unable to run AArch64 binaries. (There is no officially-supported
reverse Rosetta 2.)
2022-08-02 12:04:09 +09:00
dependabot[bot]
eef9eff20d build(deps): bump pulldown-cmark from 0.9.1 to 0.9.2 (#3294)
Bumps [pulldown-cmark](https://github.com/raphlinus/pulldown-cmark) from 0.9.1 to 0.9.2.
- [Release notes](https://github.com/raphlinus/pulldown-cmark/releases)
- [Commits](https://github.com/raphlinus/pulldown-cmark/compare/v0.9.1...v0.9.2)

---
updated-dependencies:
- dependency-name: pulldown-cmark
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-02 10:07:01 +09:00
dependabot[bot]
f3a3b09337 build(deps): bump similar from 2.1.0 to 2.2.0 (#3293)
Bumps [similar](https://github.com/mitsuhiko/similar) from 2.1.0 to 2.2.0.
- [Release notes](https://github.com/mitsuhiko/similar/releases)
- [Changelog](https://github.com/mitsuhiko/similar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mitsuhiko/similar/compare/2.1.0...2.2.0)

---
updated-dependencies:
- dependency-name: similar
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-02 10:06:46 +09:00
dependabot[bot]
d07d694fe7 build(deps): bump serde from 1.0.140 to 1.0.141 (#3292)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.140 to 1.0.141.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.140...v1.0.141)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-02 10:06:38 +09:00
dependabot[bot]
9643556376 build(deps): bump anyhow from 1.0.58 to 1.0.59 (#3291)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.58 to 1.0.59.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.58...1.0.59)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-02 10:06:28 +09:00
dependabot[bot]
f4b1f9af9a build(deps): bump arc-swap from 1.5.0 to 1.5.1 (#3290)
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.5.0...v1.5.1)

---
updated-dependencies:
- dependency-name: arc-swap
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-02 10:06:22 +09:00
Eric K
d693b37445 Modified restore_term fn in application.rs. Changed '\x1B[2 q' to '\x1B[0 q' to restore cursor to user default after exiting helix (#3289) 2022-08-02 10:05:45 +09:00
ChrHorn
11367488ac Improve Python queries, add locals (#3284) 2022-08-01 16:14:07 -05:00
ChrHorn
0c08ff1596 update catppuccin theme(s) to new palettes (#3281) 2022-08-01 15:23:23 -05:00
ChrHorn
59bf1669ec javascript queries: fix parameters (#3280) 2022-08-01 15:15:17 -05:00
Alexander Brevig
07019c3905 fix: gruvbox color modes (#3202)
* fix: gruvbox color modes

* increase contrast, and use blue and not purple
2022-08-01 12:21:37 +09:00
Charlie Groves
9f4802e101 Only add cargo-tarpaulin on x86_64 (#3252)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-07-31 14:52:54 -05:00
A-Walrus
c15b494288 Fix align_selection behaviour with tabs (#3276) 2022-07-31 14:45:51 -05:00
Banst
7e06681413 feat: add cue support (#3262) 2022-07-31 07:04:57 -05:00
Danilo Spinella
110eb73045 Add cwd parameter which is not optional anymore (#3240) 2022-07-31 06:59:15 -05:00
Danilo Spinella
ab616ab718 Add rust-version (MSRV) to helix-term package (#3244) 2022-07-31 17:09:18 +09:00
Amit Beka
fe3a9a868e clipboard: add logging and healthcheck (#3271)
* add logging to clipboard setup

* healthcheck: add clipboard provider name

Co-authored-by: amitbeka <--->
2022-07-31 17:05:34 +09:00
Alexander Brevig
e405e88c86 Flatwhite Theme (#3236) 2022-07-30 12:35:39 -05:00
Erasin
919edfb323 Add Graphviz Dot lang support (#3241)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-07-30 12:34:00 -05:00
A-Walrus
5ca98edfb1 Don't add empty prompt input to history (#3259) 2022-07-30 12:17:01 -05:00
Gokul Soumya
a8b123fe17 Fix byte index error in signature help highlighting
The language server sends a char offset range within the
signature help label text to highlight as the current parameter,
but helix uses byte offset ranges for rendering highlights. This
was brought up in the [review of the original signature help PR][1],
but the ranges were being highlighted correctly, and there were no
out of bound or indexing panics. Turns out rust-analyzer was
[incorrectly sending byte offsets] instead of char offsets and this
made it seem like all was well and good with offsets in helix during
initial testing.

[1]: https://github.com/helix-editor/helix/pull/1755#discussion_r906715371
[2]: https://github.com/rust-lang/rust-analyzer/pull/12272
2022-07-29 14:31:21 +09:00
Slug
14eca318a7 Add transparent theme based on base16_default (#3216) 2022-07-28 18:14:34 -05:00
Erasin
a1c969012d Fix cursorline and selection themes for onelight (#3226) 2022-07-28 16:58:04 -05:00
Erasin
681c0a91dc Add textobject for javascript (#3213) 2022-07-28 08:31:20 -05:00
Kyle L. Davis
cca83af3fd Update README command table (#3224) 2022-07-28 05:37:10 -05:00
Michael Davis
9ed9c3faca Remove let_declaration from Rust locals tracking (#3212) 2022-07-28 12:04:50 +09:00
Philipp Mildenberger
bf74a4652d JS/TS highlighting improvements (#3219) 2022-07-27 13:56:58 -05:00
Yusuf Bera Ertan
85a5df0391 build(nix): add a way to override what grammars get built (#3141) 2022-07-27 12:52:07 -05:00
Ricardo Silva
2f1d3d0899 Add LSP config for Odin (#3214) 2022-07-27 12:28:20 -05:00
MilanVasko
9a49623721 Use OR of all selections in search_selection command (#3138)
Closes #2312
2022-07-27 18:02:19 +09:00
Seth Bromberger
846a6b65c3 add configurable / theme-able statusline separator string (#3175)
* add configurable separator element to statusline

* themable separator

* clippy fixes

* changed default separator to │

* doc updates
2022-07-27 08:47:22 +09:00
A-Walrus
61856f1d64 Nord color modes (#3200)
* Add color modes to nord theme

* Add color-modes to nord_light theme and fixup

Fg color was not set in some places and defaulted incorrectly.
2022-07-26 22:43:39 +09:00
Erasin
df5ab8b40c Fix: Python hightlight (#3201) 2022-07-26 22:31:14 +09:00
Seth Bromberger
3dd2196e4f add position-percentage as a statusline indicator (#3168)
* added position-pct as a statusline indicator

* removed unnecessary mutable reference

* pct -> percent

* percent -> percentage
2022-07-26 15:05:12 +09:00
Gokul Soumya
de8ade8967 Shorten embedded command descriptions (#3070)
* Shorten embedded command descriptions

- Compact descriptions in command palette and infobox

* Shorten typed command descriptions

* Fix typo in decrement command description
2022-07-26 12:04:23 +09:00
Erasin
42115d02bc Suport diagnostic code (#3096)
* add code for diagnostic.

This PR provides a solution to resolve #2994. missing Code Actions for lsp

* remote unused import
2022-07-26 10:26:50 +09:00
n0s4
4f21f430e4 Remove vale from .gitignore 2022-07-26 10:22:28 +09:00
n0s4
d97c4ee217 Spacing 2022-07-26 10:22:28 +09:00
n0s4
d95c7eaa29 Fixes + consistency
Some lines went longer than the titlebars, fixed regex in
SPLITTING SELECTIONS which wasn't actually correct.
Changed 1 "bat" to a "cat" in ADDING SELECTION ON NEXT
SEARCH MATCH which makes it harder to do with a simple
s select.
2022-07-26 10:22:28 +09:00
n0s4
348951f6f9 Add SPLITTING SELECTIONS 2022-07-26 10:22:28 +09:00
n0s4
b0f8d74db9 Spelling 2022-07-26 10:22:28 +09:00
n0s4
771de41155 Add CYCLING AND REMOVING SELECTIONS 2022-07-26 10:22:28 +09:00
n0s4
9114672419 Move Jumplist section and add recap 2022-07-26 10:22:28 +09:00
n0s4
4e76436b20 Add 'ADDING SELECTION ON NEXT SEARCH MATCH' 2022-07-26 10:22:28 +09:00
n0s4
d2b292660d Add SEARCH FOR SELECTION 2022-07-26 10:22:28 +09:00
n0s4
c7f9caf6bd Add REGISTERS, update MACROS accordingly 2022-07-26 10:22:28 +09:00
n0s4
29ee7f6d01 Add REPLACING WITH YANKED TEXT and INCREMENTING/DECREMTING
Also some consistency issues
 - redundant/dated comment in JOINING LINES
 - spacing around slashes
 - etc.
2022-07-26 10:22:28 +09:00
n0s4
92d94e1f7e Add REPITITION section 2022-07-26 10:22:28 +09:00
n0s4
88902d1f59 Improve ALIGN SELECTIONS section 2022-07-26 10:22:28 +09:00
n0s4
ec4c2f3965 Reduce A-; section to a note on section 3.7
Also fixed consistency of capitalisation and spacing of notes.
2022-07-26 10:22:28 +09:00
n0s4
ce732ce664 Correct recap numbers. 2022-07-26 10:22:28 +09:00
n0s4
d0381d942d Line too long + grammar. 2022-07-26 10:22:28 +09:00
n0s4
5accb5cd58 Add vale to gitignore + spelling 2022-07-26 10:22:28 +09:00
n0s4
68acdbb9a2 Added REPLACE and moved SELECTING TO A CHARACTER into the same chapter. 2022-07-26 10:22:28 +09:00
n0s4
1fed3a2220 Add 'ALIGN SELECTIONS' and 'SPLIT SELECTIONS ON LINES' 2022-07-26 10:22:28 +09:00
n0s4
15e1a0ebf2 Move COLLAPSING SELECTION to MOTIONS AND SELECTIONS.
Also had to do a little rewording to fit the recap for MOTIONS AND SELECTIONS.
2022-07-26 10:22:28 +09:00
n0s4
aa5cebae22 Added Select mode section.
Also added a note about X on "SELECTING LINES".
2022-07-26 10:22:28 +09:00
n0s4
a0d01455ac Re-order sections. 2022-07-26 10:22:28 +09:00
Kirawi
0a2646e720 Improve python highlighting (#3103)
* improve python queries

* update python grammar to `0.20.2`

* fix variadic parameter scope

* add punctuation scopes

* fix order of punctuation scopes

* undo  `embedded` delete
2022-07-26 10:17:51 +09:00
Daniel Longeuay
2ede98c4b4 feat(tree-sitter): add go template support (#3091)
* feat(tree-sitter):  add go template support

* fix(tree-sitter): 🐛 go template highlight scope selectors

* chore(tree-sitter): 🔧 update go template grammar commit
2022-07-26 10:17:28 +09:00
Mr. E
d4a5413255 feat(themes): add mode-specific styles to the dracula themes (#3135) 2022-07-26 10:17:00 +09:00
Clay
b55573dc1d Add elixir & heex comment textobjects (#3179) 2022-07-26 10:14:45 +09:00
Blaž Hrastnik
255c1734cf Rename padding to spacer, remove by default 2022-07-26 10:10:06 +09:00
Ivan Tham
2f980471f8 Make gutters padding automatic (#3163)
Remove padding gutter type, and automatically add 1 padding if gutters is
non-empty.
2022-07-26 10:08:09 +09:00
Seth Bromberger
bfdcfec8c9 add spacer element to statusline (#3165)
* add spacer element to statusline

* docs
2022-07-26 10:07:59 +09:00
André Sá
742d16026e Add ayu themes (#3184) 2022-07-26 10:05:27 +09:00
Joe
d0c63409cc Add table of contents to keymap.md (#3174) 2022-07-26 09:41:09 +09:00
A-Walrus
cb142b5750 Highlight constructor in monokai theme (#3131) 2022-07-26 09:40:56 +09:00
Philipp Mildenberger
235237ddc4 Refactor 'helix-loader::merge_toml_values' to use a 'merge-depth' instead of 'merge_toplevel_arrays' (#3080)
- This ensures that other values than just the arrays are overridden, like nested objects, where it makes sense
- merge_depth is set to 3 so that top-level language features are merged (like 'scope'), but everything deeper is overridden with the user-config
2022-07-26 09:40:38 +09:00
bootra
b7fa9ba601 Fix non-msvc grammar compile on Windows (#3190) 2022-07-26 09:33:53 +09:00
dependabot[bot]
73a308c665 build(deps): bump serde from 1.0.139 to 1.0.140 (#3194)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.139 to 1.0.140.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.139...v1.0.140)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-26 08:17:14 +08:00
bootradev
4db01b3f82 add support for rulers to boo_berry theme (#3191) 2022-07-26 00:03:15 +05:30
Erasin
dad6d0f3b2 Fix: svelte indets.scm (#3147) 2022-07-24 17:42:27 +09:00
Joe
d6fd93788c Add rabl/jbuilder/jb extensions for Ruby (#3173)
* Add rabl and jbuilder

* Add jb
2022-07-24 11:50:04 +09:00
Clay
ec85fb9ab6 Improve HEEx comment highlights, inject comment lang (#3170) 2022-07-24 11:49:52 +09:00
Kyle L. Davis
dfc31e74af Fix different document panic (#3160)
Would panic when given the view for the current document for a different document.
2022-07-23 18:42:28 +09:00
Andrey Tkachenko
1b3a10d906 Add vh verilog header file type to file-types (#3158) 2022-07-23 09:35:20 +05:30
Michael Davis
19e51c8264 add release checklist and changelog curation docs (#2598)
* add release checklist and changelog curation docs

* remove step for deleting '-dev' suffix from VERSION
2022-07-22 10:31:40 +09:00
Aiko Mastboom
4589111d12 helix_view::theme [WARN] Theme (#3119)
* helix_view::theme [WARN] Theme

* updated: warning, error, info, hint colours
https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md#typography

Co-authored-by: Aiko Mastboom <git@aiko.sh>
2022-07-22 10:31:02 +09:00
Mr. E
b05fcaadad Indent with tabs by default (#3095) 2022-07-22 10:30:21 +09:00
Philipp Mildenberger
b6c700fce9 Replace '; inherits <language>' in treesitter queries with <language> queries instead of appending them (#2470)
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-07-22 10:28:32 +09:00
Houkime
52bb1103f8 Auto pair-removal (#2940)
* auto pair-removal

Fixes https://github.com/helix-editor/helix/issues/1673

* autopairs removal: use doc autopairs

* autopairs-removal: limit to one-char selections

* use single_grapheme() to check if range is one char

* fix errouneous deletes of " and other symmetric autopairs when at buffer start

Co-authored-by: Houkime <>
2022-07-22 10:23:52 +09:00
Robin
19b7864062 keep jump/file history when using :split (#3031)
* keep jump/file history when using :split

* move history cloning into the switch function

Co-authored-by: Robin <robinvandijk@klippa.com>
2022-07-22 10:23:00 +09:00
Bob
2f53644c6d jumplist picker (#3033)
* jumplist picker

* remove jumps slicing

Co-authored-by: Benoît Cortier <bcortier@proton.me>

* remove unnecessary deref format! parameter

Co-authored-by: Benoît Cortier <bcortier@proton.me>

Co-authored-by: Benoît Cortier <bcortier@proton.me>
2022-07-22 10:21:46 +09:00
Clay
e560212ec5 Gleam: add support for built-in language server (#3139)
* Add gleam lsp support

* Docgen gleam lsp support
2022-07-22 10:19:42 +09:00
0rphee
76756f0e5d add statusline.{mode} colors and tweak various settings (#3128) 2022-07-21 12:26:54 +05:30
Alexis Kalabura
8b2a14153b add statusline element to display file line endings (#3113)
* add statusline element to display file line endings

* run cargo fmt --all

* change the word *ending* from plural to singular

* support for the unicode-lines feature flag
2022-07-21 13:03:12 +09:00
Blaž Hrastnik
906259cc41 fix: Indent levels could bleed over on the left edge
Fixes #3087
Refs #3105
    #	modified:   theme.toml
2022-07-20 17:06:33 +09:00
Erasin
3b1ba7fb12 Add color-modes for onelight theme (#3104)
Add keyword.function and keyword.storage.type for TS
2022-07-20 11:55:22 +09:00
Mr. E
b6e06c8c0c feat(themes): add mode-specific styles to the onedark theme (#3098) 2022-07-20 11:55:08 +09:00
Michael Davis
9753da6ab7 Fix locals tracking in Rust closures (#3027)
The fix comes from the rewriting of the `closure_parameters` stanza:
it was capturing the entire `closure_parameters` node including
paretheses, whitespace, and commas. Capturing the identifiers within
fixes the tracking.

In order to make sure locals definitions from closure parameters don't
leak out of the body of the closure, though, we should also mark the
closure itself as a locals scope.
2022-07-20 11:51:35 +09:00
Gokul Soumya
791bf7e50a Add lsp signature help (#1755)
* Add lsp signature help

* Do not move signature help popup on multiple triggers

* Highlight current parameter in signature help

* Auto close signature help

* Position signature help above to not block completion

* Update signature help on backspace/insert mode delete

* Add lsp.auto-signature-help config option

* Add serde default annotation for LspConfig

* Show LSP inactive message only if signature help is invoked manually

* Do not assume valid signature help response from LSP

Malformed LSP responses are common, and these should not crash the
editor.

* Check signature help capability before sending request

* Reuse Open enum for PositionBias in popup

* Close signature popup and exit insert mode on escape

* Add config to control signature help docs display

* Use new Margin api in signature help

* Invoke signature help on changing to insert mode
2022-07-19 11:28:24 +09:00
dependabot[bot]
02f0099210 build(deps): bump grep-searcher from 0.1.8 to 0.1.10 (#3101)
Bumps [grep-searcher](https://github.com/BurntSushi/ripgrep) from 0.1.8 to 0.1.10.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/grep-searcher-0.1.8...grep-searcher-0.1.10)

---
updated-dependencies:
- dependency-name: grep-searcher
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-19 11:24:03 +09:00
dependabot[bot]
ddc0ea751c build(deps): bump clipboard-win from 4.4.1 to 4.4.2 (#3100)
Bumps [clipboard-win](https://github.com/DoumanAsh/clipboard-win) from 4.4.1 to 4.4.2.
- [Release notes](https://github.com/DoumanAsh/clipboard-win/releases)
- [Commits](https://github.com/DoumanAsh/clipboard-win/commits)

---
updated-dependencies:
- dependency-name: clipboard-win
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-19 07:17:07 +05:30
dependabot[bot]
77e5890859 build(deps): bump grep-regex from 0.1.9 to 0.1.10 (#3102)
Bumps [grep-regex](https://github.com/BurntSushi/ripgrep) from 0.1.9 to 0.1.10.
- [Release notes](https://github.com/BurntSushi/ripgrep/releases)
- [Changelog](https://github.com/BurntSushi/ripgrep/blob/master/CHANGELOG.md)
- [Commits](https://github.com/BurntSushi/ripgrep/compare/grep-regex-0.1.9...grep-regex-0.1.10)

---
updated-dependencies:
- dependency-name: grep-regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-19 07:15:57 +05:30
Bob
e5c7aaed91 support prefilling prompt (#2459)
* support prefilling prompt

* introduce with_line builder method in Prompt

* extract show_prompt

* use textobject_word as fallback input
2022-07-18 10:17:13 +09:00
Narazaki Shuji
55b45ec4a4 Set the selection point of the first file correctly (#3073) 2022-07-18 10:14:36 +09:00
Ivan Tham
e8214fb1e6 Make gutters padding optional (#2996)
If all gutters are removed, there are still an extra one padding, would be nice
to remove that to save some space.
2022-07-18 10:13:47 +09:00
Bob
2a8d38c27b support toggling pickers' preview panel (#3021)
* support toggling pickers' preview panel

* add doc for toggling preview
2022-07-18 10:11:25 +09:00
Mr. E
dbf68e0370 Customizable/configurable status line (#2434)
* feat(statusline): add the file type (language id) to the status line

* refactor(statusline): move the statusline implementation into an own struct

* refactor(statusline): split the statusline implementation into different functions

* refactor(statusline): Append elements using a consistent API

This is a preparation for the configurability which is about to be
implemented.

* refactor(statusline): implement render_diagnostics()

This avoid cluttering the render() function and will simplify
configurability.

* feat(statusline): make the status line configurable

* refactor(statusline): make clippy happy

* refactor(statusline): avoid intermediate StatusLineObject

Use a more functional approach to obtain render functions and write to
the buffers, and avoid an intermediate StatusLineElement object.

* fix(statusline): avoid rendering the left elements twice

* refactor(statusline): make clippy happy again

* refactor(statusline): rename `buffer` into `parts`

* refactor(statusline): ensure the match is exhaustive

* fix(statusline): avoid an overflow when calculating the maximal center width

* chore(statusline): Describe the statusline configurability in the book

* chore(statusline): Correct and add documentation

* refactor(statusline): refactor some code following the code review

Avoid very small helper functions for the diagnositcs and inline them
instead.
Rename the config field `status_line` to `statusline` to remain
consistent with `bufferline`.

* chore(statusline): adjust documentation following the config field refactoring

* revert(statusline): revert regression introduced by c0a1870

* chore(statusline): slight adjustment in the configuration documentation

* feat(statusline): integrate changes from #2676 after rebasing

* refactor(statusline): remove the StatusLine struct

Because none of the functions need `Self` and all of them are in an own
file, there is no explicit need for the struct.

* fix(statusline): restore the configurability of color modes

The configuration was ignored after reintegrating the changes of #2676
in 8d28f95.

* fix(statusline): remove the spinner padding

* refactor(statusline): remove unnecessary format!()
2022-07-18 09:57:01 +09:00
Joe
43761d426c Remove .git extension from SCSS tree-sitter repo url (#3089) 2022-07-17 21:41:05 +05:30
Joe
0c9594e41e Add SCSS language support (#3074) 2022-07-17 17:55:20 +08:00
Alex Kim
bcacc703d7 fix wrong value for cursor shape config in the docs (#3081) 2022-07-15 20:21:34 +05:30
Benoît Cortier
333ab27837 feat(term): uniformize word-wise movement and deletion (#2500)
Ctrl-based shortcuts are common in numerous applications.

This change:
- Adds Ctrl+{Left/Right/Backspace/Delete} for word-wise movement/deletion in prompt, picker, …
- Removes Alt-Left and Alt-Right in prompt, picker, …
- Adds Alt-Delete in insert mode for forward word deletion

In some terminals, Alt-Backspace might not work because it is ambigous.
See: https://github.com/helix-editor/helix/pull/2193#issuecomment-1105042501
Hence, Alt alternative is not removed.
2022-07-15 21:59:00 +08:00
Bob
8681fb6d9e respect count in treesitter movement (#3058) 2022-07-14 08:08:09 +08:00
Bob
4418924ec3 respect count for selecting next/previous match (#3056) 2022-07-13 23:01:42 +08:00
Bob
e6a6e251c5 respect count for repeating motion (#3057) 2022-07-13 23:00:24 +08:00
Termina94
3cced1e3c8 Add cursorline colour to darkplus theme (#3054)
Co-authored-by: Dean Revell <revell@gmail.com>
2022-07-12 15:18:41 -05:00
0rphee
7951ebfd4d [Theme] Noctis (#3043) 2022-07-12 12:42:17 -05:00
Mateusz S. Szczygieł
5f69beb87f Add textobjects.scm to GLSL (#3051) 2022-07-12 10:13:57 -05:00
Philipp Mildenberger
e97b8607c1 Added ungrammar language support (#3048) 2022-07-12 10:06:53 -05:00
dependabot[bot]
fb62569785 build(deps): bump regex from 1.5.5 to 1.6.0 (#3041)
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.5 to 1.6.0.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.5...1.6.0)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-12 11:17:24 +09:00
dependabot[bot]
930f98053e build(deps): bump serde from 1.0.138 to 1.0.139 (#3040)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-12 07:44:00 +05:30
Austen LeBeau
0cb0c30618 add fortran language (#3025) 2022-07-10 11:27:44 -05:00
Slug
e109022bfd fix: error that caused usize to overflow (#3024)
* fix: error that caused usize to overflow

* update: changed check_sub to saturating_sub
2022-07-10 10:54:06 +02:00
Timothy DeHerrera
718c3baebe nix: pass makeWrapperArgs to wrapProgram (#3003) 2022-07-09 11:17:44 -05:00
Timothy DeHerrera
fefa4d8c59 nix flake: make the binary cache "just work" (#2999) 2022-07-09 11:09:37 -05:00
Amit Beka
6100b1ba08 book: add wiki links to the title page and install page (#3017)
Co-authored-by: amitbeka <--->
2022-07-09 11:08:47 -05:00
Gokul Soumya
21b66ba068 lsp: Add workspace/applyEdit to client capabilites (#3012)
The functionality already existed, but the capability wasn't being
reported correctly to the server:

230ba264bf/helix-term/src/application.rs (L716-L728)
2022-07-09 07:31:15 +09:00
Gokul Soumya
b7a3531b8f theme(onedark): Remove bg for window separator (#3011) 2022-07-08 15:24:09 -05:00
Jake Langford
230ba264bf Introduce storage highlighting for typescript/javascript (#2961) 2022-07-06 08:54:07 -05:00
Ivan Tham
e35abe38f3 Remove broken ledger tag highlight (#2988) 2022-07-06 07:35:36 -05:00
Gokul Soumya
af35c62407 Show file path only in workspace diagnostic picker 2022-07-06 13:06:46 +02:00
Gokul Soumya
a43bcc8765 Display error code only if not none 2022-07-06 13:06:46 +02:00
Gokul Soumya
0c104685c0 Sub sort diagnostics by line number 2022-07-06 13:06:46 +02:00
Gokul Soumya
2c37e25cb5 Display diagnostic text before code in picker 2022-07-06 13:06:46 +02:00
Gokul Soumya
c4e022971d Remove source from diagnostic picker display
It is usually the name of the LSP and doesn't add much
useful information.
2022-07-06 13:06:46 +02:00
Erin van der Veen
e0cf19c612 Update tree-sitter-nickel (#2987) 2022-07-06 13:05:51 +02:00
A-Walrus
1378b911b6 Fix some typos (#2978) 2022-07-05 21:49:54 -05:00
Ivan Tham
b612211070 Update tree-sitter-ledger (#2936) 2022-07-05 09:12:28 -05:00
Michael Davis
aacd0c8aa5 Update TSQ queries (#2960)
A few changes to make TSQ highlights better:

* A parsing error has been fixed in the grammar itself
    * Previously tree-sitter-tsq did not parse the variables
      in predicates like `(#set! injection.language "javascript")`
* Theme nodes as `tag`
    * The newly added node to the parser (from the above fix) is
      `variable` which takes over the `variable` capture from nodes
* Highlight known predicates as `function` and unsupported
  predicates as `error`
    * This may help when translating queries from nvim-treesitter.
      For example `#any-of?` is a common one used in nvim-treesitter
      queries but not implemented in Helix or tree-sitter-cli.
* Inject tree-sitter-regex into `#match?` predicates
2022-07-05 20:01:05 +09:00
Matthew Toohey
d78354c537 add language idris (#2971) 2022-07-05 20:00:38 +09:00
Joe
b26e7e2e8f Add live preview to theme picker (#1798)
* Add theme picker with live preview

* Add live theme preview to :theme command

* cargo fmt

* Fix clippy warnings

* Remove picker variant

* Remove unused import

* Cleanup

* Change current_theme to last_theme

* Fix accidental comment flash deletion

* Typo

* Remove theme cache

* Add some comments

* Refactor some theme handling

TIL flatmap on Option is called  and_then

* Remove unnecessary renames

* Constrain last_theme theme preview lifecycle

* Switch to bitflag implementation

* Better handling of last_theme

* Sort theme names

* Better memory juggling

* Missed a branch

* Remove name from theme, switch bitand to &

* cargo fmt

* Update helix-view/src/editor.rs

* Switch boolean to enum

* Remove bitflag impl

* cargo fmt

* Remove un-needed type arg

* cargo fmt
2022-07-05 19:44:16 +09:00
Michael Davis
85411bed83 DAP: Make cwd required in RunTerminalArguments
The spec has `cwd` in `RunInTerminalRequestArguments` as non-optional:
https://microsoft.github.io/debug-adapter-protocol/specification#Reverse_Requests_RunInTerminal
2022-07-05 12:34:03 +02:00
Michael Davis
44f596334a DAP: Skip serializing Options when None
DAP follows the same strict TypeScript interface syntax as LSP
which states:

> The document uses TypeScript interfaces in strict mode to describe
> these. This means for example that a `null` value has to be explicitly
> listed and that a mandatory property must be listed even if a falsify
> value might exist.

So we have to skip serializing any fields that end in `?` instead
of passing `null`.
2022-07-05 12:34:03 +02:00
Jens Getreu
936ed3a226 Add Autumn night theme
Under some light conditions, one prefers a high contrast theme.
2022-07-05 12:33:37 +02:00
Jens Getreu
2e709859c4 Autumn theme: slightly adjust contrast 2022-07-05 12:33:37 +02:00
dependabot[bot]
f3e8b0f34b build(deps): bump smallvec from 1.8.1 to 1.9.0 (#2976)
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.8.1...v1.9.0)

---
updated-dependencies:
- dependency-name: smallvec
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 19:31:01 +09:00
dependabot[bot]
f3467399b7 build(deps): bump crossterm from 0.23.0 to 0.24.0 (#2968)
Bumps [crossterm](https://github.com/crossterm-rs/crossterm) from 0.23.0 to 0.24.0.
- [Release notes](https://github.com/crossterm-rs/crossterm/releases)
- [Changelog](https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossterm-rs/crossterm/compare/0.23...0.24)

---
updated-dependencies:
- dependency-name: crossterm
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 19:30:33 +09:00
dependabot[bot]
ba255e3e3e build(deps): bump serde_json from 1.0.81 to 1.0.82 (#2966)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.81 to 1.0.82.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.81...v1.0.82)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 19:25:56 +09:00
dependabot[bot]
1fc8cbeb68 build(deps): bump log from 0.4.14 to 0.4.17 (#2965)
Bumps [log](https://github.com/rust-lang/log) from 0.4.14 to 0.4.17.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.14...0.4.17)

---
updated-dependencies:
- dependency-name: log
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 19:24:37 +09:00
dependabot[bot]
b98567f248 build(deps): bump which from 4.2.4 to 4.2.5 (#2964)
Bumps [which](https://github.com/harryfei/which-rs) from 4.2.4 to 4.2.5.
- [Release notes](https://github.com/harryfei/which-rs/releases)
- [Commits](https://github.com/harryfei/which-rs/compare/4.2.4...4.2.5)

---
updated-dependencies:
- dependency-name: which
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 19:24:07 +09:00
dependabot[bot]
700431d665 build(deps): bump encoding_rs from 0.8.30 to 0.8.31 (#2963)
Bumps [encoding_rs](https://github.com/hsivonen/encoding_rs) from 0.8.30 to 0.8.31.
- [Release notes](https://github.com/hsivonen/encoding_rs/releases)
- [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.30...v0.8.31)

---
updated-dependencies:
- dependency-name: encoding_rs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 19:19:27 +09:00
dependabot[bot]
c88d736d5c build(deps): bump once_cell from 1.12.0 to 1.13.0 (#2969)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.12.0...v1.13.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 11:04:03 +08:00
dependabot[bot]
a679efa8ce build(deps): bump serde from 1.0.136 to 1.0.138 (#2967)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.136 to 1.0.138.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.136...v1.0.138)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-05 08:20:12 +05:30
Skyler Hawthorne
f392e35439 feat(theme): solarized: add cursorline, ruler, indent guide (#2962) 2022-07-04 18:06:44 -05:00
A-Walrus
2ac1de305e Fix backwards selection duplication widening bug (#2945)
* Fix backwards selection duplication widening bug

* Add integration tests

* Make tests line-ending agnostic

Make tests line-ending agnostic

Use indoc to fix tests

Fix line-ending on test input
2022-07-05 07:51:15 +09:00
川田 恵氏 (Kawada Keishi a.k.a megumish)
244825b9e1 Add runtime xcopy command on powershell in docs (#2958) 2022-07-04 12:32:46 -05:00
0rphee
e58d28a972 Add Haskell roots (#2954) 2022-07-03 22:44:17 -05:00
rsteube
4c30a3609a languages: added elvish (#2948) 2022-07-03 16:19:12 -05:00
ChrHorn
9f43dbc45d Highlight whole row in picker menus (#2939) 2022-07-02 17:29:46 +05:30
Gokul Soumya
6e2aaed5c2 Reuse menu::Item trait in picker (#2814)
* Refactor menu::Item to accomodate external state

Will be useful for storing editor state when reused by pickers.

* Add some type aliases for readability

* Reuse menu::Item trait in picker

This opens the way for merging the menu and picker code in the
future, since a picker is essentially a menu + prompt. More
excitingly, this change will also allow aligning items in the
picker, which would be useful (for example) in the command palette
for aligning the descriptions to the left and the keybinds to
the right in two separate columns.

The item formatting of each picker has been kept as is, even though
there is room for improvement now that we can format the data into
columns, since that is better tackled in a separate PR.

* Rename menu::Item::EditorData to Data

* Call and inline filter_text() in sort_text() completion

* Rename diagnostic picker's Item::Data
2022-07-02 13:21:27 +02:00
nosa
290b3ebbbe Update night_owl for cursorline (#2938) 2022-07-01 14:09:59 -05:00
Michael Jones
1fde77ad9d Sort themes, language & files by score & then name (#2675)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-07-01 11:06:14 -05:00
ramojus
cc3aded185 add statusline mode colors to meliora theme (#2933) 2022-07-01 21:24:33 +09:00
Blaž Hrastnik
a1c1abca2b fix CI 2022-07-01 21:24:10 +09:00
nosa
8a19196ad5 Updated for #2676 , but I took the opportunity to do some other changes. (#2929)
- Misspelling of 'modifiers' for markdown.heading.1 and 2.
- Errors are now just underlined instead of in red.
- Diagnostics are dimmed, as well as whitespace.
- Add constant.builtin.
2022-07-01 19:18:39 +09:00
Blaž Hrastnik
9ae70cc410 Disable tree-sitter python indents, use fallback for now
There's been a lot of complaints about the state of python indentation
and the fallback actually works better until the solution proposed
in https://github.com/helix-editor/helix/issues/763#issuecomment-1137894973=
is implemented.
2022-07-01 19:17:19 +09:00
Michael Jones
d8abd1eaf3 Sort themes, language & files by score & then name (#2675)
* Sort themes by score & then name

Previously the themes were appearing unordered after typing ':theme '.
This sorts them first by fuzzy score and then by name so that they
generally appear in a more ordered fashion in the initial list.

The sort by name does not really pay off when there is a score so an
alternative approach would be to sort by name if there is string to
fuzzy match against and otherwise sort by score.

I've lowercased the names as that avoids lower case & upper case letters
being sorted into separate groups. There might be a preferable approach
to that though.

* Sort language & files by score then name

And change to use sort_unstable_by instead of sort_unstable_by_key as it
allows us to avoid some allocations.

I don't fully understand the flow of the 'filename_impl' function but
this seems to deliver the desired results.

* Remove unnecessary reference

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-07-01 18:33:52 +09:00
plexom
f10b6f6ee2 adds --vsplit and --hsplit arguments (#2773)
* adds --vsplit and --hsplit arguments

* moved comment

* fixed lint (third time's a charm)

* changed vsplit and hsplit from two separate bools to type Option<Layout>, and some cleanup
2022-07-01 18:27:32 +09:00
Benjamin Rich
15d96c843a Add new key bindings to view mode (#2803)
* Make view mode more pager-like

Addresses #2721

* Remove view mode bindings for J and K
2022-07-01 18:27:18 +09:00
Sora
edee2f4c34 Fix backwards character deletion on other whitespaces (#2855)
* delete_backwards_char accepts any type of whitespace

* Fix inconsistency, where unicode whitespaces are treated as normal whitespaces

* Changed back to direct whitespace match

* Only accept explicit whitespace / tabs

Co-authored-by: s0LA1337 <dreamer@neoncity.dev>
2022-07-01 18:08:48 +09:00
two-six
444bc24a26 [Theme] Nord Light (#2908)
* add theme

* updated nord_light

* update to colors

* last update to colors
2022-07-01 18:08:27 +09:00
Erasin
051a7f0606 add cursorline to one light theme (#2925) 2022-07-01 18:07:46 +09:00
Jens Getreu
7baa8e837b Add color-modes to Autumn theme (#2928)
Co-authored-by: Jens Getreu <jens.getreu@dlh.lu>
2022-07-01 18:06:16 +09:00
Michael Davis
c5600c9c01 markdown: limit raw block highlight to code fence content 2022-07-01 11:04:23 +02:00
Michael Davis
c8dba2f4c6 erlang: highlight modules in behaviour attributes 2022-07-01 11:04:23 +02:00
Michael Davis
19acbfe02d erlang: highlight records with macro names
You might use a macro like `?MODULE` to name a record:

    -record(?MODULE, {a, b, c}).

With this fix, the record fields correctly get `variable.other.member`
highlights.
2022-07-01 11:04:23 +02:00
Michael Davis
bf1aa8876c git-commit: fix highlight edge cases
* branch message with current branch and diverged branch has been
  added to the parser
* scissors used in verbose commits are marked as a punctuation
  delimiter
    * we could use comment instead since they're visually the
      same but IMO this works better
2022-07-01 11:04:23 +02:00
Michael Davis
a890c4a64d tsq: update parser to fix escaping double quotes
This includes a fix for the new HTML highlights introduced a few
parent commits back:

    ["\"" (attribute_name)] @string

Would get tripped up and the entire line would be highlighted as
a string. Now `\"` is a valid escape.

I'm switching to my fork as the primary repo as the upstream hasn't
been touched in over a year (mostly because stability afaict) but
it has no watchers currently so I'm not hopeful that my PR will
be merged.
2022-07-01 11:04:23 +02:00
Michael Davis
d8f036f0a9 erlang: update parser for fix on remote calls 2022-07-01 11:04:23 +02:00
Michael Davis
199a2460ca make: add injection-regex 2022-07-01 11:04:23 +02:00
Michael Davis
4a0dab8bc2 erlang: fix '#match?' for specs/callbacks 2022-07-01 11:04:23 +02:00
Michael Davis
e4e8a39bf7 replace module captures with namespace
`module` is undocumented and does not exist in other themes. The
equivalent existing scope based on usage (Elixir for example) is
`namespace`.
2022-07-01 11:04:23 +02:00
Michael Davis
016e97314c html: highlight punctuation
* `/>` as in self-closing tags like `<hr/>`
* `=` as in the separator between attribute name and value `<a href="bar">`
2022-07-01 11:04:23 +02:00
Michael Davis
7cf88f2bac edoc: prevent rogue punctuation highlights
Punctuation highlights would show up outside of where they
were valid, for example using parentheses in some text. This
change prevents that by gating the captures to being under
the named nodes in which they are valid.
2022-07-01 11:04:23 +02:00
Michael Davis
78c944ebc3 rust: fix highlight corner-cases
* add punctuation highlights for commas as in function parameters
* remove stray `variable.parameter` highlight
    * I couldn't find any regressions from this and it fixes an
      edge case I ran into (but sadly did not record 😓)
* highlight `fn` as `keyword.function`
    * the theme docs have `fn` as an example so it seems fitting
2022-07-01 11:04:23 +02:00
Michael Davis
beb19fe1bd bash: expand injection-regex to common shells 2022-07-01 11:04:23 +02:00
Michael Davis
ca82cd86e6 markdown: highlight punctuation 2022-07-01 11:04:23 +02:00
Michael Davis
bd527c84e6 erlang: highlight unary '#' as punctuation.bracket
The '#' character may either be interpreted as a map when used
like so:

    %% Example 1
    #{a => b}

Or as an operator which updates an existing map when the left-hand
side is an expression:

    %% Example 2
    MyMap#{a => b}

This commit changes the highlight to `punctuation.bracket` when used
as a character in a literal map (example 1) and keeps the `operator`
highlight when used for updating (example 2).
2022-07-01 11:04:23 +02:00
Michael Davis
d523280e85 erlang: highlight nullary macros as constants 2022-07-01 11:04:23 +02:00
Sora
26501afe13 Update cursorline for tokyonight + tokyonight_storm (#2927)
Co-authored-by: s0LA1337 <dreamer@neoncity.dev>
2022-06-30 17:14:55 -05:00
Skyler Hawthorne
f2768da1f6 add mode colors to solarized (#2926) 2022-07-01 06:52:31 +09:00
Mathspy
d06800f1dd Add mode specific styles (#2676)
* Add mode specific styles

In similar vein to neovim's lualine and similar statusline packages this
allows helix users to style their mode based on which mode it is thus
making each mode more visually distinct at a glance

* Add an example based on rosepine

* Add editor.colors-mode config

* Document statusline mode styles
2022-06-30 18:26:00 +09:00
Falco Hirschenberger
ed89f8897e Add workspace and document diagnostics picker (#2013)
* Add workspace and document diagnostics picker

fixes #1891

* Fix some of @archseer's annotations

* Add From<&Spans> impl for String

* More descriptive parameter names.

* Adding From<Cow<str>> impls for Span and Spans

* Add new keymap entries to docs

* Avoid some clones

* Fix api change

* Update helix-term/src/application.rs

Co-authored-by: Bjorn Ove Hay Andersen <bjrnove@gmail.com>

* Fix a clippy hint

* Sort diagnostics first by URL and then by severity.

* Sort diagnostics first by URL and then by severity.

* Ignore missing lsp severity entries

* Add truncated filepath

* Typo

* Strip cwd from paths and use url-path without schema

* Make tests a doctest

* Better variable names

Co-authored-by: Falco Hirschenberger <falco.hirschenberger@itwm.fraunhofer.de>
Co-authored-by: Bjorn Ove Hay Andersen <bjrnove@gmail.com>
2022-06-30 18:16:18 +09:00
Jens Getreu
94fc41a419 Add cursorline to Autumn theme (#2918)
Co-authored-by: Jens Getreu <jens.getreu@dlh.lu>
2022-06-29 14:14:16 -05:00
Ben Lee-Cohen
15ac1142cf Adding a cursorline for the Nord theme (#2916) 2022-06-29 09:13:49 -05:00
Stuart Hinson
6ac6080969 primary cursorline for Dracula theme (#2915) 2022-06-29 09:08:05 -05:00
Michael Davis
bf1db737d4 nix: update nixCargoIntegration (#2907)
This fixes the aarch64-darwin build - the newer revision uses the
cCompiler override to compile tree-sitter with clang instead of
gcc (which fails).
2022-06-29 17:53:56 +09:00
Seth Bromberger
07e7a13a9e fixes background reset (#2900)
* fixes background reset

* moves creation of default style out of loop

* patches with background_style

* removes commented code
2022-06-28 23:59:10 +09:00
PabloMansanet
030de46e6b Fix recursive macro crash and empty macro lockout (#2902) 2022-06-28 21:30:27 +09:00
dependabot[bot]
ac1d8fa505 build(deps): bump smallvec from 1.8.0 to 1.8.1 (#2901)
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.8.0...v1.8.1)

---
updated-dependencies:
- dependency-name: smallvec
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-28 19:36:38 +09:00
dependabot[bot]
d900b8bb23 build(deps): bump thiserror from 1.0.30 to 1.0.31 (#2899)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.30 to 1.0.31.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.30...1.0.31)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-28 19:36:28 +09:00
dependabot[bot]
247ebd6689 build(deps): bump indoc from 1.0.3 to 1.0.6 (#2898)
Bumps [indoc](https://github.com/dtolnay/indoc) from 1.0.3 to 1.0.6.
- [Release notes](https://github.com/dtolnay/indoc/releases)
- [Commits](https://github.com/dtolnay/indoc/compare/1.0.3...1.0.6)

---
updated-dependencies:
- dependency-name: indoc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-28 18:25:17 +09:00
dependabot[bot]
2963fdbed1 build(deps): bump cc from 1.0.72 to 1.0.73 (#2897)
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.72 to 1.0.73.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.72...1.0.73)

---
updated-dependencies:
- dependency-name: cc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-28 18:25:08 +09:00
Michael Davis
64de0b7288 add docs for cursorline scopes (#2904) 2022-06-28 08:55:09 +05:30
Michael Davis
64cf4c859b support Bazel languages (#2903) 2022-06-28 08:48:38 +05:30
dependabot[bot]
6f932375bf build(deps): bump serde_json from 1.0.79 to 1.0.81 (#2896)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.79 to 1.0.81.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.79...v1.0.81)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-28 07:55:25 +08:00
dependabot[bot]
fd644ccfa2 build(deps): bump tree-sitter from 0.20.4 to 0.20.8 (#2895)
Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.20.4 to 0.20.8.
- [Release notes](https://github.com/tree-sitter/tree-sitter/releases)
- [Commits](https://github.com/tree-sitter/tree-sitter/commits)

---
updated-dependencies:
- dependency-name: tree-sitter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-28 07:52:27 +08:00
Gokul Soumya
3108a11d35 Refactor handling of mouse events (#2893)
- Simplified match statements by destructuring MouseEvent struct
  at the top and then matching on event.kind.
- Extracted out closures for calculating (1) position and view
  of mouse click and (2) gutter coordinates and view of mouse click.
2022-06-28 01:05:07 +09:00
Gokul Soumya
23ce5f1837 Add cursorline scope for onedark theme (#2892) 2022-06-27 17:36:41 +02:00
ramojus
db2aa57074 update meliora theme (#2890) 2022-06-27 07:49:09 -05:00
lazytanuki
096abdd19b feat: highlight / select symbol under cursor using LSP textDocument/documentHighlight (#2738)
* feat: highlight symbol under cursor using LSP textDocument/documentHighlight

* fix: please clippy

* fix: shorter description and code style
2022-06-27 20:19:56 +09:00
Blaž Hrastnik
fde9e034d4 Only draw cursorline in the currently focused buffer 2022-06-27 17:51:22 +09:00
Blaž Hrastnik
425de09d21 Fix tests again 2022-06-27 17:35:23 +09:00
Blaž Hrastnik
24f03097e3 Remove some more unwraps 2022-06-27 17:27:44 +09:00
Blaž Hrastnik
33d287a9ad Add a default cursorline style for the primary selection 2022-06-27 17:27:24 +09:00
Tobias Menzi
8dc86beabd Implement cursorline (#2170)
* Implement cursorline

* Binary search possible lines
2022-06-27 17:09:34 +09:00
Gokul Soumya
a26943de4e Right align scrollbar with track in completion popup (#2754)
- Align the scollbar to the right edge of the popup rather than at
  a margin of one.
- Add a scrollbar track and a new scope `ui.menu.scroll`.
2022-06-27 16:52:31 +09:00
Ramojus
c113531db9 add meliora theme (#2884) 2022-06-26 23:40:08 -05:00
Kihaya Sugiura
24351c20d4 languages: Fix ruby rakefile and gemfile file type (#2875) 2022-06-26 12:04:53 -05:00
Gokul Soumya
16ccc7ead8 Add single width left margin for completion popup (#2728)
* Add single width left margin for completion popup

* Clear with ui.menu style before rendering menu

When rendering a completion popup, the popup component will clear
the area with ui.popup and then the menu component would draw over
it using a table component. We remove the left edge of the area
before passing it to the table component (so that it will be left
as padding), and the table component uses ui.menu as the style.
If ui.menu and ui.popup are different the left edge of the popup
will look different from the rest of the popup. We avoid this by
clearing the whole area with ui.menu in Menu::render
2022-06-26 17:56:35 +09:00
Amit Beka
ba85779902 book: fix the description of dot repeat (#2878)
Co-authored-by: amitbeka <--->
2022-06-25 15:28:26 -05:00
Triton171
e1b1a5ebc0 Fix edge-case in tree-sitter expand_selection selection command (#2877)
Co-authored-by: Triton171 <triton0171@gmail.com>
2022-06-25 13:12:30 -05:00
two-six
18435899b2 [Theme] Acme (#2876) 2022-06-25 12:09:04 -05:00
Hekno25
33e6df8707 feat: add wgsl_analyzer as wgsl language server (#2872) 2022-06-24 16:21:26 -05:00
Saber Haj Rabiee
3dbad0442f fixes showing the last prompt on empty input (#2870) 2022-06-24 17:14:48 +02:00
Michael Davis
d948ace67b check selection's visible width when copying on mouse click (#2711)
* check selection's visible width when copying on mouse click

Mouse-click-up copies the selection produced by dragging. The event
is ignored if the selection has a width of 1 though so you don't
copy when clicking rather than dragging. The current check copies
text when it has a visible width of 1 but is actually multiple
characters in the rope like a CRLF line-ending. With this change
we check the unicode width of the character(s) in the selection
rather than the range length, so clicking on a CRLF line-ending
does not copy.

* use range.fragment to simplify getting the primary selection width
2022-06-24 22:58:04 +09:00
farwyler
886cff3bcc Redetect indent and line endings after language server replaces documents (#2778)
* redetect indent and line endings after language server replaces document

* removes nested if

* always redetect indent and line endings after format

This reverts commit 764d14f55894dc7213e48022dfa0f91829b8ef59.
2022-06-24 22:56:18 +09:00
Seth Bromberger
c107f4ea49 fixes #2856 by resetting style on diagnostic (#2861) 2022-06-22 20:53:36 +02:00
Gokul Soumya
301065fe4d Fix scrollbar length proportional to total menu items (#2860)
The scrollbar length used to increase with more entries in the menu,
which was counter-intuitive to how scrollbars worked in most
applications. Turns out there was a typo in the floor division
implementation :)
2022-06-23 03:00:12 +09:00
Erin van der Veen
b365f2d614 update tree-sitter-nickel to include ' in ident (#2859)
see https://github.com/nickel-lang/tree-sitter-nickel/pull/9
and  https://github.com/tweag/nickel/pull/737
2022-06-22 20:01:54 +09:00
Yusuf Bera Ertan
8c86cd56cb build(nix): update flake deps, add default.nix file 2022-06-21 17:39:30 -05:00
dependabot[bot]
5b3b6ffc9e build(deps): bump regex from 1.5.4 to 1.5.5 (#2851)
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.5)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-22 03:42:22 +09:00
Blaž Hrastnik
23b5b1e25a Remove a couple more unwraps 2022-06-22 02:26:24 +09:00
Blaž Hrastnik
19dccade7c Merge pull request #2359 from dead10ck/test-harness
Integration testing harness
2022-06-21 18:59:02 +02:00
Termina94
a17626a822 add history suggest to global search (#2717)
Co-authored-by: Dean Revell <revell@gmail.com>
2022-06-22 01:52:25 +09:00
Gokul Soumya
8e8367eea6 Refactor Margin for fine grained control (#2727) 2022-06-22 01:52:08 +09:00
ath3
ce85b9716d Enable shellwords for Windows (with escaping disabled) (#2767) 2022-06-22 01:48:01 +09:00
Gokul Soumya
8b67acf130 Format keys identically in statusline and command palette (#2790)
The command palette previously used + as a delimiter for denoting
a single key in a key sequence, (like C+w). This was at odds with
how the statusline displayed them with pending keys (like <C-w>).
This patch changes the palette formatting to the statusline formatting
2022-06-22 01:46:50 +09:00
Gokul Soumya
8ad0b83e30 Make indent guides configurable 2022-06-21 18:43:25 +02:00
Gokul Soumya
924b4ebb39 Add theme scopes for indent guides 2022-06-21 18:43:25 +02:00
Gokul Soumya
8c4c923e80 Add indent guides support 2022-06-21 18:43:25 +02:00
Blaž Hrastnik
458b89e21d Merge branch 'master' into test-harness 2022-06-21 18:38:21 +02:00
Matthew Toohey
6a3f7f2c39 feat: make move_vertically aware of tabs and wide characters (#2620)
* feat: make `move_vertically` aware of tabs and wide characters

* refactor: replace unnecessary checked_sub with comparison

* refactor: leave pos_at_coords unchanged and introduce separate pos_at_visual_coords

* style: include comment to explain `pos_at_visual_coords` breaking condition

* refactor: use `pos_at_visual_coords` in `text_pos_at_screen_coords`

* feat: make `copy_selection_on_line` aware of wide characters
2022-06-22 01:36:36 +09:00
Mathspy
fa4934cff9 Default rulers color to red (#2669)
* Default rulers color to red

Currently if the theme a user is using doesn't have `ui.virtual.rulers`
set and they set up a ruler it just fails silently making it really hard
to figure out what went wrong. Did they set incorrectly set the ruler?
Are they using an outdated version of Helix that doesn't support rulers?

This happened to me today, I even switched to the default theme with
the assumption that maybe my theme just doesn't have the rulers setup
properly and it still didn't work.

Not sure if this is a good idea or not, feel free to suggest better
alternatives!

* Use builtin Style methods instead of Bevy style defaults

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>

* Only default the style if there's no ui or ui.virtual

* Update themes style from ui.virtual to ui.virtual.whitespace

* Revert ui.virtual change in onelight theme

* Prefer unwrap_or_else

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-06-22 01:35:25 +09:00
Michael Davis
9f676dab57 add test textobjects queries for erlang,gleam,go,python,rust 2022-06-21 11:32:03 -05:00
Connor Lay (Clay)
67f6c85792 text-objects: add test capture & elixir queries 2022-06-21 11:32:03 -05:00
A-Walrus
43027d9104 Display highest severity diagnostic in gutter (#2835)
* Display highest severity diagnostic in gutter

* Improve gutter diagnostic performance

Very slight improvement (doesn't really make a difference), iterates over the diagnostics of the line
once instead of twice.

* Add comment justifying unwrap
2022-06-21 08:09:43 +05:30
dependabot[bot]
009f8c4d3b build(deps): bump anyhow from 1.0.57 to 1.0.58 (#2843)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.57 to 1.0.58.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.57...1.0.58)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-21 08:08:45 +05:30
Michael Davis
0ad10ce6f7 rewrite language configuration docs (#2838)
This change moves the configuration tables from the Adding
Languages guide into the overall Languages section. It also
adds more detailed documentation on the `language-server`
configuration key and fixes a typo in the "mylang" example
(the scope was `scope.mylang` instead of `source.mylang`).
2022-06-21 01:15:50 +02:00
Mathis Brossier
8c64c3dfa3 mouse selection now uses character indexing (#2839) 2022-06-20 20:41:34 +02:00
farwyler
cad4e03a00 adds missing tree-sitter-comment injection for js/ts (#2763) 2022-06-20 10:55:51 -05:00
lazytanuki
55f4f69515 fix: do not color health summary when stdout is piped (#2836)
* fix: do not color health summary when stdout is piped

* fix: use crossterm instead of is-terminal
2022-06-20 17:07:32 +02:00
Joe
e2878a6e21 Add noctis bordo theme (#2830) 2022-06-20 09:21:21 -05:00
Skyler Hawthorne
5f7c247430 replace phrase in tests 2022-06-19 00:00:31 -04:00
Skyler Hawthorne
665286c199 factor new Application with file arg to function 2022-06-19 00:00:31 -04:00
Skyler Hawthorne
65bf6836b7 update docs for integration tests 2022-06-19 00:00:31 -04:00
Skyler Hawthorne
086b63ab1b add integration-test cargo alias 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
41bf1d5811 fix(command): write-quit: do not quit if write fails
During write-quit, if the file fails to be written for any reason, helix
will still quit without saving the changes. This fixes this behavior by
introducing fallibility to the asynchronous job queues. This will also
benefit all contexts which may depend on these job queues.

Fixes #1575
2022-06-18 23:57:47 -04:00
Skyler Hawthorne
fac36bc5ea add test for write-quit happy path 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
7c0bca186c rename test helpers 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
526c9be8ca consolidate idle timer logic, make conditional 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
374724f5ac ignore failing write path tests until fixes are merged 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
8d8d389536 rename top level module to satisfy cargo fmt 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
acf931709a use a read only file to ensure write failure 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
ef8fe5a5ce use system's appropriate line ending 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
28e94fb261 need the full languages config for integration tests 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
4e34ee7d2e don't read from stdin for integration tests 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
cb0440be85 use env var for integration test log level 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
652cdda833 use test terminal backend for integration tests 2022-06-18 23:57:47 -04:00
Skyler Hawthorne
ed950fcc56 Add more context; Editor::open doesn't need to own path 2022-06-18 23:57:45 -04:00
Skyler Hawthorne
1533f48934 use Results in integration tests for more error context 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
2fbf833630 add integration feature to github tests 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
2386c81ebc use idle timer instead of fixed timeout 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
40120967e9 tests for buffer-close 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
07fc80aece tests for serialized writes 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
ee705dcb33 use main application event loop
Use the Application's main event loop to allow LSP, file writes, etc
2022-06-18 23:54:03 -04:00
Skyler Hawthorne
36e5809f63 add test for ensuring the initial cursor on a newly opened file 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
267605d147 reorganize tests into groups 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
84bbe6b8f3 refactor helpers, use new test helpers 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
0f3c10a021 Fix initial selection of Document in new view
When a new View of a Document is created, a default cursor of 0, 0 is
created, and it does not get normalized to a single width cursor until
at least one movement of the cursor happens. This appears to have no
practical negative effect that I could find, but it makes tests difficult
to work with, since the initial selection is not what you expect it to be.

This changes the initial selection of a new View to be the width of the
first grapheme in the text.
2022-06-18 23:54:03 -04:00
Skyler Hawthorne
502d3290fb improve test harness
* Use new macro syntax for encoding sequences of keys
* Make convenience helpers for common test pattern
* Use indoc for inline indented raw strings
* Add feature flag for integration testing to disable rendering
2022-06-18 23:54:03 -04:00
Blaž Hrastnik
308cab3e5c Integration testing harness 2022-06-18 23:54:03 -04:00
Blaž Hrastnik
adb6cd5376 Simplify handle_terminal_events signature 2022-06-18 23:54:03 -04:00
Skyler Hawthorne
0623a72599 move config parsing back into main 2022-06-18 23:54:03 -04:00
A-Walrus
ad15e7b5e8 Add "<<=" operator to Rust syntax highlighting (#2805) 2022-06-18 11:44:21 -05:00
Michael Davis
45ce1ebdb6 embed jsonrpc types from jsonrpc-core crate (#2801)
We should not depend on jsonrpc-core anymore:

* The project just announced it's no longer actively maintained[^1],
  preferring their new implementation in `jsonrpsee`.
* The types are too strict: we would benefit from removing some
  `#[serde(deny_unknown_fields)]` annotations to allow language
  servers that disrespect the spec[^2].
* We don't use much of the project. Just the types out of core.
  These are easy to embed directly into the `helix-lsp` crate.

[^1]: https://github.com/paritytech/jsonrpc/pull/674
[^2]: https://github.com/helix-editor/helix/issues/2786
2022-06-18 12:59:57 +09:00
Clay
b13e534b92 HEEx: upgrade version and support new special_attribute node (#2800) 2022-06-17 17:30:28 -05:00
Henry
15807d5f27 simplify some keymap key names follow up tests (#2694) 2022-06-17 09:51:45 -05:00
Grenier Célestin
33ea3eff05 Update theme base16_default (ui.menu) (#2794) 2022-06-17 20:24:18 +09:00
nosa
21d12e1487 Restore section spacing in tutor. (#2791) 2022-06-16 17:28:55 -05:00
Gygaxis Vainhardt
debd2405d9 views -> buffers in write-all (#2788) 2022-06-16 16:09:30 -05:00
Axot
4d604d3b50 Add clojure language support (#2780)
Co-authored-by: Mateusz Ledwoń <mateusz.ledwon@iteo.com>
2022-06-16 11:47:52 -05:00
nosa
3b1866f959 update tutor (#2716)
* update tutor

* Capitalize "command mode ".

* Update runtime/tutor.txt

Editing mistake.

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-06-15 15:31:26 -05:00
Bjorn Ove Hay Andersen
794576a5b0 Update auto-pairs and idle-timeout when the config is reloaded (#2736) 2022-06-15 22:59:58 +05:30
Tennix
11dadab371 Add migrate from Vim wiki link (#2781) 2022-06-15 11:04:17 -05:00
Frojdholm
402f285ba5 Improve markdown list rendering (#2687)
* Cleanup old commented code

* Implement line breaks in markdown rendering

* Implement markdown nested, numbered and multiparagraph lists
2022-06-15 13:20:19 +09:00
Roland Kovacs
c2cc2037b5 Better handling of symlinks (#2718)
- Add file-picker.follow-symlinks configuration option (default is true), this
  also controls if filename and directory completers follow symlinks.

- Update FilePicker to set editor error if opening a file fails, instead of
  panicing.

Fix #1548
Fix #2246
2022-06-15 13:17:17 +09:00
Anton Romanov
7983c71752 Introduce storage_class highlight scope (#2731) 2022-06-14 12:35:36 -05:00
Michael Davis
cdeab337cd simplify fallback for selected line-number theming (#2768) 2022-06-14 21:40:38 +05:30
Ryang Sohn
3bd5545577 Add a check to prevent re-selecting same range (#2760) 2022-06-14 08:37:40 -05:00
Kappa
d7bd441675 Cleanup for runtime/tutor.txt (#2590) 2022-06-13 23:12:13 +08:00
Bjorn Ove Hay Andersen
3b2d4031f1 Clarified the text in chapter 3 of the tutor (#2735)
* Clarified the text in chapter 3 of the tutor (#2725)

* Adjusted section 3.1 to better show how C works
2022-06-13 09:00:40 -05:00
Jonas Tepe
a766b32ed1 Expand chapter one recap of tutor
This add the missing variant of entering insert mode
to the chapter 1 recap section.
2022-06-12 14:12:52 -05:00
Ivan
0bc7259672 add prisma tree-sitter and lsp support (#2703)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-06-12 14:08:51 -05:00
Gokul Soumya
e9283b20b4 Add docstring for language_server!() macro (#2750) 2022-06-12 09:53:58 +09:00
Gokul Soumya
0b8a00ac96 Refactor textobject node capture (#2741) 2022-06-12 00:39:21 +09:00
Daniel Hines
9b9c3e5ae2 add rust-analyzer to shell environment (#2739) 2022-06-11 17:23:18 +09:00
Clay
f37ffaa3a1 elixirLS disable dialyzer by default (#2710)
Not all Elixir projects use dialyzer and it can cause the editor
to slow down quite a bit on large projects if the PLT is not built.

See https://github.com/elixir-lsp/elixir-ls#dialyzer-integration=
2022-06-10 10:45:17 +09:00
Danny
567e71fbbc fix spelling of catppuccin theme (#2713) 2022-06-08 23:33:26 +05:30
Frojdholm
e0532771cc Do not add extra line breaks in markdown lists (#2689) 2022-06-08 09:44:07 +09:00
Michael Davis
4a27e2d938 capture rust closures as function textobjects
Closures like

    iter.map(|a| a + 1)

Are sort-of functions, so `]f` or `maf` or `mif` can apply to them
as well as named function definitions.
2022-06-07 20:03:31 +09:00
Michael Davis
f7a3d35752 add textobject queries for gleam 2022-06-07 20:03:31 +09:00
Michael Davis
bcafdf404f add textobject queries for elixir 2022-06-07 20:03:31 +09:00
Michael Davis
7a9147489e add textobject queries for erlang 2022-06-07 20:03:31 +09:00
dependabot[bot]
9f8df05d96 build(deps): bump tokio-stream from 0.1.8 to 0.1.9 (#2690)
Bumps [tokio-stream](https://github.com/tokio-rs/tokio) from 0.1.8 to 0.1.9.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-stream-0.1.8...tokio-stream-0.1.9)

---
updated-dependencies:
- dependency-name: tokio-stream
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-07 14:51:36 +09:00
dependabot[bot]
5c7d9d6027 build(deps): bump tokio from 1.18.2 to 1.19.2 (#2691)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.18.2 to 1.19.2.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/commits)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-07 11:10:00 +05:30
Yusuf Bera Ertan
bb83ea8393 chore(nix): format nix files with alejandra, update deps, minor code refactors (#2683) 2022-06-06 14:24:52 -05:00
farwyler
f0d1c85553 support for openscad (#2680)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-06-06 12:26:56 -05:00
Blaž Hrastnik
26dbdb70fb Refactor push_jump so we're not needlessly fetching doc twice 2022-06-07 00:23:41 +09:00
Blaž Hrastnik
3d9923969a minor: Simplify Document.language_id() 2022-06-07 00:23:41 +09:00
Blaž Hrastnik
b14c258a2c prompt: If submitting empty prompt, use default (last used) 2022-06-07 00:23:40 +09:00
Henry
8351a82c2c simplify some keymap key names (#2677) 2022-06-05 21:22:10 -05:00
Michael Davis
0035c29fc1 Use a minimal binary to fetch grammar sources in release CI (#2557)
This is an optimization for the release CI. The release CI can take
a while since it compiles release builds for all operating systems.
We cut down on duplicate work and overall time by fetching
tree-sitter grammar repositories and then using those repositories
in all later steps. Previously we built all of helix just to run

    helix_loader::grammar::fetch_grammars()

which is wasteful on time. With this change we only build the
helix-loader crate.
2022-06-05 19:53:20 +09:00
Termina94
f1ae496860 Add shell insert commands to typable and config (#2589)
* Add shell insert commands to typable and config

* generate docs

Co-authored-by: Dean Revell <revell@gmail.com>
2022-06-05 19:52:41 +09:00
farwyler
f92a25a856 Passing extra formatting options to LSPs (#2635)
* allows passing extra formatting options to LSPs

- adds optional field 'format' to [[language]] sections in 'languages.toml'

- passes specified options the LSPs via FormattingOptions

* cleaner conversion of formatting properties

* move formatting options inside lsp::Client

* cleans up formatting properties merge
2022-06-05 19:50:57 +09:00
gavynriebau
b2bd87df81 Fix crash due to cycles when replaying macros (#2647)
In certain circumstances it was possible to get into an infinite loop
when replaying macros such as when different macros attempt to replay
each other.

This commit adds changes to track which macros are currently being
replayed and prevent getting into infinite loops.
2022-06-05 19:49:41 +09:00
Michael Davis
1c2aaf3baf ensure :quit and :quit! take no arguments (#2654) 2022-06-05 19:48:16 +09:00
yzwduck
d24ca66dbb Avoid modifying jumplist until jumping to ref (#2670)
When a goto command is cancelled, the jumplist should remain unchanged.

This commit delays saving the current selection to the jumplist until
jumping to a reference.
2022-06-05 19:44:55 +09:00
gavynriebau
026241cf72 Fix panic on close last buffer (#2367) (#2658)
* Fix panic on close last buffer (#2367)

In certain circumstances it was possible to cause a panic when closing
buffers due to some mishandling of view document history.

A change has been made to delete removed documents from the history of
accessed documents for each view. The ensures we don't attempt to jump
to a deleted document by mistake.

* Move remove document code into View function 'remove_document'

* Replace 'view.jumps.remove' call with 'view.remove_document' call
2022-06-05 11:27:41 +09:00
nosa
5b4e0a304b Update selection style of Night Owl (#2668) 2022-06-04 10:40:39 +05:30
nosa
dfd0754394 Update keymap docs for window swapping (#2659) 2022-06-03 07:09:35 -05:00
Michael Davis
fd4858c03d add tree-sitter-jsdoc (#2650) 2022-06-03 10:26:47 +05:30
Michael Davis
42d780b103 add tree-sitter-edoc (#2640)
* add tree-sitter-edoc

* fix escape character capture in markdown queries

* add field negation operator "!" to tsq highlights
2022-06-03 07:41:17 +08:00
Kirawi
4f3d0a7706 append set_line_ending to document history (#2649) 2022-06-02 10:46:53 -05:00
Frojdholm
f7c27b604f Ignore SendErrors when handling grammars (#2641)
When handling grammars, fetching and building is done in a thread
pool.  Results are communicated over channels and the receiving
channel is closed on first error. This causes subsequent sends to
fail causing a mess in stderr. This ignores all SendErrors causing
only the first error to be printed.
2022-06-02 16:54:11 +09:00
Blaž Hrastnik
378f438fb0 fix: lsp: be more defensive about URI conversions 2022-06-02 14:07:19 +09:00
Blaž Hrastnik
6de6a3edbb fix: lsp: be more defensive about URI conversions 2022-06-02 14:07:19 +09:00
Blaž Hrastnik
3d91c99c3e fix: lsp: Sort edits by start range, Omnisharp sends them in reverse 2022-06-02 14:07:19 +09:00
Michael Zeller
99e08f50bd catpuccin ui.popup should be a different color from ui.background (#2644) 2022-06-01 16:11:58 -05:00
Fanda Vacek
8d4c954060 CPON parser supports unsigned int (#2643)
Co-authored-by: Fanda Vacek <fvacek@elektroline.cz>
2022-06-01 15:11:14 -05:00
Ryan Russell
ae12c58f0f Improve Readability (#2639) 2022-06-01 12:01:37 -05:00
Ben Lee-Cohen
fc666db6b9 Solarized Light: Fixing menu colors and adding English translation (#2626) 2022-05-31 10:15:32 -05:00
Andrey Tkachenko
fa2eeccc57 Fix unwrap error when undo after shell_append_output (#2625) 2022-05-31 23:08:16 +09:00
Clay
fc8c488322 Elixir: inject Markdown into docs, remove h sigil HEEx injection (#2619)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-05-30 21:32:14 -05:00
Timothy DeHerrera
eba82250bb feat(lang): Update Nix grammar & improve queries (#2472) 2022-05-30 13:47:18 -05:00
Blaž Hrastnik
370a16d0f0 Update to ropey 1.5 2022-05-30 12:29:07 +09:00
Blaž Hrastnik
5ed6223990 fix: Remove empty scratch buffer from jumplists when removing it
Fixes #1238
2022-05-30 01:22:17 +09:00
Paul Graydon
710c4a84b2 Adjust colors in tokyonight themes (#2606) 2022-05-29 10:56:10 -05:00
Michael Zeller
b43074dad3 illumos linker doesn't currently have -z relro (#2602) 2022-05-29 10:52:48 -05:00
Marcin Puc
cd4622db9b Update from-source install instruction in README (#2603) 2022-05-29 10:52:26 -05:00
Hugo
89c6e8aa94 Remove unnecessary unwrap (#2599)
`strip_prefix` will itself check whether the string starts with the
prefix, so the extra call to `starts_with` was unnecessary.
2022-05-29 11:13:21 +09:00
Blaž Hrastnik
10415a8069 Bump dependencies, allow retain_mut for now 2022-05-29 11:10:49 +09:00
Michael Davis
93e6eac15a mention the C++ compiler in the grammar build failure message (#2597)
Earlier in the builder we enable C++ (`.cpp(true)`) but only mention
the C compiler in the build failure message. Some grammars that have
C++ external scanners can provoke build failures in this step if a
C++ compiler isn't installed, so mentioning it in the error message
should help out debugging.
2022-05-29 11:06:31 +09:00
pancake
7706a4a0d8 Add Vlang tree-sitter in the languages.toml (#2526)
Co-authored-by: pancake <pancake@nopcode.org>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-05-28 14:46:10 -05:00
booklearner
7c107d0d3a Fix link to pop-dark in CHANGELOG.md (#2594) 2022-05-28 13:11:31 -05:00
Blaž Hrastnik
27609f5065 Fix the VERSION file 2022-05-29 01:07:30 +09:00
nitish-17
b31788102e mention the requirement of C++ compiler for building grammar in doc (#2592) 2022-05-28 11:02:47 -05:00
Blaž Hrastnik
a106341fd7 Fix release action 2022-05-28 23:23:08 +09:00
Michael Davis
46f9320709 add 22.05 changelog notes (#2584) 2022-05-28 09:18:15 -05:00
Michael Davis
efae76160d add section on syntax tree motions to the usage docs (#2568) 2022-05-26 10:39:58 +09:00
Ben Lee-Cohen
7160e745f7 Changing Macro color to avoid color confusion
I noticed that in Rust, `println!`being a macro, it matched the color of string literals. This was visually confusing to me, so I checked what the nvim catpuccin theme (https://github.com/catppuccin/nvim) does. While it is pretty different, it does use different colors for strings and all function types: https://share.cleanshot.com/RLG2y1

I don't know if blue or red makes more sense given the other syntax choices, but wanted to propose this change cc @IsotoxalDev
2022-05-25 09:54:20 -05:00
Michael Davis
82da9bd4f2 update Erlang grammar and queries
The update to the grammar itself covers the case where the document
is a single expression without a trailing newline such as "min(A, B)".
A small change to the parser now parses these expressions correctly
which improves the display of the function head in the signature
help popup.

The update to the queries marks 'andalso', 'orelse', 'not', etc. as
`@keyword.operator` which improves the look - it looks odd to see
operators that are words highlighted the same as tokens like '->'
or '=:='.
2022-05-25 21:26:26 +09:00
Michael Davis
45dd54082e update Gleam grammar and queries
With respect to the queries:

The locals scope for functions was not large enough, so a function's
parameter could outlive the function body. To fix it, we just widen
the scope to the `function` node.

See also https://github.com/gleam-lang/tree-sitter-gleam/issues/25

With respect to the parser:

An external scanner has been added that fixes the parsing of strings.
Previously, a comment inside a string would act like a comment rather
than string contents.

See also https://github.com/gleam-lang/tree-sitter-gleam/issues/14#issuecomment-1129263640

A new constructor node has been added as well which makes type
highlighting more fine grained.

See also https://github.com/gleam-lang/tree-sitter-gleam/pull/29
2022-05-25 21:26:26 +09:00
Andrey Tkachenko
10463fe32c Add parameter.around text object query 2022-05-25 21:26:06 +09:00
dependabot[bot]
da29527258 build(deps): bump once_cell from 1.10.0 to 1.12.0
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.10.0 to 1.12.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.10.0...v1.12.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-25 21:25:47 +09:00
dependabot[bot]
a13ff27023 build(deps): bump regex from 1.5.5 to 1.5.6
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.5 to 1.5.6.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.5...1.5.6)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-25 21:25:34 +09:00
Andrey Tkachenko
67fe16008e Basic verilog support (#2552) 2022-05-24 12:52:32 -05:00
Erasin
386dccc84e Add lua lsp (#2560) 2022-05-24 10:03:53 -05:00
Isotoxal
c429ed660f Add Catppuccin Theme (#2546)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-05-24 09:02:26 -05:00
Blaž Hrastnik
d6865cdca3 nix: bump dependencies 2022-05-24 09:37:17 +09:00
Michael Davis
89c0998aee lower MSRV to 1.57.0
This line uses the Display trait for io::ErrorKind which was
stabilized in Rust 1.60.0. We can set MSRV all the way back to
1.57.0 by replacing it with a pretty-print.

Closes #2460.
2022-05-24 01:05:19 +09:00
Michael Davis
92df5a5425 check MSRV in CI
It's very easy to use new rust features without realizing it since
the CI and local development workflows may use the latest rust version.
We try to keep some backwards compatibility with rust versions to make
packaging easier for some OS-level package-managers like Void Linux's.
See #1881.

This change runs the "Check" step for the pinned version of rust in
the rust-toolchain.toml file as well as the MSRV version in a matrix.
In order to bump the MSRV, we need to edit

    .github/workflows/msrv-rust-toolchain.toml

This commit sets the MSRV as 1.60.0 but a later child commit will
reduce the MSRV back to 1.57.0.

Closes #2482.
2022-05-24 01:05:19 +09:00
Michael Davis
aa87adf54b pin the rust toolchain to 1.61.0
1.61.0 in particular introduced new clippy lints that unexpectedly
failed CI until addressed. The lints are a bit tough to fix since
the toolchain action starts using new rust versions almost immediately
after release, so if you aren't using rustup, you may have a hard
time reproducing the lint results until your package manager updates
rust.

This brings an extra burden that we have to remember to make a
commit/PR to update rust in CI.
2022-05-24 01:05:19 +09:00
Michael Davis
f6531c9db0 inherit rust toolchain channel from rust-toolchain.toml
We've forked actions-rs/toolchain and merged
https://github.com/actions-rs/toolchain/pull/209
so we can take advantage of full support of `rust-toolchain.toml`.
Without that PR, the action fails because the `rustup` version
built into the runners by default is too old. #2528 covers switching
back to the upstream when it includes those changes.
2022-05-24 01:05:19 +09:00
Blaž Hrastnik
35303f749e Replace handwritten CI cache with Swatinem/rust-cache
The cache kept growing as dependencies kept changing and updating.
2022-05-23 13:48:00 +09:00
Jens Getreu
6801b28da0 Highlight active window in Autumn theme (#2531)
Co-authored-by: Jens Getreu <jens.getreu@dlh.lu>
2022-05-22 10:40:27 -05:00
Joel
682bcc3a32 fix: missing quotes around variable.other.member 2022-05-22 18:36:51 +09:00
Joel
0018545263 fix: remove duplicated ui.help in themes
the bottom value is used, so i've removed the top `ui.help` values from all themes

also, the values are not merged, so:

```toml
"ui.help" = { modifiers = ["reversed"] }
"ui.help" = { fg = "white", bg = "black" }
```

is equal to:

```toml
"ui.help" = { fg = "white", bg = "black" }
```
2022-05-22 18:36:51 +09:00
Daniel S Poulin
0c05447d49 Add shrink equivalent of extend_to_line_bounds (#2450)
* Add shrink equivalent of extend_to_line_bounds

* Add a check for being past rope end in end position calc

* Include the EOL character in calculations

* Bind to `A-x` for now

* Document new keybind
2022-05-22 10:33:11 +09:00
Ivan Tham
5bcb31a6df Make Borders u8 2022-05-22 10:26:32 +09:00
Ivan Tham
1837b5e4a6 Refactor Block with Default and bitflags
Specifying empty for bitflags is not recommended, it is now removed and added
Default. For BorderType, it now defaults to plain.
2022-05-22 10:26:32 +09:00
kyrime
bfc4ff4dcf Add theme key for picker separator (#2523)
Co-authored-by: ky <>
2022-05-22 10:24:51 +09:00
Leoi Hung Kin
5c864922d8 Fix panic when reloading a shrunk file (#2506)
* fix panic when reloading a shrunk file

* linting

* use scrolloff
2022-05-22 10:24:32 +09:00
Blaž Hrastnik
8df8ff27c2 cargo xtask docgen 2022-05-22 00:20:45 +09:00
Blaž Hrastnik
d25bae844c Add Scheme support
Skipped scm for now :/ it overlaps with tree-sitter-tsq
2022-05-22 00:01:07 +09:00
Roland Kovacs
6bd8924436 Move Tree nodes on view swap
Instead of moving the Node contents on view swap if they have the same parent
reorder them to keep traversal order otherwise re-parent them.
2022-05-21 08:53:16 -05:00
Roland Kovacs
3f10473d30 Implement view swapping
* add Tree::swap_split_in_direction()
* add swap_view_{left,down,up,right} commands, bound to H,J,K,L
  respectively in the Window menu(s)
* add test for view swapping
2022-05-21 08:53:16 -05:00
Jacob Thompson
e8e252648f Added a default lsp server for Java in languages.toml (#2511)
* Added a default lsp server for Java in languages.toml

* Added a default lsp server for Java in languages.toml cont.

Co-authored-by: Jacob Thompson <a01657923@usu.edu>
2022-05-20 15:17:46 +09:00
Michael Davis
e04bb8b891 address rust 1.61.0 clippy lints (#2514) 2022-05-20 12:16:11 +09:00
Christoph Horn
9be810fd01 add missing ui.menu to themes, fix issues with some themes 2022-05-20 10:32:59 +09:00
Christoph Horn
e7e13dcf06 add ui.menu to default theme 2022-05-20 10:32:59 +09:00
Christoph Horn
82fb217b6a use ui.menu instead of ui.statusline for command completion menu theme 2022-05-20 10:32:59 +09:00
Robert Walter
776686ab24 Separate colors for different diagnostics types (#2437)
* feat(theme): add separate diagnostic colors

This commit adds separate diagnostic highlight colors for the different
types of LSP severities. If the severity type doesn't exist or is
unknown, we use some fallback coloring which was in use before this
commit.

Some initial color options were also added in the theme.toml

Resolves issue #2157

* feat(theme): add docs for new diagnostic options

* feat(theme): adjust defaults & reduce redundancy

- the different colors for different diagnostic severities are now
  disabled in the default theme, instead diagnostics are just generally
  underlined (as prior to the changes of this feature)
- the theme querying is now done once instead of every iteration in the
  loop of processing every diagnostic message
2022-05-20 10:30:28 +09:00
Paul Scott
09f9f70576 Python highlight decorator attribute 2022-05-20 10:28:52 +09:00
Paul Scott
2a2030142f Python highlight keyword argument as parameter 2022-05-20 10:28:52 +09:00
Paul Scott
e680f9644d Python handling highlighting parameters with defaults 2022-05-20 10:28:52 +09:00
Paul Scott
abef250c58 Python highlight improvements: type, parameter etc
* str, list, etc. handled as @function.builtin and @type.builtin
* None and non-conforming type indentifiers as @type in type hints
* class identifiers treated as @type
* @constructor used for constructor definitions and calls rather than
  as a catch-all for type-like things
* Parameters highlighted
* self and cls as @variable.builtin
* improved decorator highlighting as part of @function

Re-ordering of some statements to give more accurate priority.
2022-05-20 10:28:52 +09:00
Zeddicus414
8e8d4ba27f dark_plus theme constructor should be green. 2022-05-20 10:28:52 +09:00
Zeddicus414
a6da99a144 Change python highlights.scm to more fully utilize the themes.
Create type keywords
Allow _CONSTANTS to start with _
Highlight constants before constructors
Move some keywords into @keyword.control
2022-05-20 10:28:52 +09:00
Bob
6462542fc5 support insert register in prompt (#2458)
* support insert register in prompt

* use next_char_handler instead of a flag

* Fix clippy issue

* show autoinfo when inserting register

* Revert "show autoinfo when inserting register"

This reverts commit 5488344de1.

* use completion instead of autoinfo

autoinfo is overlapped when using prompt

* recalculate_completion after inserting register

* Update helix-term/src/ui/prompt.rs

Co-authored-by: Ivan Tham <pickfire@riseup.net>

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2022-05-20 10:27:59 +09:00
Roland Kovacs
8958bf0a92 Implement view transpose (#2461)
Change the layout of existing split view from horizontal to vertical and
vica-versa. It only effects the focused view and its siblings, i.e. not
recursive.

Command is mapped to 't' or 'C-t' under the Window menus.
2022-05-20 10:25:04 +09:00
Andrey Tkachenko
62fd1f6999 Include macro attributes to impls, structs, enums, functions etc. textobjects (#2494) 2022-05-20 10:19:46 +09:00
Alexis Kalabura
301ed9b48f deletion of lines affecting popup scrolling (#2497) 2022-05-20 10:18:19 +09:00
midnightexigent
8493b5fca6 Add tree-sitter ssh client config queries (#2498)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-05-18 14:49:50 -05:00
dependabot[bot]
29121a18b5 build(deps): bump signal-hook from 0.3.13 to 0.3.14 (#2485)
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.13 to 0.3.14.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.13...v0.3.14)

---
updated-dependencies:
- dependency-name: signal-hook
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-17 14:45:43 +09:00
Michael Davis
50dd11985c prevent panic when handling an LSP response with no request (#2475)
A language server may push a response which doesn't belong to any
request. With this change, we discard the response rather than
crashing.

In the case of #2474, the language server sends an error message
with a null request ID which should not ever exist in the
`pending_requests` HashMap.

closes #2474
2022-05-17 14:45:34 +09:00
dependabot[bot]
0258cf45f3 build(deps): bump etcetera from 0.3.2 to 0.4.0 (#2486)
Bumps [etcetera](https://github.com/arzg/etcetera) from 0.3.2 to 0.4.0.
- [Release notes](https://github.com/arzg/etcetera/releases)
- [Commits](https://github.com/arzg/etcetera/commits)

---
updated-dependencies:
- dependency-name: etcetera
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-17 12:32:18 +09:00
Alexis Geoffrey
595213ca74 Change default Hare tab width to 8 (#2480) 2022-05-16 16:48:28 +09:00
Timothy DeHerrera
823eaad1a1 Add Snazzy theme (#2473) 2022-05-14 16:49:06 -05:00
spindlebink
af387e6873 Default to tabs instead of spaces for Odin files (#2464) 2022-05-12 08:23:38 -05:00
Blaž Hrastnik
7b287f636f nix: update flake dependencies 2022-05-11 11:02:40 +09:00
Blaž Hrastnik
7ae6cad52e Don't panic on LSP parsing errors
This made sense initially when the implementation was still new (so we
got user reports more frequently), but a parsing error now generally
signifies a language server isn't properly implementing the spec.
2022-05-11 11:00:55 +09:00
Blaž Hrastnik
8b1a03a178 Add FUNDING.yml 2022-05-11 10:51:20 +09:00
amaihoefner
a5bc69c2b5 feat(commands): add log-open command (#2422) 2022-05-11 10:18:45 +09:00
Ivan Tham
0477d02894 Exclude cursor when doing ctrl-w (#2431)
Currently ctrl-w in insert mode deletes the cursor which results in
unexpected behavior. The patch also reduces the selection to cursor before
performing prev word to remove the behavior of removing unnecessary text
when nothing should be removed.

1. `::#(|)#::` after `ctrl-w` should be `#(|)#::`, previously `#(|)#:`
2. `#(|::)#` after `ctrl-w` should be `#(|::)#`, previously `#(|)#`

Fix #2390
2022-05-11 10:12:27 +09:00
Alexis Kalabura
c80ac84978 Run debug console in windows (#2294) 2022-05-11 10:06:57 +09:00
unrelentingtech
2cb1ea7127 feat(lang): add Meson language support (#2314)
https://mesonbuild.com/Syntax.html
2022-05-11 10:06:37 +09:00
EmmChriss
807cdc60bf configurable lsp request timeout (#2405) 2022-05-11 09:54:35 +09:00
Michael Davis
247ab25bc0 prefer Document::set_selection to inserting selections directly (#2411)
Inserting these with the `HashMap::insert` method evades the call
to `Selection::ensure_invariants`. The effect is that the scratch
buffer (or other buffers opened through these code-paths) can start
with a selection at (0, 0), when a file with equivalent contents ("\n")
would start with (0, 1).

I.e.:

    hx

and

    touch f
    hx f

start with different selections even though they have an equivalent
Rope. With this change they both start with (0, 1).
2022-05-11 09:53:54 +09:00
Michael Davis
e0b5cdfb47 prevent selection collapse when inserting a newline (#2414)
Inserting a newline currently collapses any connected selections when inserting
or appending. It's happening because we're reducing the selections down to
their cursors (`let selection = ..` line) and then computing the new selection
based on the cursor. We're discarding the original head and anchor information
which are necessary to emulate Kakoune's behavior.

In Kakoune, inserting a newline retains the existing selection and _slides_
it (moves head and anchor by the same amount) forward by the newline and
indentation amount. Appending a newline extends the selection to include the
newline and any new indentation.

With the implementation of insert_newline here, we slide by adding the global
and local offsets to both head and anchor. We extend by adding the global
offset to both head and anchor but the local offset only to the head.
2022-05-11 09:53:43 +09:00
dependabot[bot]
40647f03ed build(deps): bump serde_json from 1.0.80 to 1.0.81 (#2447)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.80 to 1.0.81.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.80...v1.0.81)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-10 07:55:31 +08:00
dependabot[bot]
544a05dabf build(deps): bump tokio from 1.18.1 to 1.18.2 (#2448)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.18.1 to 1.18.2.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.18.1...tokio-1.18.2)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-10 07:55:01 +08:00
Yt
ae19aaf1a6 languages: add inc files to php (#2440) 2022-05-09 05:53:03 -05:00
Fanda Vacek
f3164c1174 Monokai pro spectrum theme shows error in yellow on red background (#2433)
Co-authored-by: Fanda Vacek <fvacek@elektroline.cz>
2022-05-08 13:16:29 -05:00
Fanda Vacek
76d55c0d9e Cpon support tree sitter version bumped (#2424)
Co-authored-by: Fanda Vacek <fvacek@elektroline.cz>
2022-05-07 06:47:15 -05:00
ChrHorn
b38c268097 fix Markdown list highlighting (#2401) 2022-05-07 11:26:34 +09:00
Robert Walter
495ba40eaf feat(languages): add odin language (#2399) 2022-05-05 12:09:09 -05:00
Ben Lee-Cohen
2f240b018e Adding the global gitignore to the default (#2410) 2022-05-05 10:58:18 -05:00
Matthew Toohey
a5f4925f53 feat(languages): git-ignore and git-attributes (#2397) 2022-05-05 08:47:28 -05:00
ChrHorn
fc61796895 TOML highlight: use variable.other.member instead of string for quoted keys (#2391) 2022-05-05 16:14:17 +09:00
Pavel Borzenkov
f1a77370cf feat(languages): detect 't' as perl (#2395) 2022-05-04 08:32:05 -05:00
ChrHorn
5ab669f1ac replace constant.number with constant.numeric (#2389) 2022-05-04 14:51:31 +09:00
Ben Lee-Cohen
09a17e4fa3 Making the 'set-option' command help more descriptive. (#2365)
* Making the 'set-option' command help more descriptive.

* Adding the generated docs

* Making the message multi-line

* Replace newline with break in generated docs
2022-05-04 11:17:08 +09:00
Michael Davis
f59b3b91c8 rewrite auto-pairs docs (#2384) 2022-05-04 11:16:34 +09:00
Matthew Toohey
25d128b5b3 feat(languages): detect cjs as javascript (#2387) 2022-05-03 20:55:40 -05:00
Johann Dahm
e529ca1b92 Fix build on aarch64-darwin (#1789)
Co-authored-by: Yusuf Bera Ertan <y.bera003.06@protonmail.com>
2022-05-03 17:32:44 -05:00
Matouš Dzivjak
d2b1add1f4 feat(term): wrap command palette in overlay (#2378)
Looks better and is consistent with the rest, nothing else.
2022-05-03 17:28:41 +09:00
dependabot[bot]
042463a4d1 build(deps): bump serde_json from 1.0.79 to 1.0.80 (#2376)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.79 to 1.0.80.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.79...v1.0.80)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-03 09:31:55 +09:00
dependabot[bot]
e418fae61b build(deps): bump serde from 1.0.136 to 1.0.137 (#2375)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.136 to 1.0.137.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.136...v1.0.137)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-03 09:31:34 +09:00
dependabot[bot]
0f1fce9af6 build(deps): bump log from 0.4.16 to 0.4.17 (#2374)
Bumps [log](https://github.com/rust-lang/log) from 0.4.16 to 0.4.17.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/commits/0.4.17)

---
updated-dependencies:
- dependency-name: log
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-03 09:31:23 +09:00
dependabot[bot]
fc35791af9 build(deps): bump tokio from 1.17.0 to 1.18.1 (#2373)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.17.0 to 1.18.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.17.0...tokio-1.18.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-03 09:31:05 +09:00
dependabot[bot]
feea518300 build(deps): bump thiserror from 1.0.30 to 1.0.31 (#2372)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.30 to 1.0.31.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.30...1.0.31)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-03 09:30:46 +09:00
Robert Walter
fba198c1e0 Add documentation for hx --health (#2357) 2022-05-02 16:46:25 -05:00
AntonioLucibello
ac2ea800ce Add undo checkpoint command (#2115)
* added undo checkpoint command

* changed add_undo_checkpoint to commit_undo_checkpoint

* mapped commit_undo_checkpoint to Alt-u

* Update default.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-05-02 23:45:20 +09:00
Kirawi
77ff8d3550 cfg-gate unused functions on macos & windows (#2332) 2022-05-02 23:31:23 +09:00
unrelentingtech
20162a426b feat(commands): make it possible to disable format-on-save via the 'auto-format' option (#2321) 2022-05-02 23:31:07 +09:00
Vince Mutolo
f9baced216 add reflow command (#2128)
* add reflow command

Users need to be able to hard-wrap text for many applications, including
comments in code, git commit messages, plaintext documentation, etc. It
often falls to the user to manually insert line breaks where appropriate
in order to hard-wrap text.

This commit introduces the "reflow" command (both in the TUI and core
library) to automatically hard-wrap selected text to a given number of
characters (defined by Unicode "extended grapheme clusters"). It handles
lines with a repeated prefix, such as comments ("//") and indentation.

* reflow: consider newlines to be word separators

* replace custom reflow impl with textwrap crate

* Sync reflow command docs with book

* reflow: add default max_line_len language setting

Co-authored-by: Vince Mutolo <vince@mutolo.org>
2022-05-02 23:24:22 +09:00
Roland Kovacs
567ddef388 Auto-complete directory members (#1801) (#1907)
Allow tab-completion to continue when there is only a single, unambigous
completion target which is a directory. This allows e.g. nested directories
to be quickly drilled down just by hitting <tab> instead of first selecting
the completion then hitting <enter>.
2022-05-02 23:18:41 +09:00
Ryosuke Hayashi
f85f0b7272 Add run-shell-command for Commands (#1682)
* add run_shell_command

* docgen

* fix command name

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* refactored Info::new

* show 'Command failed' if execution fails

* TypedCommand takes care of error handling and printing the error to the statusline.

* docgen

* use Popup instead of autoinfo

* remove to_string in format!

* Revert chage in info.rs

* Show "Command succeed" when success

* Fix info.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-05-02 23:15:02 +09:00
Fanda Vacek
1668183590 feat(lang): Cpon lang support (#2355)
Co-authored-by: Fanda Vacek <fvacek@elektroline.cz>
2022-05-01 09:34:46 -05:00
Blaž Hrastnik
ede01b5f1e num_cpus apparently unused in helix-term 2022-05-01 11:40:04 +09:00
Blaž Hrastnik
ade4cbffaa Add a nop clipboard provider for wasm 2022-05-01 11:39:31 +09:00
Blaž Hrastnik
9191af3f8d helix-loader + helix-core now compile for WASM 2022-05-01 11:39:07 +09:00
Blaž Hrastnik
8bb89dafa2 cargo xtask docgen 2022-05-01 11:37:14 +09:00
Blaž Hrastnik
73879052c1 Add Cairo support 2022-05-01 11:24:17 +09:00
unrelentingtech
2c60798b00 feat(ui): add nbsp (non-breaking space) to rendered whitespace (#2322) 2022-04-30 09:48:52 +09:00
Michael Davis
e4c2618099 prevent rendering visible whitespace on trailing cursor (#2331) 2022-04-30 09:48:11 +09:00
unrelentingtech
2687b8fb3b feat(ui): treat slashes as word separators in prompt (#2315)
When fiddling with paths in a :o prompt, one usually would want Ctrl-W to erase a path segment
rather than the whole path. This is how Ctrl-W works in e.g. (neo)vim out of the box.
2022-04-30 09:46:51 +09:00
nosa
0106173375 Add Night Owl Color Theme. (#2330) 2022-04-29 17:27:09 -05:00
unrelentingtech
8e77e3388c feat(lang): add devicetree (Flattened Device Tree Source) (#2329) 2022-04-29 15:08:00 -05:00
unrelentingtech
030e7ab988 fix(docs): cleanup obsolete indents.toml mentions (#2327) 2022-04-29 12:40:59 -05:00
Erasin
668b39d1df change cursor for copy selection (#2323) 2022-04-29 11:11:36 -05:00
Yang Tang
667cdf929f Fix spelling errors in some themes (#2324) 2022-04-29 11:03:46 -05:00
Erin van der Veen
21487d13fd feat(lang): Update nickel to include "rec" keyword (#2320) 2022-04-29 07:34:15 -05:00
Gokul Soumya
22ae1b92a6 Fix tests for surround primitives 2022-04-29 15:51:14 +09:00
Gokul Soumya
76175dbd6d Support m in surround delete and replace 2022-04-29 15:51:14 +09:00
Gokul Soumya
de15d70171 Add m textobject to select closest surround pair 2022-04-29 15:51:14 +09:00
Ivan Tham
c22873c33f Change A-left right to C-left right in insert (#2193)
Currently A-left move one word left and the behavior will be more
consistent for people coming GUI world if the key was changed to control
given that both browsers and editors like vscode uses C-left right by
default to move word rather than alt.
2022-04-29 15:50:01 +09:00
Ivan Tham
ab6a00e196 Make A-hjkl tree-sitter nav A-pion (#2205)
A-hl currently is not very consistent with hl when next object is
selected, since it may go up/down or left/right and this behavior is
confusing such that some people think it should swap the keys with A-jk,
so it is better to use A-pn since that only specifies two direction.

A-jk have the same issue as in it usually moves right and is not
consistent with the behavior of jk so people may think A-hl is better,
maybe A-oi is better here since A-hl will be swapped to A-pn, A-oi can
convey the meaning of in and out, similar to some window manager keys?
2022-04-29 15:49:15 +09:00
nosa
e10cf08516 Extend tutor file (#2133)
* Adds tutorial sections for multiple areas including:
- Changing selections to uppercase / lowercase
- yanking and pasting
- macros
- selecting to chars with t and f

PS: I got kind of carried away and put off commiting for a while,
    will commit to commit more often in the future.

* Changed section titles to all uppercase

* Added recap and section about jumplist

* Added sections for searching in file, joining lines and indenting lines.

* Removed some trailing whitespace

* Evened out the space between sections to all be 5 lines

* Add section on opening lines (o) and recap

* Changed the amount of lines between sections

This is so that - on a 24 line terminal -
only one section is visible at a time and
page up/page down goes straight to the next
section keeping the header at the top.

* Punctuation error

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>

* Punctuation error

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>

* Spelling error

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>

* Remove unnecessary word

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>

* Reword note about searches

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>

* Change word

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>

* Update tutor file

* Made some small changes suggested by Omnikar

* Added better demo for macros.

* Small changes

- Add newlines at the end
- Make "MACROS" section fit into 22 lines
- Correct mistake of saying helix copied to clipboard in "COPYING AND PASTING TEXT"

* Reformatted notes in copying/pasting section to fit in screen

* Add a note about n and N and their difference to Vim.

* Combine f and t commands into one section.

* Removed t/T section which was merged into the f/F section.

* Merge sections on manipulating case into one.

* Gave section's numbers

* Convert 'press' to 'type' in some places

* Added examples of how prompt lines should look.

* Reformatted notes in copy/pasting section.

* More rewording to more comfortably fit sections on screen.

* Grammatical error.

* Missing periods.

* Missing capital + small reformat

* Fix mis-numbered section

* Reworded to use these conventions when referring to inputs:
- "Press" for single keypresses
- "Type" for multiple keypresses / modifiers
- "Use" when referencing two inputs as a pair.

* till not 'til

* Say 'press' instead of 'type' when referring to symbols

* 'outdent' not 'unindent'

* Typo and grammar.

* Replace all 'press's with 'type's (apart from places it would make no sense in).

* Improve examples for joining and indenting lines.

* Section alignment.

Co-authored-by: Omnikar <omkar.subramaniam@icloud.com>
2022-04-29 09:52:11 +08:00
CossonLeo
477b88e99c Wrap current directory picker with overlay widget (#2308) 2022-04-28 22:17:24 +09:00
chunghha
3a398eec56 fix typos (#2304) 2022-04-27 14:21:20 -05:00
Alexis Kalabura
2e46961886 feat(lsp): add toml lsp (#2302) 2022-04-27 13:48:04 -05:00
Gokul Soumya
3626e38e51 Add ui.virtual theme scopes for onedark theme 2022-04-27 13:40:00 -05:00
Matouš Dzivjak
52f5a4228a feat(commands): better handling of buffer-close (#1397)
* feat(commands): better handling of buffer-close

Previously, when closing buffer, you would loose cursor position in other docs.
Also, all splits where the buffer was open would be closed.

This PR changes the behavior, if the view has also other buffer
previously viewed it switches back to the last one instead of the view
being closed. As a side effect, since the views are persisted,
 the cursor history is persisted as well.

Fixes: https://github.com/helix-editor/helix/issues/1186

* Adjust buffer close behavior

* Remove closed documents from jump history

* Fix after rebase
2022-04-28 01:14:46 +09:00
Erasin
a3c0b4db48 Add onelight theme variant (#2287) 2022-04-27 08:09:45 -05:00
meak
1a3d6252b9 feat(lang): add hare language support (#2289)
Co-authored-by: Mehdi Katranji <hello@mek.yt>
2022-04-26 14:55:00 -05:00
Michael Davis
773736b03a Fix paste direction for typed paste commands (#2288) 2022-04-26 23:01:45 +05:30
Tomas Roos
fcd0ca3912 Fix base16_terminal theme using incorrect ansi-color (#2279) 2022-04-26 07:53:02 -05:00
dependabot[bot]
3d3145d511 build(deps): bump anyhow from 1.0.56 to 1.0.57 (#2273)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.56 to 1.0.57.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.56...1.0.57)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-26 11:20:58 +08:00
Jens Getreu
8eb15f5283 Autumn theme: improve markup highlighting (#2270)
Co-authored-by: Jens Getreu <jens.getreu@dlh.lu>
2022-04-25 12:39:24 -05:00
Lucy
b65fb0f64a Fix typo (#2264) 2022-04-25 07:26:02 -05:00
matt rice
db47761154 register publish_diagnostics client capability (#2241) 2022-04-25 11:14:46 +09:00
ttys3
a8cb46680d feat(lsp): add vala language support (#2243) 2022-04-24 11:21:07 -05:00
workingj
ea02b46c5d Add Pop-Dark Theme (#2189) 2022-04-24 08:04:47 -05:00
Daniel
15db6031bb Add :get-option command (#2231) 2022-04-24 16:00:18 +05:30
Michael Davis
3f2bd7770e Rename paragraph motion commands from move to goto (#2226)
* fix command name for next/prev paragraph motion

* rename move_next/prev_paragraph to goto_next/prev_paragraph
2022-04-24 10:48:22 +09:00
Lukas
5ca8dfe57c fix(lsp): divide hcl into seperate languages (#2244) 2022-04-23 16:08:12 -05:00
Paul Graydon
6047506ec5 Add tokyonight_storm theme variant (#2240) 2022-04-23 08:56:43 -05:00
Lukas
1c1ba006ae feat(lsp): add yaml lsp (#2234) 2022-04-23 08:38:29 -05:00
Michael Davis
2c7f770aa9 Only merge top-level array when merging languages.toml (#2215)
* Revert "Revert "override nested arrays when merging TOML (#2145)""

This reverts commit 35d2693630.

* flip top-level table merging flag
2022-04-23 17:10:34 +09:00
ttys3
19d042dde6 chore(lsp): check rename capabilities before send rename action (#2203) 2022-04-23 17:09:16 +09:00
Ivan Tham
c1d3d49f3f Fix ctrl-u on insert behavior (#1957)
* Fix ctrl-u on insert behavior

Now should follow vim behavior more
- no longer remove text on cursor
- no longer remove selected text while inserting
- first kill to start non-whitespace, start, previous new line

* Add comment for c-u parts
2022-04-23 17:03:52 +09:00
Kirawi
dd5a7c6191 Replace line endings using set_line_ending command (#1871)
* set_line_ending: now replace line endings

* use ending.len_chars() directly

* account for unicode-lines feaure in line-ending doc
2022-04-23 17:01:08 +09:00
Justin Ma
5c2570582b feat(lang): add nushell language support (#2225)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-04-22 09:37:51 -05:00
Jens Getreu
3c250b7528 Add autumn theme (#2212)
Co-authored-by: Jens Getreu <jens.getreu@dlh.lu>
2022-04-22 08:54:43 -05:00
Michael Davis
6de2e7634f Document ui.virtual.ruler scope in theme docs (#2199)
From the rulers feature (#2060)
2022-04-20 23:34:17 +05:30
ttys3
4144c9d2f2 feat(lang): add go.mod and go.work support (#2197) 2022-04-20 11:16:02 -05:00
ttys3
8d335f63f0 chore(filetype): bash and hcl file type add more common used extensions or files (#2201) 2022-04-20 11:08:57 -05:00
Jappie Klooster
b0bceb5674 Fix nix shell by hardcoding the flakecompat library (#2196) 2022-04-20 09:55:09 -05:00
Erin van der Veen
9616477197 Add Nickel language (#2173) 2022-04-20 09:31:59 -05:00
Emil Fresk
5247d3ae2d dark_plus: Add the borders color from the original theme (#2186) 2022-04-20 08:44:00 -05:00
Blaž Hrastnik
35d2693630 Revert "override nested arrays when merging TOML (#2145)"
Looks like there's some follow-up issues

This reverts commit c8cfd0b1a0.
2022-04-20 17:09:03 +09:00
Michael Davis
1525e3c6c8 theme ui.virtual capture for existing themes 2022-04-20 11:37:23 +09:00
Omnikar
e6b865ed0b allow whitespace to be rendered
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-04-20 11:37:23 +09:00
adaliaramon
94eba0e66a Added ability to remap 0 if it is not part of a count (#2174)
* Added ability to remap 0

* Removed duplicated match body
2022-04-20 10:50:13 +09:00
Ivan Tham
2a853cd41d Fix open on multiline selection (#2161)
Select multiple line and open should be based on the whole selection
and not just the line of the cursor, which causes weird behavior like
opening in the middle of the selection which user might not expect.
2022-04-20 10:46:46 +09:00
Thomas
5d5b6bab9b Add rulers option (#2060)
* Add color_column option

* Rename to ruler

Co-authored-by: DeviousStoat <devious@stoat.com>
2022-04-20 10:44:32 +09:00
matan h
02426072cb add table of OS/command for copy/symlink the runtime folder to the config (#2073)
* create table of OS and commands in the readme

* add link to wiki from health check (without color; just simple println)

* move the table from readme to docs and add link from the readme to docs

* drop copy on unix,and apply some style fixes from the conversations

* by mistake, I edit master insted of develop

* remove this file from pr

* Update README.md

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>

* copy table to readme

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-04-20 10:44:11 +09:00
Matthew Toohey
e452b97cdc AppImage (#2089)
* Add desktop entry file

Co-authored-by: NNB <n.at@aleeas.com>

* Add placeholder icon for AppImage

* Add AppImage step to release workflow

* Exclude grammar sources from AppImage

Co-authored-by: NNB <n.at@aleeas.com>
2022-04-20 10:43:52 +09:00
Michael Davis
c8cfd0b1a0 override nested arrays when merging TOML (#2145)
We merge the elements of arrays for the top-level array. For
`languages.toml`, this is the array of languages. For any nested
arrays, we simply take the `right` array as-is instead of using
the union of `left` and `right`.

closes #1000
2022-04-20 10:43:09 +09:00
Andrey Tkachenko
3a7bf1c40c Restore document state on completion cancel (#2096) 2022-04-20 10:42:33 +09:00
dependabot[bot]
cc68fa857d build(deps): bump toml from 0.5.8 to 0.5.9 (#2166)
Bumps [toml](https://github.com/alexcrichton/toml-rs) from 0.5.8 to 0.5.9.
- [Release notes](https://github.com/alexcrichton/toml-rs/releases)
- [Commits](https://github.com/alexcrichton/toml-rs/compare/0.5.8...0.5.9)

---
updated-dependencies:
- dependency-name: toml
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-19 08:54:20 +09:00
dependabot[bot]
c53ec95708 build(deps): bump fern from 0.6.0 to 0.6.1 (#2165)
Bumps [fern](https://github.com/daboross/fern) from 0.6.0 to 0.6.1.
- [Release notes](https://github.com/daboross/fern/releases)
- [Changelog](https://github.com/daboross/fern/blob/main/CHANGELOG.md)
- [Commits](https://github.com/daboross/fern/compare/fern-0.6.0...fern-0.6.1)

---
updated-dependencies:
- dependency-name: fern
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-19 08:54:09 +09:00
Paul Graydon
015a582d44 Add tokyonight theme (#2162) 2022-04-18 21:50:19 +05:30
Michael Davis
4e877de54d Fix Golang textobject queries (#2153)
* log textobject query construction errors

The current behavior is that invalid queries are discarded silently
which makes it difficult to debug invalid textobjects (either invalid
syntax or an update may have come through that changed the valid set
of nodes).

* fix golang textobject query

`method_spec_list` used to be a named node but was removed (I think
for Helix, it was when updated to pull in the support for generics).
Instead of a named node for the list of method specs we have a bunch
of `method_spec` children nodes now. We can match on the set of them
with a `+` wildcard.

Example go for this query:

    type Shape interface {
       area() float64
       perimeter() float64
    }

Which is parsed as:

    (source_file
      (type_declaration
        (type_spec
          name: (type_identifier)
          type: (interface_type
            (method_spec
              name: (field_identifier)
              parameters: (parameter_list)
              result: (type_identifier))
            (method_spec
              name: (field_identifier)
              parameters: (parameter_list)
              result: (type_identifier))))))
2022-04-18 23:14:48 +08:00
Michael Davis
449d1dfdfb prevent panic when receiving malformed LSP PublishDiagnostic (#2160)
Instead of panicing we can discard the malformed diagnostic. This
`.parse()` fails commonly when a non-conformant language server gives
a diagnostic with a location that breaks the spec:

    { "character": 0, "line": -1 }

can currently be returned by ElixirLS and the python LS. Other
messages in this block are discarded but this one feels special enough
to log.
2022-04-18 23:11:28 +08:00
Lucy
4b1fe367fa Remove dim attribute in onedark ui.linenr (#2155) 2022-04-18 15:52:26 +05:30
Ben Lee-Cohen
2bddec02e7 Fixing (in two ways) a small typo (#2156) 2022-04-18 13:12:47 +09:00
Kirawi
c2a40d9d52 Add support for local language configuration (#1249)
* add local configuration

* move config loading to Application::new

* simplify find_root_impl
2022-04-18 12:10:51 +09:00
Danillo Melo
be656c14e3 Ruby TextObjects and more file extensions (#2143) 2022-04-17 19:25:44 -05:00
Michael Davis
ad36a024da Update tree-sitters Erlang and HEEx (#2149) 2022-04-17 23:16:22 +05:30
Terry Brash
c45fb08a93 Add JavaScript control keywords (#2140) 2022-04-17 15:14:55 +09:00
AntonioLucibello
b67e0616dd Add command to extend selection to line above (#2117)
* added command to extend selection to line above

* fixed view not scrolling up when reaching top of the screen

* refactored shared code into separate impl
2022-04-17 12:26:14 +09:00
Robin Jadoul
33b7483db5 Send active diagnostics to LSP when requesting code actions. (#2005)
* Send active diagnostics to LSP when requesting code actions.

This allows for e.g. clangd to properly send the quickfix code actions
corresponding to those diagnostics as options.
The LSP spec v3.16.0 introduced an opaque `data` member that would allow
the server to persist arbitrary data between the diagnostic and the code
actions request, but this is not supported yet by this commit.

* Reuse existing range_to_lsp_range functionality
2022-04-17 12:05:23 +09:00
Thomas
2eca2901f3 Pipe typable command (#1972)
Co-authored-by: DeviousStoat <devious@stoat.com>
2022-04-17 12:03:47 +09:00
Andrey Tkachenko
dc8fef5dd3 Fixes #1991 LSP Auto-import (#2088) 2022-04-16 10:43:54 +09:00
Dr. David A. Kunz
b04c425c63 Make gutters configurable (#1967)
* config option line numbers none

* view tests

* added tests

* doc

* comment

* Make gutters configurable

* docu

* docu

* rm none docu

* order

* order

* precedence

* simpler

* rm todo

* fixed clippy

* order

* double quotes

* only allow diagnostics and line-numbers

* tests

* docu

* format

* rm short variant and more docu

* performance improvements

* typo

* rename
2022-04-16 10:41:25 +09:00
Evan Lecklider
450f348925 Add make file-type "mk" to languages.toml (#2120) 2022-04-15 12:15:17 -05:00
EmmChriss
50df924811 gdscript support (#1985) 2022-04-16 00:35:23 +09:00
nosa
893963df0a Additions to 'themes' section of docs (#2098)
* Added more descriptions to the themes part of the docs

* Add more descriptions to themes section of the docs

* capitalised first letters of descriptions in docs

Co-authored-by: Joe Mckay <jm@pop-os.localdomain>
2022-04-15 09:58:16 +09:00
Jared Ramirez
460e6a857b feat(languages): SQL (#2097) 2022-04-14 13:26:20 -05:00
Blaž Hrastnik
764adbdcf6 fix: prompt: pass through unmapped keys regardless of modifiers
Ctrl + Alt is apparently another common sequence for AltGr:
https://devblogs.microsoft.com/oldnewthing/20040329-00/?p=40003

Fixes #595
Fixes #2080
2022-04-13 15:19:42 +09:00
Michael Davis
4836bb38d3 add tree-sitter-heex
HEEx is a templating engine on top of Elixir's EEx templating
language specific to HTML that is included in Phoenix.LiveView
(though I think the plan is to eventually include it in base
Phoenix). It's a superset of EEx with some additional features
like components and slots.

The injections don't work perfectly because the Elixir grammar is
newline sensitive (the _terminator rule). See
https://github.com/elixir-lang/tree-sitter-elixir/issues/24
for more information.
2022-04-13 14:28:51 +09:00
Michael Davis
9d095e0fdc add tree-sitter-eex
EEx is an templating language for Elixir. Since the incremental
parsing refactor we can used combined injections which allows us
to add EEx support.
2022-04-13 14:28:51 +09:00
Michael Davis
4ac94a5c43 remove error highlighting for tree-sitter-elixir
This will become more important with the HEEx grammar being added.
Error highlighting with the Elixir grammar is a bit jumpy because
in some scenarios, a bit of missing syntax can force tree-sitter to
give up on error recovery and mark the entire tree as an error.
This ends up looking bad when editing. We don't typically highlight
error nodes so I'm inclined to leave it out of the highlights here.
2022-04-13 14:28:51 +09:00
Michael Davis
8c3c90198a update tree-sitter-elixir
The new revision handles a case that I come across often: a stab
clause (i.e. '->') with an empty right hand side:

    Enum.map(xs, fn x ->
    end)

The old version would parse the "end" token as an error.

This is technically valid syntax but more importantly it comes up
very often when editing, and the old revision would flicker between
the keyword highlight and the warning highlight.
2022-04-13 14:28:51 +09:00
scgtrp
740f565c80 Document values for editor.cursor-shape (#2094)
These are hinted at in the example config at the top (except `none`), but really should be listed explicitly near the option itself for clarity.
2022-04-13 13:00:17 +09:00
Ivan Tham
62283fdadb Make textobject select last paragraph (#1992)
* Make textobject select last paragraph

Last paragraph shoud be selected if the cursor was placed on the
whitespace paragraph part and `map` is done, otherwise it would do
nothing useful, but now we select backwards for the last paragraph
which behaves similarly to kakoune, making `map` useful for the last
paragraph with whitespace. Example usecase is to copy and paste last
ledger cli paragraph quickly by `mapyp` to duplicate last entry.

* Fix typo in core textobject

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2022-04-13 10:02:53 +09:00
Roland Kovacs
a0c6c45c1b Fix panic when using set-language on a scratch (#1996)
Skip launching a language server if a document doesn't have a valid URL.
2022-04-13 10:02:14 +09:00
Nirmal Patel
3deb1c9230 Add true or false checkbox in health output table (#1947)
hx --health output table's second and third columns were not showing
symbols like ✔ or ✘ to indicate whether LSP or DAP binaries were found.
This change adds these symbols to improve accessibility.

Fixes #1894

Signed-off-by: Nirmal Patel <npate012@gmail.com>
2022-04-12 17:21:16 +09:00
Benedikt Müller
1fb6144432 Add shell completion (#2022)
* Add shell completion

* Add shell completion to release
2022-04-12 17:10:21 +09:00
Omnikar
660e0e44b2 Add :write! to create nonexistent subdirectories (#1839)
* Make `:write` create nonexistent subdirectories

Prompting as to whether this should take place remains a TODO.

* Move subdirectory creation to new `w!` command
2022-04-12 16:52:54 +09:00
unrelentingtech
d5c0866978 Apply ui.gutter style to empty gutters (#2032)
The unstyled column on the left from the diagnostics_or_breakpoints gutter
looks sad if you want to add a background to all gutters. Let's fix this.
2022-04-12 16:48:30 +09:00
dependabot[bot]
f3dcb4034f build(deps): bump lsp-types from 0.92.1 to 0.93.0 (#2084)
Bumps [lsp-types](https://github.com/gluon-lang/lsp-types) from 0.92.1 to 0.93.0.
- [Release notes](https://github.com/gluon-lang/lsp-types/releases)
- [Changelog](https://github.com/gluon-lang/lsp-types/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gluon-lang/lsp-types/compare/v0.92.1...v0.93.0)

---
updated-dependencies:
- dependency-name: lsp-types
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-12 12:12:30 +09:00
dependabot[bot]
6530d452a0 build(deps): bump encoding_rs from 0.8.30 to 0.8.31 (#2083)
Bumps [encoding_rs](https://github.com/hsivonen/encoding_rs) from 0.8.30 to 0.8.31.
- [Release notes](https://github.com/hsivonen/encoding_rs/releases)
- [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.30...v0.8.31)

---
updated-dependencies:
- dependency-name: encoding_rs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-12 12:12:03 +09:00
dependabot[bot]
14079bd17b build(deps): bump cachix/install-nix-action from 16 to 17 (#2081)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-11 18:34:39 -05:00
dependabot[bot]
f9ddc8a9ac build(deps): bump actions/download-artifact from 2 to 3 (#2082)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-11 18:34:29 -05:00
Aral Balkan
7cb6e07ba0 Improve Dracula Theme selections (#2075) (#2077) 2022-04-11 09:21:41 -05:00
Michael Davis
3d79c60a1f Rewrite Language Support docs (#2065) 2022-04-10 23:20:05 +05:30
gavynriebau
562874a720 Add command for picking files from CWD (#1600)
The `file_picker_at_current_directory` command opens the file picker at
the current working directory (CWD). This can be useful when paired with
the built-in `:cd` command which changes the CWD.

It has been mapped to `space F` by default.
2022-04-10 11:30:09 +09:00
Michael Davis
494306ad7a add tree-sitter-embedded-template (erb & ejs) (#2055)
After the incremental parsing rewrite for injections (which was released
in 22.03 https://helix-editor.com/news/release-22-03-highlights/#incremental-injection-parsing-rewrite),
we can now do combined injections which lets us pull in some templating
grammars. The most notable of those is embedded-template - a pretty
straightforward grammar that covers ERB and EJS.

The grammar and highlights queries are shared between the two but they have
different injections.
2022-04-10 08:23:06 +09:00
Michael Davis
78b1600943 Improve documentation on Language Server installation (#2037) 2022-04-09 12:17:32 +05:30
Kurenshe Nurdaulet
0b410b0a16 Add default language server for Vue (#2043) 2022-04-08 21:04:22 -05:00
Evan Relf
7779dbfcb8 docs: Quote TOML keys containing dots (#2040) 2022-04-08 17:21:52 -05:00
Sam Sartor
209ec4468b Add dracula at night theme (#2008) 2022-04-08 15:53:12 -05:00
unrelentingtech
7f461895b0 Add language server command for OCaml (#2035) 2022-04-08 15:02:25 -05:00
Aaron Housh
9caf7c0d5a Add swift language (#2033) 2022-04-08 13:10:37 -05:00
Karl Grasegger
8e12fd5290 PHP roots and languageserver improvements (#2031)
Co-authored-by: Karl Grasegger <karl.grasegger@gebruederheitz.de>
2022-04-08 12:57:46 -05:00
Michael Davis
19ff21eaa2 Remove usage of format ident feature from tests (#2028) 2022-04-08 21:26:50 +05:30
David
61d1684a32 Add default language server for CSS (#2025) 2022-04-08 10:06:54 -05:00
David
22629ca211 Add default language server for JSON (#2024) 2022-04-08 10:06:41 -05:00
David
b5efb9d66c Add default language server for HTML (#2018) 2022-04-08 08:36:10 -05:00
Gaeulbyul
581ac5660f Fix typo (pallete -> palette) (#2020) 2022-04-08 08:35:11 -05:00
Kirawi
2d4f94eb27 [dark_plus] update tag and ui.menu.selected colors (#2014) 2022-04-07 21:08:16 -05:00
Gokul Soumya
420b5b8301 Compute style only once per source highlight event (#1966)
During a single HighlightEvent::Source, the highlight spans do not
change and we can merge them into a single style at the beginning
of the event and use it instead of re-computing it for every grapheme
2022-04-08 09:42:57 +09:00
Matthew Toohey
31c468ab95 add languages r and rmarkdown (#1998)
* add languages `r` and `rmarkdown`

* r: fix highlights

* rmarkdown: add eof in queries

* rmarkdown: update lang-support.md

* r: fix highlight query precedence
2022-04-08 09:30:44 +09:00
tomKPZ
d37369c1e0 Add paragraph textobject to match infobox (#1969) 2022-04-07 09:11:14 +08:00
Michael Davis
b03421a8c0 remove hardcoded '/' from grammar source path (#1986) 2022-04-07 00:32:00 +09:00
Michael Davis
275c05008f fix keymap doc typo for 'delete' in insert-mode (#1990)
closes #1980
see also #1180
2022-04-07 00:31:40 +09:00
Kirawi
b333186721 [dark_plus] update markup colors (#1989) 2022-04-07 00:31:28 +09:00
bootradev
0eb87996a8 add boo_berry theme (#1962) 2022-04-06 01:06:51 +09:00
VuiMuich
eb84d9493c add language ron (#1925) 2022-04-05 07:39:22 -05:00
Danilo Spinella
6b80cb8a77 Fix toggle_comments command on multiple selections (#1882) 2022-04-05 10:01:58 +09:00
Roland Kovacs
d962e06e91 Add runtime language configuration (#1794) (#1866)
* Add runtime language configuration (#1794)

* Add set-language typable command to change the language of current buffer.
* Add completer for available language options.

* Update set-language to refresh language server as well

* Add language id based config lookup on `syntax::Loader`.
* Add `Document::set_language3` to set programming language based on language
  id.
* Update `Editor::refresh_language_server` to try language detection only if
  language is not already set.

* Remove language detection from Editor::refresh_language_server

* Move document language detection to where the scratch buffer is saved.
* Rename Document::set_language3 to Document::set_language_by_language_id.

* Remove unnecessary clone in completers::language
2022-04-05 09:56:14 +09:00
Ivan Tham
6fc6f87260 Fix next paragraph logic over muliple blank lines (#1951)
Fix #1928
2022-04-05 09:43:14 +09:00
Ivan Tham
e7beb32fd7 Add paragraph to last motion (#1956)
Fix #1954
2022-04-05 09:43:04 +09:00
Ivan Tham
d3c8286ea0 Bump crossterm to 0.32.2 (#1955)
Deduplicates mio dependency which results no crate duplication now and
7 lesser crate for cargo to build.
2022-04-05 09:41:28 +09:00
Rose Hudson
f8c83f9885 clear terminal after switching to alternate screen
when using helix over mosh, the screen doesn't get cleared and
characters get left all over the place until they are overwritten. with
this change, the screen gets properly cleared as soon as helix starts
2022-04-04 16:41:11 +09:00
Kirawi
3fc4ea2938 [dark_plus] remove ui.text background (#1950) 2022-04-03 17:59:02 -05:00
Dr. David A. Kunz
9782204f73 Add typed commands buffer-next and buffer-previous (#1940) 2022-04-03 17:56:46 +05:30
Ivan Tham
ec21de0844 Add missing # back to test output 2022-04-03 00:46:53 +09:00
Ivan Tham
8b91ecde40 Rename _para to _paragraph 2022-04-03 00:46:53 +09:00
Gokul Soumya
64c2490f2d Refactor test print to be more readable 2022-04-03 00:46:53 +09:00
Ivan Tham
45b76db506 Change test mark from ^@ to #[|]# 2022-04-03 00:46:53 +09:00
Ivan Tham
8350ee9a0e Add paragraph textobject
Change parameter/argument key from p to a since paragraph only have p
but parameter are also called arguments sometimes and a is not used.
2022-04-03 00:46:53 +09:00
Ivan Tham
e2a6e33b98 Add next paragraph 2022-04-03 00:46:53 +09:00
Ivan Tham
8b02bf2ea8 Add (prev) paragraph motion
Also improved testing facility.

Fix #1580
2022-04-03 00:46:53 +09:00
Lauri Gustafsson
e4561d1dde Add texlab language server for latex (#1922) 2022-04-02 09:00:05 -05:00
Simon H
36d1df71fc Added checkmarks to health.rs output, Resolves #1894 (#1918)
* Added checkmarks to health.rs output

* replaced found/not found text with checkmarks
2022-04-02 17:32:36 +09:00
Michael Davis
ffdc2f1793 separate JSX queries from javascript (#1921)
It looks like a24fb17b2a (and
855e438f55) broke the typescript
highlights because typescript

    ; inherits: javascript

but it doesn't have those named nodes in its grammar.

So instead we can separate out JSX into its own language and copy
over everything from javascript and supplement it with the new
JSX highlights. Luckily there isn't too much duplication, just the
language configuration parts - we can re-use the parser with the
languages.toml `grammar` key and most of the queries with `inherits`.
2022-04-02 10:07:35 +09:00
joezak11
deb7ee6595 Update bash tree sitter (#1917) 2022-04-01 08:48:39 -05:00
jeepee
85c23b31de Avoid unnecessary clone when formatting error (#1903)
Instead of first cloning the query and then allocating again to format
the error, format the error using a reference to the query.
2022-04-01 22:16:51 +09:00
jeepee
8165febe23 Fix start-position of next search (#1904)
The search implementation would start searching at the next grapheme
boundary after the previous selection. In case the next occurence of the
needle is immediately after the current selection, this occurence would
not be found (without wraparound) because the first grapheme is skipped.

The correct approach is to use the ensure_grapheme_boundary functions instead
of using the functions that skip unconditionally to the next grapheme.
2022-04-01 22:16:09 +09:00
antoyo
47fe739757 Jump to the next number on the line before incrementing (#1778)
* Jump to the next number on the line before incrementing

Partially fix #1645

* Refactor to avoid duplicating find_nth_next
2022-04-01 22:14:37 +09:00
Blaž Hrastnik
855e438f55 jsx: Add special highlighting to component names 2022-04-01 17:18:44 +09:00
Blaž Hrastnik
a24fb17b2a Add JSX highlighting queries 2022-04-01 17:14:25 +09:00
Amine Hmida
d0ff2ffd89 Add support for jsx (#1906)
* Add support for javascriptreact language

* Add support for jsx files
2022-04-01 17:08:34 +09:00
جاد
a9635659f7 Reintroduce win32yank as a clipboard provider on Linux for WSL2 + Windows 10 (#1912)
* feat(clipboard): reintroduce win32yank for wsl2 linux

* refactor(clipboard): adjust win32yank position to not interrupt wayland/x11

Co-authored-by: jiqb <gthbji@ml1.net>
2022-04-01 11:35:47 +09:00
Triton171
6bb2298391 Fix an issue that caused an empty indentation query to be used instead of using the fallback method of copying the indentation from the current line. (#1908)
Co-authored-by: Triton171 <triton0171@gmail.com>
2022-04-01 11:27:06 +09:00
Blaž Hrastnik
8adf0c1b3a lsp: Implement support for workspace_folders (currently just one)
Refs #1898
2022-04-01 11:20:41 +09:00
Blaž Hrastnik
236c6b7707 fix: copy_selections was broken with selections (not cursors) 2022-04-01 10:11:44 +09:00
Marcin Puc
924462edda Add install instructions for Void Linux (#1911) 2022-03-31 14:55:55 -05:00
Blaž Hrastnik
84e799f0e4 fix: Some LSPs still want rootPath, so provide it
Refs #1898
2022-03-31 17:45:51 +09:00
Rohan Jain
5d61631507 Resolve conflicts between prompt/picker bindings (#1792)
Currently, the picker's re-using a few bindings which are also present
in the prompt. This causes some editing behaviours to not function on
the picker.

**Ctrl + k** and **Ctrl + j**
This should kill till the end of the line on prompt, but is overridden
by the picker for scrolling. Since there are redundancies (`Ctrl + p`,
`Ctrl + n`), we can remove it from picker.

**Ctrl + f** and **Ctrl + b**
This are used by the prompt for back/forward movement. We could modify
it to be Ctrl + d and Ctrl + u, to match the `vim` behaviour.
2022-03-31 16:51:11 +09:00
Michael Davis
ef91b6500c set VERSION file to dev (#1883)
* set VERSION file to dev

* bump to 22.05-dev
2022-03-31 16:31:38 +09:00
Blaž Hrastnik
d15c875214 Add a TODO for the future 2022-03-31 15:59:09 +09:00
Blaž Hrastnik
ab7885e934 fix: copy_selection needs to account for to() being exclusive
Fixes #1367
Fixes #1590
2022-03-31 15:59:09 +09:00
Max
4eed4c26e9 Use fromTOML on Nix >= 2.6.0 (#1892) 2022-03-30 11:28:05 -05:00
Triton171
58758fee61 Indentation rework (#1562)
* WIP: Rework indentation system

* Add ComplexNode for context-aware indentation (including a proof of concept for assignment statements in rust)

* Add switch statements to Go indents.toml (fixes the second half of issue #1523)
Remove commented-out code

* Migrate all existing indentation queries.
Add more options to ComplexNode and use them to improve C/C++ indentation.

* Add comments & replace Option<Vec<_>> with Vec<_>

* Add more detailed documentation for tree-sitter indentation

* Improve code style in indent.rs

* Use tree-sitter queries for indentation instead of TOML config.
Migrate existing indent queries.

* Add documentation for the new indent queries.
Change xtask docgen to look for indents.scm instead of indents.toml

* Improve code style in indent.rs.
Fix an issue with the rust indent query.

* Move indentation test sources to separate files.
Add `#not-kind-eq?`, `#same-line?` and `#not-same-line` custom predicates.
Improve the rust and c indent queries.

* Fix indent test.
Improve rust indent queries.

* Move indentation tests to integration test folder.

* Improve code style in indent.rs.
Reuse tree-sitter cursors for indentation queries.

* Migrate HCL indent query

* Replace custom loading in indent tests with a designated languages.toml

* Update indent query file name for --health command.

* Fix single-space formatting in indent queries.

* Add explanation for unwrapping.

Co-authored-by: Triton171 <triton0171@gmail.com>
2022-03-31 00:08:07 +09:00
Blaž Hrastnik
c18de0e8f0 fix: Don't rely on FormattingOptions::default()
Refs #1884
2022-03-30 15:19:21 +09:00
Nirmal Patel
8702aaaefc Handle BrokenPipe when piping hx --health through head (#1876)
Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
2022-03-30 10:39:25 +05:30
Michael Davis
7cd6050235 add tree-sitter-gleam 2022-03-30 13:24:53 +09:00
Michael Davis
1819478940 update tree-sitter-elixir
news:

- tree-sitter-elixir now powers Elixir syntax highlighting on github.com
- GitHub now supports code-navigation for Elixir repos via
  tree-sitter-elixir

changes:

- modules now use the `@module` highlight, which was added upstream to
  tree-sitter
    - it seems appropriate to use `@namespace` to follow helix convention
- added nullary range operator (e.g. `Enum.to_list(..) == []`), a new syntax
  for elixir 1.14
- a fix for stab clause nodes mis-highlighting when the right hand side of
  the stab clause contained multiple simple expressions
2022-03-30 13:24:53 +09:00
Michael Davis
e2a50711d5 update tree-sitter-erlang
changes:

- typed fields within records which do not declare a default
  value are now correctly highlighted as record fields
- the EEP49 'maybe' form is now parsed
- fixes for highlights for 'begin' and 'after' tokens
2022-03-30 13:24:53 +09:00
Marcin Puc
f2dd3d4469 Avoid using the format ident Rust feature (#1881) 2022-03-30 09:08:30 +09:00
Michael Davis
c8082a1133 update screenshot (#1879) 2022-03-30 00:16:57 +09:00
Michael Davis
d4e45fd479 changelog notes for 22.03 (#1830) 2022-03-29 22:15:00 +09:00
Blaž Hrastnik
6c276d7868 Revert "Resize is not necessary inside SIGCONT, handled by render()"
Fixes #1877

This reverts commit 85264a861a.
2022-03-29 22:08:19 +09:00
Michael Davis
838cfcc7cd publish a source tarball with version and grammars (#1875)
* publish a source tarball with version and grammars

* include_str! the release version from a VERSION file

* remove setting of .version file from tag

don't need this anymore since the file is checked into source
2022-03-29 14:34:19 +09:00
dependabot[bot]
6e7c287371 build(deps): bump log from 0.4.14 to 0.4.16 (#1874)
Bumps [log](https://github.com/rust-lang/log) from 0.4.14 to 0.4.16.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/commits)

---
updated-dependencies:
- dependency-name: log
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-29 09:07:17 +09:00
dependabot[bot]
3af0a7f3cb build(deps): bump smartstring from 1.0.0 to 1.0.1 (#1873)
Bumps [smartstring](https://github.com/bodil/smartstring) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/bodil/smartstring/releases)
- [Changelog](https://github.com/bodil/smartstring/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bodil/smartstring/compare/v1.0.0...v1.0.1)

---
updated-dependencies:
- dependency-name: smartstring
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-29 09:07:07 +09:00
Max
b63b37d5a0 grammars.nix: use github type for fetchTree where possible (#1872) 2022-03-28 16:50:18 -05:00
Blaž Hrastnik
511f37c736 clipboard: fix import on macOS 2022-03-28 11:08:38 +09:00
Blaž Hrastnik
33510d60f4 cargo fmt 2022-03-28 11:05:26 +09:00
Blaž Hrastnik
a516f5881b Address clippy lint 2022-03-28 11:03:42 +09:00
Blaž Hrastnik
8611c5b84e Refactor clipboard to make it easier to feature gate std::process 2022-03-28 11:02:56 +09:00
Blaž Hrastnik
4940db3e2d Make truncate_start a builder method instead 2022-03-28 11:02:49 +09:00
Blaž Hrastnik
20cf75dfa1 Strip some more params 2022-03-28 11:02:39 +09:00
Blaž Hrastnik
1849ad1fde Clean up global search 2022-03-28 11:02:32 +09:00
Blaž Hrastnik
92bb312f0f Make line a private property 2022-03-28 11:02:26 +09:00
Blaž Hrastnik
96a4eb8483 Remove more push_layer calls 2022-03-28 11:02:21 +09:00
Blaž Hrastnik
5c162ef995 Make regex_prompt directly call cx.push_layer 2022-03-28 11:02:13 +09:00
Blaž Hrastnik
83b3272166 This doesn't need to be mut 2022-03-28 11:02:07 +09:00
Blaž Hrastnik
9a6ee88e66 Split off dap event handlers into helix-view to allow reuse 2022-03-28 11:01:59 +09:00
Blaž Hrastnik
85264a861a Resize is not necessary inside SIGCONT, handled by render() 2022-03-28 11:01:53 +09:00
Gokul Soumya
7b3a3d562c Move top level lsp config to editor.lsp (#1868)
* Move top level lsp config to editor.lsp

This is mainly done to accomodate the new lsp.signature-help config
option that will be introduced in https://github.com/helix-editor/helix/pull/1755
which will have to be accessed by commands. The top level config
struct is split and moved to different places, making the relocation
necessary

* Revert rebase slipup
2022-03-28 10:11:52 +09:00
Joe
bee05dd32a Add refresh-config and open-config command (#1803)
* Add refresh-config and open-config command

* clippy

* Use dynamic dispatch for editor config

* Refactor Result::Ok to Ok

* Remove unused import

* cargo fmt

* Modify config error handling

* cargo xtask docgen

* impl display for ConfigLoadError

* cargo fmt

* Put keymaps behind dyn access, refactor config.load()

* Update command names

* Update helix-term/src/application.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* Switch to unbounded_channel

* Remove --edit-config command

* Update configuration docs

* Revert "Put keymaps behind dyn access", too hard

This reverts commit 06bad8cf49.

* Add refresh for keys

* Refactor default_keymaps, fix config default, add test

* swap -> store, remove unneeded clone

* cargo fmt

* Rename default_keymaps to default

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-03-25 18:05:20 +09:00
Narazaki Shuji
309f2c2c8e Revise the color for ui.cursor.match (#1862)
- bogster.toml
 - solarized_dark.toml
 - solarized_light.toml
 - spacebones_light.toml
2022-03-25 15:57:25 +09:00
Jared Ramirez
22ba668fad Fix Rescript hightlights query (#1863) 2022-03-23 14:03:58 -05:00
Blaž Hrastnik
919ac7ba15 Handle RPC returning an invalid call 2022-03-23 16:16:19 +09:00
Slin Lee
3e78b8fdad Add syntax highlighting for Solidity (#1854) 2022-03-22 11:38:49 -05:00
Slin Lee
79477ec6e7 Fix typo in query parsing error message (#1856) 2022-03-22 16:22:57 +05:30
Slin Lee
3c79bf5117 Add LSP support for Solidity (#1848)
* Add LSP support for Solidity

This requires a recent version of Solidity 0.8.11+

* Add Solidity to docs

* Update the docs
2022-03-22 11:22:34 +09:00
dependabot[bot]
5d7fa57754 build(deps): bump lsp-types from 0.92.0 to 0.92.1 (#1852)
Bumps [lsp-types](https://github.com/gluon-lang/lsp-types) from 0.92.0 to 0.92.1.
- [Release notes](https://github.com/gluon-lang/lsp-types/releases)
- [Changelog](https://github.com/gluon-lang/lsp-types/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gluon-lang/lsp-types/compare/v0.92.0...v0.92.1)

---
updated-dependencies:
- dependency-name: lsp-types
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-22 11:14:43 +09:00
dependabot[bot]
1de99cf46a build(deps): bump which from 4.2.4 to 4.2.5 (#1851)
Bumps [which](https://github.com/harryfei/which-rs) from 4.2.4 to 4.2.5.
- [Release notes](https://github.com/harryfei/which-rs/releases)
- [Commits](https://github.com/harryfei/which-rs/compare/4.2.4...4.2.5)

---
updated-dependencies:
- dependency-name: which
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-22 11:14:35 +09:00
dependabot[bot]
585347aca0 build(deps): bump actions/cache from 2.1.7 to 3 (#1850)
Bumps [actions/cache](https://github.com/actions/cache) from 2.1.7 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2.1.7...v3)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-22 11:14:14 +09:00
zetashift
7eb013c6fb Initial basic Org markup support thanks to tree-sitter-org (#1845) 2022-03-20 17:14:30 -05:00
Blaž Hrastnik
a7ee9f74f7 No need for KeymapResult anymore since we can query .sticky() 2022-03-20 16:03:14 +09:00
Blaž Hrastnik
7909d6f05e keymap: Store pending/sticky on the root level 2022-03-20 16:03:13 +09:00
Michael Davis
cfd992b151 update tree-sitter-git-commit (#1838)
changes:

- any text following a (scissors) is now contained in one (message)
    - this vastly improves performance on large verbose commits:
      no more slowness on huge commits
2022-03-19 14:43:13 +09:00
Ivan Tham
533cca7195 Improve bug report template (#1826) 2022-03-18 14:06:56 +09:00
Michael Davis
cb7b674f87 cleanup changelog markup (#1829) 2022-03-18 11:53:47 +09:00
Blaž Hrastnik
0b9620108d ropey 1.4.1 fixes the issue 2022-03-17 12:03:15 +09:00
Blaž Hrastnik
2376fc875e Temporarily turn on unicode-lines
Ropey's non-unicode lines impl has some bugs still
2022-03-17 10:53:50 +09:00
Blaž Hrastnik
16e2b2e36b ropey 1.4.0 is out! 2022-03-17 09:29:47 +09:00
Blaž Hrastnik
f67e1ee172 Put esoteric line endings behind a feature flag 2022-03-17 09:29:47 +09:00
Blaž Hrastnik
b4a282fd36 Configure ropey to only use CR/CRLF line breaks by default
Fixes #1643
2022-03-17 09:29:47 +09:00
Blaž Hrastnik
59f05088b9 Optimize rendering by using Ropey::byte_slice
This avoids costly conversions via byte_to_char (which are then
reversed back into bytes internally in Ropey).

Reduces time spent in slice/byte_to_char from ~24% to ~5%.
2022-03-17 09:29:47 +09:00
Michael Davis
c6bd105484 fix enum definition for use-grammars selections (#1818)
See https://github.com/helix-editor/helix/discussions/1817

It looks like we need the enums to have the `only`/`except` fields in order
to deserialize correctly.
2022-03-16 18:26:22 +09:00
Blaž Hrastnik
20a132e36f Update dependencies (crossterm 0.23.1)
Fixes #1654
2022-03-16 10:40:07 +09:00
Gokul Soumya
2b0835b295 Refactor :set to parse by deserializing values (#1799)
* Refactor :set to parse by deserializing values

* Implement serialize for idle_timeout config
2022-03-15 17:04:22 +09:00
ChrHorn
0902ede7b1 simplify Julia config (#1811)
* simplify Julia config

* remove trailing whitespace
2022-03-15 10:41:36 +09:00
dependabot[bot]
9400d74307 build(deps): bump tree-sitter from 0.20.5 to 0.20.6 (#1813)
Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.20.5 to 0.20.6.
- [Release notes](https://github.com/tree-sitter/tree-sitter/releases)
- [Commits](https://github.com/tree-sitter/tree-sitter/compare/v0.20.5...v0.20.6)

---
updated-dependencies:
- dependency-name: tree-sitter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-15 09:16:14 +09:00
dependabot[bot]
be2b452a39 build(deps): bump regex from 1.5.4 to 1.5.5 (#1812)
Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.5.5.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.5.5)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-15 09:16:04 +09:00
Joe
c0dbd6dc3f Add horizontal and vertical split scratch buffers (#1763)
Make subcommand name more descriptive

Fix vsplit completer

Run cargo xtask docgen
2022-03-14 11:47:52 +09:00
Gokul Soumya
85492e587c Deploy docs for master separately (#1783)
* Deploy docs for master separately

* Output docs for every tagged release

* Update .github/workflows/gh-pages.yml

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-03-14 11:46:40 +09:00
Rohan Jain
1ac576f2b3 Handle panic on move within empty picker (#1786)
When the picker results output is empty, movement actions result in a panic:
```
thread 'main' panicked at 'attempt to calculate the remainder with a divisor of zero', helix-term/src/ui/picker.rs:420:31
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

This could be a no-op instead when the matches length is zero.
2022-03-14 11:46:23 +09:00
Ivan Tham
29d6a5a9b6 Perform extend line on every selection (#1804)
Currently `x` only affect the current selection, but this will make it
affect every selection so `x` can be more useful with multi-cursors.
2022-03-14 11:45:45 +09:00
Ivan Tham
3d76fa0b81 Match in visual use head not anchor (#1805)
Currently match is finding the match based on the anchor rather than the
head (cursor) so this behavior is rather unexpected when user is doing
a match but a different item was matched instead when the selection is
more than one character.
2022-03-14 11:45:22 +09:00
Michael Davis
43fc073cb3 ci: configure restore-keys for caches (#1806)
`restore-keys` is a configuration option for the actions/cache action
which specifies fallback behavior. The [docs][docs] say it best:

> When a cache miss occurs, the action searches for alternate keys
> called `restore-keys`.
>
> If you provide `restore-keys`, the `cache` action sequentially
> searches for any caches that match the list of `restore-keys`.
> ... If there are no exact matches, the action searches for partial
> matches of the restore keys. When the action finds a partial match,
> the most recent cache is restored to the `path` directory.

So this improves caching when there's a miss. For example if I edit
`.github/workflows/languages.toml`, the current behavior is that the
cache for downloaded grammars will miss and all of them will need to
be fetched again. With `restore-keys`, we use the latest published
cache as 'good enough', we'll fetch whatever grammars changed, and
then at the end we publish a new cache under the new hash.

[docs]: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#example-using-the-cache-action
2022-03-14 11:44:51 +09:00
Blaž Hrastnik
c94c0d9f1c minor: occurance -> occurrence 2022-03-14 11:43:52 +09:00
Blaž Hrastnik
610ce93600 fix #1808 2022-03-14 11:34:21 +09:00
Narazaki Shuji
05161aa85e Fix: insert_register (#1751)
- set register name correctly
 - use autoinfo to display register contents
 - call `paste` with `Paste::Cursor`
2022-03-13 17:23:55 +09:00
Daniel S Poulin
e8cc7ace75 Update keymap documentation in the book (#1745)
* Add missing key bindings to keymap docs

* Add a note about readline bindings in insert mode

* Rewrite section on selection extend mode

We seem to have settled on this model, so no reason to say in the
docs that this is experimental. I also don't think we have any
movements that don't obey extend mode left.

* Fix table formatting

* Fix missing command for command palette binding

* Fix missed capitalization of descriptions in keymap docs

* Be consistent with multiple bindings in keymap docs

* Fix differently marked up commands in keymap docs

* Make special key capitalization consistent

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>

* Fix extra space in docs

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>

* A few more capitalizations of special keys in keymap docs

* Move a selection manipulation key map to the appropriate section in docs

* Move minor mode entry bindings to the minor modes section of keymap docs

* Add note about default register used in search commands in keymap docs

* Fix formatting of rebased addition

* Remove note about potential removal of select mode

It's been decided since to keep it

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>
2022-03-13 17:12:13 +09:00
Philipp Mildenberger
6fdf5d0920 C# highlighting improvements (#1795) 2022-03-12 12:06:56 -06:00
nibon7
43997f1936 Use ^ and $ to match the beginning and end of a line when searching (#1790)
Fixes #1737

Signed-off-by: nibon7 <nibon7@163.com>
2022-03-12 16:05:50 +09:00
Michael Davis
61828ea519 use 'cargo test --workspace' in CI (#1793)
79caa7b72b setup helix-term as the
default workspace member (which I believe is done to avoid building
xtask on every compile). This changes the behavior of 'cargo test'
though so that it only runs helix-term tests by default. To run all
tests, we switch to 'cargo test --workspace'.
2022-03-12 16:04:52 +09:00
Aaron Housh
0712eb3e3b Add csharp lsp support (#1788)
* add csharp lsp support

* remove hostPID

* update docs
2022-03-12 09:19:31 +09:00
Rohan Jain
cf8f59ddd0 theme: Use distinct colors for match pair and cursor for gruvbox (#1791) 2022-03-11 17:49:21 +05:30
Michael Davis
98851d1594 remove stray 'println!' from grammar building function (#1785) 2022-03-11 12:28:34 +09:00
Michael Davis
37fed4de80 fix '--grammar' flag in help text (#1784) 2022-03-10 22:33:51 +09:00
Blaž Hrastnik
5eb9a0167f Remove remaining helix-syntax leftovers 2022-03-10 17:46:29 +09:00
Michael Davis
94203a97e5 update revision for tree-sitter-rescript
Looks like this was rebased a few hours ago and now the 789a171
revision no longer exists.
2022-03-10 17:31:57 +09:00
Michael Davis
e01c53551d flake: use builtins.fetchTree to shallow-clone grammar repos
Here we perform a shallow fetch using builtins.fetchTree. In order
to make this work, we need to specify the `ref' for any repository
that doesn't have `master' as its default branch (I'm not sure why
this limitation exists since we don't need this when performing
the shallow fetch in `--grammar build')

This `ref' field is ignored by helix, so I have left it undocumented
for now, but I could be open to documenting it.
2022-03-10 17:31:57 +09:00
Michael Davis
7044d7d804 rename '--fetch/build-grammars' flags into '--grammar fetch/build'
The old flags were a bit long. --grammar is also aliased to -g to make
it even easier.
2022-03-10 17:31:57 +09:00
Michael Davis
37520f46ae fetch and build grammars with nix in flake
This commit replaces the out-of-date builder in the flake which relied
on submodules for fetching and the compiler for building. Now we
disable fetching and building explicitly with the environment variable
and then use builtins.fetchGit and a derivation mostly derived from
upstream to compile the grammars.

Anecdotally, this is still quite slow as builtins.fetchGit does not
seem to do shallow clones. I'm not sure I see a way around it though
without recording sha256s, which seems cumbersome.
2022-03-10 17:31:57 +09:00
Michael Davis
b157c5a8a4 fetch and compile tree-sitter grammars in helix-term build
This restores much of the behavior that existed before this PR:
helix will build the grammars when compiling. The difference is that
now fetching is also done during the build phase and is done much
more quickly - both shallow and in parallel.
2022-03-10 17:31:57 +09:00
Michael Davis
6fcab90d16 only fetch git-sourced grammars
This is a bit of a micro-optimization: in the current setup we waste
a thread in the pool for a local grammar only to println! a message
saying we're skipping fetching because it's a local grammar.
2022-03-10 17:31:57 +09:00
Skyler Hawthorne
a229f405cc shallow clone 2022-03-10 17:31:57 +09:00
Skyler Hawthorne
31b7596f09 fix context in error 2022-03-10 17:31:57 +09:00
Michael Davis
4fc991fdec migrate grammar fetching/building code into helix-loader crate
This is a rather large refactor that moves most of the code for
loading, fetching, and building grammars into a new helix-loader
module. This works well with the [[grammars]] syntax for
languages.toml defined earlier: we only have to depend on the types
for GrammarConfiguration in helix-loader and can leave all the
[[language]] entries for helix-core.
2022-03-10 17:31:57 +09:00
Michael Davis
08ee949dcb add 'use-grammars' to languages.toml
The vision with 'use-grammars' is to allow the long-requested feature
of being able to declare your own set of grammars that you would like.
A simple schema with only/except grammar names controls the list
of grammars that is fetched and built. It does not (yet) control which
grammars may be loaded at runtime if they already exist.
2022-03-10 17:31:57 +09:00
Michael Davis
db3470d973 ensure rust grammar is available in CI 2022-03-10 17:31:57 +09:00
Michael Davis
8081e9f052 replace all submodule documentation with flags documentation 2022-03-10 17:31:57 +09:00
Michael Davis
00b2d616eb implement build_grammars and fetch_grammars
build_grammars adapts the functionality that previously came from
helix-syntax to be used at runtime from the command line flags.

fetch_grammars wraps command-line git to perform the same actions
previously done in the scripts in #1560.
2022-03-10 17:31:57 +09:00
Michael Davis
8330f6af20 add --fetch-grammars and --build-grammars CLI flags 2022-03-10 17:31:57 +09:00
Michael Davis
c1f677ff75 rename tree_sitter_library in LanguageConfig to 'grammar'
This is not strictly speaking necessary. tree_sitter_library was used by
just one grammar: llvm-mir-yaml, which uses the yaml grammar. This will
make the language more consistent, though. Each language can explicitly
say that they use Some(grammar), defaulting when None to the grammar that
has a grammar_id matching the language's language_id.
2022-03-10 17:31:57 +09:00
Michael Davis
eeb3f8e963 migrate helix-syntax crate into helix-core and helix-term
helix-syntax mostly existed for the sake of the build task which
checks and compiles the submodules. Since we won't be relying on
that process anymore, it doesn't end up making much sense to have
a very thin crate just for some functions that we could port to
helix-core.

The remaining build-related code is moved to helix-term which will
be able to provide grammar builds through the --build-grammars CLI
flag.
2022-03-10 17:31:57 +09:00
Michael Davis
c1f90a127b add tree-sitter sources to languages.toml
Here we add syntax to the languages.toml languge

    [[grammar]]
    name = "<name>"
    source = { .. }

Which can be used to specify a tree-sitter grammar separately of
the language that defines it, and we make this distinction for
two reasons:

* In later commits, we will separate this code from helix-core
  and bring it to a new helix-loader crate. Using separate schemas
  for language and grammar configurations allows for a nice divide
  between the types needed to be declared in helix-loader and in
  helix-core/syntax

* Two different languages may use the same grammar. This is currently
  the case with llvm-mir-yaml and yaml. We could accomplish a config
  that works for this with just `[[languages]]`, but it gets a bit
  dicey with languages depending on one another. If you enable
  llvm-mir-yaml and disable yaml, does helix still need to fetch and
  build tree-sitter-yaml? It could be a matter of interpretation.
2022-03-10 17:31:57 +09:00
Michael Davis
fbb98300df remove all submodules
The submodules system is being replaced with a command-line flag

    hx --fetch-grammars

Which shallow-clones grammar repositories at the given revision and

    hx --build-grammars

For building grammars separate of the initial compilation of helix.

Why remove submodules?

* Cloning helix in general takes a long time because of the submodules,
  especially when the submodules are not fetched as shallow
* Packaging is consistently painful no matter the package-manager
* It is quite difficult to devise a scheme where users can declare
  a desired set of grammars and implement it with submodules

This commit fully removes the existing tree-sitter submodules from
the tree (as well as the .gitmodules file which is no longer used).
2022-03-10 17:31:57 +09:00
Joe
8d7a25b4d4 Add --edit-config flag to directly open config.toml (#1771)
Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
2022-03-10 00:04:12 +05:30
Daniel S Poulin
3f603b27f1 Update architecture.md (#1750)
* Update architecture.md

Adds some more details on how views work.

* Add additional architecture discussion from matrix, written by @sudormrfbin
2022-03-09 11:19:03 +09:00
Emil Fresk
bfa533fe78 Fix bug in LSP when creating a file in a folder that does not exist (#1775) 2022-03-09 00:21:19 +05:30
Gokul Soumya
194b09fbc1 Add --health command for troubleshooting (#1669)
* Move runtime file location definitions to core

* Add basic --health command

* Add language specific --health

* Show summary for all langs with bare --health

* Use TsFeature from xtask for --health

* cargo fmt

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-03-08 14:25:46 +09:00
Michael Davis
f31e85aca4 use latest nix-cargo-integration which depends on dream2nix (#1758)
https://github.com/nix-community/dream2nix is a fairly new and
cool-looking project for adapting upstream package manager outputs
(lockfiles mostly it would seem) for nix.

This should improve the ability to cross-compile. As a more concrete
measure of improvement, `nix flake check' now succeeds 🎉
2022-03-08 14:14:00 +09:00
Daniel S Poulin
24352b2729 Add arrow key mappings for tree-sitter parent/child/sibling nav (#1724)
* Add arrow key mappings for tree-sitter parent/child/sibling nav

This helps my use case, where I use a non-qwerty layout with a
programmable mechanical keyboard, and use a layer switching key (think
fn) to send left down up right from the traditional hjkl positions.

* Add new bindings to docs
2022-03-08 14:02:03 +09:00
Gokul Soumya
bde0307c87 Allow highlighting additional spans in md renderer 2022-03-08 13:59:38 +09:00
Gokul Soumya
970a111aa3 Extract markdown code block highlighting function 2022-03-08 13:59:38 +09:00
Blaž Hrastnik
5a60989efe Bump dependencies 2022-03-08 10:33:40 +09:00
dependabot[bot]
9a04064373 build(deps): bump tree-sitter from 0.20.4 to 0.20.5 (#1770)
Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.20.4 to 0.20.5.
- [Release notes](https://github.com/tree-sitter/tree-sitter/releases)
- [Commits](https://github.com/tree-sitter/tree-sitter/compare/v0.20.4...v0.20.5)

---
updated-dependencies:
- dependency-name: tree-sitter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 08:55:50 +08:00
dependabot[bot]
b67686d318 build(deps): bump once_cell from 1.9.0 to 1.10.0 (#1768)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 08:55:23 +08:00
dependabot[bot]
0d0165b76e build(deps): bump actions/checkout from 2 to 3 (#1767)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 09:12:37 +09:00
dependabot[bot]
1493ff7657 build(deps): bump actions/upload-artifact from 2.3.1 to 3 (#1766)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.3.1 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2.3.1...v3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-08 09:12:22 +09:00
Gokul Soumya
b0aaf08995 Change parameter object keybind from p to a (#1708)
This is largely to avoid a collision with the soon
to be merged paragraph object which takes up the p key.
2022-03-07 16:46:14 +09:00
Blaž Hrastnik
79caa7b72b Add helix-term as default-members 2022-03-07 14:41:28 +09:00
Blaž Hrastnik
19247ff0ec Split out typable commands into a separate file 2022-03-07 14:41:28 +09:00
Daniel S Poulin
9bfb0caf1b Add comment textobject for surround selection and navigation (#1605) 2022-03-06 10:54:24 +05:30
chunghha
7633c5acd3 chore(theme): apply renamed infobox theme scopes for rose_pine themes (#1754) 2022-03-05 22:52:19 +05:30
Michael Davis
f1e90ac2e3 update helix-syntax revision in flake.nix (#1747)
closes #1746

The queries for Go were updated in ddbf03613d.
The old ref was before this commit, so running helix from the flake

    nix flake run github:helix-editor/helix/d62ad8b595a4f901b9c5dba1bb6e8f70ece395bf -- path/to/file.go

will crash because the old grammar's query analysis will fail (because `iota`
was not yet a named node).

This commit updates the version of the grammars that we pull down when building
the flake so that the queries match the grammars. We'll have to do an update like
this whenever a grammar is bumped in a breaking way (which happens fairly often
in tree-sitter) until #1659 comes along and the version of the grammar becomes
tied to the version declared in source.
2022-03-05 10:10:41 +09:00
Blaž Hrastnik
d62ad8b595 fix: text_pos_at_screen_coords tests 2022-03-04 11:23:05 +09:00
Blaž Hrastnik
fd02d1bf89 Fix tab rendering to use dynamic tab width
Each tab is just wide enough to round to the nearest tab stop.

Refs #1243
2022-03-04 11:01:33 +09:00
Blaž Hrastnik
5f386fa355 Remove TODO.md
The file predates open-sourcing and we managed to implement most
of it by now. The remaining features have tracking issues.

Fixes #1155
2022-03-04 09:36:34 +09:00
Blaž Hrastnik
5d14f56fa9 Reuse visual_coords_at_pos function in view 2022-03-04 09:36:31 +09:00
Gokul Soumya
74a9dd51ff Fallback to broader scope if theme scope not found (#1714) 2022-03-04 09:35:21 +09:00
Gokul Soumya
c484b08923 Rename infobox theme scopes (#1741)
This makes it play nicely with https://github.com/helix-editor/helix/pull/1714
2022-03-04 09:31:51 +09:00
Blaž Hrastnik
0062af6a19 minor: Remove some outdated comments 2022-03-03 17:18:26 +09:00
Blaž Hrastnik
737282d0e9 Extract a common function for paste_before/_after 2022-03-03 17:06:14 +09:00
Blaž Hrastnik
376d99a51d core: transaction: Resolve some TODOs 2022-03-03 17:04:25 +09:00
Blaž Hrastnik
adf97e088e Simplify get_clipboard_provider by defining one per host 2022-03-03 16:52:41 +09:00
Blaž Hrastnik
68bad148a5 Extract idle timeout code into ui/editor.rs 2022-03-03 16:52:41 +09:00
Blaž Hrastnik
78fba8683b Picker performance improvements 2022-03-03 16:52:41 +09:00
Erin Kim
0ff3e3ea38 Add inputs.nixpkgs.follows to rust-overlay in flake.nix (#1729)
* add `inputs.nixpkgs.follows` to `rust-overlay`

* Update flake.lock
2022-03-03 10:45:45 +09:00
Blaž Hrastnik
c0b86afdc8 Refactor align_selection by simplifying the calculation 2022-03-03 10:44:57 +09:00
Bob Qi
1c1aee74b4 refactor align_selection using kakoune logic 2022-03-03 10:44:57 +09:00
Gokul Soumya
5c810e5e52 Fix bug with auto replacing components in compositor (#1711)
* Fix bug with auto replacing components in compositor

This was last known to be working with 5995568c at the
time of commit, but now doesn't work with latest rust
stable.

The issue probably stems from using
std::any::type_name() for finding a component in the
compositor, for which the docs explicitly warn against
considering it as a unique identifier for types.

`replace_or_push()` takes a boxed `Component` and
passes it to `find_id()` which compares this with a
bare Component. `type_name()` returns `Box<T>` for
the former and `T` for latter and we have a false
negative. This has been solved by using a generics
instead of trait objects to pass in a `T: Component`
and then use it for comparison.

I'm not exactly sure how this worked fine at the
time of commit of 5995568c; maybe the internal
implementation of `type_name()` changed to properly
indicate indirection with Box.

* Do not compare by type name in compositor find_id
2022-03-03 10:14:50 +09:00
Blaž Hrastnik
86b1236b46 Fix cachix.yml definition 2022-03-02 11:18:29 +09:00
Michael Davis
227e0108e9 add workflow for pushing nix flake artifacts to Cachix (#1721)
* add workflow for pushing nix flake artifacts to Cachix

* add docs on using the cachix cache from nix

* remove submodule clone from cachix workflow

* remove flake check
2022-03-02 11:12:50 +09:00
Michael Daffin
a76e94848a Add terraform lsp support (#1726)
Using terraform-ls and enables auto-formate support. Also adds tfvars as an extra filetype.
2022-03-01 20:59:03 +09:00
Philipp Mildenberger
49c5bc5934 Add jumplist support for the search (closes #1625) (#1718) 2022-03-01 20:57:57 +09:00
Mateusz S. Szczygieł
14e2ced440 Make repeat operator work with completion edits (#1640)
* add basic completion replay

* use transaction as the last completion

* completion replay only on trigger position

* cache changes in CompletionAction

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-03-01 10:45:29 +09:00
Gokul Soumya
e83cdf3fd3 Ensure non empty grouped nodes in textobject queries 2022-03-01 10:32:50 +09:00
Gokul Soumya
e6c36e82cf Allow capturing multiple nodes in textobject queries
Treesitter captures can contain multiple nodes like so:

```
(line_comment)+ @comment
```

This would match each line in a comment as a separate
`@comment` capture when what we actually want is the
whole set of contiguous `line_comment` nodes to be
captured under the `@comment` capture. This commit enables
this behaviour.
2022-03-01 10:32:50 +09:00
Daniel S Poulin
78d37fd332 Implement bulk buffer closing commands (#1677)
* Implement buffer-close-all

* Implement buffer-close-others

* Refactor all buffer close variants to use shared logic

* Fix clippy lint

* Docgen for new commands

* Shorten error message for attempting to close buffers that don't exist

* Refactor shared buffer methods to pass only editor, not whole compositor

* Switch signature of bulk buffer closing to use slice of DocumentIds

Addresses feedback that accepting an IntoIterator implementor is too
much for an internal. Also possibly saves some moving?
2022-03-01 10:31:24 +09:00
Ludwig Stecher
59c691d2db Highlight matching text in file picker suggestions (#1635)
* Highlight matching text in file picker suggestions

* Remove cache, specialize highlighting code

* Fix outdated comments
2022-03-01 10:30:02 +09:00
Daniel S Poulin
b13d44156c Show infobox to hint textobjects with mi and ma (#1686)
* Show infobox to hint textobjects with `mi` and `ma`

* Add note to infobox than any pair of characters will work too

The wording could probably be a little more clear, but I wanted to
keep it short but still accurate.

* Don't allocate a vec for the static help text

* Fix bug where `mi<esc>` would swallow next input and persist infobox

* Better help text for arbitrary pair matching in textobject selection

* Add way to add fake pending key data below status, use with `mi`/`ma`

This is a bit hacky as it makes use of global state which will end
up managed in multiple places, but has precedent in the way autoinfo
works. There should probably be a bigger refactor to handle this
kind of state better.

* Return early on anything other than `mi` and `ma` for autoinfo

* Remove "ascii" from help text with `mi` and `ma`

* Update helix-term/src/ui/editor.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-03-01 10:29:22 +09:00
Daniel S Poulin
bdbf423876 Minor cleanup of file picker file gathering logic (#1683)
* Refactor file picker filetype filter logic to remove panic, make clearer

An unwrap was unneccesarily present due to a prior contribution of mine
which was before I had any understanding of error handling in Rust. I've
also swapped a match for an if let, as was originally suggested in the
original pull request adding filetype filtering, but was merged before I
could address.

* Add some comments to the file picker code for clarity

* Switch to expect instead of ignoring type def error
2022-03-01 10:16:25 +09:00
Philipp Mildenberger
7bb1db3ab5 Bring configuration documentation up to date (missing editor.search section) (#1719) 2022-03-01 10:06:14 +09:00
dependabot[bot]
0846822371 build(deps): bump smartstring from 0.2.10 to 1.0.0 (#1722)
Bumps [smartstring](https://github.com/bodil/smartstring) from 0.2.10 to 1.0.0.
- [Release notes](https://github.com/bodil/smartstring/releases)
- [Changelog](https://github.com/bodil/smartstring/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bodil/smartstring/compare/v0.2.10...v1.0.0)

---
updated-dependencies:
- dependency-name: smartstring
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 09:38:44 +09:00
Triton171
f044059a2a Implement LSP workspace/configuration and workspace/didChangeConfiguration (#1684)
* Implement LSP `workspace/configuration` request

* Implement LSP `workspace/didChangeConfiguration` notification.

* Simplify retrieval of LSP configuration

* Implement suggestions from PR discussion

Co-authored-by: Triton171 <triton0171@gmail.com>
2022-02-28 17:57:22 +09:00
Gokul Soumya
c15996aff5 Show surround delete and replace errors in editor (#1709)
* Refactor surround commands to use early returns

* Show surround delete and replace errors in editor
2022-02-28 17:56:39 +09:00
chunghha
f9ad1cafdc chore(theme): fix "ui.selection" for rose_pine themes (#1716) 2022-02-28 17:56:03 +09:00
Michael Davis
39f7ba36e0 ignore Enter keypress when menu has no selection (#1704)
* ignore Enter keypress when menu has no selection

supersedes #1622

Builds on the work in #1285. I want to allow Enter to create a newline
when there is no selection in the autocomplete menu.

This occurs somewhat often when using LSP autocomplete in Elixir which
uses `do/end` blocks (and I set the autocomplete menu delay to 0 which
exacerbates the problem):

```elixir
defmodule MyModule do
  def do_foo(x) do
    x
  end
  def other_function(y) do|
end
```

Here the cursor is `|` in insert mode. The LSP suggests `do_foo` but I
want to create a newline. Hitting Enter currently closes the menu,
so I end up having to hit Enter twice when the module contains any
local with a `do` prefix, which can be inconsistent. With this change,
we ignore the Enter keypress to end up creating the newline in this case.

* pop compositor layer when ignoring Enter keypress

* move closing function out of consumed event result closure

* explicitly label close_fn as an 'Option<Callback>'
2022-02-27 16:20:21 +09:00
Gregory Oakes
c1251aecc7 Fix duplicate "ui.help" key. (#1713) 2022-02-27 15:39:44 +09:00
Blaž Hrastnik
6a6a9ab2b3 fix: theme: bogster: Only primary selection had a cursor style 2022-02-25 18:04:43 +09:00
Blaž Hrastnik
78a6f77e99 Work around a nix-direnv issue
https://github.com/nix-community/nix-direnv/issues/109
2022-02-25 18:01:47 +09:00
Blaž Hrastnik
66637be700 Add an optimised release profile 2022-02-25 18:01:41 +09:00
Gokul Soumya
8e07e1b898 Alert if LSP is inactive when command is invoked (#1703) 2022-02-25 17:53:10 +09:00
Matouš Dzivjak
951fd1c80e fix(commands): don't indent empty lines (#1653)
* fix(commands): don't indent empty lines

Fixes: https://github.com/helix-editor/helix/issues/1642

* Apply suggestions

* Update helix-term/src/commands.rs

* Update helix-term/src/commands.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-02-25 17:49:02 +09:00
Michael Daffin
93ec42d06e Add support for HCL language (#1705)
Queries based on the neovims ones: https://github.com/nvim-treesitter/nvim-treesitter/tree/master/queries/hcl and modified for helix support.
2022-02-25 17:48:20 +09:00
Skyler Hawthorne
a494f47a5d Configurable auto pairs (#1624)
* impl auto pairs config

Implements configuration for which pairs of tokens get auto completed.

In order to help with this, the logic for when *not* to auto complete
has been generalized from a specific hardcoded list of characters to
simply testing if the next/prev char is alphanumeric.

It is possible to configure a global list of pairs as well as at the
language level. The language config will take precedence over the
global config.

* rename AutoPair -> Pair

* clean up insert_char command

* remove Rc

* remove some explicit cloning with another impl

* fix lint

* review comments

* global auto-pairs = false takes precedence over language settings

* make clippy happy

* print out editor config on startup

* move auto pairs accessor into Document

* rearrange auto pair doc comment

* use pattern in Froms
2022-02-25 17:36:54 +09:00
Blaž Hrastnik
b935fac957 Fix 1.60 lints 2022-02-25 13:06:11 +09:00
Blaž Hrastnik
9712bbb23b Use which to resolve lsp/dap binaries
This resolves the following issue: https://github.com/helix-editor/helix/discussions/962#discussioncomment-1580046
2022-02-24 11:38:40 +09:00
chunghha
4526216139 chore(theme): update markup styles for rose_pine themes (#1706) 2022-02-24 09:08:20 +08:00
Michael Daffin
f83843ceba Add kotlin language (#1689)
* Add kotlin language

Queries taken from https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/kotlin seem to work well enough for my needs though I don't use kotlin heavily.

* Update lang-support doc

* Updates the kotlin highlight query to use helixs scopes

* Updates the queries from PR feedback

* Adds 'shallow = true' to gitmodules

* Removes kotlin locals.scm

* Remove blank line

Co-authored-by: Ivan Tham <pickfire@riseup.net>

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2022-02-23 23:25:44 +09:00
Bram
40eb1268c7 Close some popups automatically (#1285)
* Add Event::Used to use event callback without consuming

* Close popup if contents ignored event

* collect event results before executing callbacks

* don't add new result variant, use Ignored(..) instead

* break in match cases

* Make auto_close configurable

* fix merge

* auto close hover popups

* fix formatting
2022-02-23 12:46:12 +09:00
Arjun P
e1a92fd399 Readme: fix typo (#1695) 2022-02-22 21:31:19 +09:00
dependabot[bot]
806cc1c3b1 build(deps): bump tokio from 1.16.1 to 1.17.0 (#1691)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.16.1 to 1.17.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.16.1...tokio-1.17.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-22 12:29:19 +09:00
dependabot[bot]
dd549e1729 build(deps): bump cc from 1.0.72 to 1.0.73 (#1693)
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.72 to 1.0.73.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.72...1.0.73)

---
updated-dependencies:
- dependency-name: cc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-22 10:01:28 +09:00
dependabot[bot]
77b1a4a768 build(deps): bump smartstring from 0.2.9 to 0.2.10 (#1692)
Bumps [smartstring](https://github.com/bodil/smartstring) from 0.2.9 to 0.2.10.
- [Release notes](https://github.com/bodil/smartstring/releases)
- [Changelog](https://github.com/bodil/smartstring/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bodil/smartstring/compare/v0.2.9...v0.2.10)

---
updated-dependencies:
- dependency-name: smartstring
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-22 10:01:14 +09:00
dependabot[bot]
7d2a77e53c build(deps): bump anyhow from 1.0.53 to 1.0.55 (#1690)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.53 to 1.0.55.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.53...1.0.55)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-22 10:00:33 +09:00
Blaž Hrastnik
24f86017a6 fix: ui: Markdown popups stopped taking vertical padding into account
Fix #1688
2022-02-21 23:24:03 +09:00
Alex
865881ba19 update markup styles for everforest theme (#1687) 2022-02-21 17:37:02 +09:00
Blaž Hrastnik
1ca6ba03ca Simplify some code 2022-02-21 16:47:14 +09:00
Alex
d5ba0b5162 Allow separate styles for markup headings (#1618)
* update markdown highlighting to use separate heading themes

* remove markdown theme scopes in ui
2022-02-21 16:45:48 +09:00
Daniel S Poulin
700058f433 Always ignore the .git directory in file picker (#1604)
Some users (including myself) want to turn off filtering of files
prefixed with `.`, as they are often useful to edit. For example, `.env`
files, configuration for linters `.eslint.json` and the like.
2022-02-20 15:47:43 +09:00
Blaž Hrastnik
c7b326be04 ui: prompt: Render aliases + border on the doc 2022-02-20 14:55:16 +09:00
Blaž Hrastnik
2af04325d8 fix: Allow multi-line prompt documentation 2022-02-20 14:44:44 +09:00
Blaž Hrastnik
a449156702 Extract a lsp position helper 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
5af9136aec Extract some duplication in lsp goto_ calls 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
1cd710fe01 Extract jump_to_location 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
4e845409b6 Extract a common "language server or return" macro 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
c06155ace4 Extract a helper function for lsp::Location 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
504d5ce8bd Move most LSP specific commmands to commands::lsp 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
7b1d682fe5 dap: fix runInTerminal with lldb-vscode 2022-02-18 14:37:59 +09:00
Blaž Hrastnik
4e1b3b12f3 Refactor symbol picker to share code 2022-02-18 13:50:06 +09:00
Michael Davis
a8cf0c6b90 filter git revision on git command success exit code (#1674)
The unwrap (or '.ok()' rather) triggers for some errors but not
negative status codes. In the case where helix is being packaged
in an empty git repository, the existing mechanism will fail because

    git init
    git rev-parse HEAD

gives a negative exit code and prints to stderr

    stderr: "fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree....

with a stdout of "HEAD\n" (too short to slice with [..8]).
2022-02-18 13:05:12 +09:00
tomKPZ
368064e316 Fix bug when launching hx file.rs:10 (#1676) 2022-02-18 12:13:02 +09:00
Matouš Dzivjak
afec54485a feat(commands): command palette (#1400)
* feat(commands): command palette

Add new command to display command pallete that can be used
to discover and execute available commands.

Fixes: https://github.com/helix-editor/helix/issues/559

* Make picker take the whole context, not just editor

* Bind command pallete

* Typable commands also in the palette

* Show key bindings for commands

* Fix tests, small refactor

* Refactor keymap mapping, fix typo

* Ignore sequence key bindings for now

* Apply suggestions

* Fix lint issues in tests

* Fix after rebase

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-02-17 14:03:11 +09:00
Blaž Hrastnik
24f90ba8d8 Manually recalculate initial completion where it matters 2022-02-17 14:02:42 +09:00
Blaž Hrastnik
af21e2a5b4 Pass through Editor instead of Context 2022-02-17 14:02:42 +09:00
Cole Helbling
e023a78919 WIP: show all buffers that couldn't be closed 2022-02-17 14:02:42 +09:00
Cole Helbling
6118486eb2 helix-term: implement buffer completer
In order to implement this completer, the completion function needs to
be able to access the compositor's context (to allow it to get the
list of buffers currently open in the context's editor).
2022-02-17 14:02:42 +09:00
Cole Helbling
a1207fd768 helix-term/commands: display buffer id in picker 2022-02-17 14:02:42 +09:00
Blaž Hrastnik
d11b652139 Allow static strings in set_status/set_error so API is nicer 2022-02-15 16:45:28 +09:00
Blaž Hrastnik
fd0e4b1159 dap: Reduce amount of block_on uses 2022-02-15 16:30:23 +09:00
David Crespo
a629343476 Fix hover menu item text color in base16 themes (#1668)
* fix hover menu item text in base16 dark

* same ix for base16_default_light and base16_terminal
2022-02-15 14:21:52 +09:00
Gokul Soumya
ab2a0f325b Add object.movement for tree-sitter navigation 2022-02-15 14:04:46 +09:00
Gokul Soumya
989407f190 Add docs for tree-sitter based navigation 2022-02-15 14:04:46 +09:00
Gokul Soumya
966fbc5984 Add tree-sitter based function, class navigation 2022-02-15 14:04:46 +09:00
Blaž Hrastnik
1422449537 .. 2022-02-15 11:37:33 +09:00
Blaž Hrastnik
eeb9b39857 Fix build on master 2022-02-15 10:33:55 +09:00
Ludwig Stecher
4429993842 Add PageUp, PageDown, Ctrl-u, Ctrl-d, Home, End keyboard shortcuts to file picker (#1612)
* Add `PageUp`, `PageDown`, `Ctrl-u`, `Ctrl-d`, `Home`, `End` keyboard shortcuts to file picker

* Refactor file picker paging logic

* change key mapping

* Add overlay component

* Use closure instead of margin to calculate size

* Don't wrap file picker in `Overlay` automatically
2022-02-15 10:24:03 +09:00
Kirawi
23907a063c use PathBuf::to_string_lossy() instead of to_str() (#1655) 2022-02-15 10:22:55 +09:00
Michael Davis
3a83a764e3 add tree-sitter-erlang (#1657) 2022-02-15 10:14:02 +09:00
Blaž Hrastnik
8a7aec6414 fix: nix flake build 2022-02-15 10:12:37 +09:00
dependabot[bot]
225484c26c build(deps): bump serde_json from 1.0.78 to 1.0.79 (#1667)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.78 to 1.0.79.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.78...v1.0.79)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-15 10:08:39 +09:00
Gokul Soumya
4c424d5ee4 Refactor language config loading (#1658) 2022-02-15 01:41:53 +09:00
CossonLeo
e267dc834a Makefile indent must be '\t' (#1661) 2022-02-14 18:03:18 +09:00
Gokul Soumya
59acee308d Add new dap commands to docs (#1660) 2022-02-14 11:32:22 +09:00
Blaž Hrastnik
97d4b2b5fe Mark DAP as experimental 2022-02-13 18:32:57 +09:00
Blaž Hrastnik
bd549d8a20 Merge remote-tracking branch 'origin/master' into debug 2022-02-13 18:31:51 +09:00
Cydiater
7083b98a38 postpone clone after found (#1656) 2022-02-13 13:53:35 +09:00
Maximilian Schoenenberg
a19a6ca01e Added docs for ensure_selections_forward (#1651) 2022-02-11 20:25:59 +05:30
Blaž Hrastnik
1bcb624ae6 Instant is more suitable than SystemTime for spinners 2022-02-10 11:12:47 +09:00
Blaž Hrastnik
f88c077f99 Replace tendril with smartstring
Slightly smaller API surface, less dependencies.
2022-02-10 11:12:47 +09:00
Matouš Dzivjak
fdb9a1677b feat(editor): add config for search wrap_around (#1516)
* feat(editor): add config for search wrap_around

Fixes: https://github.com/helix-editor/helix/issues/1489

* Move search settings into separate config

* Disable linter
2022-02-10 11:04:40 +09:00
Gokul Soumya
59b5bf3178 Refactor document methods 2022-02-10 10:56:08 +09:00
Gokul Soumya
fa83426011 Handle newlines in register infobox 2022-02-10 10:52:06 +09:00
Gokul Soumya
bf773db451 Show infobox with register contents 2022-02-10 10:52:06 +09:00
Gokul Soumya
5995568c1d Prevent multiple code action popups 2022-02-08 16:44:39 +09:00
Gokul Soumya
547c3ecd0c Preselect first item in code action popup menu 2022-02-08 16:44:39 +09:00
Gokul Soumya
e90276df0b Replace if let with early return 2022-02-08 16:44:39 +09:00
Gokul Soumya
f0cd02d5ef Update keybind docs for treesitter, view mode (#1628) 2022-02-08 13:45:40 +09:00
dependabot[bot]
828d39e736 build(deps): bump lsp-types from 0.91.1 to 0.92.0 (#1631)
Bumps [lsp-types](https://github.com/gluon-lang/lsp-types) from 0.91.1 to 0.92.0.
- [Release notes](https://github.com/gluon-lang/lsp-types/releases)
- [Changelog](https://github.com/gluon-lang/lsp-types/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gluon-lang/lsp-types/compare/v0.91.1...v0.92.0)

---
updated-dependencies:
- dependency-name: lsp-types
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 07:51:11 +08:00
dependabot[bot]
718d4ab0f0 build(deps): bump unicode-segmentation from 1.8.0 to 1.9.0 (#1632)
Bumps [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/unicode-rs/unicode-segmentation/releases)
- [Commits](https://github.com/unicode-rs/unicode-segmentation/commits)

---
updated-dependencies:
- dependency-name: unicode-segmentation
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-08 07:50:29 +08:00
Blaž Hrastnik
23553bd37c Update dependencies (crossterm 0.23, tree-sitter 0.20.4)
Fixes #677
2022-02-07 10:47:57 +09:00
Blaž Hrastnik
ad62e1e129 fix: Revert Block widget change that broke autoinfo background 2022-02-07 10:30:03 +09:00
Blaž Hrastnik
e7f5ec5561 fix: There is no such thing as markup.normal, use ui.text 2022-02-07 10:30:03 +09:00
Jared Ramirez
f5b95beef6 feat(languages): rescript (#1616)
* Add rescript language support

* cargo xtask docgen

* Add textobjects & file line ending

* Fix text objects & rerun docgen

* Fix textobjects queries
2022-02-06 14:24:01 +09:00
Ivan Tham
6c11708fb3 Fix incorrect last modified behavior (#1621)
Looks like it checked the wrong doc id when setting last modified doc.
2022-02-06 14:23:12 +09:00
Blaž Hrastnik
6ea477ab60 Don't use block_on in jobs.finish(), we can .await 2022-02-05 15:05:19 +09:00
Blaž Hrastnik
d3221b03a2 fix: Only parse git revision, don't use the tag for version
If building from source and the source is contained in a larger
repository, we'd contain the wrong version. It's also easy to
accidentally have a newer tag that would change the version.
2022-02-03 01:19:44 +09:00
Daniel S Poulin
d6b6ad879e epocsquadron/add tree sitter twig (#1602)
* Add tree-sitter-twig grammer and highlights

The gammar itself is quite basic, but is much better than nothing
for working with real files consisting mostly of html.

* Docgen for newly added grammar
2022-02-01 12:35:07 +09:00
dependabot[bot]
983a53bfb4 build(deps): bump tokio from 1.15.0 to 1.16.1 (#1610)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.15.0 to 1.16.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.15.0...tokio-1.16.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-01 12:24:41 +09:00
dependabot[bot]
d090369404 build(deps): bump serde from 1.0.135 to 1.0.136 (#1608)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.135 to 1.0.136.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.135...v1.0.136)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-01 12:24:32 +09:00
dependabot[bot]
05aeeaca0b build(deps): bump unicode-general-category from 0.4.0 to 0.5.1 (#1609)
Bumps [unicode-general-category](https://github.com/yeslogic/unicode-general-category) from 0.4.0 to 0.5.1.
- [Release notes](https://github.com/yeslogic/unicode-general-category/releases)
- [Commits](https://github.com/yeslogic/unicode-general-category/compare/0.4.0...0.5.1)

---
updated-dependencies:
- dependency-name: unicode-general-category
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-01 12:24:23 +09:00
Blaž Hrastnik
36b975c4ce ui: menu: Don't allocate scrollbar space if options fit 2022-02-01 01:25:59 +09:00
Blaž Hrastnik
f10a06f4de ui: Only render menu scrollbar if it doesn't fit 2022-01-31 16:04:58 +09:00
Blaž Hrastnik
094a0aa3f9 Render code actions as a menu, allow adding padding to popup 2022-01-31 16:04:58 +09:00
Blaž Hrastnik
f7f55143a1 Improve code action picker by displaying it inline 2022-01-31 16:04:58 +09:00
chunghha
4c996f43df chore(theme): fix rose_pine/rose_pine_dawn themes' popup bg color (#1606) 2022-01-31 16:03:44 +09:00
Blaž Hrastnik
62561e9d23 Stop collecting highlight_iter events then turning back into iter 2022-01-30 22:38:44 +09:00
Blaž Hrastnik
5aead46f4b Remove some unnecessary clippy tags 2022-01-30 22:38:44 +09:00
Blaž Hrastnik
2a7ae963e1 Automatically commit changes to history if not in insert mode
Fixes #1500
2022-01-30 22:38:44 +09:00
Daniel S Poulin
e2833b5853 Add textobjects queries for php (#1601)
* Add textobjects queries for php

* Missing EOL fix

* Update generated docs after adding textobjects to php
2022-01-30 11:04:36 +09:00
Andrew Neth
333c2949c2 feat(helix-view): dynamic line numbers (#1522)
* feat(helix-view): dynamic line numbers

* docs: describe editor.line-number in more detail

* Make dynamic numbers the default behavior of `relative`
2022-01-26 00:18:01 +09:00
Blaž Hrastnik
48a0c80652 Run clippy on all targets (including tests) 2022-01-25 16:37:03 +09:00
Michael Davis
7bce91556a add tree-sitter-iex (#1576)
* add tree-sitter-iex

* run docgen task

* fix url for iex submodule
2022-01-25 15:50:34 +09:00
dependabot[bot]
ed03be1450 build(deps): bump which from 4.2.2 to 4.2.4 (#1577)
Bumps [which](https://github.com/harryfei/which-rs) from 4.2.2 to 4.2.4.
- [Release notes](https://github.com/harryfei/which-rs/releases)
- [Commits](https://github.com/harryfei/which-rs/compare/4.2.2...4.2.4)

---
updated-dependencies:
- dependency-name: which
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 09:59:16 +09:00
dependabot[bot]
5c007c2248 build(deps): bump clipboard-win from 4.3.0 to 4.4.1 (#1578)
Bumps [clipboard-win](https://github.com/DoumanAsh/clipboard-win) from 4.3.0 to 4.4.1.
- [Release notes](https://github.com/DoumanAsh/clipboard-win/releases)
- [Commits](https://github.com/DoumanAsh/clipboard-win/commits)

---
updated-dependencies:
- dependency-name: clipboard-win
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 09:42:14 +09:00
Eric Crosson
0ad7561135 Enable tree-sitter for .zshenv and zsh files (#1574)
This commit builds on #1460, #1571, and others, adding the .zshenv
file and all files with the zsh extension to the file-types using
bash syntax-highlighting.
2022-01-24 23:25:19 +08:00
VuiMuich
1bcff796e5 [theme] Serika light and dark (#1566)
* add theme `serika` in light and dark variant

* add `markup.*`s
2022-01-24 23:16:05 +08:00
chunghha
a4fffaed9f Enable tree-sitter for .bash_profile (#1571) 2022-01-24 08:12:46 +05:30
CossonLeo
d49e5323f9 Use markup scopes for the Markdown component (#1363) 2022-01-24 10:41:25 +09:00
Benjamin
4044c70eb2 Fix picker won't scroll down when it hits the bottom #1544 (#1567) 2022-01-23 23:06:28 +09:00
Ivan Tham
759b850859 Allow specifying file start position (#445)
Like helix-term/src/commands.rs:3426:15
2022-01-23 16:54:03 +09:00
Blaž Hrastnik
7d510429c5 Enable tree-sitter for .zshrc and .bashrc
Closes #1460
2022-01-23 16:39:18 +09:00
Omnikar
f064894e57 Fix Clippy lints in tests (#1563)
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-01-23 16:37:23 +09:00
Blaž Hrastnik
e2d2f19fd0 Merge pull request #1154 from sudormrfbin/cursor-shape-new
Change cursor shape on mode change
2022-01-23 16:35:22 +09:00
Kyra
a8e69e12f4 Add haskell-language-server-wrapper --lsp to default languages.toml (#1556)
After the changes to upgrade and reenable tree-sitter-haskell #1417
for the purpose of enabling Haskell syntax highlighting #1384, we
might as well take the final step.
2022-01-23 16:22:31 +09:00
Blaž Hrastnik
4080341977 cargo fmt + clippy lint 2022-01-23 16:15:27 +09:00
Blaž Hrastnik
7c9ebd05b8 Remove some TODOs 2022-01-23 16:10:36 +09:00
Blaž Hrastnik
80e920ba36 Update dependencies (includes tree-sitter 0.20.3) 2022-01-23 16:06:05 +09:00
Blaž Hrastnik
ac81b47a41 Don't calculate symbol width twice
This is potentially costly so we should avoid calling width()
2022-01-23 16:04:26 +09:00
Blaž Hrastnik
66a8612351 cleanup 2022-01-23 16:04:26 +09:00
Blaž Hrastnik
2302869836 fix: ensure_grapheme_boundary_next_byte needs to index at valid char 2022-01-23 16:04:26 +09:00
Blaž Hrastnik
add3be8528 Slicing micro-optimization 2022-01-23 16:04:26 +09:00
Blaž Hrastnik
df0d58e9f7 Set flags necessary for cargo-flamegraph 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
11c3ba9350 Speed up ensure_next_boundary during render
This code:

    let start = ensure_grapheme_boundary_next(text, text.byte_to_char(start));
    let end = ensure_grapheme_boundary_next(text, text.byte_to_char(end));

Would convert byte to char index, but then internally immediately convert back
to byte index, operate on it, then convert it to char index.

This change reduces the amount of time spent in ensure_grapheme_boundary from
29% to 2%.
2022-01-23 16:04:12 +09:00
Blaž Hrastnik
9d41113ae0 Make Layer::parse take &mut tree_sitter::Parser 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
e22dbf102f Use filter_map rather than flat_map 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
2f4a9fea03 Set byte range on cursor again 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
24314bd844 Only call scopes.load() once 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
4b0205f690 Resolve some outdated comments 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
9508684031 fix: Skip modifying the root layer range, it always covers 0..max 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
7315f6f3e4 Update range markers so we can determine which layers can be reused 2022-01-23 16:04:12 +09:00
Blaž Hrastnik
8a53e34e66 Try to reuse an existing layer based on layer.ranges 2022-01-23 16:04:07 +09:00
Blaž Hrastnik
72eb2ce1f1 Ignore layers without highlight captures, avoid cloning ranges 2022-01-23 16:00:24 +09:00
Blaž Hrastnik
5135fa37eb Reuse the source slice between layers 2022-01-23 16:00:24 +09:00
Blaž Hrastnik
53d881f172 Store theme scopes on the loader, this way theme isn't passed around 2022-01-23 16:00:24 +09:00
Blaž Hrastnik
6728e44490 syntax: Split parsing and highlighting 2022-01-23 16:00:24 +09:00
NNB
83bde1004d Add markup support (#1525)
* Add markup support for all Base16 themes

* Fix rose_pine `markup.link.text` attribute misname

* Add basic default markup support for all themes

* Fix cursor change color on Base16 terminal and default

* Remove old markup monokai_pro support and fix Onedark `markup.link.text` attribute misname

* Remove old markup dracula support
2022-01-23 11:18:50 +09:00
Daniel Flanagan
b8cafee9f5 docs: Fix typo in book (#1537)
* docs: Fix typo in book

* Update book/src/usage.md

Co-authored-by: Eric Crosson <EricCrosson@users.noreply.github.com>

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Co-authored-by: Eric Crosson <EricCrosson@users.noreply.github.com>
2022-01-23 00:34:19 +09:00
Rohan Jain
1c747674b6 Add tag to gruvbox theme (#1555)
Missed in the commit 943fca332e.
2022-01-23 00:33:43 +09:00
Sebastian Zivota
5c1a06d28e dracula theme: add markup support (#1554) 2022-01-23 00:32:41 +09:00
Jared Ramirez
0b55b21f30 feat(languages): GraphQL (#1515)
* Add Graphql language support

* Fix docs gen

* Add JS Graphql injection query

* Updates based on PR feedback

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-01-21 23:16:40 +09:00
Michael Davis
f453f8724d change show_subtree command into ':tree-sitter-subtree' typable command (#1524)
* add default keymap for show_subtree command

* remove space+t keymap

* add a typable command ':show-subtree'

* generate documentation for ':show-subtree'

* remove non-typable show_subtree command

* ':show-subtree'->':tree-sitter-subtree'
2022-01-21 23:15:35 +09:00
WindSoilder
4563832318 add markup support for monokai pro themes (#1553) 2022-01-21 22:03:01 +09:00
Michael Davis
392dfa0841 add select_next_sibling and select_prev_sibling commands (#1495)
* add select_next_sibling and select_prev_sibling commands

* refactor objects to use higher order functions

* address clippy feedback

* move selection cloning into commands

* add default keybindings under left/right brackets

* use [+t,]+t for selecting sibling syntax nodes

* setup Alt-{j,k,h,l} default keymaps for syntax selection commands

* reduce boilerplate of select_next/prev_sibling in commands

* import tree-sitter Node type in commands
2022-01-21 00:52:33 +09:00
Mathis Brossier
fd7080498e tree sitter comments injections (#1527)
* tree sitter comments injections

* trailing newlines & julia fix

* Update runtime/queries/julia/injections.scm

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>
2022-01-21 00:50:06 +09:00
Jared Ramirez
b2c8aa1ee7 feat(languages): Elm (#1514)
* Add Elm language support

* Fix docs gen

* Updates based on PR feedback
2022-01-21 00:47:23 +09:00
Ivan Tham
440d4ae9df Add terminal emulator to bug report (#1535) 2022-01-18 21:39:02 +05:30
dependabot[bot]
22b728d1eb build(deps): bump libloading from 0.7.2 to 0.7.3 (#1530)
Bumps [libloading](https://github.com/nagisa/rust_libloading) from 0.7.2 to 0.7.3.
- [Release notes](https://github.com/nagisa/rust_libloading/releases)
- [Commits](https://github.com/nagisa/rust_libloading/commits/0.7.3)

---
updated-dependencies:
- dependency-name: libloading
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-18 09:42:48 +08:00
dependabot[bot]
89eb22525b build(deps): bump serde_json from 1.0.74 to 1.0.75 (#1531)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.74 to 1.0.75.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.74...v1.0.75)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-18 09:42:27 +08:00
dependabot[bot]
ed45d380eb build(deps): bump smallvec from 1.7.0 to 1.8.0 (#1532)
Bumps [smallvec](https://github.com/servo/rust-smallvec) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/servo/rust-smallvec/releases)
- [Commits](https://github.com/servo/rust-smallvec/compare/v1.7.0...v1.8.0)

---
updated-dependencies:
- dependency-name: smallvec
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-18 09:42:07 +08:00
Skyler Hawthorne
96d4ca5f73 Dependabot/cargo/pulldown cmark 0.9.1 (#1533)
* build(deps): bump pulldown-cmark from 0.8.0 to 0.9.1

Bumps [pulldown-cmark](https://github.com/raphlinus/pulldown-cmark) from 0.8.0 to 0.9.1.
- [Release notes](https://github.com/raphlinus/pulldown-cmark/releases)
- [Commits](https://github.com/raphlinus/pulldown-cmark/compare/v0.8.0...v0.9.1)

---
updated-dependencies:
- dependency-name: pulldown-cmark
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* cmark 0.9 fixes

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-18 09:41:44 +08:00
Skyler Hawthorne
56a9ce5d83 fix(auto_pairs): fix auto pairs with crlf (#1470)
Auto pairs were resulting in incorrect ranges in the resulting when the
line terminators are CRLF (i.e. Windows). It turns out this is because
when we were checking if the selection was a single-width cursor, it
incorrectly assumed that this would be a single char. This is not the
case, as a cursor can cover a multi-code point grapheme. Therefore,
we must instead explicitly work with and check graphemes to determine
if the cursor should move or extend the selection.

Fixes #1436
2022-01-18 00:39:12 +09:00
Anders Christiansen Sørby
8ea5742b08 feat(languages): Lean experimental tree-sitter-lean (#1422)
* Add experimental tree-sitter-lean

* Run docgen

* Copy over the queries from lean.nvim

* Update .gitmodules

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* Update lean highlights and run docgen

* Update runtime/queries/lean/injections.scm

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>

* Lean: Move variable matcher to bottom

* Update runtime/queries/lean/locals.scm

Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>

Co-authored-by: Ivan Tham <pickfire@riseup.net>
Co-authored-by: Michael Davis <michael.davis@nfiindustries.com>
2022-01-17 23:05:17 +09:00
Blaž Hrastnik
e7eab95b94 Update to rust 1.58, fix a bunch of optional lints 2022-01-16 14:19:48 +09:00
Mathis Brossier
f5b0821860 Fix panics when resizing (#1408)
* Change buffer.get & buffer.get_mut to return Option, Implement Trait Index & IndexMut to panic

* Prevent FilePicker from drawing outside buffer (rust panics)

* apply suggestion

* add function in_bounds to avoid useless calculations

Co-authored-by: mathis <mathis.brossier@universite-paris-saclay.fr>
2022-01-16 10:55:28 +09:00
Stuart Hinson
9da0abaa5d Add modified background to dracula popup (#1434) 2022-01-16 10:42:00 +09:00
WindSoilder
22297d0b40 Add alt-backspace, alt-<, alt->, ctrl-j to insert mode (#1441)
* add alt-backspace keymap to delete word backward

* add more useful keymap

* map to correct command

* add C-j to insert_newline
2022-01-16 10:41:21 +09:00
Matouš Dzivjak
38ca8daa09 fix(commands): run fmt for all documents being closed (#1444)
When writing all documents, fmt wouldn't be run.
Run fmt in close all implementation so that all documents
are formatted if necessary.

Fixes: https://github.com/helix-editor/helix/issues/1442
2022-01-16 10:39:49 +09:00
Rohan Jain
62c78c061c Add markup. scopes in gruvbox themes (#1518)
As recommended by @archseer in https://github.com/helix-editor/helix/pull/1509#issuecomment-1013583069
2022-01-16 10:32:29 +09:00
Michael Davis
64d3e7b705 add show_subtree command for viewing tree-sitter subtree in Popup (#1453)
* add show_subtree command for viewing tree-sitter subtree in Popup

* remove '.slice(..)' from show_subtree command

* name docs and subtree Popups 'hover'
2022-01-16 10:26:09 +09:00
Daniel S Poulin
dd1f64d4dc Update tree-sitter-php to latest upstream (#1521)
Brings in PHP 8.1 features, like enums, union types and the like.
2022-01-16 10:11:47 +09:00
Kirawi
a7b0cc730c Re-enable haskell in languages.toml (#1520) 2022-01-16 10:11:31 +09:00
Kevin Sjöberg
3a34036310 Use the correct language ID for JavaScript & TypeScript (#1466)
* Use correct language ID for JavaScript/TypeScript

* Add missing slash

* Only calculate fallback when needed
2022-01-15 15:23:06 +09:00
Rohan Jain
97e6f2a38f Add gruvbox-light theme (#1509)
Similar to `gruvbox`, add the light version as well.
2022-01-14 22:33:22 +08:00
voroskoi
6bfd001b48 Update zig tree-sitter (#1501)
use latest upstream version
move comptime from @keyword.function to @keyword.directive
use AssignOp
enhance indents
2022-01-14 22:29:24 +08:00
Matouš Dzivjak
ac6b2de0fd feat(languages): enable css tree-sitter for scss files (#1507)
The grammer works fine for scss files to and it is better than no hihglighting at all
2022-01-14 16:25:44 +05:30
Alexis Mousset
f80da7b4de Add pom.xml as maven root directory marker (#1496) 2022-01-14 15:37:59 +09:00
Mathis Brossier
85cf2648a2 buffer picker allow hsplit / vsplit (#1502) 2022-01-14 15:32:24 +09:00
Jared Ramirez
a2fad4fcb0 Fix Nix flake (#1455) 2022-01-13 09:40:07 +09:00
NexiNov
f77dbc7c83 Minor(book): Add G in normal mode (#1482) 2022-01-12 23:43:03 +08:00
Kirawi
8d273a5613 remove outdated note (#1485) 2022-01-12 13:11:00 +09:00
Blaž Hrastnik
ddbf03613d Update tree-sitter-go with generics support 2022-01-11 19:10:02 +09:00
dependabot[bot]
afc602d306 build(deps): bump clipboard-win from 4.2.2 to 4.3.0 (#1476)
Bumps [clipboard-win](https://github.com/DoumanAsh/clipboard-win) from 4.2.2 to 4.3.0.
- [Release notes](https://github.com/DoumanAsh/clipboard-win/releases)
- [Commits](https://github.com/DoumanAsh/clipboard-win/commits)

---
updated-dependencies:
- dependency-name: clipboard-win
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-11 07:41:18 +08:00
dependabot[bot]
1a34a3ce57 build(deps): bump signal-hook-tokio from 0.3.0 to 0.3.1 (#1477)
Bumps [signal-hook-tokio](https://github.com/vorner/signal-hook) from 0.3.0 to 0.3.1.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.0...v0.3.1)

---
updated-dependencies:
- dependency-name: signal-hook-tokio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-11 07:40:59 +08:00
Michael Davis
e0a99ae51a add tree-sitter-git-config (#1426)
* add tree-sitter-git-config

* add todo comment for improving filetype check
2022-01-09 22:10:20 +08:00
Gokul Soumya
b3b4e78585 Merge branch 'master' into cursor-shape-new 2022-01-09 10:38:58 +05:30
Cottser
97e12f5c5a docs: editor.filepicker -> editor.file-picker (#1465) 2022-01-09 11:45:54 +09:00
Benoît Cortier
05e5520ec0 Put some tests behind #[cfg(test)] (#1459)
It was missing in a few places.
2022-01-09 00:32:50 +09:00
Michael Davis
939261fc07 expand_selection to current node with no children (#1454) 2022-01-09 00:31:05 +09:00
Eric Crosson
5b45bdd80f docs: document @keyword.control.exception scope
As identified in [this GitHub comment](https://github.com/helix-editor/helix/pull/1433#discussion_r777786140)
2022-01-09 00:30:22 +09:00
Eric Crosson
1c6bc6d455 feat: add tree-sitter-make
This commit adds syntax highlighting for GNU Make[^1] makefiles
via tree-sitter-make[^2].

[^1]: https://www.gnu.org/software/make/
[^2]: https://github.com/alemuller/tree-sitter-make
2022-01-09 00:30:22 +09:00
Owen Shepherd
c238f20e1d Add fixity keywords to haskell's highlights.scm 2022-01-09 00:28:56 +09:00
Owen Shepherd
9eacbc1887 Upgrade haskell queries 2022-01-09 00:28:56 +09:00
Owen Shepherd
41ee45ce54 Upgrade and reenable tree-sitter-haskell 2022-01-09 00:28:56 +09:00
Michael Davis
b799b0d50e capture markdown link text as markup.link.text (#1456) 2022-01-09 00:27:50 +09:00
Kevin Sjöberg
5e22694865 Add default language server for JavaScript (#1457)
* Add default language server for JavaScript

* Update lang support documentation
2022-01-09 00:27:10 +09:00
CJ van den Berg
1af8dd9912 Rework beginning of themes chapter
The specifics of configuring themes has caused some confusion. Hopefully this will clarify things a little.
2022-01-07 16:04:34 -05:00
Michael Davis
a8fd33ac01 add tree-sitter-regex (#1362)
* add tree-sitter-regex

* adapt regex highlights from upstream

* inject regex into elixir sigil_r/2 and sigil_R/2

* generate lang-support docs

* capture interesting nodes in character-ranges

* make $.character_class captures more consistent

* fix fallthrough behavior for character classes

* capture pattern characters as 'string'

* use latest tree-sitter-regex

* set elixir regex injections as combined

* add link to upstream queries

* inject regex in rust into 'Regex::new' raw string literals
2022-01-06 23:00:00 +08:00
Gokul Soumya
449624965b Merge branch 'master' into cursor-shape-new 2022-01-06 11:32:03 +05:30
Matouš Dzivjak
2e02a1d6bc feat(commands): shrink_selection (#1340)
* feat(commands): shrink_selection

Add `shrink_selection` command that can be used to shrink
previously expanded selection.

To make `shrink_selection` work it was necessary to add
selection history to the Document since we want to shrink
the selection towards the syntax tree node that was initially
selected.

Selection history is cleared any time the user changes
selection other way than by `expand_selection`. This ensures
that we don't get some funky edge cases when user calls
`shrink_selection`.

Related: https://github.com/helix-editor/helix/discussions/1328

* Refactor shrink_selection, move history to view

* Remove useless comment

* Add default key mapping for extend&shrink selection

* Rework contains_selection method

* Shrink selection without expand selects first child
2022-01-06 11:12:02 +09:00
Philipp Mildenberger
66afbc9fff Fix null and boolean constants in tree-sitter-nix highlights queries (#1428) 2022-01-06 11:04:55 +09:00
Blaž Hrastnik
3e4f81547c fix: Use std::path::MAIN_SEPARATOR to determine completion
Refs #1439
2022-01-06 11:03:54 +09:00
Stuart Hinson
b18bda928f fix slash in search selector status message (#1449) 2022-01-06 10:39:19 +09:00
Blaž Hrastnik
7767703979 fix: Only use shellwords parsing on unix platforms 2022-01-05 11:01:30 +09:00
Blaž Hrastnik
bed9aced5f Revert "Convert Windows style path separator in completers to Unix style (#1389)"
This reverts commit 49444f9c05.
2022-01-05 10:58:12 +09:00
Blaž Hrastnik
bd0d20a2b3 minor: Fix previous version's header 2022-01-04 19:25:59 +09:00
Blaž Hrastnik
1bcae78f06 minor: Fix some changelog links 2022-01-04 18:58:26 +09:00
Blaž Hrastnik
efaac6c5d3 Release 0.6 2022-01-04 18:54:37 +09:00
Blaž Hrastnik
c8794b30ee Update changelog 2022-01-04 18:54:37 +09:00
Sebastian Neubauer
5b1a628e81 Add textobjects and indents to c and cpp (#1293)
Indentation of single line statements doesn't work, i.e.

  for (;;)<hit enter>
leads to
  for(;;)
  <cursor here>

Only blocks with curly braces are indented.
2022-01-04 10:53:04 +09:00
Sebastian Neubauer
641255ccc8 Add llvm-mir highlighting (#1398)
* Add injection regex for more languages

To support embedding them in other languages like markdown.

* Add llvm-mir highlighting

LLVM Machine IR is dumped as yaml files that can embed LLVM IR and
Machine IR.

To support this, add a llvm-mir-yaml language that uses the yaml
parser, but uses different injections to highlight IR and MIR.

* Update submodule with fixed multiline comments

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-01-04 10:52:34 +09:00
dumrich
7c9d3682db Fix grammatical error (#1427)
it's to its (possessive)
2022-01-04 10:45:31 +09:00
dependabot[bot]
4d59f66b76 build(deps): bump tree-sitter from 0.20.1 to 0.20.2 (#1429)
Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.20.1 to 0.20.2.
- [Release notes](https://github.com/tree-sitter/tree-sitter/releases)
- [Commits](https://github.com/tree-sitter/tree-sitter/compare/v0.20.1...v0.20.2)

---
updated-dependencies:
- dependency-name: tree-sitter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-04 10:44:48 +09:00
dependabot[bot]
96935eb28d build(deps): bump serde_json from 1.0.73 to 1.0.74 (#1430)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.73 to 1.0.74.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.73...v1.0.74)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-04 10:44:15 +09:00
dependabot[bot]
78967779bd build(deps): bump ropey from 1.3.1 to 1.3.2 (#1431)
Bumps [ropey](https://github.com/cessen/ropey) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/cessen/ropey/releases)
- [Changelog](https://github.com/cessen/ropey/blob/master/CHANGELOG.md)
- [Commits](https://github.com/cessen/ropey/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: ropey
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-04 10:44:10 +09:00
dependabot[bot]
61fe1dc9e8 build(deps): bump serde from 1.0.132 to 1.0.133 (#1432)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.132 to 1.0.133.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.132...v1.0.133)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-04 10:44:03 +09:00
Mathis Brossier
dbaed0ba83 scroll: change only main selection, only when needed (#1420)
Co-authored-by: mathis <mathis.brossier@universite-paris-saclay.fr>
2022-01-03 11:50:53 +09:00
WindSoilder
609f7363a1 Add everforest_light, change everforest_dark string color (#1412) 2022-01-03 11:32:47 +09:00
Omnikar
ed97ecceb8 Add :cquit! command and prevent :cquit from ignoring unsaved changes (#1414)
* Add `:cquit!` command and prevent `:cquit` from ignoring unsaved changes

* `cargo xtask docgen`
2022-01-03 11:31:24 +09:00
Kirawi
ea095ca5fb Optimize lsp_pos_to_pos (#1423)
lines().count() is slow compared to len_lines()
2022-01-03 11:26:17 +09:00
Triton171
4da050b4bb Add basic indentation for languages without treesitter-based indentation rules (always use the indent of the current line for a new line). (#1341)
Fix several bugs in the treesitter indentation calculation.

Co-authored-by: Triton171 <triton0171@gmail.com>
2022-01-03 11:03:57 +09:00
Sebastian Neubauer
8f2af71340 Add LLVM TableGen highlighting (#1409)
Add a tree-sitter grammar and highlights for TableGen files.
TableGen and its grammar are described here:
https://llvm.org/docs/TableGen/index.html

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2022-01-03 10:57:55 +09:00
Kirawi
93a948d889 switch redundant current! usage to doc! (#1416) 2022-01-03 10:46:57 +09:00
Martin Junghanns
aaa42e1a69 Underline diagnostics in bogster theme (#1399) 2022-01-02 13:45:22 +09:00
Flakebi
0dab6c8c17 Fix markdown code-block highlighting
Markdown code blocks should be highlighted as a single block, so set
injection.include-children.
2022-01-01 17:36:12 +08:00
Alexis Mousset
8a019b423f Detect workspace root using language markers (#1370)
* Detect workspace root using language markers

* Avoid allocating root_markers

* Update helix-core/src/lib.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* Update helix-core/src/lib.rs

Co-authored-by: Kirawi <67773714+kirawi@users.noreply.github.com>

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Co-authored-by: Kirawi <67773714+kirawi@users.noreply.github.com>
2021-12-31 17:06:54 +09:00
Michael Davis
8fda87af2b add tree-sitter-git-rebase (#1402)
* add submodule on tree-sitter-rebase, add to languages

* add basic highlights query

* inject bash in execute statements

* update tree-sitter-rebase

* tree-sitter-rebase->tree-sitter-git-rebase

* get injection working with tree-sitter-git-commit

* set scope under source.gitrebase

* unset include-children on commit message injections

* Revert "unset include-children on commit message injections"

This reverts commit 2ecee155ea.

* fix generated language docs

* use rebase_command scopes from tree-sitter-git-commit
2021-12-31 06:58:47 +08:00
Blaž Hrastnik
a066f59dc8 Don't just filter commands by fuzzy match, also order the matches 2021-12-30 15:20:22 +09:00
Michael Davis
bcf3808e97 Add tree-sitter-git-diff (#1373)
* add submodule on tree-sitter-git-diff

* add git-diff highlights

* inject git-diff into git-commit

* update tree-sitter-git-commit with fix for bad diff case

* add git-diff to language support docs

* include-children in diff injections

This ensures that children nodes of $.message are included in the
injection, such as $.user or issue/pr numbers. Without this change,
diffs containing '#' or '@' characters can trip up the injection and
be parsed separately.

See https://github.com/helix-editor/helix/pull/1373#issuecomment-1001215629

* set diff language's scope as source.diff
2021-12-30 00:31:23 +09:00
ath3
49444f9c05 Convert Windows style path separator in completers to Unix style (#1389) 2021-12-30 00:30:20 +09:00
Sebastian Neubauer
8c29b76bcc Improve llvm highlighting and queries (#1388)
* Improve llvm highlighting and queries

The llvm tree-sitter parser was updated to support scopes and more
accurate highlighting.

* Group highlight expressions better
2021-12-29 18:30:44 +09:00
WindSoilder
f1ed042c84 Fix: when goto normal mode, only want to remove indentation if the line is blank with no text following (#1349)
* when opened new line contains other characters after current position, don't dedent

* abstract checking logic
2021-12-29 18:21:20 +09:00
Stuart Hinson
34db33e1dc Use a fuzzy matcher for commands (#1386)
* Use a fuzzy matcher for commands

* Take Clippy up on its suggestion

* Rescope FUZZY_MATCHER
2021-12-29 18:18:17 +09:00
Matouš Dzivjak
bd2ab5be43 feat(commands): ensure_selections_forward (#1393)
* feat(commands): ensure_selections_forward

Add command that ensures that selections are in forward direction.

Fixes: https://github.com/helix-editor/helix/issues/1332

* Add keybinding for ensure_selections_forward

Add `A-:` keybinding for the ensure_selections_forward command.

* Re-use range.flip for flip_selections command
2021-12-29 18:17:46 +09:00
dependabot[bot]
dc1faa35cb build(deps): bump anyhow from 1.0.51 to 1.0.52 (#1392)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.51...1.0.52)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-28 09:35:17 +09:00
dependabot[bot]
1d2009e4f0 build(deps): bump chardetng from 0.1.15 to 0.1.17 (#1390)
Bumps [chardetng](https://github.com/hsivonen/chardetng) from 0.1.15 to 0.1.17.
- [Release notes](https://github.com/hsivonen/chardetng/releases)
- [Commits](https://github.com/hsivonen/chardetng/compare/v0.1.15...v0.1.17)

---
updated-dependencies:
- dependency-name: chardetng
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-28 09:35:08 +09:00
Omnikar
5b69e9b466 Fix indentation (#1387) 2021-12-28 08:03:14 +09:00
Matouš Dzivjak
a4641a8613 feat(commands): sort command (#1288)
* feat(commands): sort/rsort  command

Add basic implementation of sort command.

* Sort by selections instead, implement reverse sort

* Generate docs

* Rename sort! to rsort
2021-12-27 13:11:06 +09:00
Stuart Hinson
7001665342 Add ruby indents (#1372)
* Add ruby indents

* Include ruby in generated docs
2021-12-27 13:07:09 +09:00
Omnikar
8340d73545 Extract macro parsing to helix-view and add unit tests 2021-12-27 10:13:18 +09:00
Omnikar
2d4bc0aec7 Change how macros separate keypresses
* Keypresses are no longer separated by spaces
* Single-character keypresses are serialized as-is
* Multi-character keypresses are delimited by `<>`
2021-12-27 10:13:18 +09:00
Ivan Tham
ee3eb4057a Update macro display as [q] in message 2021-12-27 10:13:18 +09:00
Ivan Tham
b9cb3930e2 Mark macros as experimental in docs
Given that currently macro does not integrate well with registers and
the internal representation of macros is expected to be changed.
2021-12-27 10:13:18 +09:00
Ivan Tham
9a32617b30 Rename play macro to replay macro
Macro needs to be defined first before playing so replay is more accurate.
Also, replay have the same length as record which makes it looks nice.
2021-12-27 10:13:18 +09:00
Ivan Tham
5326a05117 Improve macro error handling 2021-12-27 10:13:18 +09:00
Ivan Tham
c7a59e24e6 Switch macro Q and q 2021-12-27 10:13:18 +09:00
Tamo
a306a1052a Update settings at runtime (#798)
* feat: Update settings at runtime

fix the clippy warning

* update the documentation

* use to_value instead of to_vec+from_value

* drop the equal

* remove an useless comment

* apply suggestion
2021-12-26 10:04:33 +09:00
Michael Davis
6af0d51dc5 highlight rebase-commands as markup.raw 2021-12-26 00:12:49 +09:00
Michael Davis
c3fb86cbaa tree-sitter-gitcommit->tree-sitter-git-commit 2021-12-26 00:12:49 +09:00
Michael Davis
28c9afdd0e add commented-out diff and rebase injection queries 2021-12-26 00:12:49 +09:00
Michael Davis
c1f4c0e67a add new scopes to themes docs 2021-12-26 00:12:49 +09:00
Michael Davis
3b800025af add diff.{plus,minus,delta} to themes 2021-12-26 00:12:49 +09:00
Michael Davis
78f93239b5 add gitcommit highlights 2021-12-26 00:12:49 +09:00
Michael Davis
fd31662b70 add gitcommit grammar and language configuration 2021-12-26 00:12:49 +09:00
Matouš Dzivjak
4b0b1a5657 feat(ui): file encoding in statusline (#1355)
* feat(ui): file encoding in statusline

Display file encoding in statusline if the encoding
isn't UTF-8.

* Re-export encoding_rs from core

From there it can be imported by other mods
that rely on it.
2021-12-26 00:10:46 +09:00
Sebastian Neubauer
ec878e4011 Add textobjects and indents to cmake (#1307) 2021-12-26 00:10:19 +09:00
Gabriel Berto
5d7b5db8ab Resolve completion item (#1315)
Co-authored-by: Gabriel Berto <gabriel.berto@pottencial.com.br>
2021-12-25 19:00:57 +09:00
Matouš Dzivjak
0e7d757869 feat(lsp): configurable diagnostic severity (#1325)
* feat(lsp): configurable diagnostic severity

Allow severity of diagnostic messages to be configured.
E.g. allow turning of Hint level diagnostics.

Fixes: https://github.com/helix-editor/helix/issues/1007

* Use language_config() method

* Add documentation for diagnostic_severity

* Use unreachable for unknown severity level

* fix: documentation for diagnostic_severity config
2021-12-25 14:32:43 +09:00
BB
60f3225c7f Truncate the start of file paths in the StatusLine (#1351)
* Truncate the start of file paths in the StatusLine

* cargo fmt

Co-authored-by: Bódi Balázs <97936@4ig.hu>
2021-12-25 14:24:29 +09:00
chunghha
8aa0b8eacf chore: update rose pine themes to support markup (#1353) 2021-12-25 14:20:20 +09:00
Laurențiu Nicola
13d804418f Enable Rust proc macro support (#1350) 2021-12-24 23:56:13 +09:00
Gokul Soumya
b2f8f2ba77 Update onedark theme to use new scopes (#1297) 2021-12-24 11:18:04 +09:00
Stuart Hinson
02f24e1214 Fix match brackets comment (#1346) 2021-12-24 07:27:31 +05:30
Stuart Hinson
bb684a2b42 Typo fix in ocaml indents.toml (#1342) 2021-12-24 10:05:29 +09:00
Gokul Soumya
c0bbadcaaf Manually draw all block cursors 2021-12-23 11:56:52 +05:30
Gokul Soumya
a8618cf111 Add precise rust queries for use, mod, as (#1339)
- Differentiates between `as` keyword as a binary type cast
  operator and import renamer.
- `mod` and `use` are now under `@keyword.control.import`,
  but `mod` is a `@keyword` if used as `mod name;`.
2021-12-23 12:10:24 +09:00
Dylan Richardson
34766e242a languages: add .dockerfile extension (#1330)
Many folks use `.dockerfile` as an extension for dockerfiles in addition to plain `Dockerfile`. This change associates both file extensions with dockerfile syntax highlighting
2021-12-22 09:45:02 +09:00
Midnight Exigent
dba22c60ed Support dockerfiles (#1303)
* allow language.config (in languages.toml) to be passed in as a toml object

* Change config field for languages from json string to toml object

* remove indents on languages.toml config

* fix: remove patch version from serde_json import in helix-core

* Use same tree-sitter-zig as upstream/master

* fix(completion_popup): Fixes #1256

* Update helix-term/src/ui/completion.rs

* feat(languages): Add support for `Dockerfile`s

* docs(cargo-xtask-docgen):

* improvement(langs-dockerfile): Add `injection-regex` to `languages.toml` for
`Dockerfile`

* improvement(langs-dockerfile): Add injections.scm

* Update .gitmodules

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-12-21 18:22:15 +09:00
Matouš Dzivjak
75a8b789d2 LSP code action commands (#1304)
* feat(lsp): codeAction commands

* Don't block on command call

* Fix lifetime of command execution

* Fix lint issues
2021-12-21 18:21:45 +09:00
WindSoilder
600ce70cf6 Improve dedent behavior (#1232)
* tmp add code for dedent

* finish normal_mode with dedent behavior

* use function pointer

* rebase from origin

* check dedent condition inside normal_mode implementation

* using if let...

* fix check

* using char_is_whitespace instead of ch.is_whitespace

* fix clippy

* abstract restore_indent function
2021-12-21 18:17:55 +09:00
Skyler Hawthorne
5b4540fc2d Auto pairs selection (#1254)
* use auto pairs with selections

Previously, the auto pairs code was converting the user selection into
its cursor form, and setting the transaction's selection to that cursor.
This has the effect of destroying the user's selection if they type a
pair character that gets auto completed.

This fixes the code to work with the user's selection, inserting auto
pairs where appropriate, but either keeping or extending the user's
selection.

* use movement::Direction instead of bool

* assume 0-width cursor is forward
2021-12-21 18:17:33 +09:00
Ivan Tham
1c082cb4ef Add README for helix-syntax (#1312) 2021-12-21 12:38:32 +09:00
Gokul Soumya
176fbe760a docs: Add note about tree-sitter query precedence (#1314) 2021-12-21 11:03:44 +09:00
Sebastian Neubauer
205dc8776b Add fish highlighting (#1308)
The highlights were copied and modified from
https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/fish/highlights.scm
2021-12-21 11:02:53 +09:00
dependabot[bot]
f16651b590 build(deps): bump serde from 1.0.131 to 1.0.132 (#1323)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:49:10 +09:00
dependabot[bot]
5dfdc95f6f build(deps): bump once_cell from 1.8.0 to 1.9.0 (#1322)
Bumps [once_cell](https://github.com/matklad/once_cell) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/matklad/once_cell/releases)
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.8.0...v1.9.0)

---
updated-dependencies:
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:48:53 +09:00
dependabot[bot]
e02c0d1573 build(deps): bump signal-hook from 0.3.12 to 0.3.13 (#1318)
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.12 to 0.3.13.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.12...v0.3.13)

---
updated-dependencies:
- dependency-name: signal-hook
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:48:33 +09:00
dependabot[bot]
692ed7500f build(deps): bump actions/upload-artifact from 2.3.0 to 2.3.1 (#1316)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2.3.0...v2.3.1)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:48:13 +09:00
dependabot[bot]
73f97fbb96 build(deps): bump futures-executor from 0.3.18 to 0.3.19 (#1317)
Bumps [futures-executor](https://github.com/rust-lang/futures-rs) from 0.3.18 to 0.3.19.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.18...0.3.19)

---
updated-dependencies:
- dependency-name: futures-executor
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:47:56 +09:00
dependabot[bot]
25691061a2 build(deps): bump futures-util from 0.3.18 to 0.3.19 (#1319)
Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.18 to 0.3.19.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.18...0.3.19)

---
updated-dependencies:
- dependency-name: futures-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:47:39 +09:00
dependabot[bot]
65b7acea75 build(deps): bump num_cpus from 1.13.0 to 1.13.1 (#1320)
Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/seanmonstar/num_cpus/releases)
- [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.13.0...v1.13.1)

---
updated-dependencies:
- dependency-name: num_cpus
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:46:59 +09:00
dependabot[bot]
614e0e0026 build(deps): bump tokio from 1.14.0 to 1.15.0 (#1321)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.14.0...tokio-1.15.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-21 08:46:43 +09:00
Sebastian Zivota
7438db66ae Add dracula theme (#1258)
* Add dracula theme

* remove unused colors

* correctly name constant.character.escape

* Change cursors and selections

* add some missing ui scopes

* sorting
2021-12-20 22:37:47 +09:00
Gokul Soumya
f1c634326b Improve rust syntax highlighting (#1295)
- Highlight fragment specifiers (expr, tt, in macro
  definitions) with @type.
- Highlight attributes as macros
2021-12-20 11:47:40 +09:00
Sebastian Neubauer
23091c9d29 Highlight comments in c, cpp, cmake and llvm (#1309)
Also, reuse the c injections in glsl
2021-12-20 11:42:23 +09:00
Michael Davis
e72786df8e Add tree-sitter-comment (#1300)
* Add tree-sitter-comment

Fix #1164

* fix precedence in tree-sitter-comment highlights

connects https://github.com/helix-editor/helix/pull/1170

* set injection-regex for comment language

* remove comment filetype

* fix comment injections for neovim-style injections tags

* add comment injections for elixir

* remove f.comment

* fix spacing in .gitmodules

* run 'cargo xtask docgen'

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2021-12-19 23:56:56 +09:00
Gokul Soumya
7c01d92653 Add link and quote queries for markdown
- Rename markup.underline.link to markup.link.url
- Add markup.link.label
- Add markup.quote

(The constructor theme scope was missing from the
docs, so unrelated to this commit).
2021-12-19 15:23:39 +09:00
Blaž Hrastnik
8208d22601 nix: Update flake.lock 2021-12-19 13:46:00 +09:00
Gokul Soumya
d52eda5d1b Improve yaml syntax highlighting highlighting (#1294) 2021-12-19 10:20:52 +09:00
Sebastian Neubauer
6d183b2154 Fix tree-sitter-llvm submodule (#1298)
Fix the path to the submodule and init the submodule.
2021-12-19 09:46:47 +09:00
Ivan Tham
f174d27d0d Change text for gg to explain <n>gg (#1287) 2021-12-18 20:28:17 +05:30
Kirawi
02fc52f6d5 Apply recent nightly suggestions (#1286)
array iterators are now implicit
2021-12-18 14:57:49 +09:00
Blaž Hrastnik
a66833590c cargo xtask docgen 2021-12-18 13:42:41 +09:00
Luke Jones
edf3c70c30 Add dart lsp config and queries (#1250)
* Add language: dart

The setup requires that dart be in the users path, such as:
```
export PATH="$HOME/Android/flutter/bin/cache/dart-sdk/bin/:$PATH"
```

Refactor the dart highlights

* lang: dart: add indents and locals

* lang: dart: corrections to local scope

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-12-18 13:41:32 +09:00
Oliver Hechtl
0683f0a20a Add scala syntax highlights (#1278)
* add partial scala syntax highlights

* ran cargo xtask docgen

* updated tree-sitter-scala, fixed highlights

* fix comments

* move identifier to the end of the highlights

* add indents
2021-12-18 13:40:34 +09:00
Gokul Soumya
d4fb1d0633 Merge branch 'master' into cursor-shape-new 2021-12-18 08:33:15 +05:30
Gokul Soumya
016640f4fb Remove ui.cursor.primary and hashmap lookups 2021-12-18 08:26:11 +05:30
Chetan Vardhan
3ef115d420 Add instructions for Fedora Linux (#1270)
* Add instructions for Fedora Linux

* Update README.md

* Update install.md
2021-12-17 23:46:32 +09:00
Blaž Hrastnik
5d91335d6b Fix more highlight scopes 2021-12-17 17:04:59 +09:00
Blaž Hrastnik
9c484e88cf highlights: @include -> @keyword.control.import 2021-12-17 17:04:59 +09:00
Blaž Hrastnik
78b6155292 Partly fix julia's locals.scm 2021-12-17 17:04:59 +09:00
ath3
a8060c06d1 Add indents.toml to perl (#1280) 2021-12-17 09:56:07 +09:00
WindSoilder
0c447151cf In README, add example for windows config directory (#1273)
* better doc for windows user

* fix doc
2021-12-16 10:48:49 +09:00
Blaž Hrastnik
ac4b72fcc8 Add injections query for markdown 2021-12-15 18:03:02 +09:00
Blaž Hrastnik
40969ad452 Partly fix latex highlights and add markup scope docs 2021-12-15 17:46:40 +09:00
Blaž Hrastnik
9bfb701c94 Update lang-support.md 2021-12-15 17:38:03 +09:00
Blaž Hrastnik
49e0678741 Add markdown grammar
Fixes #215
2021-12-15 00:50:11 +09:00
Omnikar
6da2174e14 Allow paste commands to take a count (#1261)
* Allow paste commands to take a count

* Call `.repeat` within iterator methods

* Implement counts for paste-replace
2021-12-14 17:49:29 +09:00
Blaž Hrastnik
4527d63a65 fix: rust: disable unresolved-proc-macro
Since we disabled proc macro expansion, disable the related info
level lint:

https://users.rust-lang.org/t/how-to-disable-rust-analyzer-proc-macro-warnings-in-neovim/53150/3
2021-12-14 13:58:26 +09:00
Midnight Exigent
e188926138 Fix panic when scrolling through completion popup (#1260)
* fix(completion_popup): Fixes #1256

* Update helix-term/src/ui/completion.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-12-14 10:14:23 +09:00
dependabot[bot]
10ad25b95b build(deps): bump actions/upload-artifact from 2.2.4 to 2.3.0 (#1263)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2.2.4 to 2.3.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2.2.4...v2.3.0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-14 09:34:11 +09:00
dependabot[bot]
5404a3f01b build(deps): bump serde from 1.0.130 to 1.0.131 (#1264)
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.130 to 1.0.131.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.130...v1.0.131)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-14 09:33:43 +09:00
dependabot[bot]
3820258c57 build(deps): bump serde_json from 1.0.72 to 1.0.73 (#1265)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.72 to 1.0.73.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.72...v1.0.73)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-14 09:33:30 +09:00
dependabot[bot]
b711687e19 build(deps): bump encoding_rs from 0.8.29 to 0.8.30 (#1266)
Bumps [encoding_rs](https://github.com/hsivonen/encoding_rs) from 0.8.29 to 0.8.30.
- [Release notes](https://github.com/hsivonen/encoding_rs/releases)
- [Commits](https://github.com/hsivonen/encoding_rs/compare/v0.8.29...v0.8.30)

---
updated-dependencies:
- dependency-name: encoding_rs
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-14 09:26:07 +09:00
dependabot[bot]
ca0c5fb08c build(deps): bump signal-hook from 0.3.10 to 0.3.12 (#1267)
Bumps [signal-hook](https://github.com/vorner/signal-hook) from 0.3.10 to 0.3.12.
- [Release notes](https://github.com/vorner/signal-hook/releases)
- [Changelog](https://github.com/vorner/signal-hook/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/signal-hook/compare/v0.3.10...v0.3.12)

---
updated-dependencies:
- dependency-name: signal-hook
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-12-14 09:25:31 +09:00
Skyler Hawthorne
94535fa013 Add auto pairs for same-char pairs (#1219)
* Add auto pairs for same-char pairs

* Add unit tests for all existing functionality
* Add auto pairs for same-char pairs (quotes, etc). Account for
  apostrophe in prose by requiring both sides of the cursor to be
  non-pair chars or whitespace. This also incidentally will work for
  avoiding a double single quote in lifetime annotations, at least until
  <> is added
* Slight factor of moving the cursor transform of the selection to
  inside the hooks. This will enable doing auto pairing with selections,
  and fixing the bug where auto pairs destroy the selection.

Fixes #1014
2021-12-14 00:58:58 +09:00
Blaž Hrastnik
730d3be201 Add ui.gutter to theme all gutters (i.e. set bg) 2021-12-14 00:52:15 +09:00
NNB
c7ace15fd4 Add ui.gutter theming 2021-12-14 00:48:45 +09:00
Omnikar
cce34feb4e Assume true color support on Windows 2021-12-14 00:48:45 +09:00
Omnikar
42e6d96a75 Use base16_tty as 16-color default, fix theme name 2021-12-14 00:48:45 +09:00
NNB
d9727868dd change to .unwrap_or_default() and fix ui.window and ui.statusline 2021-12-14 00:48:45 +09:00
NNB
3080be8268 Fix error color, add tty theme 2021-12-14 00:48:45 +09:00
NNB
a9a9d498e8 Update theme.rs 2021-12-14 00:47:30 +09:00
NNB
cff5344a13 Rename base16_theme.toml to base16_terminal.toml 2021-12-14 00:47:30 +09:00
Omnikar
98ce2a301d Load alt default theme if true color is not supported
* Move `runtime/themes/base16_default_terminal.toml` to
  `base16_theme.toml` alongside `theme.toml`
* Use `terminfo` crate to detect whether the terminal supports true
  color and, if the user has no theme configured and their terminal does
  not support true color, load the alt default theme instead of the
  normal default.

Remove `terminfo` dependency, use `COLORTERM` env instead

Prevent user from switching to an unsupported theme

Add `true-color-override` option

If the terminal is wrongly detected to not support true color,
`true-color-override = true` will override the detection.

Rename `true-color-override` to `true-color`
2021-12-14 00:47:18 +09:00
NNB
43d17c482c Fix Base16 Dark, add Base16 Light and Terminal
Improve accuracy with line number and cursor color
2021-12-14 00:47:02 +09:00
Blaž Hrastnik
7ad8eaaef0 wip 2021-12-14 00:41:51 +09:00
Blaž Hrastnik
b25d453f64 minor: Shorten goto file(s) descriptions 2021-12-13 14:36:53 +09:00
Omnikar
e91d357fae Macros (#1234)
* Macros WIP

`helix_term::compositor::Callback` changed to take a `&mut Context` as
a parameter for use by `play_macro`

* Default to `@` register for macros

* Import `KeyEvent`

* Special-case shift-tab -> backtab in `KeyEvent` conversion

* Move key recording to the compositor

* Add comment

* Add persistent display of macro recording status

When macro recording is active, the pending keys display will be shifted
3 characters left, and the register being recorded to will be displayed
between brackets — e.g., `[@]` — right of the pending keys display.

* Fix/add documentation
2021-12-12 21:16:48 +09:00
ath3
3156577fbf Open files with spaces in filename, allow opening multiple files (#1231) 2021-12-12 21:13:33 +09:00
Blaž Hrastnik
3307f44ce2 ui: popup: Don't allow scrolling past the end of content 2021-12-10 19:23:58 +09:00
Omnikar
b66d3d3d9d Add save_selection command (#1247) 2021-12-10 11:46:24 +09:00
Omnikar
44681c5057 Add default-run = "hx" to helix-term/Cargo.toml (#1244)
Following the addition of `xtask`, `cargo run` has multiple possible
targets, necessitating the usage of `cargo run --bin hx` to run Helix
during development. This allows `cargo run` to be used to run `hx`.
2021-12-10 11:04:31 +09:00
Blaž Hrastnik
df3b88387b dap: Improve variables UI 2021-12-09 11:28:53 +09:00
Blaž Hrastnik
dac317e620 TODO 2021-12-09 10:55:32 +09:00
Blaž Hrastnik
60c86eff89 dap: Simplify a few more statements that could use the debugger macro 2021-12-09 10:55:32 +09:00
Oskar Nehlin
a1e64815cb Update book to include typable command remapping (#1240)
* Update book to include typable command remapping

* Add additional example
2021-12-09 00:26:33 +09:00
Kirawi
29c053e84e Only use a single documentation popup (#1241) 2021-12-08 16:11:18 +09:00
Gokul Soumya
d08bdfa838 Use same name used in config files for langs in docs 2021-12-08 10:23:50 +09:00
Gokul Soumya
70c989e122 Add github action to lint unmerged docs 2021-12-08 10:23:50 +09:00
Gokul Soumya
a78b789406 Auto generate docs for language support 2021-12-08 10:23:50 +09:00
Gokul Soumya
71292f9f11 docs: Auto generate command list 2021-12-08 10:23:50 +09:00
Skyler Hawthorne
9bdbafa075 Fix solarized selection colors (#1236)
* do not select a foreground color in selections, as this eliminates
  syntax coloring
* select lighter color for selections
* Make non-primary cursor cyan instead of green
2021-12-08 10:22:55 +09:00
Blaž Hrastnik
d8351d35ab dap: Extract a macro that fetches a debugger or returns 2021-12-08 00:59:11 +09:00
Blaž Hrastnik
e98993d609 dap: Fix an off-by-one error when jumping 2021-12-08 00:22:48 +09:00
Omnikar
178cd5ecfc Add note to keymap.md regarding format_selections (#1230) 2021-12-07 01:44:50 +09:00
WindSoilder
93e276cd9d Make kill_to_line_end behave like emacs (#1235) 2021-12-07 01:44:04 +09:00
Blaž Hrastnik
35ac815409 Fix compilation
nix-direnv issues still mess with my shell..
2021-12-06 12:50:28 +09:00
Blaž Hrastnik
a2b22ec152 Use binary_search when looking up diagnostics
They're sorted by range so they should also be sorted by line
2021-12-06 12:48:25 +09:00
Blaž Hrastnik
cab09093dd fix: Normalize backtab into shift-tab
Fixes #1150
2021-12-06 12:25:19 +09:00
Blaž Hrastnik
bf8437d098 clippy lint 2021-12-06 09:36:02 +09:00
Blaž Hrastnik
dc8df7ba21 Make thread_picker non-blocking 2021-12-06 09:35:59 +09:00
Blaž Hrastnik
2b4de41bf0 dap: Reply to RunInTerminal 2021-12-06 09:32:21 +09:00
Blaž Hrastnik
d5d1a9b1ae Apply suggestions from code review
Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
2021-12-06 09:32:11 +09:00
Jason Rodney Hansen
461cd20563 Small change 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
539c27e3f5 Remove Clone derive 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
0b7911d921 Remove FormatError 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
31ed91dc2e Don't increment for overlapping changes 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
584a31cd90 Used checked_add for years and months 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
c74cd48f38 Cleanup 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
febee2dc0c No need to clone format 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
37e484ee38 Add support for time and more date formats 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
c9641fcced Add Increment trait 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
2a0c685a78 Remove dependency on gregorian crate 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
64afd54654 Cleanup 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
cc04fabe40 Formatting 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
57a8e79940 No default features for gregorian 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
95cfeed2fa Add support for incrementing year and month 2021-12-05 16:22:58 +08:00
Jason Rodney Hansen
c1f6167e37 Add support for dates for increment/decrement 2021-12-05 16:22:58 +08:00
ath3
11a2f9ac31 Assert in release mode too on duplicate keys (#1228) 2021-12-05 13:04:10 +09:00
Oskar Nehlin
a06871a689 feat: Make it possible to keybind TypableCommands (#1169)
* Make TypableCommands mappable

* Fix pr comments

* Update PartialEq implementation
2021-12-04 20:17:18 +05:30
ath3
70c62530ee Support env flags in shebang (#1224) 2021-12-04 00:13:24 +09:00
chunghha
038a6ce22c rose_pine_dawn.toml colorscheme (#1226)
* adds: rose_pine_dawn.toml colorscheme

* chore: define ui.statusline.inactive colors of rose_pine
2021-12-03 23:14:03 +09:00
WindSoilder
cf40e61b0a add more monokai pro filter themes (#1220) 2021-12-03 23:13:21 +09:00
Blaž Hrastnik
5545f8ebb5 dap: Add RunInTerminal reverse request, support replying to requests 2021-12-03 16:09:28 +09:00
Blaž Hrastnik
bcf70d8e67 dap: All of these calls don't need &mut 2021-12-03 13:29:46 +09:00
Blaž Hrastnik
43fbb6d965 Make dap_start non-blocking 2021-12-03 13:27:00 +09:00
Blaž Hrastnik
371c84f70b cargo fmt 2021-12-03 12:51:55 +09:00
Blaž Hrastnik
34f46e7502 Bump rust to 1.57, fix new lint failures 2021-12-03 12:48:07 +09:00
Blaž Hrastnik
032aaffa15 dap: Split call/request in the same way LSP does 2021-12-03 12:41:07 +09:00
Blaž Hrastnik
2dbf966293 dap: Start working on runInTerminal support 2021-12-03 11:59:44 +09:00
Blaž Hrastnik
0d73a4d23a dap: console = internalConsole is actually not a lldb-vscode param 2021-12-03 10:18:23 +09:00
Blaž Hrastnik
d31bef7fea lsp: Don't panic if init fails
We correctly filter out the language server inside Document to ignore it
if the capabilities are missing, so this way it'll simply ignore the
errored out LSP rather than panicking.
2021-12-03 10:05:27 +09:00
Blaž Hrastnik
01f7a312d0 Address new lint on 1.57 2021-12-03 10:02:44 +09:00
Blaž Hrastnik
a45df12699 nix: Update to lld 13, drop flake-compat (was unused) 2021-12-03 10:02:07 +09:00
Blaž Hrastnik
119dee2980 fix: Correctly detect empty transactions
Fixes #1221
2021-12-02 23:49:54 +09:00
WindSoilder
27ffc79c44 Add monokai pro theme (#1206)
* add monokai_pro theme

* add monokai_pro theme

* claim the inspired theme and original author

* make diagnostic underlined
2021-12-02 13:51:27 +09:00
Ivan Tham
e2b428cc2d Add last modified file (gm) (#1093) 2021-12-02 13:46:57 +09:00
Bob
418b833d2b fix goto_window index crash (#1207) 2021-12-02 13:42:34 +09:00
Blaž Hrastnik
d14ca05d6b Simplify some cases that use return None to use ? 2021-12-02 10:31:19 +09:00
Blaž Hrastnik
de5e5863aa dap: Use cursor_line over cursor + char_to_line 2021-12-02 10:24:17 +09:00
Blaž Hrastnik
54f8e5c9c3 dap: Fix an off-by-one and move the function over to commands/dap 2021-12-02 10:22:17 +09:00
Blaž Hrastnik
573cb39926 dap: Remove some unwraps 2021-12-02 10:20:19 +09:00
Blaž Hrastnik
ffc89e483b Mark some more TODOs as resolved 2021-12-01 19:28:29 +09:00
Blaž Hrastnik
dfd499f5a9 dap: Highlight line of current stack frame 2021-12-01 19:23:42 +09:00
Blaž Hrastnik
c955eaa6cd Revert "Improve dedent behavior, make kill_to_line_end behave like emacs (#1173)"
1. pressing o on a line with no indentation will open a new line as
   expected, but esc will then delete the line altogether

2. the kill_line behavior happens after insert mode changes are already
   commited to history, and the change isn't commited. pressing u after
   this will break highlighting & undo history

This reverts commit c08d2fae58.
2021-12-01 13:40:54 +09:00
Blaž Hrastnik
662ecf0cd4 Annotate Theme::highlight with #[inline] 2021-12-01 13:13:50 +09:00
Blaž Hrastnik
259678585c ui: Optimize tree-sitter style lookups
Tree sitter returns an index referring to the position of the scope in
the scopes array. We can use that same index to avoid a hashmap lookup
and instead store the styles in an array.

This currently stores the styles in both a map and an array because the
UI still uses hashmap lookups, but it's a reasonable tradeoff.
2021-12-01 13:08:20 +09:00
Blaž Hrastnik
7bbf4c5b06 ui: Only calculate span styling when it's actually in bounds 2021-12-01 12:57:57 +09:00
Blaž Hrastnik
d562e13e1f minor: Use anchor::ensure in some cases 2021-12-01 12:57:22 +09:00
Blaž Hrastnik
b4fd3148e3 These TODOs have been resolved 2021-12-01 12:56:41 +09:00
George Rodrigues
3e15aead4a Fix typo on docs (#1201) 2021-12-01 09:11:25 +09:00
Blaž Hrastnik
96ae5897a1 Remove another parameter from render_view 2021-12-01 01:08:52 +09:00
Blaž Hrastnik
84e939ef58 Provide a single gutter component that does breakpoint || diagnostic 2021-12-01 00:24:45 +09:00
Blaž Hrastnik
d906911417 dap: Prevent crashes on files with no name or breakpoints 2021-11-30 17:59:30 +09:00
Blaž Hrastnik
30ac5869df dap: Extract diagnostics gutter into gutters.rs 2021-11-30 17:56:00 +09:00
Blaž Hrastnik
8ffafb826f dap: Rewrite breakpoints so that there's a single set maintained 2021-11-30 17:56:00 +09:00
Blaž Hrastnik
3633f85b38 Pass editor into render_view & gutter, reducing the number of params 2021-11-30 16:47:46 +09:00
WindSoilder
c08d2fae58 Improve dedent behavior, make kill_to_line_end behave like emacs (#1173)
* restore indent when press esc right after open a new line

* add comment for restore_indent

* fix, and make kill to line end behaves like emacs

* update comment

* fix comment

* adjust cancel restore_indent situation

* check esc logic in mode transaction

* improve comment

* add more check for dedent

* update comment

* use matches to check for last_cmd

* no need to introduct CommandFun type
2021-11-30 16:40:38 +09:00
Blaž Hrastnik
9ed930b233 Merge remote-tracking branch 'origin/master' into debug 2021-11-30 13:06:30 +09:00
dependabot[bot]
94296229e7 build(deps): bump futures-executor from 0.3.17 to 0.3.18
Bumps [futures-executor](https://github.com/rust-lang/futures-rs) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.17...0.3.18)

---
updated-dependencies:
- dependency-name: futures-executor
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 09:08:37 +09:00
dependabot[bot]
5313d0f04e build(deps): bump anyhow from 1.0.48 to 1.0.51
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.48 to 1.0.51.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.48...1.0.51)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 08:48:36 +09:00
dependabot[bot]
fcd39adcaa build(deps): bump futures-util from 0.3.17 to 0.3.18
Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.17...0.3.18)

---
updated-dependencies:
- dependency-name: futures-util
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 08:47:25 +09:00
dependabot[bot]
987c4ad97f build(deps): bump serde_json from 1.0.71 to 1.0.72
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.71 to 1.0.72.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.71...v1.0.72)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 08:47:17 +09:00
dependabot[bot]
82889d7c41 build(deps): bump actions/cache from 2.1.6 to 2.1.7
Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 2.1.7.
- [Release notes](https://github.com/actions/cache/releases)
- [Commits](https://github.com/actions/cache/compare/v2.1.6...v2.1.7)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 08:47:10 +09:00
Corey Powell
0dd2303f64 Merge pull request #1184 from nichobi/patch-1
Remove defunct helix-bin AUR link
2021-11-29 08:51:46 -05:00
Nicholas Boyd Isacsson
6204c38556 Remove defunct helix-bin AUR link 2021-11-29 13:07:32 +01:00
Gokul Soumya
058796c18e Change default cursors to block for all modes 2021-11-29 11:09:04 +05:30
Blaž Hrastnik
225e8ccf31 Extract gutters into helix-view 2021-11-29 11:00:28 +09:00
Blaž Hrastnik
27c1a84f05 Reuse a text buffer for each gutter line 2021-11-29 11:00:28 +09:00
Blaž Hrastnik
ba45db84d4 Tie the GutterFn lifetime to the doc so we can avoid cloning data 2021-11-29 11:00:28 +09:00
Blaž Hrastnik
c71c9f69e2 TODO 2021-11-29 11:00:28 +09:00
Blaž Hrastnik
30171416cb Gutter functions 2021-11-29 11:00:28 +09:00
Bob
42fde95223 Accept count for goto_window (#1033)
* accept count for goto_window

also fix view is not fullfilled issue

* fix fulfilled mispell

* Update helix-term/src/commands.rs

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* Update helix-term/src/commands.rs

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* fix merge issue

* revert line computation logic

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2021-11-29 10:58:21 +09:00
Bob
4f9390a435 gf as goto_file (#1102)
* goto_file

* support goto_file under current cursor

* add C-w f/F

* sync space w with window mode

* Update helix-term/src/commands.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-29 10:53:29 +09:00
Kirawi
6f1a7b1220 Add llvm grammar (#1167) 2021-11-29 10:38:17 +09:00
Gokul Soumya
dc53e65b9e Fix surround cursor position calculation (#1183)
Fixes #1077. This was caused by the assumption that a block
cursor is represented as zero width internally and simply
rendered to be a single width selection, where as in reality
a block cursor is an actual single width selection in form and
function.

Behavioural changes:

1. Surround selection no longer works when cursor is _on_ a
    surround character that has matching pairs (like `'`
    or `"`). This was the intended behaviour from the start
    but worked till now because of the cursor position
    calculation mismatch.
2021-11-29 10:33:53 +09:00
ath3
1d773bcefb Implement black hole register (#1165) 2021-11-28 10:21:40 +09:00
RustyStriker
103b5125e4 Detect filetype on :write (#1141)
fixes #1136

* removed a log::info

* removed temp.rs

* cargo clippy no longer complains

* new get_lang_server function

* get_lang_server is now launch_language_server

* launch_lang_server will now close the previous one

* better code readability

* remove resfresh_ls(and a wrong comment)
2021-11-28 10:19:54 +09:00
ath3
3b2b7341a5 Fix next char delete key documentation for prompt (#1180) 2021-11-28 10:18:25 +09:00
Kirawi
4ec20eaeff Add language support for WGSL (#1166) 2021-11-27 07:49:40 +05:30
Blaž Hrastnik
6e62c3de47 Simplify some code in editor.rs 2021-11-26 18:26:22 +09:00
Gokul Soumya
17473b51d3 Use serde attribute to rename to lowercase 2021-11-25 22:35:07 +05:30
Ivan Tham
67bf4250ca Optimize space for DocumentId with NonZeroUsize (#1097)
Now Option<DocumentId> uses one byte rather than two
2021-11-25 11:07:23 +09:00
Thanabodee Charoenpiriyakij
e8f800a141 Do not crash when run goto command without line number (#1160)
* Do not crash when run goto command without line number

Report an error when running goto command without entering a
line number.

Fixes #1159

* Use is_empty() instead check len zero
2021-11-25 11:02:51 +09:00
Thanabodee Charoenpiriyakij
95f392b18d Fix bug report template use wrong hx version (#1158) 2021-11-24 20:58:25 +05:30
shenlebantongying
1eecd9a2ac Add language: racket (#1143) 2021-11-24 22:47:12 +09:00
ath3
72f606ee19 Implement no-yank delete/change (#1099) 2021-11-24 16:46:40 +09:00
Gokul Soumya
7961355ba1 Change cursor shape on mode change
Fixes #323. Due to terminal limitations we can only
change the shape of the primary cursor.
2021-11-24 12:26:49 +05:30
Martin Junghanns
57c14d4a93 Add :<line> and :goto <line> commands (#1128)
* Add typable `goto` command

* Support `:<line-number>` on prompt

* Rename function according to convention

* Directly call into goto_line_number function
2021-11-24 15:26:55 +09:00
Bob
21143e8d22 Align selections via & (#1101)
* align lines

* remove log statement

* use selections to align

* fix a clippy issue

* only accept 1,2,3 as user count

* Update helix-term/src/commands.rs

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* return if user count is not correct

* add doc

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2021-11-23 23:08:05 +09:00
dependabot[bot]
f24e5a3c41 build(deps): bump tokio from 1.13.1 to 1.14.0 (#1146)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.13.1 to 1.14.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.13.1...tokio-1.14.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-23 10:07:59 +09:00
dependabot[bot]
2cc19bd8e4 build(deps): bump serde_json from 1.0.70 to 1.0.71 (#1147)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.70 to 1.0.71.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.70...v1.0.71)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-23 09:56:58 +09:00
dependabot[bot]
a2f301ee4f build(deps): bump anyhow from 1.0.46 to 1.0.48 (#1144)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.46 to 1.0.48.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.46...1.0.48)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-23 09:56:35 +09:00
dependabot[bot]
8fec8c0791 build(deps): bump tree-sitter from 0.20.0 to 0.20.1 (#1145)
Bumps [tree-sitter](https://github.com/tree-sitter/tree-sitter) from 0.20.0 to 0.20.1.
- [Release notes](https://github.com/tree-sitter/tree-sitter/releases)
- [Commits](https://github.com/tree-sitter/tree-sitter/compare/v0.20.0...v0.20.1)

---
updated-dependencies:
- dependency-name: tree-sitter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-23 09:55:20 +09:00
NexiNov
4238a843f7 Add link to Keymap page in book. (#1137) 2021-11-22 20:14:42 +05:30
Blaž Hrastnik
72576822f3 dap: Replace breakpoint when changed event comes through 2021-11-22 16:30:56 +09:00
Blaž Hrastnik
85b4410703 dap: Toggle breakpoints without changing selection, fix offset calc 2021-11-22 16:30:35 +09:00
Blaž Hrastnik
177b6fcdc9 cargo fmt 2021-11-22 12:10:37 +09:00
Blaž Hrastnik
28fd704bce ui: Since diagnostics are sorted, we can use binary search 2021-11-22 11:26:16 +09:00
Blaž Hrastnik
b55ca8fdb8 dap: Always edit breakpoints on the correct document 2021-11-22 11:22:08 +09:00
Blaž Hrastnik
0eadeab8c7 dap: Remove the prompt line parameter, use insert_str instead 2021-11-22 11:14:10 +09:00
Blaž Hrastnik
5f329a22c4 dap: Modify breakpoints in place with no cloning 2021-11-22 11:09:09 +09:00
Blaž Hrastnik
3b3c396ca4 nix: Update to lld 13, drop flake-compat (was unused) 2021-11-22 10:32:35 +09:00
NNB
1724930765 Fix "good first issue" link (#1140) 2021-11-22 07:16:26 +09:00
Blaž Hrastnik
05d3ad4a0e dap: Remove an excess clone on enable_exceptions 2021-11-22 00:02:58 +09:00
Blaž Hrastnik
d1854d8e6a Merge remote-tracking branch 'origin/master' into debug 2021-11-21 20:06:45 +09:00
Dan Nases Sha
6a4d9693ba File picker config (#988)
* squashed WIP commits

* hide_gitignore working with config

* pass reference to new config parameter of file_picker()

* update config option name to match name on walk builder

* add comments to config and documentation of option to book

* add git_ignore option to WalkBuilder within prompt in commands.rs

* WIP: add FilePickerConfig struct

* WIP: cleanup

* WIP: add more options including max_depth

* WIP: changed defaults to match ignore crate defaults

* WIP: change WalkBuilder in global_search() to use config options

* WIP: removed follow_links, changed max_depth to follow config setting

* WIP: update book with file-picker inline table notation

* update documentation for file-picker config in book

* adjusted to [editor.file-picker] in book configuration.md

* adjust comments in editor.rs to be doc comments, cleanup

* adjust comments

* adjust book
2021-11-20 23:23:36 +09:00
Skyler Hawthorne
05c6cb1d0b Solarized theme: fix popup colors, adjust menu (#1124)
* fix popup colors, adjust menu

* fix hardcoded horizontal rule color
2021-11-20 23:17:38 +09:00
Martin Junghanns
a3a3b0b517 Jump to end char of surrounding pair from any cursor pos (#1121)
* Jump to end char of surrounding pair from any cursor pos

* Separate bracket matching into exact and fuzzy search

* Add constants for bracket chars

* Abort early if char under cursor is not a bracket

* Simplify bracket char validation

* Refactor node search and unify find methods

* Remove bracket constants
2021-11-20 23:17:25 +09:00
Koen Van der Auwera
b95c9470de Add spacebones light theme (#1131)
* Add spacebones light theme

* Fix error background
2021-11-20 07:22:06 +05:30
Kirawi
ed76cdf238 revert log truncation (#895) (#1130) 2021-11-19 13:26:39 +09:00
Blaž Hrastnik
2b7c086653 fix: Expand tilde first, then deal with relative paths
Otherwise the ~ gets treated as a relative path.

Fixes #1107
2021-11-19 12:09:17 +09:00
Martin Junghanns
f2b4ff23ba Document scrolling for hover command in keymap.md (#1117)
* Document scrolling for hover command in keymap.md

* Move popup keys to a dedicated section
2021-11-19 11:58:22 +09:00
WindSoilder
5959356a24 Implement indent-aware delete (#1120)
* delete character backward can make undent behavior

* improve to handle mixed indentation
2021-11-19 00:19:40 +09:00
Ivan Tham
bd56dde6e2 Ensure cursor in view after pipe (#1123)
Fix #1024
2021-11-18 18:46:27 +09:00
Blaž Hrastnik
e9dc658de4 Remove unused imports 2021-11-18 18:41:44 +09:00
Blaž Hrastnik
9dcccb45bb ui: Stop hardcoding markdown doc colors 2021-11-18 18:40:27 +09:00
Blaž Hrastnik
27ceeb83bb Simplify view/doc macros 2021-11-18 14:13:42 +09:00
Blaž Hrastnik
fa4c59df46 Simplify compositor.find 2021-11-18 11:09:04 +09:00
ath3
90fd09f2cc Fix selection remove doc comment (#1122) 2021-11-18 09:49:56 +09:00
WindSoilder
1132b7088a improve nord status bar line 2021-11-16 22:06:21 +08:00
Blaž Hrastnik
8db6fffe90 ui: Increase diagnostics sideline width to 100 max and wrap if needed 2021-11-16 15:02:48 +09:00
Skyler Hawthorne
335ed7fa69 Improve Solarzed Dark theme (#1105)
Adjusts the Solarized Dark theme to be modeled more closely after
vim's incarnation. Also adjust the Solarized Light theme to match.
2021-11-16 12:34:25 +09:00
dependabot[bot]
f1d3d97004 build(deps): bump libloading from 0.7.1 to 0.7.2 (#1113)
Bumps [libloading](https://github.com/nagisa/rust_libloading) from 0.7.1 to 0.7.2.
- [Release notes](https://github.com/nagisa/rust_libloading/releases)
- [Commits](https://github.com/nagisa/rust_libloading/commits)

---
updated-dependencies:
- dependency-name: libloading
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-16 11:22:01 +09:00
dependabot[bot]
39479949fc build(deps): bump serde_json from 1.0.69 to 1.0.70 (#1112)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.69 to 1.0.70.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.69...v1.0.70)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-16 11:21:32 +09:00
dependabot[bot]
bc31d998de build(deps): bump cc from 1.0.71 to 1.0.72 (#1111)
Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.71 to 1.0.72.
- [Release notes](https://github.com/alexcrichton/cc-rs/releases)
- [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.71...1.0.72)

---
updated-dependencies:
- dependency-name: cc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-16 11:21:20 +09:00
dependabot[bot]
411f522e5d build(deps): bump arc-swap from 1.4.0 to 1.5.0 (#1110)
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/vorner/arc-swap/releases)
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: arc-swap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-16 11:21:14 +09:00
dependabot[bot]
7e4418468a build(deps): bump tokio from 1.13.0 to 1.13.1 (#1109)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.13.0 to 1.13.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.13.0...tokio-1.13.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-16 11:21:02 +09:00
Cole Helbling
225e7904ec helix-view/editor: use SCRATCH_BUFFER_NAME const (#1104) 2021-11-16 01:46:39 +09:00
NexiNov
c95cb2be28 Remove extra instance of delete_word_backword in book (#1103) 2021-11-16 01:46:27 +09:00
Blaž Hrastnik
dd98727bad fix: editor.close now takes only a single parameter 2021-11-16 00:37:30 +09:00
Jason Hansen
6cb35d28a8 Add command to inc/dec number under cursor (#1027)
* Add command to inc/dec number under cursor

With the cursor over a number in normal mode, Ctrl + A will increment the
number and Ctrl + X will decrement the number. It works with binary, octal,
decimal, and hexidecimal numbers. Here are some examples.

0b01110100
0o1734
-24234
0x1F245

If the number isn't over a number it will try to find a number after the
cursor on the same line.

* Move several functions to helix-core

* Change to work based on word under selection

* It no longer finds the next number if the cursor isn't already over
  a number.
* It only matches numbers that are part of words with other characters
  like "foo123bar".
* It now works with multiple selections.

* Add some unit tests

* Fix for clippy

* Simplify some things

* Keep previous selection after incrementing

* Use short word instead of long word

This change requires us to manually handle minus sign.

* Don't pad decimal numbers if no leading zeros

* Handle numbers with `_` separators

* Refactor and add tests

* Move most of the code into core
* Add tests for the incremented output

* Use correct range

* Formatting

* Rename increment functions

* Make docs more specific

* This is easier to read

* This is clearer

* Type can be inferred
2021-11-16 00:32:58 +09:00
Bob
46d9ae2b62 Readline style insert mode (#1039)
* readline style insert mode

* update keymap.md

* don't save change history in insert mode

* Revert "don't save change history in insert mode"

This reverts commit cb47f946d7.

* don't affect register and history in insert mode

* add insert_register

* don't call exit_select_mode in insert mode

* avoid set_selection

* avoid duplicated current!
2021-11-16 00:31:20 +09:00
Cole Helbling
c638b6b60e helix-term/commands: implement buffer-close (bc, bclose) (#1035)
* helix-view/view: impl method to remove document from jumps

* helix-view/editor: impl close_document

* helix-view/editor: remove close_buffer argument from `close`

According to archseer, this was never implemented or used properly. Now
that we have a proper "buffer close" function, we can get rid of this.

* helix-term/commands: implement buffer-close (bc, bclose)

This behaves the same as Kakoune's `delete-buffer` / `db` command:

* With 3 files opened by the user with `:o ab`, `:o cd`, and `:o ef`:
  * `buffer-close` once closes `ef` and switches to `cd`
  * `buffer-close` again closes `cd` and switches to `ab`
  * `buffer-close` again closes `ab` and switches to a scratch buffer
* With 3 files opened from the command line with `hx -- ab cd ef`:
  * `buffer-close` once closes `ab` and switches to `cd`
  * `buffer-close` again closes `cd` and switches to `ef`
  * `buffer-close` again closes `ef` and switches to a scratch buffer
* With 1 file opened (`ab`):
  * `buffer-close` once closes `ab` and switches to a scratch buffer
  * `buffer-close` again closes the scratch buffer and switches to a new
    scratch buffer

* helix-term/commands: implement buffer-close! (bclose!, bc!)

Namely, if you have a document open in multiple splits, all the splits
will  be closed at the same time, leaving only splits without that
document focused (or a scratch buffer if they were all focused on that
buffer).

* helix-view/tree: reset focus if Tree is empty
2021-11-16 00:30:45 +09:00
Blaž Hrastnik
cccc1949eb Enable thin LTO
It compiles about half a second slower for me, so it seems fine to use
by default.
2021-11-15 14:38:03 +09:00
Cole Helbling
87e61a0894 helix-term/commands: implement cquit (#1096)
This allows you to exit helix with an exit code, e.g. `:cq 2`.
2021-11-15 13:06:12 +09:00
Blaž Hrastnik
f5e070e808 minor: Remove leftover log line 2021-11-15 10:33:14 +09:00
Blaž Hrastnik
e128a8702e Implement MarkedString rendering
Solves typescript and python documentation rendering
2021-11-15 10:30:05 +09:00
Kirawi
8f7ada12ac Solarized dark theme (#999)
* init

* wip

* wip
2021-11-15 09:29:39 +09:00
Ivan Tham
b7c3877e94 Add movement shortcut for history (#1088)
alt-u and alt-U
2021-11-15 00:16:47 +09:00
ath3
6fa76d9fe7 Add trim_selections command (#1092) 2021-11-15 00:16:20 +09:00
Ebbe Steenhoudt
edc976b6bb Added workspace_symbol_picker (#1041)
* Added workspace_symbol_picker

* Moved truncation of the symbol pickers to the end.

* Fixed typo
2021-11-15 00:12:56 +09:00
Blaž Hrastnik
1817b7f581 minor: Import Range too 2021-11-15 00:12:14 +09:00
ath3
35c974c9c4 Implement "Goto last modification" command (#1067) 2021-11-15 00:11:53 +09:00
Gygaxis Vainhardt
0949a0de7f Add commit hash to version info, if present (#957)
* Add commit hash to version info, if present

* Rename GIT_HASH to indicate that it includes version, fix linter error

* Add whitespace after use statement

Co-authored-by: Ivan Tham <pickfire@riseup.net>

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2021-11-15 00:09:02 +09:00
Cole Helbling
b74912ea78 helix-term/editor: display scratch buffer name in status bar 2021-11-14 12:33:17 +05:30
Cole Helbling
b824e091a9 helix-term/commands: move SCRATCH_BUFFER_NAME to helix-view/document (#1091)
This way, the name is accessible everywhere `Document` and related types
are.
2021-11-13 13:15:41 +09:00
Omnikar
6d4409c00f Make prompts consistent (#1080) 2021-11-13 01:34:49 +09:00
Blaž Hrastnik
d3def16584 fix: shift-tab mappings broken after efc2b4c7 2021-11-12 16:21:03 +09:00
Gokul Soumya
fa0cb010e1 docs: Mark more keybinds that require LSP and treesitter (#1081) 2021-11-12 10:35:32 +09:00
NexiNov
187197afb1 Add arrow keys to view mode (#987)
* Add arrow keys to view mode

* Drop C-up and C-down

* Update docs for #987

* Format correctly

* Drop other keymaps

* Correct keymap.md

* Add arrow keys to view mode

Drop C-up and C-down

Update docs for #987

Format correctly

Drop other keymaps

Correct keymap.md

Rebase

Co-authored-by: Rust & Python <nexinov@localhost.gud-o15>
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-12 09:48:37 +09:00
Omnikar
bf95a9ed04 Add remove_selections command (#1065)
* Add `remove_selections` command

* Document `remove_selections`

* Update helix-term/src/keymap.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-12 09:34:08 +09:00
Ivan Tham
9d591427be Fix earlier/later missing changeset update (#1069)
Fix #1059
2021-11-11 22:32:44 +09:00
Omnikar
d131a9dd0e Allow keys to be mapped to sequences of commands (#589)
* Allow keys to be mapped to sequences of commands

* Handle `Sequence` at the start of `Keymap::get`

* Use `"[Multiple commands]"` as command sequence doc

* Add command sequence example to `remapping.md`
2021-11-11 13:44:50 +09:00
Cole Helbling
bf70cfd050 helix-term/command: make scratch buffer name consistent (#1071) 2021-11-11 12:22:15 +09:00
Omnikar
ebc14d9d20 Add m textobject for pair under cursor (#961) 2021-11-11 11:33:31 +09:00
Bob
4d22454386 add wonly -- window only (#1057)
* add wonly

* Update book/src/keymap.md

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* add `wonly` to space w mode too

* remove the TODO

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-11 11:32:23 +09:00
ath3
c7cb7527be Fix moving with arrow keys in prompt (#1070) 2021-11-11 11:08:19 +09:00
Mateusz S. Szczygieł
e0540fbcc4 Add json indents.toml file (#1055)
* add glsl language support

* glsl: use indents.toml file

* add json indents.toml
2021-11-11 01:01:19 +09:00
Gokul Soumya
efc2b4c77b Refactor keyevent handling using key, ctrl macros (#1058)
Adds ctrl! and alt! macros (which existed before the big keymap
refactor) and uses them in event handling of Components. Note
that this converts crossterm's KeyEvent to our own KeyEvent on
each invocation of handle_event in Components.
2021-11-11 00:58:46 +09:00
Gokul Soumya
e863e3b62d Ensure that identical keymaps stay in sync (#1056)
Space mode and view mode are duplicated on two different
keybinds, and they tend to get out of sync by contributers
forgetting to update both of them. This commit adds a test
that explicitly checks that they are identical. Prevents
issues like #1050.
2021-11-11 00:58:35 +09:00
Gokul Soumya
f9e9efb3ec Check for duplicate keys in default keymap 2021-11-11 00:58:25 +09:00
Gokul Soumya
80036b8bd3 Change page keybinds in view mode
b which was assigned to page_up conflicts with
align to bottom, so this commit replaces page up,
down, etc keybinds to use normal mode keybinds
(C-f, C-b, etc) in view mode too.
2021-11-11 00:58:25 +09:00
Omnikar
5654909135 Update space w window mode (#1050) 2021-11-10 11:04:03 +09:00
Jason Hansen
cf831b1a65 Allow piping from stdin into a buffer on startup (#996)
* Allow piping from stdin into a buffer on startup

* Refactor

* Don't allow piping into new buffer on macOS

* Update helix-term/src/application.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* Update helix-term/src/application.rs

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* Fix

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-10 10:53:14 +09:00
CossonLeo
68224232af buffer picker add is_modifier flag (#1020) 2021-11-10 10:52:39 +09:00
Gokul Soumya
92d23430c0 Cleanup keymap doc book page (#1042)
- Clearly mark keybinds that require LSP
- Fix incorrect rendering of Prompt section due to missing newline
2021-11-10 10:47:07 +09:00
Ivan Tham
97893cca64 Restore screen position when abort search (#1047) 2021-11-10 10:46:55 +09:00
Bob
7c9f620236 add <C-h>, <C-u>, <C-d>, Delete in prompt mode (#1034) 2021-11-09 14:43:50 +09:00
CossonLeo
490919df4f Add rename_symbol to book/ (#1031)
* rename_symbol book

* Update book/src/keymap.md

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-09 11:12:11 +09:00
CossonLeo
a69caff450 search_impl will only align cursor center when it isn't in view (#959) 2021-11-09 11:11:45 +09:00
CossonLeo
f96be0fcbc add solarized_light theme (#1010)
* add solarized_light theme

* solarized_light add constant.numeric
2021-11-09 11:08:08 +09:00
Omnikar
a424ef4e20 Use default languages.toml if user's is invalid (#994) 2021-11-09 11:07:54 +09:00
dependabot[bot]
eb68cd3767 build(deps): bump serde_json from 1.0.68 to 1.0.69 (#1030)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.68 to 1.0.69.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.68...v1.0.69)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-09 11:04:44 +09:00
dependabot[bot]
81015266d9 build(deps): bump anyhow from 1.0.44 to 1.0.46 (#1029)
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.44 to 1.0.46.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.44...1.0.46)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-09 11:04:38 +09:00
Blaž Hrastnik
e18198aeb2 Revert "fix(core): stop merging array toml config values (#1004)"
It breaks languages.toml merging

This reverts commit 4304b52ff8.
2021-11-09 10:58:23 +09:00
Blaž Hrastnik
f804ed3192 Make shebangs optional, they don't make sense outside of scripts 2021-11-09 10:57:08 +09:00
Curiosidad-Racional
41fc326325 Fix panicked missing field shebangs (#1025)
Fix the error:
```
thread 'main' panicked at 'Could not parse merged (built-in + user) languages.toml: Error { inner: ErrorInner { kind: Custom, line: None, col: 0, at: None, message: "missing field `shebangs`", key: ["language"] } }', helix-term/src/application.rs:87:14
```
2021-11-09 10:49:43 +09:00
Mateusz S. Szczygieł
3f0345ff58 glsl support (#993)
* add glsl language support

* glsl: use indents.toml file
2021-11-09 00:48:00 +09:00
Blaž Hrastnik
549cdee561 Refactor shebang detection to reuse the loaded buffer 2021-11-09 00:30:34 +09:00
ath3
77dbbc73f9 Detect filetype from shebang line (#1001) 2021-11-09 00:19:44 +09:00
CossonLeo
29e6849413 Add LSP rename_symbol (space-r) (#1011)
improve apply_workspace_edit
2021-11-09 00:17:54 +09:00
LollipopFt
bf4c70e027 added Down keymapping. (#1019) 2021-11-09 00:14:03 +09:00
ath3
30744646cb Perl support (#978) 2021-11-08 10:05:12 +09:00
Blaž Hrastnik
cdc2107bca fix: #896 broke some of the default highlights 2021-11-08 10:03:53 +09:00
Blaž Hrastnik
82ff5b0ab6 Specify capacity on toggle_line_comments 2021-11-08 10:03:21 +09:00
Blaž Hrastnik
8b85903116 wip 2021-11-08 10:03:08 +09:00
jgart
4010b327e2 Adds mint language server (#974) 2021-11-08 10:01:55 +09:00
Daniel S Poulin
1e793c2bbf Adds single and double quotes to matching pairs (#995)
This enables `mm` to work on quote characters as well as highlighting of
matching quote when on it.
2021-11-08 09:57:26 +09:00
Omnikar
a252ecd8c8 Add WORD textobject (#991)
* Add WORD textobject

* Document WORD textobject
2021-11-08 09:54:39 +09:00
Gokul Soumya
e0e227d172 Touch up docs for adding new language (#1002) 2021-11-08 09:52:51 +09:00
Carter Snook
4304b52ff8 fix(core): stop merging array toml config values (#1004) 2021-11-08 09:50:03 +09:00
Blaž Hrastnik
09f5796537 dap: Simplify get_breakpoint_at_current_line 2021-11-07 22:03:55 +09:00
Blaž Hrastnik
c39d9f44a0 dap: Simplify debug_parameter_prompt 2021-11-07 21:58:06 +09:00
Blaž Hrastnik
3042ff3e5a dap: Clean up dap_start_impl, no need to clone arg keys 2021-11-07 21:47:44 +09:00
Blaž Hrastnik
9963a5614d dap: Minor simplifications 2021-11-07 21:37:00 +09:00
Blaž Hrastnik
65868081fc dap: Simplify launch & start
There's no need to re-detect language config, just use the one available
on the document.
2021-11-07 21:26:03 +09:00
Blaž Hrastnik
4f2a01cc09 dap: Error implements Display so we can format with {} 2021-11-07 21:20:58 +09:00
Blaž Hrastnik
2bd8a9b39d dap: Consistently rename type as ty 2021-11-07 21:18:53 +09:00
Blaž Hrastnik
31b431bfdd dap: Remove Deref for DebuggerCapabilities
Looks like a mistake
2021-11-07 21:17:09 +09:00
Blaž Hrastnik
9dd17c46a2 dap: Avoid cloning old_breakpoints if we are immediately replacing them 2021-11-07 18:58:47 +09:00
Blaž Hrastnik
757babb1b4 dap: Avoid cloning *entire* stack frames when picking a thread 2021-11-07 18:56:09 +09:00
Blaž Hrastnik
5803de2067 dap: Simplify more calls 2021-11-07 18:51:29 +09:00
Blaž Hrastnik
155c608237 dap: Drop examples 2021-11-07 18:38:27 +09:00
Blaž Hrastnik
9baddc825d dap: Get rid of excessive cloning 2021-11-07 18:38:04 +09:00
Blaž Hrastnik
fd9b826f2c dap: Inline empty completer 2021-11-07 18:15:17 +09:00
Blaž Hrastnik
5938ab1bf1 dap: Fully extract template parameter prompts 2021-11-07 18:13:37 +09:00
Blaž Hrastnik
3b8d5102ac Make picker take the whole context, not just editor 2021-11-07 18:03:04 +09:00
Blaž Hrastnik
64bb1f7563 dap: Extract out variable rendering
Will improve on the UI later
2021-11-07 17:55:01 +09:00
Blaž Hrastnik
29fe504398 book: Mention git submodule sync too 2021-11-07 10:33:05 +09:00
ammkrn
acced82be6 feat(book/src/languages.md) (#979)
* feat(book/src/languages.md)

Add a section in the book about language-specific settings and the languages.toml file.

* Update book/src/languages.md

Co-authored-by: Gokul Soumya <gokulps15@gmail.com>

* feat(book/src/guides/adding_languages.md)

Add book section on adding a new language to the compile-time/root languages.toml file.

* Update book/src/guides/adding_languages.md

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* Update book/src/guides/adding_languages.md

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* refactor(revise book/src/languages.md)

Change the book page on language settings to match suggestions by archseer and mention both toml files.

Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-07 10:31:12 +09:00
Omnikar
ed23057ff8 Launch with defaults upon invalid config/theme (#982)
* Launch with defaults upon invalid config/theme

* Startup message if there is a problematic config
* Statusline error if trying to switch to an invalid theme

* Use serde `deny_unknown_fields` for config
2021-11-07 00:57:14 +09:00
Blaž Hrastnik
e2a23ac0b5 If there is no live debugger, treat breakpoints as unverified 2021-11-07 00:48:34 +09:00
Blaž Hrastnik
2e1aa5f15b Fix compilation 2021-11-07 00:32:28 +09:00
Blaž Hrastnik
a5ea61433c dap: Bump helix-core 2021-11-07 00:29:43 +09:00
Blaž Hrastnik
09d8c139af dap: Enable sticky mode for the submode 2021-11-07 00:29:12 +09:00
Blaž Hrastnik
14a3502cf1 dap: Move template selection into a picker
It's time to move all these components out of ui/editor.rs
2021-11-07 00:28:57 +09:00
Blaž Hrastnik
f2b709a3c3 Merge branch 'master' into debug 2021-11-07 00:28:19 +09:00
Blaž Hrastnik
f979bdc442 Specify capacity on toggle_line_comments 2021-11-06 23:57:42 +09:00
Blaž Hrastnik
2c1313c064 Specify vector capacity on surround_add 2021-11-06 23:52:49 +09:00
Blaž Hrastnik
1a1685acf7 Simplify current!(..).1 into doc!() 2021-11-06 23:52:26 +09:00
Blaž Hrastnik
e80708eba7 Make sure document diagnostics are sorted 2021-11-06 18:58:58 +09:00
Blaž Hrastnik
0f4cd73000 Simplify goto_*_diagnostic commands 2021-11-06 18:58:58 +09:00
Blaž Hrastnik
f659e1178a minor: view!(..).doc is slightly more efficient than current!(..).1.id() 2021-11-06 17:54:04 +09:00
Blaž Hrastnik
4c1321b3b6 minor: Extend search was decclared twice in the keymap 2021-11-06 17:49:18 +09:00
Blaž Hrastnik
b81a554424 Retain range direction on search
Co-authored-by: CossonLeo <20379044+cossonleo@users.noreply.github.com>
2021-11-06 17:41:30 +09:00
Blaž Hrastnik
6431b26a6a Implement Selection::replace to replace a single range
Fixes #985

Co-authored-by: Daniel S Poulin <crimsonmage+github@gmail.com>
2021-11-06 17:37:45 +09:00
Gygaxis Vainhardt
911b9b3276 Add reverse search functionality (#958)
* Add reverse search functionality

* Change keybindings for extend to be in select mode, incorporate Movement and Direction enums

* Fix accidental revert of #948 in rebase

* Add reverse search to docs, clean up mismatched whitespace

* Reverse search optimization

* More optimization via github feedback
2021-11-06 17:33:30 +09:00
Omnikar
cfc8285867 Allow infoboxes to be disabled (#972)
* Allow infoboxes to be disabled

* Document `infoboxes` default value

* Rename `infoboxes` to `auto_info`

* Document `auto-info`

* Fix incomplete rename
2021-11-05 11:25:08 +09:00
Omnikar
51b4d35dce Inform when reaching undo/redo bounds (#981)
* Inform when reaching undo/redo bounds

* `Already at oldest change` when undo fails
* `Already at newest change` when redo fails

* Add missing `the`
2021-11-05 10:20:06 +09:00
ath3
aa4d0b4646 Fix crash on changing from empty scratch buffer to itself (#975) 2021-11-04 17:57:04 +09:00
Blaž Hrastnik
7b65a6d687 Rewrite goto_buffer 2021-11-04 14:03:03 +09:00
ath3
78c68fae91 Implement "Goto next buffer / Goto previous buffer" commands 2021-11-04 14:03:03 +09:00
Blaž Hrastnik
e2560f427e Replace documents SlotMap with BTreeMap 2021-11-04 13:43:45 +09:00
CossonLeo
39584cbccd Add c-s to pick word under doc cursor to prompt line & search completion (#831)
* Add prompt shourtcut to book
Add completions to search
Add c-s to pick word under doc cursor to prompt line

* limit 20 last items of search completion, update book

* Update book/src/keymap.md

Co-authored-by: Ivan Tham <pickfire@riseup.net>

* limit search completions 200

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2021-11-04 12:26:01 +09:00
diegodox
70d21a903f Prevent preview binary or large file (#939)
* Prevent preview binary or large file (#847)

* fix wrong method name

* fix add use trait

* update lock file

* rename MAX_PREVIEW_SIZE from MAX_BYTE_PREVIEW

* read small bytes to determine cotent type

* [WIP] add preview struct to represent calcurated preveiw

* Refactor content type detection

- Remove unwraps
- Reuse a single read buffer to avoid 1kb reallocations between previews

* Refactor preview rendering so we don't construct docs when not necessary

* Replace unwarap whit Preview::NotFound

* Use index access to hide unwrap

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>

* fix Get and unwarp equivalent to referce of Index acess

* better preview implementation

* Rename Preview enum and vairant

Co-authored-by: Gokul Soumya <gokulps15@gmail.com>

* fixup! Rename Preview enum and vairant

* simplify long match

* Center text, add docs, fix formatting, refactor

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
2021-11-04 12:24:52 +09:00
Omnikar
5b5d1b9dff Truncate the starts of file paths instead of the ends in picker (#951)
* Truncate the starts of file paths in picker

* Simplify the truncate implementation

* Break loop at appropriate point

* Fix alignment and ellipsis presence

* Remove extraneous usage of `x_offset`

Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2021-11-04 12:24:05 +09:00
Omnikar
e39cfa40df Hide keys bound to no_op from infobox (#971) 2021-11-04 09:50:38 +09:00
Gokul Soumya
253bd6b3a8 Add better description for copy_selection command (#969) 2021-11-03 22:22:41 +09:00
Ivan Tham
3eb829e233 Ensure coords in screen depends on char width (#885)
The issue affected files with lots of tabs at the start as well.

Fix #840
2021-11-03 12:02:29 +09:00
Kirawi
ee889aaa85 Updated tree-sitter query scopes (#896)
* updated theme scopes

variable.property -> variable.field
property -> variable.field

* updated theme scopes

* update book and themes

updated book and themes to reflect scope changes

* wip

* update more queries

* update dark_plus.toml
2021-11-03 12:00:52 +09:00
Triton171
7a0c4322ea Simplify BTreeSet construction
Co-authored-by: Ivan Tham <pickfire@riseup.net>
2021-11-03 11:56:55 +09:00
Daniel Ebert
eb8745db09 Implement key ordering for info box 2021-11-03 11:56:55 +09:00
Carter Snook
e505bf2b48 chore(doc): use faq for finding helix log file (#963) 2021-11-03 09:57:18 +09:00
Daniel Poulin
9e247bf6ee Add indents definition based on the one from nvim-treesitter 2021-11-02 17:53:24 +09:00
Daniel Poulin
924b7d3b19 Adjust PHP indentation defaults to 4 spaces
In the PHP community, 4 spaces is widely considered the default, as
it is recommended by the PSR-2 and PSR-12 standards, as well as popular
derivative standards like those for Laravel and Symphony.
2021-11-02 17:53:24 +09:00
CossonLeo
1720b98760 only remove primary index when search next without extend (#948) 2021-11-02 13:32:57 +09:00
dependabot[bot]
44ff597841 build(deps): bump tokio-stream from 0.1.7 to 0.1.8 (#953)
Bumps [tokio-stream](https://github.com/tokio-rs/tokio) from 0.1.7 to 0.1.8.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-stream-0.1.7...tokio-stream-0.1.8)

---
updated-dependencies:
- dependency-name: tokio-stream
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-02 09:34:39 +09:00
dependabot[bot]
0c381adcb1 build(deps): bump lsp-types from 0.91.0 to 0.91.1 (#954)
Bumps [lsp-types](https://github.com/gluon-lang/lsp-types) from 0.91.0 to 0.91.1.
- [Release notes](https://github.com/gluon-lang/lsp-types/releases)
- [Changelog](https://github.com/gluon-lang/lsp-types/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gluon-lang/lsp-types/compare/v0.91.0...v0.91.1)

---
updated-dependencies:
- dependency-name: lsp-types
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-02 09:15:25 +09:00
dependabot[bot]
a13af476c1 build(deps): bump tokio from 1.12.0 to 1.13.0 (#955)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.12.0...tokio-1.13.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-11-02 09:15:05 +09:00
Omnikar
2f8ad7f890 If switching away from an empty scratch buffer, remove it (#935)
* If switching away from an empty scratch buffer, remove it

* Move `view.jumps.push` call into `else` clause

* Refactor
2021-10-31 09:42:49 +09:00
kabirz
592fba1100 add cmake-language-server as cmake language server 2021-10-30 13:17:30 +05:30
Gokul Soumya
ea452bec80 Update onedark theme (#936)
- Use named color palette
- Remove blue highlight for variables (too much noise)
- Add purple highlight for control statements (if, match, etc)
2021-10-30 14:17:51 +09:00
Gygaxis Vainhardt
f140a2a00e Add arrow-key bindings for window switching (#933) 2021-10-30 10:48:00 +09:00
Blaž Hrastnik
e5de103728 Extract a clear_completion method 2021-10-29 16:48:41 +09:00
Za Wilcox
68697cb332 Move 'Note' from incorrect location (#921) 2021-10-29 14:11:42 +09:00
Houkime
a1c7e55e3b update cpp queries (#930)
Co-authored-by: Houkime <>
2021-10-29 14:11:19 +09:00
Ivan Tham
49f6c2623f Bump lsp-types to 0.91.0 (#932) 2021-10-29 12:00:18 +09:00
Kirawi
cec0cfdaec Uncomment mapping LSP diagnostics through changes (#925) 2021-10-29 10:11:30 +09:00
Ivan Tham
bc6a34d97e Make match work with extend and multi cursors (#920) 2021-10-29 10:08:53 +09:00
Ivan Tham
21d535565b Support extend for multiple goto (#909)
gg, ge, [n]gg
2021-10-29 10:07:07 +09:00
cossonleo
befecc8a9a select smaller range on some case 2021-10-29 10:04:12 +09:00
cossonleo
f1d339919f add expand_selection to last_motion 2021-10-29 10:04:12 +09:00
Omnikar
45fadf6151 Add hyperlinks to fix cargo doc warn (#931) 2021-10-29 09:55:15 +09:00
ath3
58b8100751 Mention CMake support in changelog (#926) 2021-10-28 21:23:13 +09:00
Blaž Hrastnik
c02534d261 changelog: Add links to all pull requests 2021-10-28 16:57:44 +09:00
Blaž Hrastnik
8af6d713cd Fix the release date 2021-10-28 16:49:13 +09:00
Dmitry Sharshakov
cde57dae35 lldb: add gdbserver connection template
Can be better customized in a personal languages.toml for perfect fit
2021-10-24 17:34:24 +03:00
Dmitry Sharshakov
6aa9838ea6 dap: support arrays as arguments 2021-10-24 17:24:18 +03:00
Blaž Hrastnik
d6e8a44d85 dap: Fix examples 2021-10-17 14:12:03 +09:00
Blaž Hrastnik
bda05ec4bf Use a newtype for ThreadId 2021-10-17 14:06:52 +09:00
Blaž Hrastnik
83a8167402 Invert core -> dap dependency 2021-10-17 13:58:11 +09:00
Blaž Hrastnik
ea59f77a6b Port over parsing improvements from the LSP
We need to terminate if we ever read 0 bytes which indicates closed
stream.
2021-10-17 13:54:47 +09:00
Blaž Hrastnik
0a6b60085a Merge branch 'master' into debug 2021-10-17 13:51:56 +09:00
Dmitry Sharshakov
bc0084d071 fix command descriptions 2021-10-09 16:06:32 +03:00
Dmitry Sharshakov
48cb81eff1 Merge branch 'master' into debug 2021-10-09 16:03:46 +03:00
Dmitry Sharshakov
814dcfa8d2 fix lints 2021-09-26 21:54:36 +03:00
Dmitry Sharshakov
d943a51e3e editor: add Node.js debugger 2021-09-26 21:36:06 +03:00
Dmitry Sharshakov
0e51e5fbaf editor: support setExceptionBreakpoints 2021-09-26 10:24:58 +03:00
Dmitry Sharshakov
bf53aff27d Merge branch 'master' into debug 2021-09-25 23:14:59 +03:00
Dmitry Sharshakov
413e477dc2 lldb: use stdio transport by default 2021-09-06 13:49:31 +03:00
Dmitry Sharshakov
507a1f8dd6 Get breakpoint reports from debugger 2021-09-06 08:47:54 +03:00
Dmitry Sharshakov
c9cd06e904 Fetch stack traces for all threads when debugger sets all_thread_stopped flag 2021-09-05 16:09:38 +03:00
Dmitry Sharshakov
bdd636d8ee Clean up import 2021-09-05 15:21:39 +03:00
Dmitry Sharshakov
9b8c5bdade Remove redundant fetching of stack traces 2021-09-05 15:19:52 +03:00
Dmitry Sharshakov
0add0c5639 Make conditional logpoints underlined 2021-09-05 15:12:13 +03:00
Dmitry Sharshakov
2d35b7b99c Normalize line in picker preview to avoid crash 2021-09-05 14:31:16 +03:00
Dmitry Sharshakov
b6c58ea23e Support thread previews 2021-09-05 13:39:27 +03:00
Dmitry Sharshakov
bb26c589b4 Keybinding for editing log 2021-09-05 08:52:30 +03:00
Dmitry Sharshakov
0e1e4edc5e different display for conditional logpoints 2021-09-05 08:51:33 +03:00
Dmitry Sharshakov
8a609047c3 Mouse command for editing logpoint 2021-09-05 08:50:03 +03:00
Dmitry Sharshakov
7bdead5b4b Drop old commands
TODO: edit logpoints with a keybinding and mouse
2021-09-05 08:20:21 +03:00
Dmitry Sharshakov
3b0ec750ff Support editing breakpoint condition with right click 2021-09-05 08:14:17 +03:00
Dmitry Sharshakov
1befbd076c Add command for editing breakpoint condition 2021-09-04 22:57:58 +03:00
Dmitry Sharshakov
e36fc57fff refactor breakpoint edit 2021-09-04 22:18:42 +03:00
Dmitry Sharshakov
698583c241 Support setting breakpoints with mouse 2021-09-04 21:14:24 +03:00
Dmitry Sharshakov
df0ea6674a examples: ensure target stopped by waiting for enter from user 2021-09-04 19:36:36 +03:00
Dmitry Sharshakov
430c80ff2a Fix crash when trying to select (view) threads when debuggee is running 2021-09-04 10:28:11 +03:00
Dmitry Sharshakov
c6186ce600 jump to selected stack frame 2021-09-04 10:24:00 +03:00
Dmitry Sharshakov
cb31d20b46 mark thread as running when resumed 2021-09-04 10:22:29 +03:00
Dmitry Sharshakov
9a1916ebfd show thread states in thread picker 2021-09-04 10:14:04 +03:00
Dmitry Sharshakov
00cccdc62a Don't show thread picker for single-threaded targets 2021-09-04 09:19:19 +03:00
Dmitry Sharshakov
9939dbf119 Fix clippy warnings 2021-09-04 09:08:52 +03:00
Dmitry Sharshakov
cf7237d0b9 compat: make thread IDs signed
Delve needs it
2021-09-03 23:11:06 +03:00
Blaž Hrastnik
c63ad60c31 dap: Allow switching between stack frames 2021-09-03 17:25:11 +09:00
Blaž Hrastnik
7b61c63ece Handle stderr 2021-09-03 13:26:30 +09:00
Blaž Hrastnik
b997d2cdeb dap: Allow setting breakpoints before starting the adapter 2021-09-03 13:26:30 +09:00
Blaž Hrastnik
289303a30d dap: small TODO 2021-09-03 11:48:55 +09:00
Blaž Hrastnik
42f9718f55 dap: Extract thread_picker, make pause explicitly select a thread 2021-09-03 11:43:11 +09:00
Blaž Hrastnik
27c1b3f98b dap: Extract a thread_states map 2021-09-03 11:30:25 +09:00
Blaž Hrastnik
5b920c53f0 Refactor resume_application state handling 2021-09-03 11:11:22 +09:00
Blaž Hrastnik
4c410eef87 Merge remote-tracking branch 'origin/master' into debug 2021-09-03 11:03:34 +09:00
Dmitry Sharshakov
9c64650a26 force update of stack trace when stopped 2021-09-02 22:51:41 +03:00
Dmitry Sharshakov
2c89107349 Fix crash when stack trace not loaded
Still doesn't address the issue though
2021-09-02 19:58:03 +03:00
Dmitry Sharshakov
e0180a4b88 find main thread automatically if thread stopped is not known 2021-09-02 11:08:24 +03:00
Dmitry Sharshakov
5b20f6020a Merge remote-tracking branch 'origin/master' into debug
Contains type fix on helix-term/src/ui/editor.rs:752:13
2021-08-31 21:29:11 +03:00
Dmitry Sharshakov
6265e196b7 compat: change lldb to lldb-vscode
This should be preferred ID, although now lldb-vscode works with any
2021-08-30 16:09:41 +03:00
Blaž Hrastnik
0b0b1d850a dap: Stop comparing file paths per line number 2021-08-30 11:22:26 +09:00
Blaž Hrastnik
2c7b75475f dap: refactor frame handling 2021-08-30 11:07:59 +09:00
Blaž Hrastnik
986828e75c dap: Remap keys, match current thread behavior from dap-mode, switch-thread 2021-08-29 23:32:46 +09:00
Blaž Hrastnik
03b2d81406 dap: better yet, use Selection::single.. 2021-08-29 23:03:27 +09:00
Blaž Hrastnik
4d24a43651 dap: use smallvec! macro 2021-08-29 23:02:46 +09:00
Blaž Hrastnik
81f51c13fa dap: continued: THis check is already done before the match statement 2021-08-29 23:01:18 +09:00
Blaž Hrastnik
51328a4966 dap: extract dap_pos_to_pos 2021-08-29 22:59:29 +09:00
Blaž Hrastnik
d6ccc150c7 Extract dap commands into a separate file 2021-08-29 22:43:08 +09:00
Blaž Hrastnik
ee2ba744a2 Rename dap_in/_out to dap_step_in/_out 2021-08-29 22:37:21 +09:00
Blaž Hrastnik
2a7e38a2b4 helix-core doesn't need to import serde_json 2021-08-29 22:33:42 +09:00
Dmitry Sharshakov
db7f693550 More advanced completions 2021-08-29 14:55:42 +03:00
Dmitry Sharshakov
b42631942b Defaults in completions, better schema 2021-08-29 14:51:47 +03:00
Dmitry Sharshakov
f53d8411cb Add extra annotations to completions 2021-08-29 14:06:36 +03:00
Dmitry Sharshakov
98fda6b8f0 better completion 2021-08-29 13:16:57 +03:00
Dmitry Sharshakov
9d2f2a9e32 Support multiple arguments for debug configs 2021-08-29 13:06:22 +03:00
Dmitry Sharshakov
2d42766a71 wip: refactor parameters in UI start 2021-08-29 10:23:36 +03:00
Dmitry Sharshakov
af657ef2ec Fix lints 2021-08-28 19:15:13 +03:00
Dmitry Sharshakov
94901b8677 Customized completion for template parameters 2021-08-28 19:11:19 +03:00
Dmitry Sharshakov
ef155e62ef Add filename autocomplete to template args 2021-08-28 15:36:16 +03:00
Dmitry Sharshakov
e315394631 Merge remote-tracking branch 'origin/master' into debug 2021-08-28 14:59:26 +03:00
Dmitry Sharshakov
8df6739759 New way of starting debug sessions 2021-08-28 14:23:54 +03:00
Dmitry Sharshakov
5e4da09be2 Don't let picker be too narrow 2021-08-28 13:55:52 +03:00
Dmitry Sharshakov
890b51b568 Paginated variables 2021-08-28 10:13:19 +03:00
Dmitry Sharshakov
3b87fce0ce Print errors occurred in debug commands 2021-08-25 21:01:15 +03:00
Dmitry Sharshakov
2ad2838a27 Fix tests 2021-08-25 19:36:49 +03:00
Dmitry Sharshakov
c7759a5aa0 Merge remote-tracking branch 'origin/master' into debug 2021-08-25 19:22:01 +03:00
Dmitry Sharshakov
4ee66b8766 Support remote debug adapter 2021-08-25 19:14:47 +03:00
Dmitry Sharshakov
ba96f5d296 Format Cargo.toml 2021-08-25 08:40:53 +03:00
Dmitry Sharshakov
326293cb57 only show variables' names and types 2021-08-25 08:33:46 +03:00
Dmitry Sharshakov
2c3e2b979b Workaround for debugging Go tests 2021-08-24 21:28:51 +03:00
Dmitry Sharshakov
8cc6d68160 Autocomplete files for debug command 2021-08-24 20:38:49 +03:00
Dmitry Sharshakov
235a84d989 Remove shortcut for starting debug 2021-08-24 20:32:38 +03:00
Dmitry Sharshakov
299da5a35b Support attach request 2021-08-24 20:27:54 +03:00
Dmitry Sharshakov
b001008a69 Support templates in debug configurations 2021-08-24 20:04:14 +03:00
Dmitry Sharshakov
31212e133d Rename functions 2021-08-24 16:48:38 +03:00
Dmitry Sharshakov
1041a5bb07 Support launching configs by name 2021-08-24 12:21:00 +03:00
Dmitry Sharshakov
0e779381a8 Format 2021-08-24 12:01:58 +03:00
Dmitry Sharshakov
774ab6f8b6 Add new format configs for Rust and C/C++ 2021-08-24 12:01:05 +03:00
Dmitry Sharshakov
c463142e5e Create new debugger config format 2021-08-24 11:56:18 +03:00
Dmitry Sharshakov
34c6094604 refactor 2021-08-24 11:32:44 +03:00
Dmitry Sharshakov
2158366b24 Enable variable types in DAP config
We have this feature
2021-08-24 10:51:52 +03:00
Dmitry Sharshakov
fdad7d67aa Check capabilities for breakpoint config 2021-08-24 10:48:47 +03:00
Dmitry Sharshakov
c4085b4e88 Use saturating_sub for lenght 2021-08-24 08:54:32 +03:00
Dmitry Sharshakov
5d3c69d565 Support logpoints
Tested with Node (Delve and LLDB do not support logpoints)
2021-08-24 08:47:20 +03:00
Dmitry Sharshakov
ec599a1eac Do not panic if entered unknown code via stack trace
e.g. Rust std library
2021-08-23 21:25:58 +03:00
Dmitry Sharshakov
3a5e044c89 languages: support debug for Rust with LLDB 2021-08-23 21:11:45 +03:00
Dmitry Sharshakov
b3469df5bf add lldb for c++ 2021-08-23 20:52:16 +03:00
Dmitry Sharshakov
c09b15197b fix freeze with lldb terminated event 2021-08-23 20:38:17 +03:00
Dmitry Sharshakov
09c994a97a editor: drop telemetry output messages 2021-08-23 20:22:55 +03:00
Dmitry Sharshakov
b5b79e3656 types: make some fields optional as in spec 2021-08-23 20:22:21 +03:00
Dmitry Sharshakov
e529f4eb21 add lldb debugger for C 2021-08-23 18:12:28 +03:00
Dmitry Sharshakov
56d00fa7f4 Fix tests 2021-08-23 18:00:30 +03:00
Dmitry Sharshakov
802ef20dbc chore: bump helix-dap version to 0.4.1 2021-08-23 17:27:39 +03:00
Dmitry Sharshakov
b6b99b2487 config: minor fixes 2021-08-23 17:26:12 +03:00
Dmitry Sharshakov
839d210573 Enable stdio transport via config 2021-08-23 17:18:03 +03:00
Dmitry Sharshakov
f55a012fb7 editor: add debug session config 2021-08-23 16:56:41 +03:00
Dmitry Sharshakov
c5b210df59 Add debug-adapter field to languages.toml 2021-08-23 16:48:06 +03:00
Dmitry Sharshakov
dabec2d799 Fix line endings 2021-08-22 15:59:42 +03:00
Dmitry Sharshakov
b78f70e602 show breakpoint condition in diagnostics 2021-08-22 15:52:05 +03:00
Dmitry Sharshakov
53ee57f84a clippy 2021-08-22 15:16:59 +03:00
Dmitry Sharshakov
f247858055 Support conditional breakpoints 2021-08-22 15:06:27 +03:00
Dmitry Sharshakov
3197c2536e Add eval command 2021-08-22 14:44:16 +03:00
Dmitry Sharshakov
838f69929d Simplify variables display 2021-08-22 12:49:18 +03:00
Dmitry Sharshakov
060a422c7e fix crash when pausing 2021-08-22 12:26:36 +03:00
Dmitry Sharshakov
74102bfc6d examples: fix build 2021-08-22 12:13:43 +03:00
Dmitry Sharshakov
d0b0c9b2ef editor: select a range if stack pointer has an end 2021-08-22 12:06:43 +03:00
Dmitry Sharshakov
132198323c editor: go to pos where stack pointer is located 2021-08-22 11:56:22 +03:00
Dmitry Sharshakov
be9dc5802a editor: mark target as running when continued 2021-08-22 11:21:02 +03:00
Dmitry Sharshakov
d93cd2a261 editor: support stepIn, stepOut, next and pause commands 2021-08-22 11:16:11 +03:00
Dmitry Sharshakov
dfc70a12f3 dap: support stepIn, stepOut, next and pause commands 2021-08-22 11:02:54 +03:00
Blaž Hrastnik
28658836ee Add more event types, simplify event decoding 2021-08-22 16:05:12 +09:00
Dmitry Sharshakov
2aee5f02d0 Style 2021-08-22 09:52:37 +03:00
Dmitry Sharshakov
7233ab2deb Merge branch 'debug' of https://github.com/sh7dm/helix into debug 2021-08-22 09:47:22 +03:00
Blaž Hrastnik
a964cbae65 Extract handle_debugger_message, we should avoid bloating tokio::select! 2021-08-22 15:36:07 +09:00
Dmitry Sharshakov
91f2c60b36 Jump to stack pointer when stopped 2021-08-22 09:28:50 +03:00
Dmitry Sharshakov
89ad54a2e5 Add variable type to output 2021-08-22 08:31:01 +03:00
Dmitry Sharshakov
cc66475592 Add commands for variable introspection 2021-08-22 08:25:38 +03:00
Dmitry Sharshakov
95ba4ff5bd Hide stack pointer when continued 2021-08-21 21:00:18 +03:00
Dmitry Sharshakov
f3e47bfee4 Disable continuing when running 2021-08-21 20:55:45 +03:00
Dmitry Sharshakov
5230a2b669 Continue command in keymap 2021-08-21 20:44:14 +03:00
Dmitry Sharshakov
66c035fa99 Continue command 2021-08-21 20:42:13 +03:00
Dmitry Sharshakov
6709b4242f Drop and terminate debugger 2021-08-21 20:38:03 +03:00
Dmitry Sharshakov
26dee49dc9 Add command to detach debugger 2021-08-21 20:33:56 +03:00
Dmitry Sharshakov
462c8a6ec8 Show debugger output in the statusline 2021-08-21 20:29:01 +03:00
Dmitry Sharshakov
afeaba1113 add rx dispatcher to examples 2021-08-21 20:19:11 +03:00
Dmitry Sharshakov
5a06263b78 report status when target started or stopped 2021-08-21 20:08:37 +03:00
Dmitry Sharshakov
bcab93c94e Update editor window when stopped 2021-08-21 17:26:51 +03:00
Dmitry Sharshakov
a938f5a87a refactor: handle DAP events in editor main loop 2021-08-21 17:21:35 +03:00
Dmitry Sharshakov
3fc501c99f Correctly display 1-based breakpoints 2021-08-21 15:17:25 +03:00
Dmitry Sharshakov
7087558918 Don't leave debugged programs running 2021-08-21 15:14:29 +03:00
Dmitry Sharshakov
56bddb12f8 Highlight line number of stack pointer 2021-08-21 14:58:05 +03:00
Dmitry Sharshakov
5f5b383979 Fix clippy warnings 2021-08-21 14:35:53 +03:00
Dmitry Sharshakov
6458edecfd Add stack pointer display when stopped 2021-08-21 14:15:29 +03:00
Dmitry Sharshakov
738e8a4dd3 Unify init and launch commands 2021-08-20 19:11:37 +03:00
Dmitry Sharshakov
9e22842d51 move debug command to keybinding 2021-08-20 19:06:52 +03:00
Dmitry Sharshakov
e2c74d26e0 Add command to run debug target 2021-08-20 18:18:35 +03:00
Dmitry Sharshakov
c4970c617e make CI green 2021-08-20 16:48:59 +03:00
Blaž Hrastnik
a54b09e3fe dap: Split out launch from init 2021-08-20 14:06:55 +09:00
Blaž Hrastnik
94a1951d40 Work towards a breakpoint UI 2021-08-20 13:51:38 +09:00
Blaž Hrastnik
8759dc7e33 Add Default to some structs 2021-08-20 13:48:33 +09:00
Blaž Hrastnik
86102a651f wip 2021-08-20 13:48:33 +09:00
Blaž Hrastnik
2094ff1aaf Silence TCP client messages on stdout, log them in the future 2021-08-20 13:48:33 +09:00
Blaž Hrastnik
d39baa3b4e Start integrating into the editor's event loop 2021-08-20 13:48:32 +09:00
Blaž Hrastnik
0300dbdeb3 Avoid cloning a request on send 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
54dc2f8107 Fix example compilation 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
8fbda0abaf fix: Used the wrong type for variables 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
184abdc510 dap: Significantly simplify code using the Request trait 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
3a9e1c305b Refactor types, add a Request trait 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
2d1ae2e44b dap: Split types off into types.rs 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
6225401e84 A request always needs to have a response, per spec (the body can be empty) 2021-08-20 13:43:54 +09:00
Blaž Hrastnik
3f62799656 Get cargo check to pass in the subcrate 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
b9797a7dd2 client: support tcp_process transport 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
6c0f7eafc3 examples: continue handling output events 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
279db98d3c refactor: use tagged enum for handling DAP payloads 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
36fb8d1b1a examples: make examples identical 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
f92fb966c0 working lldb example 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
ae32159247 Revert "compat: don't wait for launch and attach response"
This reverts commit 766e3380622e2c7ddf5051ed672b78ece8d99f1f.

Not required for lldb-vscode
2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
4f2b8fb05a dap-dlv: rename from dap-go 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
2a6210806b dap-lldb: adjust breakpoint position 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
f5b1655eab format 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
e7f543fe66 format 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
eb0605c13d dap: create C example 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
809990a3a4 format 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
d4c215b35d compat: don't wait for launch and attach response
I could not get one from codelldb
2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
e388079a0b compat: add all possible debugger caps 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
43c9eba037 compat: remove missing caps
Only report present features now
2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
c5492788a2 compat: remove seq from Response and Event 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
cc650c7f4f types: capitalize ID in names
Part of LLDB integration
2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
b3be6b269a dap-basic: parse stop event 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
0777948fc0 dap-basic: better output formatting 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
09390be6a5 dap-basic: handle output events 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
c72475bc30 client: handle events multiple times 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
d6de5408b7 dispatch events in client 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
59d6b92e5b refactor response processing 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
9678df1c62 refactor server message handling 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
541f7a0514 Add attach command 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
aac586b546 types: simplify working with client's launch args 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
6bb653f820 dap: move launch request argumets outside of client 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
3d64cf8356 fix: move adapter_id out of DAP client 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
fabee03983 dap: support TCP clients 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
26a55dcefd dap: make transport IO-agnostic 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
e11b67b0db dap: add missing fields to structs 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
0fa127b105 dap: support getting scopes and variables 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
7d2d4ed4a8 dap: implement threads request 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
5f3e806341 dap-basic: pretty-print results 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
5fd0a2ddda format 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
fd709bc56d dap: logging using fern 2021-08-20 13:43:54 +09:00
Dmitry Sharshakov
0f6e81b85b Initial debug adapter protocol implementation 2021-08-20 13:43:54 +09:00
575 changed files with 47153 additions and 10761 deletions

3
.cargo/config Normal file
View File

@@ -0,0 +1,3 @@
[alias]
xtask = "run --package xtask --"
integration-test = "test --features integration --workspace --test integration"

1
.envrc
View File

@@ -3,3 +3,4 @@ watch_file flake.lock
# try to use flakes, if it fails use normal nix (ie. shell.nix)
use flake || use nix
eval "$shellHook"

11
.gitattributes vendored Normal file
View File

@@ -0,0 +1,11 @@
# Auto detect text files and perform normalization
* text=auto
*.rs text diff=rust
*.toml text diff=toml
*.scm text diff=scheme
*.md text diff=markdown
book/theme/highlight.js linguist-vendored
Cargo.lock text

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
open_collective: helix-editor

View File

@@ -1,28 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: C-bug
assignees: ''
---
<!-- Your issue may already be reported!
Please search on the issue tracker before creating one. -->
### Reproduction steps
<!-- Ideally provide a key sequence and/or asciinema.org recording. -->
### Environment
- Platform: <!-- macOS / Windows / Linux -->
- Helix version: <!-- 'hx -v' if using a release, 'git describe' if building from master -->
<details><summary>~/.cache/helix/helix.log</summary>
```
please provide a copy of `~/.cache/helix/helix.log` here if possible, you may need to redact some of the lines
```
</details>

67
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View File

@@ -0,0 +1,67 @@
name: Bug Report
description: Create a report to help us improve
labels: C-bug
body:
- type: markdown
attributes:
value: Thank you for filing a bug report! 🐛
- type: textarea
id: problem
attributes:
label: Summary
description: >
Please provide a short summary of the bug, along with any information
you feel relevant to replicate the bug.
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: Reproduction Steps
value: |
<!-- Ideally provide a key sequence and/or asciinema.org recording. -->
I tried this:
1. `hx`
I expected this to happen:
Instead, this happened:
- type: textarea
id: helix-log
attributes:
label: Helix log
description: See `hx -h` for log file path
value: |
<details><summary>~/.cache/helix/helix.log</summary>
```
please provide a copy of `~/.cache/helix/helix.log` here if possible, you may need to redact some of the lines
```
</details>
- type: input
id: platform
attributes:
label: Platform
placeholder: Linux / macOS / Windows
validations:
required: true
- type: input
id: terminal-emulator
attributes:
label: Terminal Emulator
placeholder: wezterm 20220101-133340-7edc5b5a
validations:
required: true
- type: input
id: helix-version
attributes:
label: Helix Version
description: >
Helix version (`hx -V` if using a release, `git describe` if building
from master)
placeholder: "helix 0.6.0 (c0dbd6dc)"
validations:
required: true

13
.github/ISSUE_TEMPLATE/enhancement.md vendored Normal file
View File

@@ -0,0 +1,13 @@
---
name: Enhancement
about: Suggest an improvement
title: ''
labels: C-enhancement
assignees: ''
---
<!--
Your enhancement may already be reported!
Please search on the issue tracker before creating a new issue.
If this is an idea for a feature, please open an "Idea" Discussion instead.
-->

View File

@@ -1,13 +0,0 @@
---
name: Feature request
about: Suggest a new feature or improvement
title: ''
labels: C-enhancement
assignees: ''
---
<!-- Your feature may already be reported!
Please search on the issue tracker before creating one. -->
#### Describe your feature request

View File

@@ -11,36 +11,24 @@ jobs:
check:
name: Check
runs-on: ubuntu-latest
strategy:
matrix:
rust: [stable, msrv]
steps:
- name: Checkout sources
uses: actions/checkout@v2
with:
submodules: true
uses: actions/checkout@v3
- name: Use MSRV rust toolchain
if: matrix.rust == 'msrv'
run: cp .github/workflows/msrv-rust-toolchain.toml rust-toolchain.toml
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
uses: helix-editor/rust-toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Cache cargo registry
uses: actions/cache@v2.1.6
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-v2-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v2.1.6
with:
path: ~/.cargo/git
key: ${{ runner.os }}-v2-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v2.1.6
with:
path: target
key: ${{ runner.os }}-v2-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- uses: Swatinem/rust-cache@v1
- name: Run cargo check
uses: actions-rs/cargo@v1
@@ -50,81 +38,58 @@ jobs:
test:
name: Test Suite
runs-on: ${{ matrix.os }}
env:
RUST_BACKTRACE: 1
HELIX_LOG_LEVEL: info
steps:
- name: Checkout sources
uses: actions/checkout@v2
with:
submodules: true
uses: actions/checkout@v3
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
uses: helix-editor/rust-toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
- name: Cache cargo registry
uses: actions/cache@v2.1.6
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-v2-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- uses: Swatinem/rust-cache@v1
- name: Cache cargo index
uses: actions/cache@v2.1.6
- name: Cache test tree-sitter grammar
uses: actions/cache@v3
with:
path: ~/.cargo/git
key: ${{ runner.os }}-v2-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v2.1.6
with:
path: target
key: ${{ runner.os }}-v2-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
path: runtime/grammars
key: ${{ runner.os }}-stable-v${{ env.CACHE_VERSION }}-tree-sitter-grammars-${{ hashFiles('languages.toml') }}
restore-keys: ${{ runner.os }}-stable-v${{ env.CACHE_VERSION }}-tree-sitter-grammars-
- name: Run cargo test
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Run cargo integration-test
uses: actions-rs/cargo@v1
with:
command: integration-test
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable]
lints:
name: Lints
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
with:
submodules: true
uses: actions/checkout@v3
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
uses: helix-editor/rust-toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Cache cargo registry
uses: actions/cache@v2.1.6
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-v2-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v2.1.6
with:
path: ~/.cargo/git
key: ${{ runner.os }}-v2-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
uses: actions/cache@v2.1.6
with:
path: target
key: ${{ runner.os }}-v2-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- uses: Swatinem/rust-cache@v1
- name: Run cargo fmt
uses: actions-rs/cargo@v1
@@ -136,4 +101,53 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
args: --all-targets -- -D warnings
docs:
name: Docs
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: helix-editor/rust-toolchain@v1
with:
profile: minimal
override: true
- uses: Swatinem/rust-cache@v1
- name: Generate docs
uses: actions-rs/cargo@v1
with:
command: xtask
args: docgen
- name: Check uncommitted documentation changes
run: |
git diff
git diff-files --quiet \
|| (echo "Run 'cargo xtask docgen', commit the changes and push again" \
&& exit 1)
queries:
name: Tree-sitter queries
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: helix-editor/rust-toolchain@v1
with:
profile: minimal
override: true
- uses: Swatinem/rust-cache@v1
- name: Generate docs
uses: actions-rs/cargo@v1
with:
command: xtask
args: query-check

26
.github/workflows/cachix.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
# Publish the Nix flake outputs to Cachix
name: Cachix
on:
push:
branches:
- master
jobs:
publish:
name: Publish Flake
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install nix
uses: cachix/install-nix-action@v17
- name: Authenticate with Cachix
uses: cachix/cachix-action@v10
with:
name: helix
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Build nix flake
run: nix build

View File

@@ -4,12 +4,14 @@ on:
push:
branches:
- master
tags:
- '*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
@@ -18,10 +20,22 @@ jobs:
# mdbook-version: '0.4.8'
- run: mdbook build book
- name: Set output directory
run: |
OUTDIR=$(basename ${{ github.ref }})
echo "OUTDIR=$OUTDIR" >> $GITHUB_ENV
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/master'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./book/book
destination_dir: ./${{ env.OUTDIR }}
- name: Deploy stable
uses: peaceiris/actions-gh-pages@v3
if: startswith(github.ref, 'refs/tags/')
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./book/book

26
.github/workflows/languages.toml vendored Normal file
View File

@@ -0,0 +1,26 @@
# This languages.toml is used for testing in CI.
[[language]]
name = "rust"
scope = "source.rust"
injection-regex = "rust"
file-types = ["rs"]
comment-token = "//"
roots = ["Cargo.toml", "Cargo.lock"]
indent = { tab-width = 4, unit = " " }
[[grammar]]
name = "rust"
source = { git = "https://github.com/tree-sitter/tree-sitter-rust", rev = "a360da0a29a19c281d08295a35ecd0544d2da211" }
[[language]]
name = "nix"
scope = "source.nix"
injection-regex = "nix"
file-types = ["nix"]
shebangs = []
roots = []
comment-token = "#"
# A grammar entry is not necessary for this language - it is only used for
# testing TOML merging behavior.

View File

@@ -0,0 +1,3 @@
[toolchain]
channel = "1.57.0"
components = ["rustfmt", "rust-src"]

View File

@@ -1,32 +1,59 @@
name: Release
on:
# schedule:
# - cron: '0 0 * * *' # midnight UTC
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
## - release
- '[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+'
jobs:
fetch-grammars:
name: Fetch Grammars
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: helix-editor/rust-toolchain@v1
with:
profile: minimal
override: true
- uses: Swatinem/rust-cache@v1
- name: Fetch tree-sitter grammars
uses: actions-rs/cargo@v1
with:
command: run
args: --package=helix-loader --bin=hx-loader
- name: Bundle grammars
run: tar cJf grammars.tar.xz -C runtime/grammars/sources .
- uses: actions/upload-artifact@v3
with:
name: grammars
path: grammars.tar.xz
dist:
name: Dist
needs: [fetch-grammars]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # don't fail other jobs if one fails
matrix:
build: [x86_64-linux, aarch64-linux, x86_64-macos, x86_64-windows] #, x86_64-win-gnu, win32-msvc
build: [x86_64-linux, x86_64-macos, x86_64-windows] #, x86_64-win-gnu, win32-msvc
include:
- build: x86_64-linux
os: ubuntu-20.04
rust: stable
target: x86_64-unknown-linux-gnu
cross: false
- build: aarch64-linux
os: ubuntu-20.04
rust: stable
target: aarch64-unknown-linux-gnu
cross: true
# - build: aarch64-linux
# os: ubuntu-20.04
# rust: stable
# target: aarch64-unknown-linux-gnu
# cross: true
- build: x86_64-macos
os: macos-latest
rust: stable
@@ -37,10 +64,12 @@ jobs:
rust: stable
target: x86_64-pc-windows-msvc
cross: false
# - build: aarch64-macos
# os: macos-latest
# rust: stable
# target: aarch64-apple-darwin
- build: aarch64-macos
os: macos-latest
rust: stable
target: aarch64-apple-darwin
cross: false
skip_tests: true # x86_64 host can't run aarch64 code
# - build: x86_64-win-gnu
# os: windows-2019
# rust: stable-x86_64-gnu
@@ -52,9 +81,16 @@ jobs:
steps:
- name: Checkout sources
uses: actions/checkout@v2
with:
submodules: true
uses: actions/checkout@v3
- name: Download grammars
uses: actions/download-artifact@v3
- name: Move grammars under runtime
if: "!startsWith(matrix.os, 'windows')"
run: |
mkdir -p runtime/grammars/sources
tar xJf grammars/grammars.tar.xz -C runtime/grammars/sources
- name: Install ${{ matrix.rust }} toolchain
uses: actions-rs/toolchain@v1
@@ -66,10 +102,11 @@ jobs:
- name: Run cargo test
uses: actions-rs/cargo@v1
if: "!matrix.skip_tests"
with:
use-cross: ${{ matrix.cross }}
command: test
args: --release --locked --target ${{ matrix.target }}
args: --release --locked --target ${{ matrix.target }} --workspace
- name: Build release binary
uses: actions-rs/cargo@v1
@@ -79,7 +116,7 @@ jobs:
args: --release --locked --target ${{ matrix.target }}
- name: Strip release binary (linux and macos)
if: matrix.build == 'x86_64-linux' || matrix.build == 'x86_64-macos'
if: matrix.build == 'x86_64-linux' || endsWith(matrix.build, 'macos')
run: strip "target/${{ matrix.target }}/release/hx"
- name: Strip release binary (arm)
@@ -91,18 +128,63 @@ jobs:
aarch64-linux-gnu-strip \
/target/${{ matrix.target }}/release/hx
- name: Build AppImage
shell: bash
if: matrix.build == 'x86_64-linux'
run: |
mkdir dist
name=dev
if [[ $GITHUB_REF == refs/tags/* ]]; then
name=${GITHUB_REF:10}
fi
export VERSION="$name"
export ARCH=x86_64
export APP=helix
export OUTPUT="helix-$VERSION-$ARCH.AppImage"
export UPDATE_INFORMATION="gh-releases-zsync|$GITHUB_REPOSITORY_OWNER|helix|latest|$APP-*-$ARCH.AppImage.zsync"
mkdir -p "$APP.AppDir"/usr/{bin,lib/helix}
cp "target/${{ matrix.target }}/release/hx" "$APP.AppDir/usr/bin/hx"
rm -rf runtime/grammars/sources
cp -r runtime "$APP.AppDir/usr/lib/helix/runtime"
cat << 'EOF' > "$APP.AppDir/AppRun"
#!/bin/sh
APPDIR="$(dirname "$(readlink -f "${0}")")"
HELIX_RUNTIME="$APPDIR/usr/lib/helix/runtime" exec "$APPDIR/usr/bin/hx" "$@"
EOF
chmod 755 "$APP.AppDir/AppRun"
curl -Lo linuxdeploy-x86_64.AppImage \
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage
./linuxdeploy-x86_64.AppImage \
--appdir "$APP.AppDir" -d contrib/Helix.desktop \
-i contrib/helix.png --output appimage
mv "$APP-$VERSION-$ARCH.AppImage" \
"$APP-$VERSION-$ARCH.AppImage.zsync" dist
- name: Build archive
shell: bash
run: |
mkdir dist
mkdir -p dist
if [ "${{ matrix.os }}" = "windows-2019" ]; then
cp "target/${{ matrix.target }}/release/hx.exe" "dist/"
else
cp "target/${{ matrix.target }}/release/hx" "dist/"
fi
if [ -d runtime/grammars/sources ]; then
rm -rf runtime/grammars/sources
fi
cp -r runtime dist
- uses: actions/upload-artifact@v2.2.4
- uses: actions/upload-artifact@v3
with:
name: bins-${{ matrix.build }}
path: dist
@@ -113,20 +195,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
with:
submodules: false
uses: actions/checkout@v3
- uses: actions/download-artifact@v2
# with:
# path: dist
# - run: ls -al ./dist
- run: ls -al bins-*
- uses: actions/download-artifact@v3
- name: Calculate tag name
run: |
name=dev
if [[ $GITHUB_REF == refs/tags/v* ]]; then
if [[ $GITHUB_REF == refs/tags/* ]]; then
name=${GITHUB_REF:10}
fi
echo ::set-output name=val::$name
@@ -138,8 +214,13 @@ jobs:
run: |
set -ex
rm -rf tmp
mkdir tmp
source="$(pwd)"
mkdir -p runtime/grammars/sources
tar xJf grammars/grammars.tar.xz -C runtime/grammars/sources
rm -rf grammars
cd "$(mktemp -d)"
mv $source/bins-* .
mkdir dist
for dir in bins-* ; do
@@ -148,19 +229,28 @@ jobs:
exe=".exe"
fi
pkgname=helix-$TAG-$platform
mkdir tmp/$pkgname
cp LICENSE README.md tmp/$pkgname
mv bins-$platform/runtime tmp/$pkgname/
mv bins-$platform/hx$exe tmp/$pkgname
chmod +x tmp/$pkgname/hx$exe
mkdir $pkgname
cp $source/LICENSE $source/README.md $pkgname
mkdir $pkgname/contrib
cp -r $source/contrib/completion $pkgname/contrib
mv bins-$platform/runtime $pkgname/
mv bins-$platform/hx$exe $pkgname
chmod +x $pkgname/hx$exe
if [[ "$platform" = "x86_64-linux" ]]; then
mv bins-$platform/helix-*.AppImage* dist/
fi
if [ "$exe" = "" ]; then
tar cJf dist/$pkgname.tar.xz -C tmp $pkgname
tar cJf dist/$pkgname.tar.xz $pkgname
else
(cd tmp && 7z a -r ../dist/$pkgname.zip $pkgname)
7z a -r dist/$pkgname.zip $pkgname
fi
done
tar cJf dist/helix-$TAG-source.tar.xz -C $source .
mv dist $source/
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:

1
.gitignore vendored
View File

@@ -1,6 +1,5 @@
target
.direnv
helix-term/rustfmt.toml
helix-syntax/languages/
result
runtime/grammars

136
.gitmodules vendored
View File

@@ -1,136 +0,0 @@
[submodule "helix-syntax/languages/tree-sitter-cpp"]
path = helix-syntax/languages/tree-sitter-cpp
url = https://github.com/tree-sitter/tree-sitter-cpp
shallow = true
[submodule "helix-syntax/languages/tree-sitter-javascript"]
path = helix-syntax/languages/tree-sitter-javascript
url = https://github.com/tree-sitter/tree-sitter-javascript
shallow = true
[submodule "helix-syntax/languages/tree-sitter-julia"]
path = helix-syntax/languages/tree-sitter-julia
url = https://github.com/tree-sitter/tree-sitter-julia
shallow = true
[submodule "helix-syntax/languages/tree-sitter-python"]
path = helix-syntax/languages/tree-sitter-python
url = https://github.com/tree-sitter/tree-sitter-python
shallow = true
[submodule "helix-syntax/languages/tree-sitter-typescript"]
path = helix-syntax/languages/tree-sitter-typescript
url = https://github.com/tree-sitter/tree-sitter-typescript
shallow = true
[submodule "helix-syntax/languages/tree-sitter-agda"]
path = helix-syntax/languages/tree-sitter-agda
url = https://github.com/tree-sitter/tree-sitter-agda
shallow = true
[submodule "helix-syntax/languages/tree-sitter-go"]
path = helix-syntax/languages/tree-sitter-go
url = https://github.com/tree-sitter/tree-sitter-go
shallow = true
[submodule "helix-syntax/languages/tree-sitter-ruby"]
path = helix-syntax/languages/tree-sitter-ruby
url = https://github.com/tree-sitter/tree-sitter-ruby
shallow = true
[submodule "helix-syntax/languages/tree-sitter-java"]
path = helix-syntax/languages/tree-sitter-java
url = https://github.com/tree-sitter/tree-sitter-java
shallow = true
[submodule "helix-syntax/languages/tree-sitter-php"]
path = helix-syntax/languages/tree-sitter-php
url = https://github.com/tree-sitter/tree-sitter-php
shallow = true
[submodule "helix-syntax/languages/tree-sitter-html"]
path = helix-syntax/languages/tree-sitter-html
url = https://github.com/tree-sitter/tree-sitter-html
shallow = true
[submodule "helix-syntax/languages/tree-sitter-scala"]
path = helix-syntax/languages/tree-sitter-scala
url = https://github.com/tree-sitter/tree-sitter-scala
shallow = true
[submodule "helix-syntax/languages/tree-sitter-bash"]
path = helix-syntax/languages/tree-sitter-bash
url = https://github.com/tree-sitter/tree-sitter-bash
shallow = true
[submodule "helix-syntax/languages/tree-sitter-rust"]
path = helix-syntax/languages/tree-sitter-rust
url = https://github.com/tree-sitter/tree-sitter-rust
shallow = true
[submodule "helix-syntax/languages/tree-sitter-json"]
path = helix-syntax/languages/tree-sitter-json
url = https://github.com/tree-sitter/tree-sitter-json
shallow = true
[submodule "helix-syntax/languages/tree-sitter-css"]
path = helix-syntax/languages/tree-sitter-css
url = https://github.com/tree-sitter/tree-sitter-css
shallow = true
[submodule "helix-syntax/languages/tree-sitter-c-sharp"]
path = helix-syntax/languages/tree-sitter-c-sharp
url = https://github.com/tree-sitter/tree-sitter-c-sharp
shallow = true
[submodule "helix-syntax/languages/tree-sitter-c"]
path = helix-syntax/languages/tree-sitter-c
url = https://github.com/tree-sitter/tree-sitter-c
shallow = true
[submodule "helix-syntax/languages/tree-sitter-haskell"]
path = helix-syntax/languages/tree-sitter-haskell
url = https://github.com/tree-sitter/tree-sitter-haskell
shallow = true
[submodule "helix-syntax/languages/tree-sitter-swift"]
path = helix-syntax/languages/tree-sitter-swift
url = https://github.com/tree-sitter/tree-sitter-swift
shallow = true
[submodule "helix-syntax/languages/tree-sitter-toml"]
path = helix-syntax/languages/tree-sitter-toml
url = https://github.com/ikatyang/tree-sitter-toml
shallow = true
[submodule "helix-syntax/languages/tree-sitter-elixir"]
path = helix-syntax/languages/tree-sitter-elixir
url = https://github.com/elixir-lang/tree-sitter-elixir
shallow = true
[submodule "helix-syntax/languages/tree-sitter-nix"]
path = helix-syntax/languages/tree-sitter-nix
url = https://github.com/cstrahan/tree-sitter-nix
shallow = true
[submodule "helix-syntax/languages/tree-sitter-latex"]
path = helix-syntax/languages/tree-sitter-latex
url = https://github.com/latex-lsp/tree-sitter-latex
shallow = true
[submodule "helix-syntax/languages/tree-sitter-ledger"]
path = helix-syntax/languages/tree-sitter-ledger
url = https://github.com/cbarrete/tree-sitter-ledger
shallow = true
[submodule "helix-syntax/languages/tree-sitter-protobuf"]
path = helix-syntax/languages/tree-sitter-protobuf
url = https://github.com/yusdacra/tree-sitter-protobuf.git
shallow = true
[submodule "helix-syntax/languages/tree-sitter-ocaml"]
path = helix-syntax/languages/tree-sitter-ocaml
url = https://github.com/tree-sitter/tree-sitter-ocaml
shallow = true
[submodule "helix-syntax/languages/tree-sitter-lua"]
path = helix-syntax/languages/tree-sitter-lua
url = https://github.com/nvim-treesitter/tree-sitter-lua
shallow = true
[submodule "helix-syntax/languages/tree-sitter-yaml"]
path = helix-syntax/languages/tree-sitter-yaml
url = https://github.com/ikatyang/tree-sitter-yaml
shallow = true
[submodule "helix-syntax/languages/tree-sitter-zig"]
path = helix-syntax/languages/tree-sitter-zig
url = https://github.com/maxxnino/tree-sitter-zig
shallow = true
[submodule "helix-syntax/languages/tree-sitter-svelte"]
path = helix-syntax/languages/tree-sitter-svelte
url = https://github.com/Himujjal/tree-sitter-svelte
shallow = true
[submodule "helix-syntax/languages/tree-sitter-vue"]
path = helix-syntax/languages/tree-sitter-vue
url = https://github.com/ikatyang/tree-sitter-vue
shallow = true
[submodule "helix-syntax/languages/tree-sitter-tsq"]
path = helix-syntax/languages/tree-sitter-tsq
url = https://github.com/tree-sitter/tree-sitter-tsq
shallow = true
[submodule "helix-syntax/languages/tree-sitter-cmake"]
path = helix-syntax/languages/tree-sitter-cmake
url = https://github.com/uyha/tree-sitter-cmake
shallow = true

5
.ignore Normal file
View File

@@ -0,0 +1,5 @@
# Things that we don't want ripgrep to search that we do want in git
# https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#automatic-filtering
# Minified JS vendored from mdbook
book/theme/highlight.js

View File

@@ -1,5 +1,741 @@
# 22.08.1 (2022-09-01)
# 0.5.0 (2021-11-28)
This is a patch release that fixes a panic caused by closing splits or buffers. ([#3633](https://github.com/helix-editor/helix/pull/3633))
# 22.08 (2022-08-31)
A big _thank you_ to our contributors! This release had 87 contributors.
As usual, the following is a summary of each of the changes since the last release.
For the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.05..22.08).
Breaking changes:
- Special keymap names for `+`, `;` and `%` have been replaced with those literal characters ([#2677](https://github.com/helix-editor/helix/pull/2677), [#3556](https://github.com/helix-editor/helix/pull/3556))
- `A-Left` and `A-Right` have become `C-Left` and `C-Right` for word-wise motion ([#2500](https://github.com/helix-editor/helix/pull/2500))
- The `catppuccin` theme's name has been corrected from `catpuccin` ([#2713](https://github.com/helix-editor/helix/pull/2713))
- `catppuccin` has been replaced by its variants, `catppuccin_frappe`, `catppuccin_latte`, `catppuccin_macchiato`, `catppuccin_mocha` ([#3281](https://github.com/helix-editor/helix/pull/3281))
- `C-n` and `C-p` have been removed from the default insert mode keymap ([#3340](https://github.com/helix-editor/helix/pull/3340))
- The `extend_line` command has been replaced with `extend_line_below` and a new `extend_line` command now exists ([#3046](https://github.com/helix-editor/helix/pull/3046))
Features:
- Add an integration testing harness ([#2359](https://github.com/helix-editor/helix/pull/2359))
- Indent guides ([#1796](https://github.com/helix-editor/helix/pull/1796), [906259c](https://github.com/helix-editor/helix/commit/906259c))
- Cursorline ([#2170](https://github.com/helix-editor/helix/pull/2170), [fde9e03](https://github.com/helix-editor/helix/commit/fde9e03))
- Select all instances of the symbol under the cursor (`<space>h`) ([#2738](https://github.com/helix-editor/helix/pull/2738))
- A picker for document and workspace LSP diagnostics (`<space>g`/`<space>G`) ([#2013](https://github.com/helix-editor/helix/pull/2013), [#2984](https://github.com/helix-editor/helix/pull/2984))
- Allow styling the mode indicator per-mode ([#2676](https://github.com/helix-editor/helix/pull/2676))
- Live preview for the theme picker ([#1798](https://github.com/helix-editor/helix/pull/1798))
- Configurable statusline ([#2434](https://github.com/helix-editor/helix/pull/2434))
- LSP SignatureHelp ([#1755](https://github.com/helix-editor/helix/pull/1755), [a8b123f](https://github.com/helix-editor/helix/commit/a8b123f))
- A picker for the jumplist ([#3033](https://github.com/helix-editor/helix/pull/3033))
- Configurable external formatter binaries ([#2942](https://github.com/helix-editor/helix/pull/2942))
- Bracketed paste support ([#3233](https://github.com/helix-editor/helix/pull/3233), [12ddd03](https://github.com/helix-editor/helix/commit/12ddd03))
Commands:
- `:insert-output` and `:append-output` which insert/append output from a shell command ([#2589](https://github.com/helix-editor/helix/pull/2589))
- The `t` textobject (`]t`/`[t`/`mit`/`mat`) for navigating tests ([#2807](https://github.com/helix-editor/helix/pull/2807))
- `C-Backspace` and `C-Delete` for word-wise deletion in prompts and pickers ([#2500](https://github.com/helix-editor/helix/pull/2500))
- `A-Delete` for forward word-wise deletion in insert mode ([#2500](https://github.com/helix-editor/helix/pull/2500))
- `C-t` for toggling the preview pane in pickers ([#3021](https://github.com/helix-editor/helix/pull/3021))
- `extend_line` now extends in the direction of the cursor ([#3046](https://github.com/helix-editor/helix/pull/3046))
Usability improvements and fixes:
- Fix tree-sitter parser builds on illumos ([#2602](https://github.com/helix-editor/helix/pull/2602))
- Remove empty stratch buffer from jumplists when removing ([5ed6223](https://github.com/helix-editor/helix/commit/5ed6223))
- Fix panic on undo after `shell_append_output` ([#2625](https://github.com/helix-editor/helix/pull/2625))
- Sort LSP edits by start range ([3d91c99](https://github.com/helix-editor/helix/commit/3d91c99))
- Be more defensive about LSP URI conversions ([6de6a3e](https://github.com/helix-editor/helix/commit/6de6a3e), [378f438](https://github.com/helix-editor/helix/commit/378f438))
- Ignore SendErrors when grammar builds fail ([#2641](https://github.com/helix-editor/helix/pull/2641))
- Append `set_line_ending` to document history ([#2649](https://github.com/helix-editor/helix/pull/2649))
- Use last prompt entry when empty ([b14c258](https://github.com/helix-editor/helix/commit/b14c258), [#2870](https://github.com/helix-editor/helix/pull/2870))
- Do not add extra line breaks in markdown lists ([#2689](https://github.com/helix-editor/helix/pull/2689))
- Disable dialyzer by default for ElixirLS ([#2710](https://github.com/helix-editor/helix/pull/2710))
- Refactor textobject node capture ([#2741](https://github.com/helix-editor/helix/pull/2741))
- Prevent re-selecting the same range with `expand_selection` ([#2760](https://github.com/helix-editor/helix/pull/2760))
- Introduce `keyword.storage` highlight scope ([#2731](https://github.com/helix-editor/helix/pull/2731))
- Handle symlinks more consistently ([#2718](https://github.com/helix-editor/helix/pull/2718))
- Improve markdown list rendering ([#2687](https://github.com/helix-editor/helix/pull/2687))
- Update auto-pairs and idle-timout settings when the config is reloaded ([#2736](https://github.com/helix-editor/helix/pull/2736))
- Fix panic on closing last buffer ([#2658](https://github.com/helix-editor/helix/pull/2658))
- Prevent modifying jumplist until jumping to a reference ([#2670](https://github.com/helix-editor/helix/pull/2670))
- Ensure `:quit` and `:quit!` take no arguments ([#2654](https://github.com/helix-editor/helix/pull/2654))
- Fix crash due to cycles when replaying macros ([#2647](https://github.com/helix-editor/helix/pull/2647))
- Pass LSP FormattingOptions ([#2635](https://github.com/helix-editor/helix/pull/2635))
- Prevent showing colors when the health-check is piped ([#2836](https://github.com/helix-editor/helix/pull/2836))
- Use character indexing for mouse selection ([#2839](https://github.com/helix-editor/helix/pull/2839))
- Display the highest severity diagnostic for a line in the gutter ([#2835](https://github.com/helix-editor/helix/pull/2835))
- Default the ruler color to red background ([#2669](https://github.com/helix-editor/helix/pull/2669))
- Make `move_vertically` aware of tabs and wide characters ([#2620](https://github.com/helix-editor/helix/pull/2620))
- Enable shellwords for Windows ([#2767](https://github.com/helix-editor/helix/pull/2767))
- Add history suggestions to global search ([#2717](https://github.com/helix-editor/helix/pull/2717))
- Fix the scrollbar's length proportional to total menu items ([#2860](https://github.com/helix-editor/helix/pull/2860))
- Reset terminal modifiers for diagnostic text ([#2861](https://github.com/helix-editor/helix/pull/2861), [#2900](https://github.com/helix-editor/helix/pull/2900))
- Redetect indents and line-endings after a Language Server replaces the document ([#2778](https://github.com/helix-editor/helix/pull/2778))
- Check selection's visible width when copying on mouse click ([#2711](https://github.com/helix-editor/helix/pull/2711))
- Fix edge-case in tree-sitter `expand_selection` command ([#2877](https://github.com/helix-editor/helix/pull/2877))
- Add a single-width left margin for the completion popup ([#2728](https://github.com/helix-editor/helix/pull/2728))
- Right-align the scrollbar in the completion popup ([#2754](https://github.com/helix-editor/helix/pull/2754))
- Fix recursive macro crash and empty macro lockout ([#2902](https://github.com/helix-editor/helix/pull/2902))
- Fix backwards character deletion on other whitespaces ([#2855](https://github.com/helix-editor/helix/pull/2855))
- Add search and space/backspace bindings to view modes ([#2803](https://github.com/helix-editor/helix/pull/2803))
- Add `--vsplit` and `--hsplit` CLI arguments for opening in splits ([#2773](https://github.com/helix-editor/helix/pull/2773), [#3073](https://github.com/helix-editor/helix/pull/3073))
- Sort themes, languages and files inputs by score and name ([#2675](https://github.com/helix-editor/helix/pull/2675))
- Highlight entire rows in ([#2939](https://github.com/helix-editor/helix/pull/2939))
- Fix backwards selection duplication widening bug ([#2945](https://github.com/helix-editor/helix/pull/2945), [#3024](https://github.com/helix-editor/helix/pull/3024))
- Skip serializing Option type DAP fields ([44f5963](https://github.com/helix-editor/helix/commit/44f5963))
- Fix required `cwd` field in DAP `RunTerminalArguments` type ([85411be](https://github.com/helix-editor/helix/commit/85411be), [#3240](https://github.com/helix-editor/helix/pull/3240))
- Add LSP `workspace/applyEdit` to client capabilities ([#3012](https://github.com/helix-editor/helix/pull/3012))
- Respect count for repeating motion ([#3057](https://github.com/helix-editor/helix/pull/3057))
- Respect count for selecting next/previous match ([#3056](https://github.com/helix-editor/helix/pull/3056))
- Respect count for tree-sitter motions ([#3058](https://github.com/helix-editor/helix/pull/3058))
- Make gutters padding optional ([#2996](https://github.com/helix-editor/helix/pull/2996))
- Support pre-filling prompts ([#2459](https://github.com/helix-editor/helix/pull/2459), [#3259](https://github.com/helix-editor/helix/pull/3259))
- Add statusline element to display file line-endings ([#3113](https://github.com/helix-editor/helix/pull/3113))
- Keep jump and file history when using `:split` ([#3031](https://github.com/helix-editor/helix/pull/3031), [#3160](https://github.com/helix-editor/helix/pull/3160))
- Make tree-sitter query `; inherits <language>` feature imperative ([#2470](https://github.com/helix-editor/helix/pull/2470))
- Indent with tabs by default ([#3095](https://github.com/helix-editor/helix/pull/3095))
- Fix non-msvc grammar compilation on Windows ([#3190](https://github.com/helix-editor/helix/pull/3190))
- Add spacer element to the statusline ([#3165](https://github.com/helix-editor/helix/pull/3165), [255c173](https://github.com/helix-editor/helix/commit/255c173))
- Make gutters padding automatic ([#3163](https://github.com/helix-editor/helix/pull/3163))
- Add `code` for LSP `Diagnostic` type ([#3096](https://github.com/helix-editor/helix/pull/3096))
- Add position percentage to the statusline ([#3168](https://github.com/helix-editor/helix/pull/3168))
- Add a configurable and themable statusline separator string ([#3175](https://github.com/helix-editor/helix/pull/3175))
- Use OR of all selections when `search_selection` acts on multiple selections ([#3138](https://github.com/helix-editor/helix/pull/3138))
- Add clipboard information to logs and the healthcheck ([#3271](https://github.com/helix-editor/helix/pull/3271))
- Fix align selection behavior on tabs ([#3276](https://github.com/helix-editor/helix/pull/3276))
- Fix terminal cursor shape reset ([#3289](https://github.com/helix-editor/helix/pull/3289))
- Add an `injection.include-unnamed-children` predicate to injections queries ([#3129](https://github.com/helix-editor/helix/pull/3129))
- Add a `-c`/`--config` CLI flag for specifying config file location ([#2666](https://github.com/helix-editor/helix/pull/2666))
- Detect indent-style in `:set-language` command ([#3330](https://github.com/helix-editor/helix/pull/3330))
- Fix non-deterministic highlighting ([#3275](https://github.com/helix-editor/helix/pull/3275))
- Avoid setting the stdin handle when not necessary ([#3248](https://github.com/helix-editor/helix/pull/3248), [#3379](https://github.com/helix-editor/helix/pull/3379))
- Fix indent guide styling ([#3324](https://github.com/helix-editor/helix/pull/3324))
- Fix tab highlight when tab is partially visible ([#3313](https://github.com/helix-editor/helix/pull/3313))
- Add completion for nested settings ([#3183](https://github.com/helix-editor/helix/pull/3183))
- Advertise WorkspaceSymbolClientCapabilities LSP client capability ([#3361](https://github.com/helix-editor/helix/pull/3361))
- Remove duplicate entries from the theme picker ([#3439](https://github.com/helix-editor/helix/pull/3439))
- Shorted output for grammar fetching and building ([#3396](https://github.com/helix-editor/helix/pull/3396))
- Add a `tabpad` option for visible tab padding whitespace characters ([#3458](https://github.com/helix-editor/helix/pull/3458))
- Make DAP external terminal provider configurable ([cb7615e](https://github.com/helix-editor/helix/commit/cb7615e))
- Use health checkmark character with shorter width ([#3505](https://github.com/helix-editor/helix/pull/3505))
- Reset document mode to normal on view focus loss ([e4c9d40](https://github.com/helix-editor/helix/commit/e4c9d40))
- Render indented code-blocks in markdown ([#3503](https://github.com/helix-editor/helix/pull/3503))
- Add WezTerm to DAP terminal provider defaults ([#3588](https://github.com/helix-editor/helix/pull/3588))
- Derive `Document` language name from `languages.toml` `name` key ([#3338](https://github.com/helix-editor/helix/pull/3338))
- Fix process spawning error handling ([#3349](https://github.com/helix-editor/helix/pull/3349))
- Don't resolve links for `:o` completion ([8a4fbf6](https://github.com/helix-editor/helix/commit/8a4fbf6))
- Recalculate completion after pasting into prompt ([e77b7d1](https://github.com/helix-editor/helix/commit/e77b7d1))
- Fix extra selections with regex anchors ([#3598](https://github.com/helix-editor/helix/pull/3598))
- Move mode transition logic to `handle_keymap_event` ([#2634](https://github.com/helix-editor/helix/pull/2634))
- Add documents to view history when using the jumplist ([#3593](https://github.com/helix-editor/helix/pull/3593))
- Prevent panic when loading tree-sitter queries ([fa1dc7e](https://github.com/helix-editor/helix/commit/fa1dc7e))
- Discard LSP publishDiagnostic when LS is not initialized ([#3403](https://github.com/helix-editor/helix/pull/3403))
- Refactor tree-sitter textobject motions as repeatable motions ([#3264](https://github.com/helix-editor/helix/pull/3264))
- Avoid command execution hooks on closed docs ([#3613](https://github.com/helix-editor/helix/pull/3613))
- Share `restore_term` code between panic and normal exits ([#2612](https://github.com/helix-editor/helix/pull/2612))
- Show clipboard info in `--health` output ([#2947](https://github.com/helix-editor/helix/pull/2947))
- Recalculate completion when going through prompt history ([#3193](https://github.com/helix-editor/helix/pull/3193))
Themes:
- Update `tokyonight` and `tokyonight_storm` themes ([#2606](https://github.com/helix-editor/helix/pull/2606))
- Update `solarized_light` themes ([#2626](https://github.com/helix-editor/helix/pull/2626))
- Fix `catpuccin` `ui.popup` theme ([#2644](https://github.com/helix-editor/helix/pull/2644))
- Update selection style of `night_owl` ([#2668](https://github.com/helix-editor/helix/pull/2668))
- Fix spelling of `catppuccin` theme ([#2713](https://github.com/helix-editor/helix/pull/2713))
- Update `base16_default`'s `ui.menu` ([#2794](https://github.com/helix-editor/helix/pull/2794))
- Add `noctis_bordo` ([#2830](https://github.com/helix-editor/helix/pull/2830))
- Add `acme` ([#2876](https://github.com/helix-editor/helix/pull/2876))
- Add `meliora` ([#2884](https://github.com/helix-editor/helix/pull/2884), [#2890](https://github.com/helix-editor/helix/pull/2890))
- Add cursorline scopes to various themes ([33d287a](https://github.com/helix-editor/helix/commit/33d287a), [#2892](https://github.com/helix-editor/helix/pull/2892), [#2915](https://github.com/helix-editor/helix/pull/2915), [#2916](https://github.com/helix-editor/helix/pull/2916), [#2918](https://github.com/helix-editor/helix/pull/2918), [#2927](https://github.com/helix-editor/helix/pull/2927), [#2925](https://github.com/helix-editor/helix/pull/2925), [#2938](https://github.com/helix-editor/helix/pull/2938), [#2962](https://github.com/helix-editor/helix/pull/2962), [#3054](https://github.com/helix-editor/helix/pull/3054))
- Add mode colors to various themes ([#2926](https://github.com/helix-editor/helix/pull/2926), [#2933](https://github.com/helix-editor/helix/pull/2933), [#2929](https://github.com/helix-editor/helix/pull/2929), [#3098](https://github.com/helix-editor/helix/pull/3098), [#3104](https://github.com/helix-editor/helix/pull/3104), [#3128](https://github.com/helix-editor/helix/pull/3128), [#3135](https://github.com/helix-editor/helix/pull/3135), [#3200](https://github.com/helix-editor/helix/pull/3200))
- Add `nord_light` ([#2908](https://github.com/helix-editor/helix/pull/2908))
- Update `night_owl` ([#2929](https://github.com/helix-editor/helix/pull/2929))
- Update `autumn` ([2e70985](https://github.com/helix-editor/helix/commit/2e70985), [936ed3a](https://github.com/helix-editor/helix/commit/936ed3a))
- Update `one_dark` ([#3011](https://github.com/helix-editor/helix/pull/3011))
- Add `noctis` ([#3043](https://github.com/helix-editor/helix/pull/3043), [#3128](https://github.com/helix-editor/helix/pull/3128))
- Update `boo_berry` ([#3191](https://github.com/helix-editor/helix/pull/3191))
- Update `monokai` ([#3131](https://github.com/helix-editor/helix/pull/3131))
- Add `ayu_dark`, `ayu_light`, `ayu_mirage` ([#3184](https://github.com/helix-editor/helix/pull/3184))
- Update `onelight` ([#3226](https://github.com/helix-editor/helix/pull/3226))
- Add `base16_transparent` ([#3216](https://github.com/helix-editor/helix/pull/3216), [b565fff](https://github.com/helix-editor/helix/commit/b565fff))
- Add `flatwhite` ([#3236](https://github.com/helix-editor/helix/pull/3236))
- Update `dark_plus` ([#3302](https://github.com/helix-editor/helix/pull/3302))
- Add `doom_acario_dark` ([#3308](https://github.com/helix-editor/helix/pull/3308), [#3539](https://github.com/helix-editor/helix/pull/3539))
- Add `rose_pine_moon` ([#3229](https://github.com/helix-editor/helix/pull/3229))
- Update `spacebones_light` ([#3342](https://github.com/helix-editor/helix/pull/3342))
- Fix typos in themes ([8deaebd](https://github.com/helix-editor/helix/commit/8deaebd), [#3412](https://github.com/helix-editor/helix/pull/3412))
- Add `emacs` ([#3410](https://github.com/helix-editor/helix/pull/3410))
- Add `papercolor-light` ([#3426](https://github.com/helix-editor/helix/pull/3426), [#3470](https://github.com/helix-editor/helix/pull/3470), [#3585](https://github.com/helix-editor/helix/pull/3585))
- Add `penumbra+` ([#3398](https://github.com/helix-editor/helix/pull/3398))
- Add `fleetish` ([#3591](https://github.com/helix-editor/helix/pull/3591), [#3607](https://github.com/helix-editor/helix/pull/3607))
- Add `sonokai` ([#3595](https://github.com/helix-editor/helix/pull/3595))
- Update all themes for theme lints ([#3587](https://github.com/helix-editor/helix/pull/3587))
LSP:
- V ([#2526](https://github.com/helix-editor/helix/pull/2526))
- Prisma ([#2703](https://github.com/helix-editor/helix/pull/2703))
- Clojure ([#2780](https://github.com/helix-editor/helix/pull/2780))
- WGSL ([#2872](https://github.com/helix-editor/helix/pull/2872))
- Elvish ([#2948](https://github.com/helix-editor/helix/pull/2948))
- Idris ([#2971](https://github.com/helix-editor/helix/pull/2971))
- Fortran ([#3025](https://github.com/helix-editor/helix/pull/3025))
- Gleam ([#3139](https://github.com/helix-editor/helix/pull/3139))
- Odin ([#3214](https://github.com/helix-editor/helix/pull/3214))
New languages:
- V ([#2526](https://github.com/helix-editor/helix/pull/2526))
- EDoc ([#2640](https://github.com/helix-editor/helix/pull/2640))
- JSDoc ([#2650](https://github.com/helix-editor/helix/pull/2650))
- OpenSCAD ([#2680](https://github.com/helix-editor/helix/pull/2680))
- Prisma ([#2703](https://github.com/helix-editor/helix/pull/2703))
- Clojure ([#2780](https://github.com/helix-editor/helix/pull/2780))
- Starlark ([#2903](https://github.com/helix-editor/helix/pull/2903))
- Elvish ([#2948](https://github.com/helix-editor/helix/pull/2948))
- Fortran ([#3025](https://github.com/helix-editor/helix/pull/3025))
- Ungrammar ([#3048](https://github.com/helix-editor/helix/pull/3048))
- SCSS ([#3074](https://github.com/helix-editor/helix/pull/3074))
- Go Template ([#3091](https://github.com/helix-editor/helix/pull/3091))
- Graphviz dot ([#3241](https://github.com/helix-editor/helix/pull/3241))
- Cue ([#3262](https://github.com/helix-editor/helix/pull/3262))
- Slint ([#3355](https://github.com/helix-editor/helix/pull/3355))
- Beancount ([#3297](https://github.com/helix-editor/helix/pull/3297))
- Taskwarrior ([#3468](https://github.com/helix-editor/helix/pull/3468))
- xit ([#3521](https://github.com/helix-editor/helix/pull/3521))
- ESDL ([#3526](https://github.com/helix-editor/helix/pull/3526))
- Awk ([#3528](https://github.com/helix-editor/helix/pull/3528), [#3535](https://github.com/helix-editor/helix/pull/3535))
- Pascal ([#3542](https://github.com/helix-editor/helix/pull/3542))
Updated languages and queries:
- Nix ([#2472](https://github.com/helix-editor/helix/pull/2472))
- Elixir ([#2619](https://github.com/helix-editor/helix/pull/2619))
- CPON ([#2643](https://github.com/helix-editor/helix/pull/2643))
- Textobjects queries for Erlang, Elixir, Gleam ([#2661](https://github.com/helix-editor/helix/pull/2661))
- Capture rust closures as function textobjects ([4a27e2d](https://github.com/helix-editor/helix/commit/4a27e2d))
- Heex ([#2800](https://github.com/helix-editor/helix/pull/2800), [#3170](https://github.com/helix-editor/helix/pull/3170))
- Add `<<=` operator highlighting for Rust ([#2805](https://github.com/helix-editor/helix/pull/2805))
- Fix comment injection in JavaScript/TypeScript ([#2763](https://github.com/helix-editor/helix/pull/2763))
- Nickel ([#2859](https://github.com/helix-editor/helix/pull/2859))
- Add `Rakefile` and `Gemfile` to Ruby file-types ([#2875](https://github.com/helix-editor/helix/pull/2875))
- Erlang ([#2910](https://github.com/helix-editor/helix/pull/2910), [ac669ad](https://github.com/helix-editor/helix/commit/ac669ad))
- Markdown ([#2910](https://github.com/helix-editor/helix/pull/2910), [#3108](https://github.com/helix-editor/helix/pull/3108), [#3400](https://github.com/helix-editor/helix/pull/3400))
- Bash ([#2910](https://github.com/helix-editor/helix/pull/2910))
- Rust ([#2910](https://github.com/helix-editor/helix/pull/2910), [#3397](https://github.com/helix-editor/helix/pull/3397))
- Edoc ([#2910](https://github.com/helix-editor/helix/pull/2910))
- HTML ([#2910](https://github.com/helix-editor/helix/pull/2910))
- Make ([#2910](https://github.com/helix-editor/helix/pull/2910))
- TSQ ([#2910](https://github.com/helix-editor/helix/pull/2910), [#2960](https://github.com/helix-editor/helix/pull/2960))
- git-commit ([#2910](https://github.com/helix-editor/helix/pull/2910))
- Use default fallback for Python indents ([9ae70cc](https://github.com/helix-editor/helix/commit/9ae70cc))
- Add Haskell LSP roots ([#2954](https://github.com/helix-editor/helix/pull/2954))
- Ledger ([#2936](https://github.com/helix-editor/helix/pull/2936), [#2988](https://github.com/helix-editor/helix/pull/2988))
- Nickel ([#2987](https://github.com/helix-editor/helix/pull/2987))
- JavaScript/TypeScript ([#2961](https://github.com/helix-editor/helix/pull/2961), [#3219](https://github.com/helix-editor/helix/pull/3219), [#3213](https://github.com/helix-editor/helix/pull/3213), [#3280](https://github.com/helix-editor/helix/pull/3280), [#3301](https://github.com/helix-editor/helix/pull/3301))
- GLSL ([#3051](https://github.com/helix-editor/helix/pull/3051))
- Fix locals tracking in Rust ([#3027](https://github.com/helix-editor/helix/pull/3027), [#3212](https://github.com/helix-editor/helix/pull/3212), [#3345](https://github.com/helix-editor/helix/pull/3345))
- Verilog ([#3158](https://github.com/helix-editor/helix/pull/3158))
- Ruby ([#3173](https://github.com/helix-editor/helix/pull/3173), [#3527](https://github.com/helix-editor/helix/pull/3527))
- Svelte ([#3147](https://github.com/helix-editor/helix/pull/3147))
- Add Elixir and HEEx comment textobjects ([#3179](https://github.com/helix-editor/helix/pull/3179))
- Python ([#3103](https://github.com/helix-editor/helix/pull/3103), [#3201](https://github.com/helix-editor/helix/pull/3201), [#3284](https://github.com/helix-editor/helix/pull/3284))
- PHP ([#3317](https://github.com/helix-editor/helix/pull/3317))
- Latex ([#3370](https://github.com/helix-editor/helix/pull/3370))
- Clojure ([#3387](https://github.com/helix-editor/helix/pull/3387))
- Swift ([#3461](https://github.com/helix-editor/helix/pull/3461))
- C# ([#3480](https://github.com/helix-editor/helix/pull/3480), [#3494](https://github.com/helix-editor/helix/pull/3494))
- Org ([#3489](https://github.com/helix-editor/helix/pull/3489))
- Elm ([#3497](https://github.com/helix-editor/helix/pull/3497))
- Dart ([#3419](https://github.com/helix-editor/helix/pull/3419))
- Julia ([#3507](https://github.com/helix-editor/helix/pull/3507))
- Fix Rust textobjects ([#3590](https://github.com/helix-editor/helix/pull/3590))
- C ([00d88e5](https://github.com/helix-editor/helix/commit/00d88e5))
- Update Rust ([0ef0ef9](https://github.com/helix-editor/helix/commit/0ef0ef9))
Packaging:
- Add `rust-analyzer` to Nix flake devShell ([#2739](https://github.com/helix-editor/helix/pull/2739))
- Add cachix information to the Nix flake ([#2999](https://github.com/helix-editor/helix/pull/2999))
- Pass makeWrapperArgs to wrapProgram in the Nix flake ([#3003](https://github.com/helix-editor/helix/pull/3003))
- Add a way to override which grammars are built by Nix ([#3141](https://github.com/helix-editor/helix/pull/3141))
- Add a GitHub actions release for `aarch64-macos` ([#3137](https://github.com/helix-editor/helix/pull/3137))
- Add shell auto-completions for Elvish ([#3331](https://github.com/helix-editor/helix/pull/3331))
# 22.05 (2022-05-28)
An even bigger shout out than usual to all the contributors - we had a whopping
110 contributors in this release! That's more than double the number of
contributors as last release!
Check out some of the highlights in the [news section](https://helix-editor.com/news/release-22-05-highlights/).
As usual, the following is a summary of each of the changes since the last release.
For the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.03..22.05).
Breaking Changes:
- Removed `C-j`, `C-k` bindings from file picker ([#1792](https://github.com/helix-editor/helix/pull/1792))
- Replaced `C-f` with `C-d` and `C-b` with `C-u` bindings in file picker ([#1792](https://github.com/helix-editor/helix/pull/1792))
- `A-hjkl` bindings have been moved to `A-pion` ([#2205](https://github.com/helix-editor/helix/pull/2205))
- `A-Left`/`A-Right` have been moved to `C-Left`/`C-Right` ([#2193](https://github.com/helix-editor/helix/pull/2193))
Features:
- The indentation mechanism has been reworked ([#1562](https://github.com/helix-editor/helix/pull/1562), [#1908](https://github.com/helix-editor/helix/pull/1908))
- Configurable gutters ([#1967](https://github.com/helix-editor/helix/pull/1967))
- Support for local language configuration ([#1249](https://github.com/helix-editor/helix/pull/1249))
- Configurable themed rulers ([#2060](https://github.com/helix-editor/helix/pull/2060))
- Render visible whitespace ([e6b865e](https://github.com/helix-editor/helix/commit/e6b865e), [#2322](https://github.com/helix-editor/helix/pull/2322), [#2331](https://github.com/helix-editor/helix/pull/2331))
Commands:
- Paragraph motion and textobject (`]p`, `[p`) ([#1627](https://github.com/helix-editor/helix/pull/1627), [#1956](https://github.com/helix-editor/helix/pull/1956), [#1969](https://github.com/helix-editor/helix/pull/1969), [#1992](https://github.com/helix-editor/helix/pull/1992), [#2226](https://github.com/helix-editor/helix/pull/2226))
- `:buffer-next`, `:buffer-previous` ([#1940](https://github.com/helix-editor/helix/pull/1940))
- `:set-language` to set the buffers language ([#1866](https://github.com/helix-editor/helix/pull/1866), [#1996](https://github.com/helix-editor/helix/pull/1996))
- Command for picking files from the current working directory (`Space-F`) ([#1600](https://github.com/helix-editor/helix/pull/1600), [#2308](https://github.com/helix-editor/helix/pull/2308))
- `:write!` which creates non-existent subdirectories ([#1839](https://github.com/helix-editor/helix/pull/1839))
- Add `m` textobject that selects closest surrounding pair ([de15d70](https://github.com/helix-editor/helix/commit/de15d70), [76175db](https://github.com/helix-editor/helix/commit/76175db))
- `:pipe` typable command for piping selections ([#1972](https://github.com/helix-editor/helix/pull/1972))
- `extend_line_above` which extends to previous lines ([#2117](https://github.com/helix-editor/helix/pull/2117))
- `set_line_ending` which replaces line endings ([#1871](https://github.com/helix-editor/helix/pull/1871))
- `:get-option` for getting the current value of an option (`:get`) ([#2231](https://github.com/helix-editor/helix/pull/2231))
- `:run-shell-command` which does not interact with selections ([#1682](https://github.com/helix-editor/helix/pull/1682))
- `:reflow` which hard-wraps selected text ([#2128](https://github.com/helix-editor/helix/pull/2128))
- `commit_undo_checkpoint` which adds an undo checkpoint ([#2115](https://github.com/helix-editor/helix/pull/2115))
- `:log-open` which opens the log file ([#2422](https://github.com/helix-editor/helix/pull/2422))
- `transpose_view` which transposes window splits ([#2461](https://github.com/helix-editor/helix/pull/2461))
- View-swapping: `swap_view_right`, `swap_view_left`, `swap_view_up`, `swap_view_down` ([#2445](https://github.com/helix-editor/helix/pull/2445))
- `shrink_to_line_bounds` which shrinks selections to line-bounds ([#2450](https://github.com/helix-editor/helix/pull/2450))
Usability improvements and fixes:
- Handle broken pipes when piping `hx --health` through `head` ([#1876](https://github.com/helix-editor/helix/pull/1876))
- Fix for `copy_selection` on newlines ([ab7885e](https://github.com/helix-editor/helix/commit/ab7885e), [236c6b7](https://github.com/helix-editor/helix/commit/236c6b7))
- Use `win32yank` clipboard provider on WSL2 ([#1912](https://github.com/helix-editor/helix/pull/1912))
- Jump to the next number on the line before incrementing ([#1778](https://github.com/helix-editor/helix/pull/1778))
- Fix start position of next search ([#1904](https://github.com/helix-editor/helix/pull/1904))
- Use check and X marks for health check output ([#1918](https://github.com/helix-editor/helix/pull/1918))
- Clear terminal after switching to alternate screens ([#1944](https://github.com/helix-editor/helix/pull/1944))
- Fix `toggle_comments` command on multiple selections ([#1882](https://github.com/helix-editor/helix/pull/1882))
- Apply `ui.gutter` theming to empty gutter spans ([#2032](https://github.com/helix-editor/helix/pull/2032))
- Use checkboxes in `hx --health` output ([#1947](https://github.com/helix-editor/helix/pull/1947))
- Pass unmapped keys through prompt regardless of modifiers ([764adbd](https://github.com/helix-editor/helix/commit/764adbd))
- LSP: pull formatting options from config ([c18de0e](https://github.com/helix-editor/helix/commit/c18de0e))
- LSP: provide `rootPath` ([84e799f](https://github.com/helix-editor/helix/commit/84e799f))
- LSP: implement `workspace_folders` ([8adf0c1](https://github.com/helix-editor/helix/commit/8adf0c1))
- LSP: fix auto-import ([#2088](https://github.com/helix-editor/helix/pull/2088))
- Send active diagnostic to LSP when requesting code actions ([#2005](https://github.com/helix-editor/helix/pull/2005))
- Prevent panic when parsing malformed LSP `PublishDiagnostic` ([#2160](https://github.com/helix-editor/helix/pull/2160))
- Restore document state on completion cancel ([#2096](https://github.com/helix-editor/helix/pull/2096))
- Only merge top-level array when merging `languages.toml` ([#2145](https://github.com/helix-editor/helix/pull/2145), [#2215](https://github.com/helix-editor/helix/pull/2215))
- Fix open on multiline selection ([#2161](https://github.com/helix-editor/helix/pull/2161))
- Allow re-binding `0` if it is not used in a count ([#2174](https://github.com/helix-editor/helix/pull/2174))
- Fix `ctrl-u` behavior in insert mode ([#1957](https://github.com/helix-editor/helix/pull/1957))
- Check LSP rename capabilities before sending rename action ([#2203](https://github.com/helix-editor/helix/pull/2203))
- Register the `publish_diagnostics` LSP capability ([#2241](https://github.com/helix-editor/helix/pull/2241))
- Fix paste direction for typed paste commands ([#2288](https://github.com/helix-editor/helix/pull/2288))
- Improve handling of buffer-close ([#1397](https://github.com/helix-editor/helix/pull/1397))
- Extend the tutor file ([#2133](https://github.com/helix-editor/helix/pull/2133))
- Treat slashes as word separators in prompts ([#2315](https://github.com/helix-editor/helix/pull/2315))
- Auto-complete directory members ([#1682](https://github.com/helix-editor/helix/pull/1682))
- Allow disabling format-on-save as a global editor setting ([#2321](https://github.com/helix-editor/helix/pull/2321))
- Wrap command palette in overlay ([#2378](https://github.com/helix-editor/helix/pull/2378))
- Prevent selections from collapsing when inserting newlines ([#2414](https://github.com/helix-editor/helix/pull/2414))
- Allow configuration of LSP request timeout ([#2405](https://github.com/helix-editor/helix/pull/2405))
- Use debug console on Windows for DAP terminal ([#2294](https://github.com/helix-editor/helix/pull/2294))
- Exclude cursor when deleting with `C-w` in insert mode ([#2431](https://github.com/helix-editor/helix/pull/2431))
- Prevent panics from LSP parsing errors ([7ae6cad](https://github.com/helix-editor/helix/commit/7ae6cad))
- Prevent panics from LSP responses without requests ([#2475](https://github.com/helix-editor/helix/pull/2475))
- Fix scroll rate for documentation popups ([#2497](https://github.com/helix-editor/helix/pull/2497))
- Support inserting into prompts from registers ([#2458](https://github.com/helix-editor/helix/pull/2458))
- Separate theme scopes for diagnostic types ([#2437](https://github.com/helix-editor/helix/pull/2437))
- Use `ui.menu` instead of `ui.statusline` for command completion menu theming ([82fb217](https://github.com/helix-editor/helix/commit/82fb217))
- Panic when reloading a shrunk file ([#2506](https://github.com/helix-editor/helix/pull/2506))
- Add theme key for picker separator ([#2523](https://github.com/helix-editor/helix/pull/2523))
Themes:
- Remove `ui.text` background from dark_plus ([#1950](https://github.com/helix-editor/helix/pull/1950))
- Add `boo_berry` ([#1962](https://github.com/helix-editor/helix/pull/1962))
- Update `dark_plus` markup colors ([#1989](https://github.com/helix-editor/helix/pull/1989))
- Update `dark_plus` `tag` and `ui.menu.selected` colors ([#2014](https://github.com/helix-editor/helix/pull/2014))
- Add `dracula_at_night` ([#2008](https://github.com/helix-editor/helix/pull/2008))
- Improve `dracula` selection theming ([#2077](https://github.com/helix-editor/helix/pull/2077))
- Remove dim attribute on `onedark` line-number gutter ([#2155](https://github.com/helix-editor/helix/pull/2155))
- Add `tokyonight` ([#2162](https://github.com/helix-editor/helix/pull/2162))
- Use border colors from the original `dark_plus` theme ([#2186](https://github.com/helix-editor/helix/pull/2186))
- Add `autumn` ([#2212](https://github.com/helix-editor/helix/pull/2212), [#2270](https://github.com/helix-editor/helix/pull/2270), [#2531](https://github.com/helix-editor/helix/pull/2531))
- Add `tokyonight_storm` ([#2240](https://github.com/helix-editor/helix/pull/2240))
- Add `pop-dark` ([#2189](https://github.com/helix-editor/helix/pull/2189))
- Fix `base16_terminal` theme using incorrect ansi-color ([#2279](https://github.com/helix-editor/helix/pull/2279))
- Add `onelight` ([#2287](https://github.com/helix-editor/helix/pull/2287), [#2323](https://github.com/helix-editor/helix/pull/2323))
- Add `ui.virtual` scopes to `onedark` theme ([3626e38](https://github.com/helix-editor/helix/commit/3626e38))
- Add `night_owl` ([#2330](https://github.com/helix-editor/helix/pull/2330))
- Use yellow foreground and red background for `monokai_pro_spectrum` ([#2433](https://github.com/helix-editor/helix/pull/2433))
- Add `snazzy` ([#2473](https://github.com/helix-editor/helix/pull/2473))
- Update `dark_plus` constructor color ([8e8d4ba](https://github.com/helix-editor/helix/commit/8e8d4ba))
- Add `ui.menu` to the default theme ([e7e13dc](https://github.com/helix-editor/helix/commit/e7e13dc))
- Add `ui.menu` to any themes missing the key ([9be810f](https://github.com/helix-editor/helix/commit/9be810f))
- Add `catppuccin` ([#2546](https://github.com/helix-editor/helix/pull/2546), [7160e74](https://github.com/helix-editor/helix/commit/7160e74))
LSP:
- Use texlab for latex ([#1922](https://github.com/helix-editor/helix/pull/1922))
- HTML ([#2018](https://github.com/helix-editor/helix/pull/2018))
- JSON ([#2024](https://github.com/helix-editor/helix/pull/2024))
- CSS ([#2025](https://github.com/helix-editor/helix/pull/2025))
- PHP ([#2031](https://github.com/helix-editor/helix/pull/2031))
- Swift ([#2033](https://github.com/helix-editor/helix/pull/2033))
- OCaml ([#2035](https://github.com/helix-editor/helix/pull/2035))
- Vue ([#2043](https://github.com/helix-editor/helix/pull/2043))
- Yaml ([#2234](https://github.com/helix-editor/helix/pull/2234))
- Vala ([#2243](https://github.com/helix-editor/helix/pull/2243))
- TOML ([#2302](https://github.com/helix-editor/helix/pull/2302))
- Java ([#2511](https://github.com/helix-editor/helix/pull/2511))
- Lua ([#2560](https://github.com/helix-editor/helix/pull/2560))
- Verilog ([#2552](https://github.com/helix-editor/helix/pull/2552))
New Languages:
- JSX ([#1906](https://github.com/helix-editor/helix/pull/1906), [a24fb17](https://github.com/helix-editor/helix/commit/a24fb17), [855e438](https://github.com/helix-editor/helix/commit/855e438), [#1921](https://github.com/helix-editor/helix/pull/1921))
- Rust Object Notation (RON) ([#1925](https://github.com/helix-editor/helix/pull/1925))
- R and R Markdown ([#1998](https://github.com/helix-editor/helix/pull/1998))
- Swift ([#2033](https://github.com/helix-editor/helix/pull/2033))
- EJS and ERB ([#2055](https://github.com/helix-editor/helix/pull/2055))
- EEx ([9d095e0](https://github.com/helix-editor/helix/commit/9d095e0))
- HEEx ([4836bb3](https://github.com/helix-editor/helix/commit/4836bb3), [#2149](https://github.com/helix-editor/helix/pull/2149))
- SQL ([#2097](https://github.com/helix-editor/helix/pull/2097))
- GDScript ([#1985](https://github.com/helix-editor/helix/pull/1985))
- Nickel ([#2173](https://github.com/helix-editor/helix/pull/2173), [#2320](https://github.com/helix-editor/helix/pull/2320))
- `go.mod` and `go.work` ([#2197](https://github.com/helix-editor/helix/pull/2197))
- Nushell ([#2225](https://github.com/helix-editor/helix/pull/2225))
- Vala ([#2243](https://github.com/helix-editor/helix/pull/2243))
- Hare ([#2289](https://github.com/helix-editor/helix/pull/2289), [#2480](https://github.com/helix-editor/helix/pull/2480))
- DeviceTree ([#2329](https://github.com/helix-editor/helix/pull/2329))
- Cairo ([7387905](https://github.com/helix-editor/helix/commit/7387905))
- CPON ([#2355](https://github.com/helix-editor/helix/pull/2355), [#2424](https://github.com/helix-editor/helix/pull/2424))
- git-ignore ([#2397](https://github.com/helix-editor/helix/pull/2397))
- git-attributes ([#2397](https://github.com/helix-editor/helix/pull/2397))
- Odin ([#2399](https://github.com/helix-editor/helix/pull/2399), [#2464](https://github.com/helix-editor/helix/pull/2464))
- Meson ([#2314](https://github.com/helix-editor/helix/pull/2314))
- SSH Client Config ([#2498](https://github.com/helix-editor/helix/pull/2498))
- Scheme ([d25bae8](https://github.com/helix-editor/helix/commit/d25bae8))
- Verilog ([#2552](https://github.com/helix-editor/helix/pull/2552))
Updated Languages and Queries:
- Erlang ([e2a5071](https://github.com/helix-editor/helix/commit/e2a5071), [#2149](https://github.com/helix-editor/helix/pull/2149), [82da9bd](https://github.com/helix-editor/helix/commit/82da9bd))
- Elixir ([1819478](https://github.com/helix-editor/helix/commit/1819478), [8c3c901](https://github.com/helix-editor/helix/commit/8c3c901), [4ac94a5](https://github.com/helix-editor/helix/commit/4ac94a5))
- Gleam ([7cd6050](https://github.com/helix-editor/helix/commit/7cd6050), [45dd540](https://github.com/helix-editor/helix/commit/45dd540))
- Bash ([#1917](https://github.com/helix-editor/helix/pull/1917))
- JavaScript ([#2140](https://github.com/helix-editor/helix/pull/2140))
- Ruby textobject queries ([#2143](https://github.com/helix-editor/helix/pull/2143))
- Fix Golang textobject queries ([#2153](https://github.com/helix-editor/helix/pull/2153))
- Add more bash and HCL file extensions ([#2201](https://github.com/helix-editor/helix/pull/2201))
- Divide HCL and tfvars into separate languages ([#2244](https://github.com/helix-editor/helix/pull/2244))
- Use JavaScript for `cjs` files ([#2387](https://github.com/helix-editor/helix/pull/2387))
- Use Perl for `t` files ([#2395](https://github.com/helix-editor/helix/pull/2395))
- Use `markup.list` scopes for lists ([#2401](https://github.com/helix-editor/helix/pull/2401))
- Use PHP for `inc` files ([#2440](https://github.com/helix-editor/helix/pull/2440))
- Improve Rust textobjects ([#2494](https://github.com/helix-editor/helix/pull/2494), [10463fe](https://github.com/helix-editor/helix/commit/10463fe))
- Python ([#2451](https://github.com/helix-editor/helix/pull/2451))
Packaging:
- Use `builtins.fromTOML` in Nix Flake on Nix 2.6+ ([#1892](https://github.com/helix-editor/helix/pull/1892))
- Shell auto-completion files are now available ([#2022](https://github.com/helix-editor/helix/pull/2022))
- Create an AppImage on release ([#2089](https://github.com/helix-editor/helix/pull/2089))
# 22.03 (2022-03-28)
A big shout out to all the contributors! We had 51 contributors in this release.
This release is particularly large and featureful. Check out some of the
highlights in the [news section](https://helix-editor.com/news/release-22-03-highlights/).
As usual, the following is a summary of each of the changes since the last release.
For the full log, check out the [git log](https://github.com/helix-editor/helix/compare/v0.6.0..22.03).
Breaking changes:
- LSP config now lives under `editor.lsp` ([#1868](https://github.com/helix-editor/helix/pull/1868))
- Expand-selection was moved from `]o` to `Alt-h` ([#1495](https://github.com/helix-editor/helix/pull/1495))
Features:
- Experimental Debug Adapter Protocol (DAP) support ([#574](https://github.com/helix-editor/helix/pull/574))
- Primary cursor shape may now be customized per mode ([#1154](https://github.com/helix-editor/helix/pull/1154))
- Overhaul incremental highlights and enable combined injections ([`6728344..4080341`](https://github.com/helix-editor/helix/compare/6728344..4080341))
- Allow specifying file start position ([#445](https://github.com/helix-editor/helix/pull/445), [#1676](https://github.com/helix-editor/helix/pull/1676))
- Dynamic line numbers ([#1522](https://github.com/helix-editor/helix/pull/1522))
- Show an info box with the contents of registers ([#980](https://github.com/helix-editor/helix/pull/980))
- Wrap-around behavior during search is now configurable ([#1516](https://github.com/helix-editor/helix/pull/1516))
- Tree-sitter textobjects motions for classes, functions, and parameters ([#1619](https://github.com/helix-editor/helix/pull/1619), [#1708](https://github.com/helix-editor/helix/pull/1708), [#1805](https://github.com/helix-editor/helix/pull/1805))
- Command palette: a picker for available commands ([#1400](https://github.com/helix-editor/helix/pull/1400))
- LSP `workspace/configuration` and `workspace/didChangeConfiguration` support ([#1684](https://github.com/helix-editor/helix/pull/1684))
- `hx --health [LANG]` command ([#1669](https://github.com/helix-editor/helix/pull/1669))
- Refactor of the tree-sitter grammar system ([#1659](https://github.com/helix-editor/helix/pull/1659))
- All submodules have been removed
- New `hx --grammar {fetch|build}` flags for fetching and building tree-sitter grammars
- A custom grammar selection may now be declared with the `use-grammars` key in `languages.toml`
Commands:
- `:cquit!` - quit forcefully with a non-zero exit-code ([#1414](https://github.com/helix-editor/helix/pull/1414))
- `shrink_selection` - shrink the selection to a child tree-sitter node (`Alt-j`, [#1340](https://github.com/helix-editor/helix/pull/1340))
- `:tree-sitter-subtree` - show the tree-sitter subtree under the primary selection ([#1453](https://github.com/helix-editor/helix/pull/1453), [#1524](https://github.com/helix-editor/helix/pull/1524))
- Add `Alt-Backspace`, `Alt-<`, `Alt->`, and `Ctrl-j` to insert mode ([#1441](https://github.com/helix-editor/helix/pull/1441))
- `select_next_sibling`, `select_prev_sibling` - select next and previous tree-sitter nodes (`Alt-l` and `Alt-h`, [#1495](https://github.com/helix-editor/helix/pull/1495))
- `:buffer-close-all`, `:buffer-close-all!`, `:buffer-close-others`, and `:buffer-close-others!` ([#1677](https://github.com/helix-editor/helix/pull/1677))
- `:vsplit-new` and `:hsplit-new` - open vertical and horizontal splits with new scratch buffers ([#1763](https://github.com/helix-editor/helix/pull/1763))
- `:open-config` to open the config file and `:refresh-config` to refresh config after changes ([#1771](https://github.com/helix-editor/helix/pull/1771), [#1803](https://github.com/helix-editor/helix/pull/1803))
Usability improvements and fixes:
- Prevent `:cquit` from ignoring unsaved changes ([#1414](https://github.com/helix-editor/helix/pull/1414))
- Scrolling view keeps selections ([#1420](https://github.com/helix-editor/helix/pull/1420))
- Only use shellwords parsing on unix platforms ([`7767703`](https://github.com/helix-editor/helix/commit/7767703))
- Fix slash in search selector status message ([#1449](https://github.com/helix-editor/helix/pull/1449))
- Use `std::path::MAIN_SEPARATOR` to determine completion ([`3e4f815`](https://github.com/helix-editor/helix/commit/3e4f815))
- Expand to current node with `expand_selection` when the node has no children ([#1454](https://github.com/helix-editor/helix/pull/1454))
- Add vertical and horizontal splits to the buffer picker ([#1502](https://github.com/helix-editor/helix/pull/1502))
- Use the correct language ID for JavaScript & TypeScript LSP ([#1466](https://github.com/helix-editor/helix/pull/1466))
- Run format command for all buffers being written ([#1444](https://github.com/helix-editor/helix/pull/1444))
- Fix panics during resizing ([#1408](https://github.com/helix-editor/helix/pull/1408))
- Fix auto-pairs with CRLF ([#1470](https://github.com/helix-editor/helix/pull/1470))
- Fix picker scrolling when the bottom is reached ([#1567](https://github.com/helix-editor/helix/pull/1567))
- Use markup themes for the markdown component ([#1363](https://github.com/helix-editor/helix/pull/1363))
- Automatically commit changes to history if not in insert mode ([`2a7ae96`](https://github.com/helix-editor/helix/commit/2a7ae96))
- Render code-actions as a menu and add padding to popup ([`094a0aa`](https://github.com/helix-editor/helix/commit/094a0aa))
- Only render menu scrollbar if the menu doesn't fit ([`f10a06f`](https://github.com/helix-editor/helix/commit/f10a06f), [`36b975c`](https://github.com/helix-editor/helix/commit/36b975c))
- Parse git revision instead of tag for version ([`d3221b0`](https://github.com/helix-editor/helix/commit/d3221b0), [#1674](https://github.com/helix-editor/helix/pull/1674))
- Fix incorrect last modified buffer ([#1621](https://github.com/helix-editor/helix/pull/1621))
- Add `PageUp`, `PageDown`, `Ctrl-u`, `Ctrl-d`, `Home`, `End` bindings to the file picker ([#1612](https://github.com/helix-editor/helix/pull/1612))
- Display buffer IDs in the buffer picker ([#1134](https://github.com/helix-editor/helix/pull/1134))
- Allow multi-line prompt documentation ([`2af0432`](https://github.com/helix-editor/helix/commit/2af0432))
- Ignore the `.git` directory from the file picker ([#1604](https://github.com/helix-editor/helix/pull/1604))
- Allow separate styling for markup heading levels ([#1618](https://github.com/helix-editor/helix/pull/1618))
- Automatically close popups ([#1285](https://github.com/helix-editor/helix/pull/1285))
- Allow auto-pairs tokens to be configured ([#1624](https://github.com/helix-editor/helix/pull/1624))
- Don't indent empty lines in `indent` command ([#1653](https://github.com/helix-editor/helix/pull/1653))
- Ignore `Enter` keypress when a menu has no selection ([#1704](https://github.com/helix-editor/helix/pull/1704))
- Show errors when surround deletions and replacements fail ([#1709](https://github.com/helix-editor/helix/pull/1709))
- Show infobox hints for `mi` and `ma` ([#1686](https://github.com/helix-editor/helix/pull/1686))
- Highlight matching text in file picker suggestions ([#1635](https://github.com/helix-editor/helix/pull/1635))
- Allow capturing multiple nodes in textobject queries ([#1611](https://github.com/helix-editor/helix/pull/1611))
- Make repeat operator work with completion edits ([#1640](https://github.com/helix-editor/helix/pull/1640))
- Save to the jumplist when searching ([#1718](https://github.com/helix-editor/helix/pull/1718))
- Fix bug with auto-replacement of components in compositor ([#1711](https://github.com/helix-editor/helix/pull/1711))
- Use Kakoune logic for `align_selection` ([#1675](https://github.com/helix-editor/helix/pull/1675))
- Fix `follows` for `nixpkgs` in `flake.nix` ([#1729](https://github.com/helix-editor/helix/pull/1729))
- Performance improvements for the picker ([`78fba86`](https://github.com/helix-editor/helix/commit/78fba86))
- Rename infobox theme scopes ([#1741](https://github.com/helix-editor/helix/pull/1741))
- Fallback to broader scopes if a theme scope is not found ([#1714](https://github.com/helix-editor/helix/pull/1714))
- Add arrow-keys bindings for tree-sitter sibling selection commands ([#1724](https://github.com/helix-editor/helix/pull/1724))
- Fix a bug in LSP when creating a file in a folder that does not exist ([#1775](https://github.com/helix-editor/helix/pull/1775))
- Use `^` and `$` regex location assertions for search ([#1793](https://github.com/helix-editor/helix/pull/1793))
- Fix register names in `insert_register` command ([#1751](https://github.com/helix-editor/helix/pull/1751))
- Perform extend line for all selections ([#1804](https://github.com/helix-editor/helix/pull/1804))
- Prevent panic when moving in an empty picker ([#1786](https://github.com/helix-editor/helix/pull/1786))
- Fix line number calculations for non CR/CRLF line breaks ([`b4a282f`](https://github.com/helix-editor/helix/commit/b4a282f), [`0b96201`](https://github.com/helix-editor/helix/commit/0b96201))
- Deploy documentation for `master` builds separately from release docs ([#1783](https://github.com/helix-editor/helix/pull/1783))
Themes:
- Add everforest_light ([#1412](https://github.com/helix-editor/helix/pull/1412))
- Add gruvbox_light ([#1509](https://github.com/helix-editor/helix/pull/1509))
- Add modified background to dracula popup ([#1434](https://github.com/helix-editor/helix/pull/1434))
- Markup support for monokai pro themes ([#1553](https://github.com/helix-editor/helix/pull/1553))
- Markup support for dracula theme ([#1554](https://github.com/helix-editor/helix/pull/1554))
- Add `tag` to gruvbox theme ([#1555](https://github.com/helix-editor/helix/pull/1555))
- Markup support for remaining themes ([#1525](https://github.com/helix-editor/helix/pull/1525))
- Serika light and dark ([#1566](https://github.com/helix-editor/helix/pull/1566))
- Fix rose_pine and rose_pine_dawn popup background color ([#1606](https://github.com/helix-editor/helix/pull/1606))
- Fix hover menu item text color in base16 themes ([#1668](https://github.com/helix-editor/helix/pull/1668))
- Update markup heading styles for everforest ([#1687](https://github.com/helix-editor/helix/pull/1687))
- Update markup heading styles for rose_pine themes ([#1706](https://github.com/helix-editor/helix/pull/1706))
- Style bogster cursors ([`6a6a9ab`](https://github.com/helix-editor/helix/commit/6a6a9ab))
- Fix `ui.selection` in rose_pine themes ([#1716](https://github.com/helix-editor/helix/pull/1716))
- Use distinct colors for cursor and matched pair in gruvbox ([#1791](https://github.com/helix-editor/helix/pull/1791))
- Improve colors for `ui.cursor.match` capture in some themes ([#1862](https://github.com/helix-editor/helix/pull/1862))
LSP:
- Add default language server for JavaScript ([#1457](https://github.com/helix-editor/helix/pull/1457))
- Add `pom.xml` as maven root directory marker ([#1496](https://github.com/helix-editor/helix/pull/1496))
- Haskell LSP ([#1556](https://github.com/helix-editor/helix/pull/1556))
- C-sharp LSP support ([#1788](https://github.com/helix-editor/helix/pull/1788))
- Clean up Julia LSP config ([#1811](https://github.com/helix-editor/helix/pull/1811))
New Languages:
- llvm-mir ([#1398](https://github.com/helix-editor/helix/pull/1398))
- regex ([#1362](https://github.com/helix-editor/helix/pull/1362))
- Make ([#1433](https://github.com/helix-editor/helix/pull/1433), [#1661](https://github.com/helix-editor/helix/pull/1661))
- git-config ([#1426](https://github.com/helix-editor/helix/pull/1426))
- Lean ([#1422](https://github.com/helix-editor/helix/pull/1422))
- Elm ([#1514](https://github.com/helix-editor/helix/pull/1514))
- GraphQL ([#1515](https://github.com/helix-editor/helix/pull/1515))
- Twig ([#1602](https://github.com/helix-editor/helix/pull/1602))
- Rescript ([#1616](https://github.com/helix-editor/helix/pull/1616), [#1863](https://github.com/helix-editor/helix/pull/1863))
- Erlang ([#1657](https://github.com/helix-editor/helix/pull/1657))
- Kotlin ([#1689](https://github.com/helix-editor/helix/pull/1689))
- HCL ([#1705](https://github.com/helix-editor/helix/pull/1705), [#1726](https://github.com/helix-editor/helix/pull/1726))
- Org ([#1845](https://github.com/helix-editor/helix/pull/1845))
- Solidity ([#1848](https://github.com/helix-editor/helix/pull/1848), [#1854](https://github.com/helix-editor/helix/pull/1854))
Updated Languages and Queries:
- Textobject and indent queries for c and cpp ([#1293](https://github.com/helix-editor/helix/pull/1293))
- Fix null and boolean constant highlights for nix ([#1428](https://github.com/helix-editor/helix/pull/1428))
- Capture markdown link text as `markup.link.text` ([#1456](https://github.com/helix-editor/helix/pull/1456))
- Update and re-enable Haskell ([#1417](https://github.com/helix-editor/helix/pull/1417), [#1520](https://github.com/helix-editor/helix/pull/1520))
- Update Go with generics support ([`ddbf036`](https://github.com/helix-editor/helix/commit/ddbf036))
- Use `tree-sitter-css` for SCSS files ([#1507](https://github.com/helix-editor/helix/pull/1507))
- Update Zig ([#1501](https://github.com/helix-editor/helix/pull/1501))
- Update PHP ([#1521](https://github.com/helix-editor/helix/pull/1521))
- Expand language support for comment injections ([#1527](https://github.com/helix-editor/helix/pull/1527))
- Use tree-sitter-bash for `.zshrc` and `.bashrc` ([`7d51042`](https://github.com/helix-editor/helix/commit/7d51042))
- Use tree-sitter-bash for `.bash_profile` ([#1571](https://github.com/helix-editor/helix/pull/1571))
- Use tree-sitter-bash for `.zshenv` and ZSH files ([#1574](https://github.com/helix-editor/helix/pull/1574))
- IEx ([#1576](https://github.com/helix-editor/helix/pull/1576))
- Textobject queries for PHP ([#1601](https://github.com/helix-editor/helix/pull/1601))
- C-sharp highlight query improvements ([#1795](https://github.com/helix-editor/helix/pull/1795))
- Git commit performance has been improved on large verbose commits ([#1838](https://github.com/helix-editor/helix/pull/1838))
Packaging:
- The submodules system has been replaced with command-line flags for fetching and building tree-sitter grammars ([#1659](https://github.com/helix-editor/helix/pull/1659))
- Flake outputs are pushed to Cachix on each push to `master` ([#1721](https://github.com/helix-editor/helix/pull/1721))
- Update flake's `nix-cargo-integration` to depend on `dream2nix` ([#1758](https://github.com/helix-editor/helix/pull/1758))
# 0.6.0 (2022-01-04)
Happy new year and a big shout out to all the contributors! We had 55 contributors in this release.
Helix has popped up in DPorts and Fedora Linux via COPR ([#1270](https://github.com/helix-editor/helix/pull/1270))
As usual the following is a brief summary, refer to the git history for a full log:
Breaking changes:
- fix: Normalize backtab into shift-tab
Features:
- Macros ([#1234](https://github.com/helix-editor/helix/pull/1234))
- Add reverse search functionality ([#958](https://github.com/helix-editor/helix/pull/958))
- Allow keys to be mapped to sequences of commands ([#589](https://github.com/helix-editor/helix/pull/589))
- Make it possible to keybind TypableCommands ([#1169](https://github.com/helix-editor/helix/pull/1169))
- Detect workspace root using language markers ([#1370](https://github.com/helix-editor/helix/pull/1370))
- Add WORD textobject ([#991](https://github.com/helix-editor/helix/pull/991))
- Add LSP rename_symbol (`space-r`) ([#1011](https://github.com/helix-editor/helix/pull/1011))
- Added workspace_symbol_picker ([#1041](https://github.com/helix-editor/helix/pull/1041))
- Detect filetype from shebang line ([#1001](https://github.com/helix-editor/helix/pull/1001))
- Allow piping from stdin into a buffer on startup ([#996](https://github.com/helix-editor/helix/pull/996))
- Add auto pairs for same-char pairs ([#1219](https://github.com/helix-editor/helix/pull/1219))
- Update settings at runtime ([#798](https://github.com/helix-editor/helix/pull/798))
- Enable thin LTO ([`cccc194`](https://github.com/helix-editor/helix/commit/cccc194))
Commands:
- `:wonly` -- window only ([#1057](https://github.com/helix-editor/helix/pull/1057))
- buffer-close (`:bc`, `:bclose`) ([#1035](https://github.com/helix-editor/helix/pull/1035))
- Add `:<line>` and `:goto <line>` commands ([#1128](https://github.com/helix-editor/helix/pull/1128))
- `:sort` command ([#1288](https://github.com/helix-editor/helix/pull/1288))
- Add m textobject for pair under cursor ([#961](https://github.com/helix-editor/helix/pull/961))
- Implement "Goto next buffer / Goto previous buffer" commands ([#950](https://github.com/helix-editor/helix/pull/950))
- Implement "Goto last modification" command ([#1067](https://github.com/helix-editor/helix/pull/1067))
- Add trim_selections command ([#1092](https://github.com/helix-editor/helix/pull/1092))
- Add movement shortcut for history ([#1088](https://github.com/helix-editor/helix/pull/1088))
- Add command to inc/dec number under cursor ([#1027](https://github.com/helix-editor/helix/pull/1027))
- Add support for dates for increment/decrement
- Align selections (`&`) ([#1101](https://github.com/helix-editor/helix/pull/1101))
- Implement no-yank delete/change ([#1099](https://github.com/helix-editor/helix/pull/1099))
- Implement black hole register ([#1165](https://github.com/helix-editor/helix/pull/1165))
- `gf` as goto_file (`gf`) ([#1102](https://github.com/helix-editor/helix/pull/1102))
- Add last modified file (`gm`) ([#1093](https://github.com/helix-editor/helix/pull/1093))
- ensure_selections_forward ([#1393](https://github.com/helix-editor/helix/pull/1393))
- Readline style insert mode ([#1039](https://github.com/helix-editor/helix/pull/1039))
Usability improvements and fixes:
- Detect filetype on `:write` ([#1141](https://github.com/helix-editor/helix/pull/1141))
- Add single and double quotes to matching pairs ([#995](https://github.com/helix-editor/helix/pull/995))
- Launch with defaults upon invalid config/theme (rather than panicking) ([#982](https://github.com/helix-editor/helix/pull/982))
- If switching away from an empty scratch buffer, remove it ([#935](https://github.com/helix-editor/helix/pull/935))
- Truncate the starts of file paths instead of the ends in picker ([#951](https://github.com/helix-editor/helix/pull/951))
- Truncate the start of file paths in the StatusLine ([#1351](https://github.com/helix-editor/helix/pull/1351))
- Prevent picker from previewing binaries or large file ([#939](https://github.com/helix-editor/helix/pull/939))
- Inform when reaching undo/redo bounds ([#981](https://github.com/helix-editor/helix/pull/981))
- search_impl will only align cursor center when it isn't in view ([#959](https://github.com/helix-editor/helix/pull/959))
- Add `<C-h>`, `<C-u>`, `<C-d>`, Delete in prompt mode ([#1034](https://github.com/helix-editor/helix/pull/1034))
- Restore screen position when aborting search ([#1047](https://github.com/helix-editor/helix/pull/1047))
- Buffer picker: show is_modifier flag ([#1020](https://github.com/helix-editor/helix/pull/1020))
- Add commit hash to version info, if present ([#957](https://github.com/helix-editor/helix/pull/957))
- Implement indent-aware delete ([#1120](https://github.com/helix-editor/helix/pull/1120))
- Jump to end char of surrounding pair from any cursor pos ([#1121](https://github.com/helix-editor/helix/pull/1121))
- File picker configuration ([#988](https://github.com/helix-editor/helix/pull/988))
- Fix surround cursor position calculation ([#1183](https://github.com/helix-editor/helix/pull/1183))
- Accept count for goto_window ([#1033](https://github.com/helix-editor/helix/pull/1033))
- Make kill_to_line_end behave like emacs ([#1235](https://github.com/helix-editor/helix/pull/1235))
- Only use a single documentation popup ([#1241](https://github.com/helix-editor/helix/pull/1241))
- ui: popup: Don't allow scrolling past the end of content ([`3307f44c`](https://github.com/helix-editor/helix/commit/3307f44c))
- Open files with spaces in filename, allow opening multiple files ([#1231](https://github.com/helix-editor/helix/pull/1231))
- Allow paste commands to take a count ([#1261](https://github.com/helix-editor/helix/pull/1261))
- Auto pairs selection ([#1254](https://github.com/helix-editor/helix/pull/1254))
- Use a fuzzy matcher for commands ([#1386](https://github.com/helix-editor/helix/pull/1386))
- Add `<C-s>` to pick word under doc cursor to prompt line & search completion ([#831](https://github.com/helix-editor/helix/pull/831))
- Fix `:earlier`/`:later` missing changeset update ([#1069](https://github.com/helix-editor/helix/pull/1069))
- Support extend for multiple goto ([#909](https://github.com/helix-editor/helix/pull/909))
- Add arrow-key bindings for window switching ([#933](https://github.com/helix-editor/helix/pull/933))
- Implement key ordering for info box ([#952](https://github.com/helix-editor/helix/pull/952))
LSP:
- Implement MarkedString rendering ([`e128a8702`](https://github.com/helix-editor/helix/commit/e128a8702))
- Don't panic if init fails ([`d31bef7`](https://github.com/helix-editor/helix/commit/d31bef7))
- Configurable diagnostic severity ([#1325](https://github.com/helix-editor/helix/pull/1325))
- Resolve completion item ([#1315](https://github.com/helix-editor/helix/pull/1315))
- Code action command support ([#1304](https://github.com/helix-editor/helix/pull/1304))
Grammars:
- Adds mint language server ([#974](https://github.com/helix-editor/helix/pull/974))
- Perl ([#978](https://github.com/helix-editor/helix/pull/978)) ([#1280](https://github.com/helix-editor/helix/pull/1280))
- GLSL ([#993](https://github.com/helix-editor/helix/pull/993))
- Racket ([#1143](https://github.com/helix-editor/helix/pull/1143))
- WGSL ([#1166](https://github.com/helix-editor/helix/pull/1166))
- LLVM ([#1167](https://github.com/helix-editor/helix/pull/1167)) ([#1388](https://github.com/helix-editor/helix/pull/1388)) ([#1409](https://github.com/helix-editor/helix/pull/1409)) ([#1398](https://github.com/helix-editor/helix/pull/1398))
- Markdown ([`49e06787`](https://github.com/helix-editor/helix/commit/49e06787))
- Scala ([#1278](https://github.com/helix-editor/helix/pull/1278))
- Dart ([#1250](https://github.com/helix-editor/helix/pull/1250))
- Fish ([#1308](https://github.com/helix-editor/helix/pull/1308))
- Dockerfile ([#1303](https://github.com/helix-editor/helix/pull/1303))
- Git (commit, rebase, diff) ([#1338](https://github.com/helix-editor/helix/pull/1338)) ([#1402](https://github.com/helix-editor/helix/pull/1402)) ([#1373](https://github.com/helix-editor/helix/pull/1373))
- tree-sitter-comment ([#1300](https://github.com/helix-editor/helix/pull/1300))
- Highlight comments in c, cpp, cmake and llvm ([#1309](https://github.com/helix-editor/helix/pull/1309))
- Improve yaml syntax highlighting highlighting ([#1294](https://github.com/helix-editor/helix/pull/1294))
- Improve rust syntax highlighting ([#1295](https://github.com/helix-editor/helix/pull/1295))
- Add textobjects and indents to cmake ([#1307](https://github.com/helix-editor/helix/pull/1307))
- Add textobjects and indents to c and cpp ([#1293](https://github.com/helix-editor/helix/pull/1293))
New themes:
- Solarized dark ([#999](https://github.com/helix-editor/helix/pull/999))
- Solarized light ([#1010](https://github.com/helix-editor/helix/pull/1010))
- Spacebones light ([#1131](https://github.com/helix-editor/helix/pull/1131))
- Monokai Pro ([#1206](https://github.com/helix-editor/helix/pull/1206))
- Base16 Light and Terminal ([#1078](https://github.com/helix-editor/helix/pull/1078))
- and a default 16 color theme, truecolor detection
- Dracula ([#1258](https://github.com/helix-editor/helix/pull/1258))
# 0.5.0 (2021-10-28)
A big shout out to all the contributors! We had 46 contributors in this release.
@@ -16,74 +752,76 @@ Breaking changes:
- `keep_primary_selection` moved from `space+space` to `,`
- `Alt-,` is now `remove_primary_selection` which keeps all selections except the primary one
- Opening files in a split moved from `C-h` to `C-s`
- Some configuration options moved from a `[terminal]` section to `[editor]`. [Consult the documentation for more information.](https://docs.helix-editor.com/configuration.html).
- Some configuration options moved from a `[terminal]` section to `[editor]`. [Consult the documentation for more information.](https://docs.helix-editor.com/configuration.html)
Features:
- LSP compatibility greatly improved for some implementations (Julia, Python, Typescript)
- Autocompletion! Completion now triggers automatically after a set idle timeout
- Completion documentation is now displayed next to the popup (#691)
- Treesitter textobjects (select a function via `mf`, class via `mc`) (#728)
- Global search across entire workspace `space+/` (#651)
- Relative line number support (#485)
- Prompts now store a history (72cf86e)
- `:vsplit` and `:hsplit` commands (#639)
- `C-w h/j/k/l` can now be used to navigate between splits (#860)
- `C-j` and `C-k` are now alternative keybindings to `C-n` and `C-p` in the UI (#876)
- Shell commands (shell-pipe, pipe-to, shell-insert-output, shell-append-output, keep-pipe) (#547)
- Searching now defaults to smart case search (case insensitive unless uppercase is used) (#761)
- Completion documentation is now displayed next to the popup ([#691](https://github.com/helix-editor/helix/pull/691))
- Treesitter textobjects (select a function via `mf`, class via `mc`) ([#728](https://github.com/helix-editor/helix/pull/728))
- Global search across entire workspace `space+/` ([#651](https://github.com/helix-editor/helix/pull/651))
- Relative line number support ([#485](https://github.com/helix-editor/helix/pull/485))
- Prompts now store a history ([`72cf86e`](https://github.com/helix-editor/helix/commit/72cf86e))
- `:vsplit` and `:hsplit` commands ([#639](https://github.com/helix-editor/helix/pull/639))
- `C-w h/j/k/l` can now be used to navigate between splits ([#860](https://github.com/helix-editor/helix/pull/860))
- `C-j` and `C-k` are now alternative keybindings to `C-n` and `C-p` in the UI ([#876](https://github.com/helix-editor/helix/pull/876))
- Shell commands (shell-pipe, pipe-to, shell-insert-output, shell-append-output, keep-pipe) ([#547](https://github.com/helix-editor/helix/pull/547))
- Searching now defaults to smart case search (case insensitive unless uppercase is used) ([#761](https://github.com/helix-editor/helix/pull/761))
- The preview pane was improved to highlight and center line ranges
- The user `languages.toml` is now merged into defaults, no longer need to copy the entire file (dc57f8dc)
- Show hidden files in completions (#648)
- Grammar injections are now properly handled (dd0b15e)
- `v` in select mode now switches back to normal mode (#660)
- View mode can now be triggered as a "sticky" mode (#719)
- `f`/`t` and object selection motions can now be repeated via `Alt-.` (#891)
- Statusline now displays total selection count and diagnostics counts for both errors and warnings (#916)
- The user `languages.toml` is now merged into defaults, no longer need to copy the entire file ([`dc57f8dc`](https://github.com/helix-editor/helix/commit/dc57f8dc))
- Show hidden files in completions ([#648](https://github.com/helix-editor/helix/pull/648))
- Grammar injections are now properly handled ([`dd0b15e`](https://github.com/helix-editor/helix/commit/dd0b15e))
- `v` in select mode now switches back to normal mode ([#660](https://github.com/helix-editor/helix/pull/660))
- View mode can now be triggered as a "sticky" mode ([#719](https://github.com/helix-editor/helix/pull/719))
- `f`/`t` and object selection motions can now be repeated via `Alt-.` ([#891](https://github.com/helix-editor/helix/pull/891))
- Statusline now displays total selection count and diagnostics counts for both errors and warnings ([#916](https://github.com/helix-editor/helix/pull/916))
New grammars:
- Ledger (#572)
- Protobuf (#614)
- Zig (#631)
- YAML (#667)
- Lua (#665)
- OCaml (#666)
- Svelte (#733)
- Vue (#787)
- Tree-sitter queries (#845)
- Elixir (we switched over to the official grammar) (6c0786e)
- Language server definitions for Nix and Elixir (#725)
- Ledger ([#572](https://github.com/helix-editor/helix/pull/572))
- Protobuf ([#614](https://github.com/helix-editor/helix/pull/614))
- Zig ([#631](https://github.com/helix-editor/helix/pull/631))
- YAML ([#667](https://github.com/helix-editor/helix/pull/667))
- Lua ([#665](https://github.com/helix-editor/helix/pull/665))
- OCaml ([#666](https://github.com/helix-editor/helix/pull/666))
- Svelte ([#733](https://github.com/helix-editor/helix/pull/733))
- Vue ([#787](https://github.com/helix-editor/helix/pull/787))
- Tree-sitter queries ([#845](https://github.com/helix-editor/helix/pull/845))
- CMake ([#888](https://github.com/helix-editor/helix/pull/888))
- Elixir (we switched over to the official grammar) ([`6c0786e`](https://github.com/helix-editor/helix/commit/6c0786e))
- Language server definitions for Nix and Elixir ([#725](https://github.com/helix-editor/helix/pull/725))
- Python now uses `pylsp` instead of `pyls`
- Python now supports indentation
New themes:
- Monokai (#628)
- Everforest Dark (#760)
- Nord (#799)
- Base16 Default Dark (#833)
- Rose Pine (#897)
- Monokai ([#628](https://github.com/helix-editor/helix/pull/628))
- Everforest Dark ([#760](https://github.com/helix-editor/helix/pull/760))
- Nord ([#799](https://github.com/helix-editor/helix/pull/799))
- Base16 Default Dark ([#833](https://github.com/helix-editor/helix/pull/833))
- Rose Pine ([#897](https://github.com/helix-editor/helix/pull/897))
Fixes:
- Fix crash on empty rust file (#592)
- Exit select mode after toggle comment (#598)
- Pin popups with no positioning to the initial position (12ea3888)
- xsel copy should not freeze the editor (6dd7dc4)
- `*` now only sets the search register and doesn't jump to the next occurrence (3426285)
- Goto line start/end commands extend when in select mode (#739)
- Fix documentation popups sometimes not getting fully highlighted (066367c)
- Refactor apply_workspace_edit to remove assert (b02d872)
- Wrap around the top of the picker menu when scrolling (c7d6e44)
- Don't allow closing the last split if there's unsaved changes (3ff5b00)
- Indentation used different default on hx vs hx new_file.txt (c913bad)
- Fix crash on empty rust file ([#592](https://github.com/helix-editor/helix/pull/592))
- Exit select mode after toggle comment ([#598](https://github.com/helix-editor/helix/pull/598))
- Pin popups with no positioning to the initial position ([`12ea3888`](https://github.com/helix-editor/helix/commit/12ea3888))
- xsel copy should not freeze the editor ([`6dd7dc4`](https://github.com/helix-editor/helix/commit/6dd7dc4))
- `*` now only sets the search register and doesn't jump to the next occurrence ([`3426285`](https://github.com/helix-editor/helix/commit/3426285))
- Goto line start/end commands extend when in select mode ([#739](https://github.com/helix-editor/helix/pull/739))
- Fix documentation popups sometimes not getting fully highlighted ([`066367c`](https://github.com/helix-editor/helix/commit/066367c))
- Refactor apply_workspace_edit to remove assert ([`b02d872`](https://github.com/helix-editor/helix/commit/b02d872))
- Wrap around the top of the picker menu when scrolling ([`c7d6e44`](https://github.com/helix-editor/helix/commit/c7d6e44))
- Don't allow closing the last split if there's unsaved changes ([`3ff5b00`](https://github.com/helix-editor/helix/commit/3ff5b00))
- Indentation used different default on hx vs hx new_file.txt ([`c913bad`](https://github.com/helix-editor/helix/commit/c913bad))
# 0.4.1 (2021-08-14)
A minor release that includes:
- A fix for rendering glitches that would occur after editing with multiple selections.
- CI fix for grammars not being cross-compiled for aarch64
- CI fix for grammars not being cross-compiled for aarch64
# 0.4.0 (2021-08-13)
@@ -103,10 +841,10 @@ selections in the future as well as resolves many bugs and edge cases.
- Autoinfo: `whichkey`-like popups which show available sub-mode shortcuts ([#316](https://github.com/helix-editor/helix/pull/316))
- Added WORD movements (W/B/E) ([#390](https://github.com/helix-editor/helix/pull/390))
- Vertical selections (repeat selection above/below) ([#462](https://github.com/helix-editor/helix/pull/462))
- Selection rotation via `(` and `)` ([66a90130](https://github.com/helix-editor/helix/commit/66a90130a5f99d769e9f6034025297f78ecaa3ec))
- Selection contents rotation via `Alt-(` and `Alt-)` ([02cba2a](https://github.com/helix-editor/helix/commit/02cba2a7f403f48eccb18100fb751f7b42373dba))
- Completion behavior improvements ([f917b5a4](https://github.com/helix-editor/helix/commit/f917b5a441ff3ae582358b6939ffbf889f4aa530), [627b899](https://github.com/helix-editor/helix/commit/627b89931576f7af86166ae8d5cbc55537877473))
- Fixed a language server crash ([385a6b5a](https://github.com/helix-editor/helix/commit/385a6b5a1adddfc26e917982641530e1a7c7aa81))
- Selection rotation via `(` and `)` ([`66a90130`](https://github.com/helix-editor/helix/commit/66a90130a5f99d769e9f6034025297f78ecaa3ec))
- Selection contents rotation via `Alt-(` and `Alt-)` ([`02cba2a`](https://github.com/helix-editor/helix/commit/02cba2a7f403f48eccb18100fb751f7b42373dba))
- Completion behavior improvements ([`f917b5a4`](https://github.com/helix-editor/helix/commit/f917b5a441ff3ae582358b6939ffbf889f4aa530), [`627b899`](https://github.com/helix-editor/helix/commit/627b89931576f7af86166ae8d5cbc55537877473))
- Fixed a language server crash ([`385a6b5a`](https://github.com/helix-editor/helix/commit/385a6b5a1adddfc26e917982641530e1a7c7aa81))
- Case change commands (`` ` ``, `~`, ``<a-`>``) ([#441](https://github.com/helix-editor/helix/pull/441))
- File pickers (including goto) now provide a preview! ([#534](https://github.com/helix-editor/helix/pull/534))
- Injection query support. Rust macro calls and embedded languages are now properly highlighted ([#430](https://github.com/helix-editor/helix/pull/430))
@@ -122,7 +860,7 @@ selections in the future as well as resolves many bugs and edge cases.
- Comment toggling now uses a language specific comment token ([#463](https://github.com/helix-editor/helix/pull/463))
- Julia support ([#413](https://github.com/helix-editor/helix/pull/413))
- Java support ([#448](https://github.com/helix-editor/helix/pull/448))
- Prompts have an (in-memory) history ([63e54e30](https://github.com/helix-editor/helix/commit/63e54e30a74bb0d1d782877ddbbcf95f2817d061))
- Prompts have an (in-memory) history ([`63e54e30`](https://github.com/helix-editor/helix/commit/63e54e30a74bb0d1d782877ddbbcf95f2817d061))
# 0.3.0 (2021-06-27)
@@ -136,7 +874,7 @@ Highlights:
- Support for other line endings (CRLF). Significantly improved Windows support. ([#224](https://github.com/helix-editor/helix/pull/224))
- Encodings other than UTF-8 are now supported! ([#228](https://github.com/helix-editor/helix/pull/228))
- Key bindings can now be configured via a `config.toml` file ([#268](https://github.com/helix-editor/helix/pull/268))
- Theme can now be configured and changed at runtime ([please feel free to contribute more themes!](https://github.com/helix-editor/helix/tree/master/runtime/themes)) ([#267](https://github.com/helix-editor/helix/pull/267))
- Theme can now be configured and changed at runtime. ([Please feel free to contribute more themes!](https://github.com/helix-editor/helix/tree/master/runtime/themes)) ([#267](https://github.com/helix-editor/helix/pull/267))
- System clipboard yank/paste is now supported! ([#310](https://github.com/helix-editor/helix/pull/310))
- Surround commands were implemented ([#320](https://github.com/helix-editor/helix/pull/320))
@@ -153,7 +891,7 @@ Features:
- Code is being migrated from helix-term to helix-view (prerequisite for
alternative frontends) ([#366](https://github.com/helix-editor/helix/pull/366))
- `x` and `X` merged
([f41688d9](https://github.com/helix-editor/helix/commit/f41688d960ef89c29c4a51c872b8406fb8f81a85))
([`f41688d9`](https://github.com/helix-editor/helix/commit/f41688d960ef89c29c4a51c872b8406fb8f81a85))
Fixes:
@@ -161,12 +899,12 @@ Fixes:
- A bunch of bugs regarding `o`/`O` behavior ([#281](https://github.com/helix-editor/helix/pull/281))
- `~` expansion now works in file completion ([#284](https://github.com/helix-editor/helix/pull/284))
- Several UI related overflow crashes ([#318](https://github.com/helix-editor/helix/pull/318))
- Fix a test failure occuring only on `test --release` ([4f108ab1](https://github.com/helix-editor/helix/commit/4f108ab1b2197809506bd7305ad903a3525eabfa))
- Fix a test failure occurring only on `test --release` ([`4f108ab1`](https://github.com/helix-editor/helix/commit/4f108ab1b2197809506bd7305ad903a3525eabfa))
- Prompts now support unicode input ([#295](https://github.com/helix-editor/helix/pull/295))
- Completion documentation no longer overlaps the popup ([#322](https://github.com/helix-editor/helix/pull/322))
- Fix a crash when trying to select `^` ([9c534614](https://github.com/helix-editor/helix/commit/9c53461429a3e72e3b1fb87d7ca490e168d7dee2))
- Prompt completions are now paginated ([39dc09e6](https://github.com/helix-editor/helix/commit/39dc09e6c4172299bc79de4c1c52288d3f624bd7))
- Goto did not work on Windows ([503ca112](https://github.com/helix-editor/helix/commit/503ca112ae57ebdf3ea323baf8940346204b46d2))
- Fix a crash when trying to select `^` ([`9c534614`](https://github.com/helix-editor/helix/commit/9c53461429a3e72e3b1fb87d7ca490e168d7dee2))
- Prompt completions are now paginated ([`39dc09e6`](https://github.com/helix-editor/helix/commit/39dc09e6c4172299bc79de4c1c52288d3f624bd7))
- Goto did not work on Windows ([`503ca112`](https://github.com/helix-editor/helix/commit/503ca112ae57ebdf3ea323baf8940346204b46d2))
# 0.2.1

763
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,13 +4,26 @@ members = [
"helix-view",
"helix-term",
"helix-tui",
"helix-syntax",
"helix-lsp",
"helix-dap",
"helix-loader",
"xtask",
]
# Build helix-syntax in release mode to make the code path faster in development.
# [profile.dev.package."helix-syntax"]
# opt-level = 3
default-members = [
"helix-term"
]
[profile.dev]
split-debuginfo = "unpacked"
[profile.release]
lto = "thin"
# debug = true
[profile.opt]
inherits = "release"
lto = "fat"
codegen-units = 1
# strip = "debuginfo" # TODO: or strip = true
opt-level = 3

View File

@@ -1,6 +1,5 @@
# Helix
[![Build status](https://github.com/helix-editor/helix/actions/workflows/build.yml/badge.svg)](https://github.com/helix-editor/helix/actions)
![Screenshot](./screenshot.png)
@@ -27,25 +26,35 @@ All shortcuts/keymaps can be found [in the documentation on the website](https:/
It's a terminal-based editor first, but I'd like to explore a custom renderer
(similar to emacs) in wgpu or skulpin.
Note: Only certain languages have indentation definitions at the moment. Check
`runtime/queries/<lang>/` for `indents.scm`.
# Installation
Note: Only certain languages have indentation definitions at the moment. Check
`runtime/queries/<lang>/` for `indents.toml`.
Packages are available for various distributions (see [Installation docs](https://docs.helix-editor.com/install.html)).
We provide packaging for various distributions, but here's a quick method to
build from source.
If you would like to build from source:
```
git clone --recurse-submodules --shallow-submodules -j8 https://github.com/helix-editor/helix
```shell
git clone https://github.com/helix-editor/helix
cd helix
cargo install --path helix-term
```
This will install the `hx` binary to `$HOME/.cargo/bin`.
This will install the `hx` binary to `$HOME/.cargo/bin` and build tree-sitter grammars.
If you want to customize your `languages.toml` config,
tree-sitter grammars may be manually fetched and built with `hx --grammar fetch` and `hx --grammar build`.
Helix also needs its runtime files so make sure to copy/symlink the `runtime/` directory into the
config directory (for example `~/.config/helix/runtime` on Linux/macOS). This location can be overriden
via the `HELIX_RUNTIME` environment variable.
config directory (for example `~/.config/helix/runtime` on Linux/macOS, or `%AppData%/helix/runtime` on Windows).
| OS | Command |
| -------------------- | -------------------------------------------- |
| Windows (cmd.exe) | `xcopy /e runtime %AppData%\helix\runtime` |
| Windows (PowerShell) | `xcopy /e runtime $Env:AppData\helix\runtime` |
| Linux/macOS | `ln -s $PWD/runtime ~/.config/helix/runtime` |
This location can be overridden via the `HELIX_RUNTIME` environment variable.
Packages already solve this for you by wrapping the `hx` binary with a wrapper
that sets the variable to the install dir.
@@ -53,33 +62,23 @@ that sets the variable to the install dir.
> NOTE: running via cargo also doesn't require setting explicit `HELIX_RUNTIME` path, it will automatically
> detect the `runtime` directory in the project root.
In order to use LSP features like auto-complete, you will need to
[install the appropriate Language Server](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers)
for a language.
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg)](https://repology.org/project/helix/versions)
## MacOS
Helix can be installed on MacOS through homebrew via:
Helix can be installed on MacOS through homebrew:
```
brew tap helix-editor/helix
brew install helix
```
# Contributing
Contributors are very welcome! **No contribution is too small and all contributions are valued.**
Some suggestions to get started:
- You can look at the [good first issue](https://github.com/helix-editor/helix/labels/E-easy) label on the issue tracker.
- Help with packaging on various distributions needed!
- To use print debugging to the `~/.cache/helix/helix.log` file, you must:
* Print using `log::info!`, `warn!`, or `error!`. (`log::info!("helix!")`)
* Pass the appropriate verbosity level option for the desired log level. (`hx -v <file>` for info, more `v`s for higher severity inclusive)
- If your preferred language is missing, integrating a tree-sitter grammar for
it and defining syntax highlight queries for it is straight forward and
doesn't require much knowledge of the internals.
We provide an [architecture.md](./docs/architecture.md) that should give you
a good overview of the internals.
Contributing guidelines can be found [here](./docs/CONTRIBUTING.md).
# Getting help

32
TODO.md
View File

@@ -1,32 +0,0 @@
- tree sitter:
- markdown
- regex
- kotlin
- clojure
- erlang
- [ ] completion isIncomplete support
1
- [ ] respect view fullscreen flag
- [ ] Implement marks (superset of Selection/Range)
- [ ] = for auto indent line/selection
- [ ] :x for closing buffers
- [ ] lsp: signature help
2
- [ ] macro recording
- [ ] extend selection (treesitter select parent node) (replaces viw, vi(, va( etc )
- [ ] selection align
- [ ] store some state between restarts: file positions, prompt history
- [ ] highlight matched characters in picker
3
- [ ] diff mode with highlighting?
- [ ] snippet support (tab to jump between marks)
- [ ] gamelisp/wasm scripting
X
- [ ] rendering via skulpin/skia or raw wgpu

1
VERSION Normal file
View File

@@ -0,0 +1 @@
22.08.1

50
base16_theme.toml Normal file
View File

@@ -0,0 +1,50 @@
# Author: NNB <nnbnh@protonmail.com>
"ui.menu" = { fg = "black", bg = "white" }
"ui.menu.selected" = { modifiers = ["reversed"] }
"ui.linenr" = { fg = "gray", bg = "black" }
"ui.popup" = { modifiers = ["reversed"] }
"ui.linenr.selected" = { fg = "white", bg = "black", modifiers = ["bold"] }
"ui.selection" = { fg = "black", bg = "blue" }
"ui.selection.primary" = { fg = "white", bg = "blue" }
"comment" = { fg = "gray" }
"ui.statusline" = { fg = "black", bg = "white" }
"ui.statusline.inactive" = { fg = "gray", bg = "white" }
"ui.cursor" = { fg = "white", modifiers = ["reversed"] }
"variable" = "red"
"constant.numeric" = "yellow"
"constant" = "yellow"
"attributes" = "yellow"
"type" = "yellow"
"ui.cursor.match" = { fg = "yellow", modifiers = ["underlined"] }
"string" = "green"
"variable.other.member" = "green"
"constant.character.escape" = "cyan"
"function" = "blue"
"constructor" = "blue"
"special" = "blue"
"keyword" = "magenta"
"label" = "magenta"
"namespace" = "magenta"
"ui.help" = { fg = "white", bg = "black" }
"markup.heading" = "blue"
"markup.list" = "red"
"markup.bold" = { fg = "yellow", modifiers = ["bold"] }
"markup.italic" = { fg = "magenta", modifiers = ["italic"] }
"markup.link.url" = { fg = "yellow", modifiers = ["underlined"] }
"markup.link.text" = "red"
"markup.quote" = "cyan"
"markup.raw" = "green"
"diff.plus" = "green"
"diff.delta" = "yellow"
"diff.minus" = "red"
"diagnostic" = { modifiers = ["underlined"] }
"ui.gutter" = { bg = "black" }
"info" = "blue"
"hint" = "gray"
"debug" = "gray"
"warning" = "yellow"
"error" = "red"

View File

@@ -1,12 +1,19 @@
# Summary
[Helix](./title-page.md)
- [Installation](./install.md)
- [Usage](./usage.md)
- [Keymap](./keymap.md)
- [Commands](./commands.md)
- [Language Support](./lang-support.md)
- [Migrating from Vim](./from-vim.md)
- [Configuration](./configuration.md)
- [Themes](./themes.md)
- [Keymap](./keymap.md)
- [Key Remapping](./remapping.md)
- [Hooks](./hooks.md)
- [Languages](./languages.md)
- [Guides](./guides/README.md)
- [Adding Languages](./guides/adding_languages.md)
- [Adding Textobject Queries](./guides/textobject.md)
- [Adding Indent Queries](./guides/indent.md)

5
book/src/commands.md Normal file
View File

@@ -0,0 +1,5 @@
# Commands
Command mode can be activated by pressing `:`, similar to vim. Built-in commands:
{{#include ./generated/typable-cmd.md}}

View File

@@ -5,9 +5,32 @@ To override global configuration parameters, create a `config.toml` file located
* Linux and Mac: `~/.config/helix/config.toml`
* Windows: `%AppData%\helix\config.toml`
> Hint: You can easily open the config file by typing `:config-open` within Helix normal mode.
Example config:
```toml
theme = "onedark"
[editor]
line-number = "relative"
mouse = false
[editor.cursor-shape]
insert = "bar"
normal = "block"
select = "underline"
[editor.file-picker]
hidden = false
```
You may also specify a file to use for configuration with the `-c` or
`--config` CLI argument: `hx -c path/to/custom-config.toml`.
## Editor
`[editor]` section of the config.
### `[editor]` Section
| Key | Description | Default |
|--|--|---------|
@@ -16,17 +39,193 @@ To override global configuration parameters, create a `config.toml` file located
| `middle-click-paste` | Middle click paste support. | `true` |
| `scroll-lines` | Number of lines to scroll per scroll wheel step. | `3` |
| `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` |
| `line-number` | Line number display (`absolute`, `relative`) | `absolute` |
| `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` |
| `auto-pairs` | Enable automatic insertion of pairs to parenthese, brackets, etc. | `true` |
| `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers. | `absolute` |
| `cursorline` | Highlight all lines with a cursor. | `false` |
| `gutters` | Gutters to display: Available are `diagnostics` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "line-numbers"]` |
| `auto-completion` | Enable automatic pop up of auto-completion. | `true` |
| `auto-format` | Enable automatic formatting on save. | `true` |
| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` |
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `auto-info` | Whether to display infoboxes | `true` |
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` |
| `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file. | `[]` |
| `color-modes` | Whether to color the mode indicator with different colors depending on the mode itself | `false` |
## LSP
### `[editor.statusline]` Section
Allows configuring the statusline at the bottom of the editor.
The configuration distinguishes between three areas of the status line:
`[ ... ... LEFT ... ... | ... ... ... ... CENTER ... ... ... ... | ... ... RIGHT ... ... ]`
Statusline elements can be defined as follows:
To display all language server messages in the status line add the following to your `config.toml`:
```toml
[lsp]
display-messages = true
[editor.statusline]
left = ["mode", "spinner"]
center = ["file-name"]
right = ["diagnostics", "selections", "position", "file-encoding", "file-line-ending", "file-type"]
separator = "│"
```
The following elements can be configured:
| Key | Description |
| ------ | ----------- |
| `mode` | The current editor mode (`NOR`/`INS`/`SEL`) |
| `spinner` | A progress spinner indicating LSP activity |
| `file-name` | The path/name of the opened file |
| `file-encoding` | The encoding of the opened file if it differs from UTF-8 |
| `file-line-ending` | The file line endings (CRLF or LF) |
| `file-type` | The type of the opened file |
| `diagnostics` | The number of warnings and/or errors |
| `selections` | The number of active selections |
| `position` | The cursor position |
| `position-percentage` | The cursor position as a percentage of the total number of lines |
| `separator` | The string defined in `editor.statusline.separator` (defaults to `"│"`) |
| `spacer` | Inserts a space between elements (multiple/contiguous spacers may be specified) |
### `[editor.lsp]` Section
| Key | Description | Default |
| --- | ----------- | ------- |
| `display-messages` | Display LSP progress messages below statusline[^1] | `false` |
| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
| `display-signature-help-docs` | Display docs under signature help popup | `true` |
[^1]: By default, a progress spinner is shown in the statusline beside the file path.
### `[editor.cursor-shape]` Section
Defines the shape of cursor in each mode. Note that due to limitations
of the terminal environment, only the primary cursor can change shape.
Valid values for these options are `block`, `bar`, `underline`, or `hidden`.
| Key | Description | Default |
| --- | ----------- | ------- |
| `normal` | Cursor shape in [normal mode][normal mode] | `block` |
| `insert` | Cursor shape in [insert mode][insert mode] | `block` |
| `select` | Cursor shape in [select mode][select mode] | `block` |
[normal mode]: ./keymap.md#normal-mode
[insert mode]: ./keymap.md#insert-mode
[select mode]: ./keymap.md#select--extend-mode
### `[editor.file-picker]` Section
Sets options for file picker and global search. All but the last key listed in
the default file-picker configuration below are IgnoreOptions: whether hidden
files and files listed within ignore files are ignored by (not visible in) the
helix file picker and global search. There is also one other key, `max-depth`
available, which is not defined by default.
All git related options are only enabled in a git repository.
| Key | Description | Default |
|--|--|---------|
|`hidden` | Enables ignoring hidden files. | true
|`parents` | Enables reading ignore files from parent directories. | true
|`ignore` | Enables reading `.ignore` files. | true
|`git-ignore` | Enables reading `.gitignore` files. | true
|`git-global` | Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option. | true
|`git-exclude` | Enables reading `.git/info/exclude` files. | true
|`max-depth` | Set with an integer value for maximum depth to recurse. | Defaults to `None`.
### `[editor.auto-pairs]` Section
Enables automatic insertion of pairs to parentheses, brackets, etc. Can be a
simple boolean value, or a specific mapping of pairs of single characters.
To disable auto-pairs altogether, set `auto-pairs` to `false`:
```toml
[editor]
auto-pairs = false # defaults to `true`
```
The default pairs are <code>(){}[]''""``</code>, but these can be customized by
setting `auto-pairs` to a TOML table:
```toml
[editor.auto-pairs]
'(' = ')'
'{' = '}'
'[' = ']'
'"' = '"'
'`' = '`'
'<' = '>'
```
Additionally, this setting can be used in a language config. Unless
the editor setting is `false`, this will override the editor config in
documents with this language.
Example `languages.toml` that adds <> and removes ''
```toml
[[language]]
name = "rust"
[language.auto-pairs]
'(' = ')'
'{' = '}'
'[' = ']'
'"' = '"'
'`' = '`'
'<' = '>'
```
### `[editor.search]` Section
Search specific options.
| Key | Description | Default |
|--|--|---------|
| `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` |
| `wrap-around`| Whether the search should wrap after depleting the matches | `true` |
### `[editor.whitespace]` Section
Options for rendering whitespace with visible characters. Use `:set whitespace.render all` to temporarily enable visible whitespace.
| Key | Description | Default |
|-----|-------------|---------|
| `render` | Whether to render whitespace. May either be `"all"` or `"none"`, or a table with sub-keys `space`, `tab`, and `newline`. | `"none"` |
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `newline` or `tabpad` | See example below |
Example
```toml
[editor.whitespace]
render = "all"
# or control each character
[editor.whitespace.render]
space = "all"
tab = "all"
newline = "none"
[editor.whitespace.characters]
space = "·"
nbsp = "⍽"
tab = "→"
newline = "⏎"
tabpad = "·" # Tabs will look like "→···" (depending on tab width)
```
### `[editor.indent-guides]` Section
Options for rendering vertical indent guides.
| Key | Description | Default |
| --- | --- | --- |
| `render` | Whether to render indent guides. | `false` |
| `character` | Literal character to use for rendering the indent guide | `│` |
Example:
```toml
[editor.indent-guides]
render = true
character = "╎"
```

View File

@@ -7,6 +7,6 @@ going to act on (a word, a paragraph, a line, etc) is selected first and the
action itself (delete, change, yank, etc) comes second. A cursor is simply a
single width selection.
See also Kakoune's [Migrating from Vim](https://github.com/mawww/kakoune/wiki/Migrating-from-Vim).
See also Kakoune's [Migrating from Vim](https://github.com/mawww/kakoune/wiki/Migrating-from-Vim) and Helix's [Migrating from Vim](https://github.com/helix-editor/helix/wiki/Migrating-from-Vim).
> TODO: Mention texobjects, surround, registers
> TODO: Mention textobjects, surround, registers

View File

@@ -0,0 +1,120 @@
| Language | Syntax Highlighting | Treesitter Textobjects | Auto Indent | Default LSP |
| --- | --- | --- | --- | --- |
| awk | ✓ | ✓ | | `awk-language-server` |
| bash | ✓ | | | `bash-language-server` |
| beancount | ✓ | | | |
| c | ✓ | ✓ | ✓ | `clangd` |
| c-sharp | ✓ | ✓ | | `OmniSharp` |
| cairo | ✓ | | | |
| clojure | ✓ | | | `clojure-lsp` |
| cmake | ✓ | ✓ | ✓ | `cmake-language-server` |
| comment | ✓ | | | |
| cpon | ✓ | | ✓ | |
| cpp | ✓ | ✓ | ✓ | `clangd` |
| css | ✓ | | | `vscode-css-language-server` |
| cue | ✓ | | | `cuelsp` |
| dart | ✓ | | ✓ | `dart` |
| devicetree | ✓ | | | |
| dockerfile | ✓ | | | `docker-langserver` |
| dot | ✓ | | | `dot-language-server` |
| edoc | ✓ | | | |
| eex | ✓ | | | |
| ejs | ✓ | | | |
| elixir | ✓ | ✓ | | `elixir-ls` |
| elm | ✓ | | | `elm-language-server` |
| elvish | ✓ | | | `elvish` |
| erb | ✓ | | | |
| erlang | ✓ | ✓ | | `erlang_ls` |
| esdl | ✓ | | | |
| fish | ✓ | ✓ | ✓ | |
| fortran | ✓ | | ✓ | `fortls` |
| gdscript | ✓ | | | |
| git-attributes | ✓ | | | |
| git-commit | ✓ | | | |
| git-config | ✓ | | | |
| git-diff | ✓ | | | |
| git-ignore | ✓ | | | |
| git-rebase | ✓ | | | |
| gleam | ✓ | ✓ | | `gleam` |
| glsl | ✓ | ✓ | ✓ | |
| go | ✓ | ✓ | ✓ | `gopls` |
| gomod | ✓ | | | `gopls` |
| gotmpl | ✓ | | | `gopls` |
| gowork | ✓ | | | `gopls` |
| graphql | ✓ | | | |
| hare | ✓ | | | |
| haskell | ✓ | | | `haskell-language-server-wrapper` |
| hcl | ✓ | | ✓ | `terraform-ls` |
| heex | ✓ | ✓ | | |
| html | ✓ | | | `vscode-html-language-server` |
| idris | | | | `idris2-lsp` |
| iex | ✓ | | | |
| java | ✓ | | | `jdtls` |
| javascript | ✓ | ✓ | ✓ | `typescript-language-server` |
| jsdoc | ✓ | | | |
| json | ✓ | | ✓ | `vscode-json-language-server` |
| jsx | ✓ | ✓ | ✓ | `typescript-language-server` |
| julia | ✓ | | | `julia` |
| kotlin | ✓ | | | `kotlin-language-server` |
| latex | ✓ | ✓ | | `texlab` |
| lean | ✓ | | | `lean` |
| ledger | ✓ | | | |
| llvm | ✓ | ✓ | ✓ | |
| llvm-mir | ✓ | ✓ | ✓ | |
| llvm-mir-yaml | ✓ | | ✓ | |
| lua | ✓ | | ✓ | `lua-language-server` |
| make | ✓ | | | |
| markdown | ✓ | | | |
| markdown.inline | ✓ | | | |
| meson | ✓ | | ✓ | |
| mint | | | | `mint` |
| nickel | ✓ | | ✓ | `nls` |
| nix | ✓ | | | `rnix-lsp` |
| nu | ✓ | | | |
| ocaml | ✓ | | ✓ | `ocamllsp` |
| ocaml-interface | ✓ | | | `ocamllsp` |
| odin | ✓ | | | `ols` |
| openscad | ✓ | | | `openscad-language-server` |
| org | ✓ | | | |
| pascal | ✓ | ✓ | | `pasls` |
| perl | ✓ | ✓ | ✓ | |
| php | ✓ | ✓ | ✓ | `intelephense` |
| prisma | ✓ | | | `prisma-language-server` |
| prolog | | | | `swipl` |
| protobuf | ✓ | | ✓ | |
| python | ✓ | ✓ | | `pylsp` |
| r | ✓ | | | `R` |
| racket | | | | `racket` |
| regex | ✓ | | | |
| rescript | ✓ | ✓ | | `rescript-language-server` |
| rmarkdown | ✓ | | ✓ | `R` |
| ron | ✓ | | ✓ | |
| ruby | ✓ | ✓ | ✓ | `solargraph` |
| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
| scala | ✓ | | ✓ | `metals` |
| scheme | ✓ | | | |
| scss | ✓ | | | `vscode-css-language-server` |
| slint | ✓ | | ✓ | `slint-lsp` |
| solidity | ✓ | | | `solc` |
| sql | ✓ | | | |
| sshclientconfig | ✓ | | | |
| starlark | ✓ | ✓ | | |
| svelte | ✓ | | | `svelteserver` |
| swift | ✓ | | | `sourcekit-lsp` |
| tablegen | ✓ | ✓ | ✓ | |
| task | ✓ | | | |
| tfvars | | | | `terraform-ls` |
| toml | ✓ | | | `taplo` |
| tsq | ✓ | | | |
| tsx | ✓ | ✓ | ✓ | `typescript-language-server` |
| twig | ✓ | | | |
| typescript | ✓ | ✓ | ✓ | `typescript-language-server` |
| ungrammar | ✓ | | | |
| v | ✓ | | | `vls` |
| vala | ✓ | | | `vala-language-server` |
| verilog | ✓ | ✓ | | `svlangserver` |
| vue | ✓ | | | `vls` |
| wgsl | ✓ | | | `wgsl_analyzer` |
| xit | ✓ | | | |
| yaml | ✓ | | ✓ | `yaml-language-server` |
| zig | ✓ | | ✓ | `zls` |

View File

@@ -0,0 +1,70 @@
| Name | Description |
| --- | --- |
| `:quit`, `:q` | Close the current view. |
| `:quit!`, `:q!` | Force close the current view, ignoring unsaved changes. |
| `:open`, `:o` | Open a file from disk into the current view. |
| `:buffer-close`, `:bc`, `:bclose` | Close the current buffer. |
| `:buffer-close!`, `:bc!`, `:bclose!` | Close the current buffer forcefully, ignoring unsaved changes. |
| `:buffer-close-others`, `:bco`, `:bcloseother` | Close all buffers but the currently focused one. |
| `:buffer-close-others!`, `:bco!`, `:bcloseother!` | Force close all buffers but the currently focused one. |
| `:buffer-close-all`, `:bca`, `:bcloseall` | Close all buffers without quitting. |
| `:buffer-close-all!`, `:bca!`, `:bcloseall!` | Force close all buffers ignoring unsaved changes without quitting. |
| `:buffer-next`, `:bn`, `:bnext` | Goto next buffer. |
| `:buffer-previous`, `:bp`, `:bprev` | Goto previous buffer. |
| `:write`, `:w` | Write changes to disk. Accepts an optional path (:write some/path.txt) |
| `:write!`, `:w!` | Force write changes to disk creating necessary subdirectories. Accepts an optional path (:write some/path.txt) |
| `:new`, `:n` | Create a new scratch buffer. |
| `:format`, `:fmt` | Format the file using the LSP formatter. |
| `:indent-style` | Set the indentation style for editing. ('t' for tabs or 1-8 for number of spaces.) |
| `:line-ending` | Set the document's default line ending. Options: crlf, lf. |
| `:earlier`, `:ear` | Jump back to an earlier point in edit history. Accepts a number of steps or a time span. |
| `:later`, `:lat` | Jump to a later point in edit history. Accepts a number of steps or a time span. |
| `:write-quit`, `:wq`, `:x` | Write changes to disk and close the current view. Accepts an optional path (:wq some/path.txt) |
| `:write-quit!`, `:wq!`, `:x!` | Write changes to disk and close the current view forcefully. Accepts an optional path (:wq! some/path.txt) |
| `:write-all`, `:wa` | Write changes from all buffers to disk. |
| `:write-quit-all`, `:wqa`, `:xa` | Write changes from all buffers to disk and close all views. |
| `:write-quit-all!`, `:wqa!`, `:xa!` | Write changes from all buffers to disk and close all views forcefully (ignoring unsaved changes). |
| `:quit-all`, `:qa` | Close all views. |
| `:quit-all!`, `:qa!` | Force close all views ignoring unsaved changes. |
| `:cquit`, `:cq` | Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2). |
| `:cquit!`, `:cq!` | Force quit with exit code (default 1) ignoring unsaved changes. Accepts an optional integer exit code (:cq! 2). |
| `:theme` | Change the editor theme. |
| `:clipboard-yank` | Yank main selection into system clipboard. |
| `:clipboard-yank-join` | Yank joined selections into system clipboard. A separator can be provided as first argument. Default value is newline. |
| `:primary-clipboard-yank` | Yank main selection into system primary clipboard. |
| `:primary-clipboard-yank-join` | Yank joined selections into system primary clipboard. A separator can be provided as first argument. Default value is newline. |
| `:clipboard-paste-after` | Paste system clipboard after selections. |
| `:clipboard-paste-before` | Paste system clipboard before selections. |
| `:clipboard-paste-replace` | Replace selections with content of system clipboard. |
| `:primary-clipboard-paste-after` | Paste primary clipboard after selections. |
| `:primary-clipboard-paste-before` | Paste primary clipboard before selections. |
| `:primary-clipboard-paste-replace` | Replace selections with content of system primary clipboard. |
| `:show-clipboard-provider` | Show clipboard provider name in status bar. |
| `:change-current-directory`, `:cd` | Change the current working directory. |
| `:show-directory`, `:pwd` | Show the current working directory. |
| `:encoding` | Set encoding. Based on `https://encoding.spec.whatwg.org`. |
| `:reload` | Discard changes and reload from the source file. |
| `:tree-sitter-scopes` | Display tree sitter scopes, primarily for theming and development. |
| `:debug-start`, `:dbg` | Start a debug session from a given template with given parameters. |
| `:debug-remote`, `:dbg-tcp` | Connect to a debug adapter by TCP address and start a debugging session from a given template with given parameters. |
| `:debug-eval` | Evaluate expression in current debug context. |
| `:vsplit`, `:vs` | Open the file in a vertical split. |
| `:vsplit-new`, `:vnew` | Open a scratch buffer in a vertical split. |
| `:hsplit`, `:hs`, `:sp` | Open the file in a horizontal split. |
| `:hsplit-new`, `:hnew` | Open a scratch buffer in a horizontal split. |
| `:tutor` | Open the tutorial. |
| `:goto`, `:g` | Goto line number. |
| `:set-language`, `:lang` | Set the language of current buffer. |
| `:set-option`, `:set` | Set a config option at runtime.<br>For example to disable smart case search, use `:set search.smart-case false`. |
| `:get-option`, `:get` | Get the current value of a config option. |
| `:sort` | Sort ranges in selection. |
| `:rsort` | Sort ranges in selection in reverse order. |
| `:reflow` | Hard-wrap the current selection of lines to a given width. |
| `:tree-sitter-subtree`, `:ts-subtree` | Display tree sitter subtree under cursor, primarily for debugging queries. |
| `:config-reload` | Refresh user config. |
| `:config-open` | Open the user config.toml file. |
| `:log-open` | Open the helix log file. |
| `:insert-output` | Run shell command, inserting output after each selection. |
| `:append-output` | Run shell command, appending output after each selection. |
| `:pipe` | Pipe each selection to the shell command. |
| `:run-shell-command`, `:sh` | Run a shell command |

View File

@@ -1,4 +1,4 @@
# Guides
This section contains guides for adding new language server configurations,
tree-sitter grammers, textobject queries, etc.
tree-sitter grammars, textobject queries, etc.

View File

@@ -0,0 +1,45 @@
# Adding languages
## Language configuration
To add a new language, you need to add a `[[language]]` entry to the
`languages.toml` (see the [language configuration section]).
When adding a new language or Language Server configuration for an existing
language, run `cargo xtask docgen` to add the new configuration to the
[Language Support][lang-support] docs before creating a pull request.
When adding a Language Server configuration, be sure to update the
[Language Server Wiki][install-lsp-wiki] with installation notes.
## Grammar configuration
If a tree-sitter grammar is available for the language, add a new `[[grammar]]`
entry to `languages.toml`.
You may use the `source.path` key rather than `source.git` with an absolute path
to a locally available grammar for testing, but switch to `source.git` before
submitting a pull request.
## Queries
For a language to have syntax-highlighting and indentation among
other things, you have to add queries. Add a directory for your
language with the path `runtime/queries/<name>/`. The tree-sitter
[website](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries)
gives more info on how to write queries.
> NOTE: When evaluating queries, the first matching query takes
precedence, which is different from other editors like neovim where
the last matching query supersedes the ones before it. See
[this issue][neovim-query-precedence] for an example.
## Common Issues
- If you get errors when running after switching branches, you may have to update the tree-sitter grammars. Run `hx --grammar fetch` to fetch the grammars and `hx --grammar build` to build any out-of-date grammars.
- If a parser is segfaulting or you want to remove the parser, make sure to remove the compiled parser in `runtime/grammar/<name>.so`
[language configuration section]: ../languages.md
[neovim-query-precedence]: https://github.com/helix-editor/helix/pull/1170#issuecomment-997294090
[install-lsp-wiki]: https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers
[lang-support]: ../lang-support.md

79
book/src/guides/indent.md Normal file
View File

@@ -0,0 +1,79 @@
# Adding Indent Queries
Helix uses tree-sitter to correctly indent new lines. This requires
a tree-sitter grammar and an `indent.scm` query file placed in
`runtime/queries/{language}/indents.scm`. The indentation for a line
is calculated by traversing the syntax tree from the lowest node at the
beginning of the new line. Each of these nodes contributes to the total
indent when it is captured by the query (in what way depends on the name
of the capture).
Note that it matters where these added indents begin. For example,
multiple indent level increases that start on the same line only increase
the total indent level by 1.
## Scopes
Added indents don't always apply to the whole node. For example, in most
cases when a node should be indented, we actually only want everything
except for its first line to be indented. For this, there are several
scopes (more scopes may be added in the future if required):
- `all`:
This scope applies to the whole captured node. This is only different from
`tail` when the captured node is the first node on its line.
- `tail`:
This scope applies to everything except for the first line of the
captured node.
Every capture type has a default scope which should do the right thing
in most situations. When a different scope is required, this can be
changed by using a `#set!` declaration anywhere in the pattern:
```scm
(assignment_expression
right: (_) @indent
(#set! "scope" "all"))
```
## Capture Types
- `@indent` (default scope `tail`):
Increase the indent level by 1. Multiple occurrences in the same line
don't stack. If there is at least one `@indent` and one `@outdent`
capture on the same line, the indent level isn't changed at all.
- `@outdent` (default scope `all`):
Decrease the indent level by 1. The same rules as for `@indent` apply.
## Predicates
In some cases, an S-expression cannot express exactly what pattern should be matched.
For that, tree-sitter allows for predicates to appear anywhere within a pattern,
similar to how `#set!` declarations work:
```scm
(some_kind
(child_kind) @indent
(#predicate? arg1 arg2 ...)
)
```
The number of arguments depends on the predicate that's used.
Each argument is either a capture (`@name`) or a string (`"some string"`).
The following predicates are supported by tree-sitter:
- `#eq?`/`#not-eq?`:
The first argument (a capture) must/must not be equal to the second argument
(a capture or a string).
- `#match?`/`#not-match?`:
The first argument (a capture) must/must not match the regex given in the
second argument (a string).
Additionally, we support some custom predicates for indent queries:
- `#not-kind-eq?`:
The kind of the first argument (a capture) must not be equal to the second
argument (a string).
- `#same-line?`/`#not-same-line?`:
The captures given by the 2 arguments must/must not start on the same line.

View File

@@ -5,7 +5,7 @@ require an accompanying tree-sitter grammar and a `textobjects.scm` query file
to work properly. Tree-sitter allows us to query the source code syntax tree
and capture specific parts of it. The queries are written in a lisp dialect.
More information on how to write queries can be found in the [official tree-sitter
documentation](tree-sitter-queries).
documentation][tree-sitter-queries].
Query files should be placed in `runtime/queries/{language}/textobjects.scm`
when contributing. Note that to test the query files locally you should put
@@ -20,11 +20,30 @@ The following [captures][tree-sitter-captures] are recognized:
| `function.around` |
| `class.inside` |
| `class.around` |
| `test.inside` |
| `test.around` |
| `parameter.inside` |
| `comment.inside` |
| `comment.around` |
[Example query files][textobject-examples] can be found in the helix GitHub repository.
## Queries for Textobject Based Navigation
[Tree-sitter based navigation][textobjects-nav] is done using captures in the
following order:
- `object.movement`
- `object.around`
- `object.inside`
For example if a `function.around` capture has been already defined for a language
in it's `textobjects.scm` file, function navigation should also work automatically.
`function.movement` should be defined only if the node captured by `function.around`
doesn't make sense in a navigation context.
[textobjects]: ../usage.md#textobjects
[textobjects-nav]: ../usage.md#tree-sitter-textobject-based-navigation
[tree-sitter-queries]: https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax
[tree-sitter-captures]: https://tree-sitter.github.io/tree-sitter/using-parsers#capturing-nodes
[textobject-examples]: https://github.com/search?q=repo%3Ahelix-editor%2Fhelix+filename%3Atextobjects.scm&type=Code&ref=advsearch&l=&l=

View File

@@ -6,10 +6,9 @@ We provide pre-built binaries on the [GitHub Releases page](https://github.com/h
## OSX
A Homebrew tap is available:
Helix is available in homebrew-core:
```
brew tap helix-editor/helix
brew install helix
```
@@ -19,20 +18,42 @@ brew install helix
A [flake](https://nixos.wiki/wiki/Flakes) containing the package is available in
the project root. The flake can also be used to spin up a reproducible development
shell for working on Helix.
shell for working on Helix with `nix develop`.
Flake outputs are cached for each push to master using
[Cachix](https://www.cachix.org/). The flake is configured to
automatically make use of this cache assuming the user accepts
the new settings on first use.
If you are using a version of Nix without flakes enabled you can
[install Cachix cli](https://docs.cachix.org/installation); `cachix use helix` will
configure Nix to use cached outputs when possible.
### Arch Linux
Releases are available in the `community` repository.
Packages are also available on AUR:
- [helix-bin](https://aur.archlinux.org/packages/helix-bin/) contains the pre-built release
- [helix-git](https://aur.archlinux.org/packages/helix-git/) builds the master branch
A [helix-git](https://aur.archlinux.org/packages/helix-git/) package is also available on the AUR, which builds the master branch.
### Fedora Linux
You can install the COPR package for Helix via
```
sudo dnf copr enable varlad/helix
sudo dnf install helix
```
### Void Linux
```
sudo xbps-install helix
```
## Build from source
```
git clone --recurse-submodules --shallow-submodules -j8 https://github.com/helix-editor/helix
git clone https://github.com/helix-editor/helix
cd helix
cargo install --path helix-term
```
@@ -40,5 +61,31 @@ cargo install --path helix-term
This will install the `hx` binary to `$HOME/.cargo/bin`.
Helix also needs it's runtime files so make sure to copy/symlink the `runtime/` directory into the
config directory (for example `~/.config/helix/runtime` on Linux/macOS). This location can be overriden
config directory (for example `~/.config/helix/runtime` on Linux/macOS). This location can be overridden
via the `HELIX_RUNTIME` environment variable.
| OS | command |
|-------------------|-----------|
|windows(cmd.exe) |`xcopy /e runtime %AppData%/helix/runtime` |
|windows(powershell)|`xcopy /e runtime $Env:AppData\helix\runtime` |
|linux/macos |`ln -s $PWD/runtime ~/.config/helix/runtime`|
## Finishing up the installation
To make sure everything is set up as expected you should finally run the helix healthcheck via
```
hx --health
```
For more information on the information displayed in the healthcheck results refer to [Healthcheck](https://github.com/helix-editor/helix/wiki/Healthcheck).
### Building tree-sitter grammars
Tree-sitter grammars must be fetched and compiled if not pre-packaged.
Fetch grammars with `hx --grammar fetch` (requires `git`) and compile them
with `hx --grammar build` (requires a C++ compiler).
### Installing language servers
Language servers can optionally be installed if you want their features (auto-complete, diagnostics etc.).
Follow the [instructions on the wiki page](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers) to add your language servers of choice.

View File

@@ -1,124 +1,169 @@
# Keymap
- [Normal mode](#normal-mode)
- [Movement](#movement)
- [Changes](#changes)
- [Shell](#shell)
- [Selection manipulation](#selection-manipulation)
- [Search](#search)
- [Minor modes](#minor-modes)
- [View mode](#view-mode)
- [Goto mode](#goto-mode)
- [Match mode](#match-mode)
- [Window mode](#window-mode)
- [Space mode](#space-mode)
- [Popup](#popup)
- [Unimpaired](#unimpaired)
- [Insert Mode](#insert-mode)
- [Select / extend mode](#select--extend-mode)
- [Picker](#picker)
- [Prompt](#prompt)
> 💡 Mappings marked (**LSP**) require an active language server for the file.
> 💡 Mappings marked (**TS**) require a tree-sitter grammar for the filetype.
## Normal mode
### Movement
> NOTE: Unlike vim, `f`, `F`, `t` and `T` are not confined to the current line.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `h`/`Left` | Move left | `move_char_left` |
| `j`/`Down` | Move down | `move_line_down` |
| `k`/`Up` | Move up | `move_line_up` |
| `l`/`Right` | Move right | `move_char_right` |
| `w` | Move next word start | `move_next_word_start` |
| `b` | Move previous word start | `move_prev_word_start` |
| `e` | Move next word end | `move_next_word_end` |
| `W` | Move next WORD start | `move_next_long_word_start` |
| `B` | Move previous WORD start | `move_prev_long_word_start` |
| `E` | Move next WORD end | `move_next_long_word_end` |
| `t` | Find 'till next char | `find_till_char` |
| `f` | Find next char | `find_next_char` |
| `T` | Find 'till previous char | `till_prev_char` |
| `F` | Find previous char | `find_prev_char` |
| `Alt-.` | Repeat last motion (`f`, `t` or `m`) | `repeat_last_motion` |
| `Home` | Move to the start of the line | `goto_line_start` |
| `End` | Move to the end of the line | `goto_line_end` |
| `PageUp` | Move page up | `page_up` |
| `PageDown` | Move page down | `page_down` |
| `Ctrl-u` | Move half page up | `half_page_up` |
| `Ctrl-d` | Move half page down | `half_page_down` |
| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` |
| `Ctrl-o` | Jump backward on the jumplist | `jump_backward` |
| `v` | Enter [select (extend) mode](#select--extend-mode) | `select_mode` |
| `g` | Enter [goto mode](#goto-mode) | N/A |
| `m` | Enter [match mode](#match-mode) | N/A |
| `:` | Enter command mode | `command_mode` |
| `z` | Enter [view mode](#view-mode) | N/A |
| `Z` | Enter sticky [view mode](#view-mode) | N/A |
| `Ctrl-w` | Enter [window mode](#window-mode) | N/A |
| `Space` | Enter [space mode](#space-mode) | N/A |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `h`, `Left` | Move left | `move_char_left` |
| `j`, `Down` | Move down | `move_line_down` |
| `k`, `Up` | Move up | `move_line_up` |
| `l`, `Right` | Move right | `move_char_right` |
| `w` | Move next word start | `move_next_word_start` |
| `b` | Move previous word start | `move_prev_word_start` |
| `e` | Move next word end | `move_next_word_end` |
| `W` | Move next WORD start | `move_next_long_word_start` |
| `B` | Move previous WORD start | `move_prev_long_word_start` |
| `E` | Move next WORD end | `move_next_long_word_end` |
| `t` | Find 'till next char | `find_till_char` |
| `f` | Find next char | `find_next_char` |
| `T` | Find 'till previous char | `till_prev_char` |
| `F` | Find previous char | `find_prev_char` |
| `G` | Go to line number `<n>` | `goto_line` |
| `Alt-.` | Repeat last motion (`f`, `t` or `m`) | `repeat_last_motion` |
| `Home` | Move to the start of the line | `goto_line_start` |
| `End` | Move to the end of the line | `goto_line_end` |
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
| `Ctrl-u` | Move half page up | `half_page_up` |
| `Ctrl-d` | Move half page down | `half_page_down` |
| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` |
| `Ctrl-o` | Jump backward on the jumplist | `jump_backward` |
| `Ctrl-s` | Save the current selection to the jumplist | `save_selection` |
### Changes
| Key | Description | Command |
| ----- | ----------- | ------- |
| `r` | Replace with a character | `replace` |
| `R` | Replace with yanked text | `replace_with_yanked` |
| `~` | Switch case of the selected text | `switch_case` |
| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` |
| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` |
| `i` | Insert before selection | `insert_mode` |
| `a` | Insert after selection (append) | `append_mode` |
| `I` | Insert at the start of the line | `prepend_to_line` |
| `A` | Insert at the end of the line | `append_to_line` |
| `o` | Open new line below selection | `open_below` |
| `O` | Open new line above selection | `open_above` |
| `.` | Repeat last change | N/A |
| `u` | Undo change | `undo` |
| `U` | Redo change | `redo` |
| `y` | Yank selection | `yank` |
| `p` | Paste after selection | `paste_after` |
| `P` | Paste before selection | `paste_before` |
| `"` `<reg>` | Select a register to yank to or paste from | `select_register` |
| `>` | Indent selection | `indent` |
| `<` | Unindent selection | `unindent` |
| `=` | Format selection | `format_selections` |
| `d` | Delete selection | `delete_selection` |
| `c` | Change selection (delete and enter insert mode) | `change_selection` |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `r` | Replace with a character | `replace` |
| `R` | Replace with yanked text | `replace_with_yanked` |
| `~` | Switch case of the selected text | `switch_case` |
| `` ` `` | Set the selected text to lower case | `switch_to_lowercase` |
| `` Alt-` `` | Set the selected text to upper case | `switch_to_uppercase` |
| `i` | Insert before selection | `insert_mode` |
| `a` | Insert after selection (append) | `append_mode` |
| `I` | Insert at the start of the line | `prepend_to_line` |
| `A` | Insert at the end of the line | `append_to_line` |
| `o` | Open new line below selection | `open_below` |
| `O` | Open new line above selection | `open_above` |
| `.` | Repeat last insert | N/A |
| `u` | Undo change | `undo` |
| `U` | Redo change | `redo` |
| `Alt-u` | Move backward in history | `earlier` |
| `Alt-U` | Move forward in history | `later` |
| `y` | Yank selection | `yank` |
| `p` | Paste after selection | `paste_after` |
| `P` | Paste before selection | `paste_before` |
| `"` `<reg>` | Select a register to yank to or paste from | `select_register` |
| `>` | Indent selection | `indent` |
| `<` | Unindent selection | `unindent` |
| `=` | Format selection (currently nonfunctional/disabled) (**LSP**) | `format_selections` |
| `d` | Delete selection | `delete_selection` |
| `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` |
| `c` | Change selection (delete and enter insert mode) | `change_selection` |
| `Alt-c` | Change selection (delete and enter insert mode, without yanking) | `change_selection_noyank` |
| `Ctrl-a` | Increment object (number) under cursor | `increment` |
| `Ctrl-x` | Decrement object (number) under cursor | `decrement` |
| `Q` | Start/stop macro recording to the selected register (experimental) | `record_macro` |
| `q` | Play back a recorded macro from the selected register (experimental) | `replay_macro` |
#### Shell
| Key | Description | Command |
| ------ | ----------- | ------- |
| <code>&#124;</code> | Pipe each selection through shell command, replacing with output | `shell_pipe` |
| <code>A-&#124;</code> | Pipe each selection into shell command, ignoring output | `shell_pipe_to` |
| `!` | Run shell command, inserting output before each selection | `shell_insert_output` |
| `A-!` | Run shell command, appending output after each selection | `shell_append_output` |
| Key | Description | Command |
| ------ | ----------- | ------- |
| <code>&#124;</code> | Pipe each selection through shell command, replacing with output | `shell_pipe` |
| <code>Alt-&#124;</code> | Pipe each selection into shell command, ignoring output | `shell_pipe_to` |
| `!` | Run shell command, inserting output before each selection | `shell_insert_output` |
| `Alt-!` | Run shell command, appending output after each selection | `shell_append_output` |
| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` |
### Selection manipulation
| Key | Description | Command |
| ----- | ----------- | ------- |
| `s` | Select all regex matches inside selections | `select_regex` |
| `S` | Split selection into subselections on regex matches | `split_selection` |
| `Alt-s` | Split selection on newlines | `split_selection_on_newline` |
| `;` | Collapse selection onto a single cursor | `collapse_selection` |
| `Alt-;` | Flip selection cursor and anchor | `flip_selections` |
| `,` | Keep only the primary selection | `keep_primary_selection` |
| `Alt-,` | Remove the primary selection | `remove_primary_selection` |
| `C` | Copy selection onto the next line | `copy_selection_on_next_line` |
| `Alt-C` | Copy selection onto the previous line | `copy_selection_on_prev_line` |
| `(` | Rotate main selection backward | `rotate_selections_backward` |
| `)` | Rotate main selection forward | `rotate_selections_forward` |
| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` |
| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` |
| `%` | Select entire file | `select_all` |
| `x` | Select current line, if already selected, extend to next line | `extend_line` |
| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` |
| | Expand selection to parent syntax node TODO: pick a key | `expand_selection` |
| `J` | Join lines inside selection | `join_selections` |
| `K` | Keep selections matching the regex | `keep_selections` |
| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` |
| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `s` | Select all regex matches inside selections | `select_regex` |
| `S` | Split selection into subselections on regex matches | `split_selection` |
| `Alt-s` | Split selection on newlines | `split_selection_on_newline` |
| `&` | Align selection in columns | `align_selections` |
| `_` | Trim whitespace from the selection | `trim_selections` |
| `;` | Collapse selection onto a single cursor | `collapse_selection` |
| `Alt-;` | Flip selection cursor and anchor | `flip_selections` |
| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` |
| `,` | Keep only the primary selection | `keep_primary_selection` |
| `Alt-,` | Remove the primary selection | `remove_primary_selection` |
| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` |
| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` |
| `(` | Rotate main selection backward | `rotate_selections_backward` |
| `)` | Rotate main selection forward | `rotate_selections_forward` |
| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` |
| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` |
| `%` | Select entire file | `select_all` |
| `x` | Select current line, if already selected, extend to next line | `extend_line_below` |
| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` |
| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` |
| `J` | Join lines inside selection | `join_selections` |
| `K` | Keep selections matching the regex | `keep_selections` |
| `Alt-K` | Remove selections matching the regex | `remove_selections` |
| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` |
| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` |
| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` |
| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` |
| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` |
### Search
> TODO: The search implementation isn't ideal yet -- we don't support searching in reverse.
Search commands all operate on the `/` register by default. Use `"<char>` to operate on a different one.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `/` | Search for regex pattern | `search` |
| `?` | Search for previous pattern | `rsearch` |
| `n` | Select next search match | `search_next` |
| `N` | Add next search match to selection | `extend_search_next` |
| `N` | Select previous search match | `search_prev` |
| `*` | Use current selection as the search pattern | `search_selection` |
### Minor modes
These sub-modes are accessible from normal mode and typically switch back to normal mode after a command.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `v` | Enter [select (extend) mode](#select--extend-mode) | `select_mode` |
| `g` | Enter [goto mode](#goto-mode) | N/A |
| `m` | Enter [match mode](#match-mode) | N/A |
| `:` | Enter command mode | `command_mode` |
| `z` | Enter [view mode](#view-mode) | N/A |
| `Z` | Enter sticky [view mode](#view-mode) | N/A |
| `Ctrl-w` | Enter [window mode](#window-mode) | N/A |
| `Space` | Enter [space mode](#space-mode) | N/A |
#### View mode
View mode is intended for scrolling and manipulating the view without changing
@@ -127,50 +172,53 @@ key to return to normal mode after usage (useful when you're simply looking
over text and not actively editing it).
| Key | Description | Command |
| ----- | ----------- | ------- |
| `z` , `c` | Vertically center the line | `align_view_center` |
| `t` | Align the line to the top of the screen | `align_view_top` |
| `b` | Align the line to the bottom of the screen | `align_view_bottom` |
| `m` | Align the line to the middle of the screen (horizontally) | `align_view_middle` |
| `j` | Scroll the view downwards | `scroll_down` |
| `k` | Scroll the view upwards | `scroll_up` |
| `f` | Move page down | `page_down` |
| `b` | Move page up | `page_up` |
| `d` | Move half page down | `half_page_down` |
| `u` | Move half page up | `half_page_up` |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `z`, `c` | Vertically center the line | `align_view_center` |
| `t` | Align the line to the top of the screen | `align_view_top` |
| `b` | Align the line to the bottom of the screen | `align_view_bottom` |
| `m` | Align the line to the middle of the screen (horizontally) | `align_view_middle` |
| `j`, `down` | Scroll the view downwards | `scroll_down` |
| `k`, `up` | Scroll the view upwards | `scroll_up` |
| `Ctrl-f`, `PageDown` | Move page down | `page_down` |
| `Ctrl-b`, `PageUp` | Move page up | `page_up` |
| `Ctrl-d` | Move half page down | `half_page_down` |
| `Ctrl-u` | Move half page up | `half_page_up` |
#### Goto mode
Jumps to various locations.
> NOTE: Some of these features are only available with the LSP present.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `g` | Go to the start of the file | `goto_file_start` |
| `g` | Go to line number `<n>` else start of file | `goto_file_start` |
| `e` | Go to the end of the file | `goto_last_line` |
| `f` | Go to files in the selection | `goto_file` |
| `h` | Go to the start of the line | `goto_line_start` |
| `l` | Go to the end of the line | `goto_line_end` |
| `s` | Go to first non-whitespace character of the line | `goto_first_nonwhitespace` |
| `t` | Go to the top of the screen | `goto_window_top` |
| `m` | Go to the middle of the screen | `goto_window_middle` |
| `c` | Go to the middle of the screen | `goto_window_center` |
| `b` | Go to the bottom of the screen | `goto_window_bottom` |
| `d` | Go to definition | `goto_definition` |
| `y` | Go to type definition | `goto_type_definition` |
| `r` | Go to references | `goto_reference` |
| `i` | Go to implementation | `goto_implementation` |
| `d` | Go to definition (**LSP**) | `goto_definition` |
| `y` | Go to type definition (**LSP**) | `goto_type_definition` |
| `r` | Go to references (**LSP**) | `goto_reference` |
| `i` | Go to implementation (**LSP**) | `goto_implementation` |
| `a` | Go to the last accessed/alternate file | `goto_last_accessed_file` |
| `m` | Go to the last modified/alternate file | `goto_last_modified_file` |
| `n` | Go to next buffer | `goto_next_buffer` |
| `p` | Go to previous buffer | `goto_previous_buffer` |
| `.` | Go to last modification in current file | `goto_last_modification` |
#### Match mode
Enter this mode using `m` from normal mode. See the relavant section
Enter this mode using `m` from normal mode. See the relevant section
in [Usage](./usage.md) for an explanation about [surround](./usage.md#surround)
and [textobject](./usage.md#textobject) usage.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `m` | Goto matching bracket | `match_brackets` |
| `m` | Goto matching bracket (**TS**) | `match_brackets` |
| `s` `<char>` | Surround current selection with `<char>` | `surround_add` |
| `r` `<from><to>` | Replace surround character `<from>` with `<to>` | `surround_replace` |
| `d` `<char>` | Delete surround character `<char>` | `surround_delete` |
@@ -183,78 +231,174 @@ TODO: Mappings for selecting syntax nodes (a superset of `[`).
This layer is similar to vim keybindings as kakoune does not support window.
| Key | Description | Command |
| ----- | ------------- | ------- |
| `w`, `Ctrl-w` | Switch to next window | `rotate_view` |
| `v`, `Ctrl-v` | Vertical right split | `vsplit` |
| `s`, `Ctrl-s` | Horizontal bottom split | `hsplit` |
| `h`, `Ctrl-h` | Move to left split | `jump_view_left` |
| `j`, `Ctrl-j` | Move to split below | `jump_view_down` |
| `k`, `Ctrl-k` | Move to split above | `jump_view_up` |
| `l`, `Ctrl-l` | Move to right split | `jump_view_right` |
| `q`, `Ctrl-q` | Close current window | `wclose` |
| Key | Description | Command |
| ----- | ------------- | ------- |
| `w`, `Ctrl-w` | Switch to next window | `rotate_view` |
| `v`, `Ctrl-v` | Vertical right split | `vsplit` |
| `s`, `Ctrl-s` | Horizontal bottom split | `hsplit` |
| `f` | Go to files in the selection in horizontal splits | `goto_file` |
| `F` | Go to files in the selection in vertical splits | `goto_file` |
| `h`, `Ctrl-h`, `Left` | Move to left split | `jump_view_left` |
| `j`, `Ctrl-j`, `Down` | Move to split below | `jump_view_down` |
| `k`, `Ctrl-k`, `Up` | Move to split above | `jump_view_up` |
| `l`, `Ctrl-l`, `Right` | Move to right split | `jump_view_right` |
| `q`, `Ctrl-q` | Close current window | `wclose` |
| `o`, `Ctrl-o` | Only keep the current window, closing all the others | `wonly` |
| `H` | Swap window to the left | `swap_view_left` |
| `J` | Swap window downwards | `swap_view_down` |
| `K` | Swap window upwards | `swap_view_up` |
| `L` | Swap window to the right | `swap_view_right` |
#### Space mode
This layer is a kludge of mappings, mostly pickers.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `k` | Show documentation for the item under the cursor | `hover` |
| `f` | Open file picker | `file_picker` |
| `b` | Open buffer picker | `buffer_picker` |
| `s` | Open symbol picker (current document) | `symbol_picker` |
| `a` | Apply code action | `code_action` |
| `'` | Open last fuzzy picker | `last_picker` |
| `w` | Enter [window mode](#window-mode) | N/A |
| `p` | Paste system clipboard after selections | `paste_clipboard_after` |
| `P` | Paste system clipboard before selections | `paste_clipboard_before` |
| `y` | Join and yank selections to clipboard | `yank_joined_to_clipboard` |
| `Y` | Yank main selection to clipboard | `yank_main_selection_to_clipboard` |
| `R` | Replace selections by clipboard contents | `replace_selections_with_clipboard` |
| `/` | Global search in workspace folder | `global_search` |
> NOTE: Global search display results in a fuzzy picker, use `space + '` to bring it back up after opening a file.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `f` | Open file picker | `file_picker` |
| `b` | Open buffer picker | `buffer_picker` |
| `j` | Open jumplist picker | `jumplist_picker` |
| `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` |
| `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
| `g` | Open document diagnostics picker (**LSP**) | `diagnostics_picker` |
| `G` | Open workspace diagnostics picker (**LSP**) | `workspace_diagnostics_picker`
| `r` | Rename symbol (**LSP**) | `rename_symbol` |
| `a` | Apply code action (**LSP**) | `code_action` |
| `'` | Open last fuzzy picker | `last_picker` |
| `w` | Enter [window mode](#window-mode) | N/A |
| `p` | Paste system clipboard after selections | `paste_clipboard_after` |
| `P` | Paste system clipboard before selections | `paste_clipboard_before` |
| `y` | Join and yank selections to clipboard | `yank_joined_to_clipboard` |
| `Y` | Yank main selection to clipboard | `yank_main_selection_to_clipboard` |
| `R` | Replace selections by clipboard contents | `replace_selections_with_clipboard` |
| `/` | Global search in workspace folder | `global_search` |
| `?` | Open command palette | `command_palette` |
> TIP: Global search displays results in a fuzzy picker, use `space + '` to bring it back up after opening a file.
##### Popup
Displays documentation for item under cursor.
| Key | Description |
| ---- | ----------- |
| `Ctrl-u` | Scroll up |
| `Ctrl-d` | Scroll down |
#### Unimpaired
Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired).
| Key | Description | Command |
| ----- | ----------- | ------- |
| `[d` | Go to previous diagnostic | `goto_prev_diag` |
| `]d` | Go to next diagnostic | `goto_next_diag` |
| `[D` | Go to first diagnostic in document | `goto_first_diag` |
| `]D` | Go to last diagnostic in document | `goto_last_diag` |
| `[space` | Add newline above | `add_newline_above` |
| `]space` | Add newline below | `add_newline_below` |
| Key | Description | Command |
| ----- | ----------- | ------- |
| `[d` | Go to previous diagnostic (**LSP**) | `goto_prev_diag` |
| `]d` | Go to next diagnostic (**LSP**) | `goto_next_diag` |
| `[D` | Go to first diagnostic in document (**LSP**) | `goto_first_diag` |
| `]D` | Go to last diagnostic in document (**LSP**) | `goto_last_diag` |
| `]f` | Go to next function (**TS**) | `goto_next_function` |
| `[f` | Go to previous function (**TS**) | `goto_prev_function` |
| `]c` | Go to next class (**TS**) | `goto_next_class` |
| `[c` | Go to previous class (**TS**) | `goto_prev_class` |
| `]a` | Go to next argument/parameter (**TS**) | `goto_next_parameter` |
| `[a` | Go to previous argument/parameter (**TS**) | `goto_prev_parameter` |
| `]o` | Go to next comment (**TS**) | `goto_next_comment` |
| `[o` | Go to previous comment (**TS**) | `goto_prev_comment` |
| `]t` | Go to next test (**TS**) | `goto_next_test` |
| `]t` | Go to previous test (**TS**) | `goto_prev_test` |
| `]p` | Go to next paragraph | `goto_next_paragraph` |
| `[p` | Go to previous paragraph | `goto_prev_paragraph` |
| `[space` | Add newline above | `add_newline_above` |
| `]space` | Add newline below | `add_newline_below` |
## Insert Mode
| Key | Description | Command |
| ----- | ----------- | ------- |
| `Escape` | Switch to normal mode | `normal_mode` |
| `Ctrl-x` | Autocomplete | `completion` |
| `Ctrl-w` | Delete previous word | `delete_word_backward` |
We support many readline/emacs style bindings in insert mode for
convenience. These can be helpful for making simple modifications
without escaping to normal mode, but beware that you will not have an
undo-able "save point" until you return to normal mode.
| Key | Description | Command |
| ----- | ----------- | ------- |
| `Escape` | Switch to normal mode | `normal_mode` |
| `Ctrl-x` | Autocomplete | `completion` |
| `Ctrl-r` | Insert a register content | `insert_register` |
| `Ctrl-w`, `Alt-Backspace`, `Ctrl-Backspace` | Delete previous word | `delete_word_backward` |
| `Alt-d`, `Alt-Delete`, `Ctrl-Delete` | Delete next word | `delete_word_forward` |
| `Alt-b`, `Ctrl-Left` | Backward a word | `move_prev_word_end` |
| `Ctrl-b`, `Left` | Backward a char | `move_char_left` |
| `Alt-f`, `Ctrl-Right` | Forward a word | `move_next_word_start` |
| `Ctrl-f`, `Right` | Forward a char | `move_char_right` |
| `Ctrl-e`, `End` | Move to line end | `goto_line_end_newline` |
| `Ctrl-a`, `Home` | Move to line start | `goto_line_start` |
| `Ctrl-u` | Delete to start of line | `kill_to_line_start` |
| `Ctrl-k` | Delete to end of line | `kill_to_line_end` |
| `Ctrl-j`, `Enter` | Insert new line | `insert_newline` |
| `Backspace`, `Ctrl-h` | Delete previous char | `delete_char_backward` |
| `Delete`, `Ctrl-d` | Delete next char | `delete_char_forward` |
| `Ctrl-p`, `Up` | Move to previous line | `move_line_up` |
| `Ctrl-n`, `Down` | Move to next line | `move_line_down` |
| `PageUp` | Move one page up | `page_up` |
| `PageDown` | Move one page down | `page_down` |
| `Alt->` | Go to end of buffer | `goto_file_end` |
| `Alt-<` | Go to start of buffer | `goto_file_start` |
## Select / extend mode
I'm still pondering whether to keep this mode or not. It changes movement
commands (including goto) to extend the existing selection instead of replacing it.
This mode echoes Normal mode, but changes any movements to extend
selections rather than replace them. Goto motions are also changed to
extend, so that `vgl` for example extends the selection to the end of
the line.
> NOTE: It's a bit confusing at the moment because extend hasn't been
> implemented for all movement commands yet.
Search is also affected. By default, `n` and `N` will remove the current
selection and select the next instance of the search term. Toggling this
mode before pressing `n` or `N` makes it possible to keep the current
selection. Toggling it on and off during your iterative searching allows
you to selectively add search terms to your selections.
# Picker
## Picker
Keys to use within picker. Remapping currently not supported.
| Key | Description |
| ----- | ------------- |
| `Up`, `Ctrl-k`, `Ctrl-p` | Previous entry |
| `Down`, `Ctrl-j`, `Ctrl-n` | Next entry |
| `Tab`, `Up`, `Ctrl-p` | Previous entry |
| `PageUp`, `Ctrl-u` | Page up |
| `Shift-tab`, `Down`, `Ctrl-n`| Next entry |
| `PageDown`, `Ctrl-d` | Page down |
| `Home` | Go to first entry |
| `End` | Go to last entry |
| `Ctrl-space` | Filter options |
| `Enter` | Open selected |
| `Ctrl-s` | Open horizontally |
| `Ctrl-v` | Open vertically |
| `Ctrl-t` | Toggle preview |
| `Escape`, `Ctrl-c` | Close picker |
## Prompt
Keys to use within prompt, Remapping currently not supported.
| Key | Description |
| ----- | ------------- |
| `Escape`, `Ctrl-c` | Close prompt |
| `Alt-b`, `Ctrl-Left` | Backward a word |
| `Ctrl-b`, `Left` | Backward a char |
| `Alt-f`, `Ctrl-Right` | Forward a word |
| `Ctrl-f`, `Right` | Forward a char |
| `Ctrl-e`, `End` | Move prompt end |
| `Ctrl-a`, `Home` | Move prompt start |
| `Ctrl-w`, `Alt-Backspace`, `Ctrl-Backspace` | Delete previous word |
| `Alt-d`, `Alt-Delete`, `Ctrl-Delete` | Delete next word |
| `Ctrl-u` | Delete to start of line |
| `Ctrl-k` | Delete to end of line |
| `backspace`, `Ctrl-h` | Delete previous char |
| `delete`, `Ctrl-d` | Delete next char |
| `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
| `Ctrl-p`, `Up` | Select previous history |
| `Ctrl-n`, `Down` | Select next history |
| `Ctrl-r` | Insert the content of the register selected by following input char |
| `Tab` | Select next completion item |
| `BackTab` | Select previous completion item |
| `Enter` | Open selected |

16
book/src/lang-support.md Normal file
View File

@@ -0,0 +1,16 @@
# Language Support
The following languages and Language Servers are supported. In order to use
Language Server features, you must first [install][lsp-install-wiki] the
appropriate Language Server.
Check the language support in your installed helix version with `hx --health`.
Also see the [Language Configuration][lang-config] docs and the [Adding
Languages][adding-languages] guide for more language configuration information.
{{#include ./generated/lang-support.md}}
[lsp-install-wiki]: https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers
[lang-config]: ./languages.md
[adding-languages]: ./guides/adding_languages.md

130
book/src/languages.md Normal file
View File

@@ -0,0 +1,130 @@
# Languages
Language-specific settings and settings for language servers are configured
in `languages.toml` files.
## `languages.toml` files
There are three possible `languages.toml` files. The first is compiled into
Helix and lives in the [Helix repository](https://github.com/helix-editor/helix/blob/master/languages.toml).
This provides the default configurations for languages and language servers.
You may define a `languages.toml` in your [configuration directory](./configuration.md)
which overrides values from the built-in language configuration. For example
to disable auto-LSP-formatting in Rust:
```toml
# in <config_dir>/helix/languages.toml
[[language]]
name = "rust"
auto-format = false
```
Language configuration may also be overridden local to a project by creating
a `languages.toml` file under a `.helix` directory. Its settings will be merged
with the language configuration in the configuration directory and the built-in
configuration.
## Language configuration
Each language is configured by adding a `[[language]]` section to a
`languages.toml` file. For example:
```toml
[[language]]
name = "mylang"
scope = "source.mylang"
injection-regex = "^mylang$"
file-types = ["mylang", "myl"]
comment-token = "#"
indent = { tab-width = 2, unit = " " }
language-server = { command = "mylang-lsp", args = ["--stdio"] }
formatter = { command = "mylang-formatter" , args = ["--stdin"] }
```
These configuration keys are available:
| Key | Description |
| ---- | ----------- |
| `name` | The name of the language |
| `scope` | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.<name>` or `text.<name>` in case of markup languages |
| `injection-regex` | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. |
| `file-types` | The filetypes of the language, for example `["yml", "yaml"]`. Extensions and full file names are supported. |
| `shebangs` | The interpreters from the shebang line, for example `["sh", "bash"]` |
| `roots` | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` |
| `auto-format` | Whether to autoformat this language when saving |
| `diagnostic-severity` | Minimal severity of diagnostic for it to be displayed. (Allowed values: `Error`, `Warning`, `Info`, `Hint`) |
| `comment-token` | The token to use as a comment-token |
| `indent` | The indent to use. Has sub keys `tab-width` and `unit` |
| `language-server` | The Language Server to run. See the Language Server configuration section below. |
| `config` | Language Server configuration |
| `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) |
| `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 |
### Language Server configuration
The `language-server` field takes the following keys:
| Key | Description |
| --- | ----------- |
| `command` | The name of the language server binary to execute. Binaries must be in `$PATH` |
| `args` | A list of arguments to pass to the language server binary |
| `timeout` | The maximum time a request to the language server may take, in seconds. Defaults to `20` |
| `language-id` | The language name to pass to the language server. Some language servers support multiple languages and use this field to determine which one is being served in a buffer |
The top-level `config` field is used to configure the LSP initialization options. A `format`
sub-table within `config` can be used to pass extra formatting options to
[Document Formatting Requests](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md#document-formatting-request--leftwards_arrow_with_hook).
For example with typescript:
```toml
[[language]]
name = "typescript"
auto-format = true
# pass format options according to https://github.com/typescript-language-server/typescript-language-server#workspacedidchangeconfiguration omitting the "[language].format." prefix.
config = { format = { "semicolons" = "insert", "insertSpaceBeforeFunctionParenthesis" = true } }
```
## Tree-sitter grammar configuration
The source for a language's tree-sitter grammar is specified in a `[[grammar]]`
section in `languages.toml`. For example:
```toml
[[grammar]]
name = "mylang"
source = { git = "https://github.com/example/mylang", rev = "a250c4582510ff34767ec3b7dcdd3c24e8c8aa68" }
```
Grammar configuration takes these keys:
| Key | Description |
| --- | ----------- |
| `name` | The name of the tree-sitter grammar |
| `source` | The method of fetching the grammar - a table with a schema defined below |
Where `source` is a table with either these keys when using a grammar from a
git repository:
| Key | Description |
| --- | ----------- |
| `git` | A git remote URL from which the grammar should be cloned |
| `rev` | The revision (commit hash or tag) which should be fetched |
| `subpath` | A path within the grammar directory which should be built. Some grammar repositories host multiple grammars (for example `tree-sitter-typescript` and `tree-sitter-ocaml`) in subdirectories. This key is used to point `hx --grammar build` to the correct path for compilation. When omitted, the root of repository is used |
### Choosing grammars
You may use a top-level `use-grammars` key to control which grammars are
fetched and built when using `hx --grammar fetch` and `hx --grammar build`.
```toml
# Note: this key must come **before** the [[language]] and [[grammar]] sections
use-grammars = { only = [ "rust", "c", "cpp" ] }
# or
use-grammars = { except = [ "yaml", "json" ] }
```
When omitted, all grammars are fetched and built.
[treesitter-language-injection]: https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection

View File

@@ -11,15 +11,19 @@ this:
```toml
# At most one section each of 'keys.normal', 'keys.insert' and 'keys.select'
[keys.normal]
C-s = ":w" # Maps the Control-s to the typable command :w which is an alias for :write (save file)
C-o = ":open ~/.config/helix/config.toml" # Maps the Control-o to opening of the helix config file
a = "move_char_left" # Maps the 'a' key to the move_char_left command
w = "move_line_up" # Maps the 'w' key move_line_up
"C-S-esc" = "extend_line" # Maps Control-Shift-Escape to extend_line
g = { a = "code_action" } # Maps `ga` to show possible code actions
"ret" = ["open_below", "normal_mode"] # Maps the enter key to open_below then re-enter normal mode
[keys.insert]
"A-x" = "normal_mode" # Maps Alt-X to enter normal mode
j = { k = "normal_mode" } # Maps `jk` to exit insert mode
```
> NOTE: Typable commands can also be remapped, remember to keep the `:` prefix to indicate it's a typable command.
Control, Shift and Alt modifiers are encoded respectively with the prefixes
`C-`, `S-` and `A-`. Special keys are encoded as follows:
@@ -29,21 +33,16 @@ Control, Shift and Alt modifiers are encoded respectively with the prefixes
| Backspace | `"backspace"` |
| Space | `"space"` |
| Return/Enter | `"ret"` |
| < | `"lt"` |
| \> | `"gt"` |
| \+ | `"plus"` |
| \- | `"minus"` |
| ; | `"semicolon"` |
| % | `"percent"` |
| Left | `"left"` |
| Right | `"right"` |
| Up | `"up"` |
| Down | `"down"` |
| Home | `"home"` |
| End | `"end"` |
| Page | `"pageup"` |
| Page | `"pagedown"` |
| Page Up | `"pageup"` |
| Page Down | `"pagedown"` |
| Tab | `"tab"` |
| Back | `"backtab"` |
| Delete | `"del"` |
| Insert | `"ins"` |
| Null | `"null"` |
@@ -51,4 +50,5 @@ Control, Shift and Alt modifiers are encoded respectively with the prefixes
Keys can be disabled by binding them to the `no_op` command.
Commands can be found in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs)
Commands can be found at [Keymap](https://docs.helix-editor.com/keymap.html) Commands.
> Commands can also be found in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs) at the invocation of `static_commands!` macro and the `TypableCommandList`.

View File

@@ -1,14 +1,14 @@
# Themes
First you'll need to place selected themes in your `themes` directory (i.e `~/.config/helix/themes`), the directory might have to be created beforehand.
To use a custom theme add `theme = <name>` to your [`config.toml`](./configuration.md) or override it during runtime using `:theme <name>`.
The default theme.toml can be found [here](https://github.com/helix-editor/helix/blob/master/theme.toml), and user submitted themes [here](https://github.com/helix-editor/helix/blob/master/runtime/themes).
To use a theme add `theme = "<name>"` to your [`config.toml`](./configuration.md) at the very top of the file before the first section or select it during runtime using `:theme <name>`.
## Creating a theme
First create a file with the name of your theme as file name (i.e `mytheme.toml`) and place it in your `themes` directory (i.e `~/.config/helix/themes`).
Create a file with the name of your theme as file name (i.e `mytheme.toml`) and place it in your `themes` directory (i.e `~/.config/helix/themes`). The directory might have to be created beforehand.
The names "default" and "base16_default" are reserved for the builtin themes and cannot be overridden by user defined themes.
The default theme.toml can be found [here](https://github.com/helix-editor/helix/blob/master/theme.toml), and user submitted themes [here](https://github.com/helix-editor/helix/blob/master/runtime/themes).
Each line in the theme file is specified as below:
@@ -37,8 +37,8 @@ configuration values in your theme. To do this, add a table called
`palette` to your theme file:
```toml
ui.background = "white"
ui.text = "black"
"ui.background" = "white"
"ui.text" = "black"
[palette]
white = "#ffffff"
@@ -103,17 +103,21 @@ We use a similar set of scopes as
[SublimeText](https://www.sublimetext.com/docs/scope_naming.html). See also
[TextMate](https://macromates.com/manual/en/language_grammars) scopes.
- `escape` (TODO: rename to (constant).character.escape)
- `attribute` - Class attributes, html tag attributes
- `type` - Types
- `builtin` - Primitive types provided by the language (`int`, `usize`)
- `constructor`
- `constant` (TODO: constant.other.placeholder for %v)
- `builtin` Special constants provided by the language (`true`, `false`, `nil` etc)
- `boolean`
- `character`
- `escape`
- `numeric` (numbers)
- `integer`
- `float`
- `number` (TODO: rename to constant.number/.numeric.{integer, float, complex})
- `string` (TODO: string.quoted.{single, double}, string.raw/.unquoted)?
- `regexp` - Regular expressions
- `special`
@@ -129,67 +133,125 @@ We use a similar set of scopes as
- `variable` - Variables
- `builtin` - Reserved language variables (`self`, `this`, `super`, etc)
- `parameter` - Function parameters
- `property`
- `function` (TODO: ?)
- `other`
- `member` - Fields of composite data types (e.g. structs, unions)
- `label`
- `punctuation`
- `delimiter` - Commas, colons
- `bracket` - Parentheses, angle brackets, etc.
- `special` - String interpolation brackets.
- `keyword`
- `control`
- `conditional` - `if`, `else`
- `repeat` - `for`, `while`, `loop`
- `import` - `import`, `export`
- (TODO: return?)
- `return`
- `exception`
- `operator` - `or`, `in`
- `directive` - Preprocessor directives (`#if` in C)
- `function` - `fn`, `func`
- `storage` - Keywords describing how things are stored
- `type` - The type of something, `class`, `function`, `var`, `let`, etc.
- `modifier` - Storage modifiers like `static`, `mut`, `const`, `ref`, etc.
- `operator` - `||`, `+=`, `>`, `or`
- `operator` - `||`, `+=`, `>`
- `function`
- `builtin`
- `method`
- `macro`
- `special` (preprocesor in C)
- `special` (preprocessor in C)
- `tag` - Tags (e.g. `<body>` in HTML)
- `namespace`
- `markup`
- `heading`
- `marker`
- `1`, `2`, `3`, `4`, `5`, `6` - heading text for h1 through h6
- `list`
- `unnumbered`
- `numbered`
- `bold`
- `italic`
- `link`
- `url` - urls pointed to by links
- `label` - non-url link references
- `text` - url and image descriptions in links
- `quote`
- `raw`
- `inline`
- `block`
- `diff` - version control changes
- `plus` - additions
- `minus` - deletions
- `delta` - modifications
- `moved` - renamed or moved files/changes
#### Interface
These scopes are used for theming the editor interface.
- `markup`
- `normal`
- `completion` - for completion doc popup ui
- `hover` - for hover popup ui
- `heading`
- `completion` - for completion doc popup ui
- `hover` - for hover popup ui
- `raw`
- `inline`
- `completion` - for completion doc popup ui
- `hover` - for hover popup ui
| Key | Notes |
| --- | --- |
| `ui.background` | |
| `ui.cursor` | |
| `ui.cursor.insert` | |
| `ui.cursor.select` | |
| `ui.cursor.match` | Matching bracket etc. |
| `ui.cursor.primary` | Cursor with primary selection |
| `ui.linenr` | |
| `ui.linenr.selected` | |
| `ui.statusline` | Statusline |
| `ui.statusline.inactive` | Statusline (unfocused document) |
| `ui.popup` | |
| `ui.window` | |
| `ui.help` | |
| `ui.text` | |
| `ui.text.focus` | |
| `ui.info` | |
| `ui.info.text` | |
| `ui.menu` | |
| `ui.menu.selected` | |
| `ui.selection` | For selections in the editing area |
| `ui.selection.primary` | |
| `warning` | Diagnostics warning (gutter) |
| `error` | Diagnostics error (gutter) |
| `info` | Diagnostics info (gutter) |
| `hint` | Diagnostics hint (gutter) |
| `diagnostic` | For text in editing area |
| Key | Notes |
| --- | --- |
| `ui.background` | |
| `ui.background.separator` | Picker separator below input line |
| `ui.cursor` | |
| `ui.cursor.insert` | |
| `ui.cursor.select` | |
| `ui.cursor.match` | Matching bracket etc. |
| `ui.cursor.primary` | Cursor with primary selection |
| `ui.linenr` | Line numbers |
| `ui.linenr.selected` | Line number for the line the cursor is on |
| `ui.statusline` | Statusline |
| `ui.statusline.inactive` | Statusline (unfocused document) |
| `ui.statusline.normal` | Statusline mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) |
| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
| `ui.statusline.separator` | Separator character in statusline |
| `ui.popup` | Documentation popups (e.g space-k) |
| `ui.popup.info` | Prompt for multiple key options |
| `ui.window` | Border lines separating splits |
| `ui.help` | Description box for commands |
| `ui.text` | Command prompts, popup text, etc. |
| `ui.text.focus` | |
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section])|
| `ui.virtual.whitespace` | Visible white-space characters |
| `ui.virtual.indent-guide` | Vertical indent width guides |
| `ui.menu` | Code and command completion menus |
| `ui.menu.selected` | Selected autocomplete item |
| `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar |
| `ui.selection` | For selections in the editing area |
| `ui.selection.primary` | |
| `ui.cursorline.primary` | The line of the primary cursor |
| `ui.cursorline.secondary` | The lines of any other cursors |
| `warning` | Diagnostics warning (gutter) |
| `error` | Diagnostics error (gutter) |
| `info` | Diagnostics info (gutter) |
| `hint` | Diagnostics hint (gutter) |
| `diagnostic` | Diagnostics fallback style (editing area) |
| `diagnostic.hint` | Diagnostics hint (editing area) |
| `diagnostic.info` | Diagnostics info (editing area) |
| `diagnostic.warning` | Diagnostics warning (editing area) |
| `diagnostic.error` | Diagnostics error (editing area) |
[editor-section]: ./configuration.md#editor-section

17
book/src/title-page.md Normal file
View File

@@ -0,0 +1,17 @@
# Helix
Docs for bleeding edge master can be found at
[https://docs.helix-editor.com/master](https://docs.helix-editor.com/master).
See the [usage] section for a quick overview of the editor, [keymap]
section for all available keybindings and the [configuration] section
for defining custom keybindings, setting themes, etc.
For everything else (e.g., how to install supported language servers), see the [Helix Wiki].
Refer the [FAQ] for common questions.
[FAQ]: https://github.com/helix-editor/helix/wiki/FAQ
[usage]: ./usage.md
[keymap]: ./keymap.md
[configuration]: ./configuration.md
[Helix Wiki]: https://github.com/helix-editor/helix/wiki

View File

@@ -23,8 +23,10 @@ If there is a selected register before invoking a change or delete command, the
| `/` | Last search |
| `:` | Last executed command |
| `"` | Last yanked text |
| `_` | Black hole |
> There is no special register for copying to system clipboard, instead special commands and keybindings are provided. See the [keymap](keymap.md#space-mode) for the specifics.
> The black hole register works as a no-op register, meaning no data will be written to / read from it.
## Surround
@@ -40,7 +42,7 @@ helix. The keymappings have been inspired from [vim-sandwich](https://github.com
`ms` acts on a selection, so select the text first and use `ms<char>`. `mr` and `md` work
on the closest pairs found and selections are not required; use counts to act in outer pairs.
It can also act on multiple seletions (yay!). For example, to change every occurance of `(use)` to `[use]`:
It can also act on multiple selections (yay!). For example, to change every occurrence of `(use)` to `[use]`:
- `%` to select the whole file
- `s` to split the selections on a search term
@@ -49,6 +51,78 @@ It can also act on multiple seletions (yay!). For example, to change every occur
Multiple characters are currently not supported, but planned.
## Syntax-tree Motions
`A-p`, `A-o`, `A-i`, and `A-n` (or `Alt` and arrow keys) move the primary
selection according to the selection's place in the syntax tree. Let's walk
through an example to get familiar with them. Many languages have a syntax like
so for function calls:
```
func(arg1, arg2, arg3)
```
A function call might be parsed by tree-sitter into a tree like the following.
```tsq
(call
function: (identifier) ; func
arguments:
(arguments ; (arg1, arg2, arg3)
(identifier) ; arg1
(identifier) ; arg2
(identifier))) ; arg3
```
Use `:tree-sitter-subtree` to view the syntax tree of the primary selection. In
a more intuitive tree format:
```
┌────┐
│call│
┌─────┴────┴─────┐
│ │
┌─────▼────┐ ┌────▼────┐
│identifier│ │arguments│
│ "func" │ ┌────┴───┬─────┴───┐
└──────────┘ │ │ │
│ │ │
┌─────────▼┐ ┌────▼─────┐ ┌▼─────────┐
│identifier│ │identifier│ │identifier│
│ "arg1" │ │ "arg2" │ │ "arg3" │
└──────────┘ └──────────┘ └──────────┘
```
Say we have a selection that wraps `arg1`. The selection is on the `arg1` leaf
in the tree above.
```
func([arg1], arg2, arg3)
```
Using `A-n` would select the next sibling in the syntax tree: `arg2`.
```
func(arg1, [arg2], arg3)
```
While `A-o` would expand the selection to the parent node. In the tree above we
can see that we would select the `arguments` node.
```
func[(arg1, arg2, arg3)]
```
There is also some nuanced behavior that prevents you from getting stuck on a
node with no sibling. If we have a selection on `arg1`, `A-p` would bring us
to the previous child node. Since `arg1` doesn't have a sibling to its left,
though, we climb the syntax tree and then take the previous selection. So `A-p`
will move the selection over to the "func" `identifier`.
```
[func](arg1, arg2, arg3)
```
## Textobjects
Currently supported: `word`, `surround`, `function`, `class`, `parameter`.
@@ -62,12 +136,35 @@ Currently supported: `word`, `surround`, `function`, `class`, `parameter`.
| Key after `mi` or `ma` | Textobject selected |
| --- | --- |
| `w` | Word |
| `W` | WORD |
| `(`, `[`, `'`, etc | Specified surround pairs |
| `m` | Closest surround pair |
| `f` | Function |
| `c` | Class |
| `p` | Parameter |
| `a` | Argument/parameter |
| `o` | Comment |
| `t` | Test |
Note: `f`, `c`, etc need a tree-sitter grammar active for the current
> NOTE: `f`, `c`, etc need a tree-sitter grammar active for the current
document and a special tree-sitter query file to work properly. [Only
some grammars](https://github.com/search?q=repo%3Ahelix-editor%2Fhelix+filename%3Atextobjects.scm&type=Code&ref=advsearch&l=&l=)
currently have the query file implemented. Contributions are welcome !
some grammars][lang-support] currently have the query file implemented.
Contributions are welcome!
## Tree-sitter Textobject Based Navigation
Navigating between functions, classes, parameters, etc is made
possible by leveraging tree-sitter and textobjects queries. For
example to move to the next function use `]f`, to move to previous
class use `[c`, and so on.
![tree-sitter-nav-demo][tree-sitter-nav-demo]
See the [unimpaired][unimpaired-keybinds] section of the keybind
documentation for the full reference.
> NOTE: This feature is dependent on tree-sitter based textobjects
and therefore requires the corresponding query file to work properly.
[lang-support]: ./lang-support.md
[unimpaired-keybinds]: ./keymap.md#unimpaired
[tree-sitter-nav-demo]: https://user-images.githubusercontent.com/23398472/152332550-7dfff043-36a2-4aec-b8f2-77c13eb56d6f.gif

View File

@@ -601,10 +601,10 @@ function playground_text(playground) {
});
})();
(function controllMenu() {
(function controlMenu() {
var menu = document.getElementById('menu-bar');
(function controllPosition() {
(function controlPosition() {
var scrollTop = document.scrollingElement.scrollTop;
var prevScrollTop = scrollTop;
var minMenuY = -menu.clientHeight - 50;
@@ -647,7 +647,7 @@ function playground_text(playground) {
prevScrollTop = scrollTop;
}, { passive: true });
})();
(function controllBorder() {
(function controlBorder() {
menu.classList.remove('bordered');
document.addEventListener('scroll', function () {
if (menu.offsetTop === 0) {

View File

@@ -390,7 +390,7 @@ ul#searchresults span.teaser em {
.chapter li {
display: flex;
color: var(--sidebar-non-existant);
color: var(--sidebar-non-existent);
}
.chapter li a {
display: block;

View File

@@ -16,7 +16,7 @@
--sidebar-bg: #14191f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #5c6773;
--sidebar-non-existent: #5c6773;
--sidebar-active: #ffb454;
--sidebar-spacer: #2d334f;
@@ -56,7 +56,7 @@
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-non-existent: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
@@ -96,7 +96,7 @@
--sidebar-bg: #fafafa;
--sidebar-fg: hsl(0, 0%, 0%);
--sidebar-non-existant: #aaaaaa;
--sidebar-non-existent: #aaaaaa;
--sidebar-active: #1f1fff;
--sidebar-spacer: #f4f4f4;
@@ -136,7 +136,7 @@
--sidebar-bg: #282d3f;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274;
--sidebar-non-existent: #505274;
--sidebar-active: #2b79a2;
--sidebar-spacer: #2d334f;
@@ -176,7 +176,7 @@
--sidebar-bg: #3b2e2a;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505254;
--sidebar-non-existent: #505254;
--sidebar-active: #e69f67;
--sidebar-spacer: #45373a;
@@ -217,7 +217,7 @@
--sidebar-bg: #292c2f;
--sidebar-fg: #a1adb8;
--sidebar-non-existant: #505254;
--sidebar-non-existent: #505254;
--sidebar-active: #3473ad;
--sidebar-spacer: #393939;
@@ -259,7 +259,7 @@
--sidebar-bg: #281733;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274;
--sidebar-non-existent: #505274;
--sidebar-active: #a4a0e8;
--sidebar-spacer: #2d334f;
@@ -304,7 +304,7 @@
--sidebar-bg: #281733;
--sidebar-fg: #c8c9db;
--sidebar-non-existant: #505274;
--sidebar-non-existent: #505274;
--sidebar-active: #a4a0e8;
--sidebar-spacer: #2d334f;

89
contrib/Helix.desktop Normal file
View File

@@ -0,0 +1,89 @@
[Desktop Entry]
Name=Helix
GenericName=Text Editor
GenericName[de]=Texteditor
GenericName[fr]=Éditeur de texte
GenericName[ru]=Текстовый редактор
GenericName[sr]=Едитор текст
GenericName[tr]=Metin Düzenleyici
Comment=Edit text files
Comment[af]=Redigeer tekslêers
Comment[am]=የጽሑፍ ፋይሎች ያስተካክሉ
Comment[ar]=حرّر ملفات نصية
Comment[az]=Mətn fayllarını redaktə edin
Comment[be]=Рэдагаваньне тэкставых файлаў
Comment[bg]=Редактиране на текстови файлове
Comment[bn]=টেক্স্ট ফাইল এডিট করুন
Comment[bs]=Izmijeni tekstualne datoteke
Comment[ca]=Edita fitxers de text
Comment[cs]=Úprava textových souborů
Comment[cy]=Golygu ffeiliau testun
Comment[da]=Redigér tekstfiler
Comment[de]=Textdateien bearbeiten
Comment[el]=Επεξεργασία αρχείων κειμένου
Comment[en_CA]=Edit text files
Comment[en_GB]=Edit text files
Comment[es]=Edita archivos de texto
Comment[et]=Redigeeri tekstifaile
Comment[eu]=Editatu testu-fitxategiak
Comment[fa]=ویرایش پرونده‌های متنی
Comment[fi]=Muokkaa tekstitiedostoja
Comment[fr]=Éditer des fichiers texte
Comment[ga]=Eagar comhad Téacs
Comment[gu]=લખાણ ફાઇલોમાં ફેરફાર કરો
Comment[he]=ערוך קבצי טקסט
Comment[hi]=पाठ फ़ाइलें संपादित करें
Comment[hr]=Uređivanje tekstualne datoteke
Comment[hu]=Szövegfájlok szerkesztése
Comment[id]=Edit file teks
Comment[it]=Modifica file di testo
Comment[ja]=テキストファイルを編集します
Comment[kn]=ಪಠ್ಯ ಕಡತಗಳನ್ನು ಸಂಪಾದಿಸು
Comment[ko]=텍스트 파일을 편집합니다
Comment[lt]=Redaguoti tekstines bylas
Comment[lv]=Rediģēt teksta failus
Comment[mk]=Уреди текстуални фајлови
Comment[ml]=വാചക രചനകള് തിരുത്തുക
Comment[mn]=Текст файл боловсруулах
Comment[mr]=गद्य फाइल संपादित करा
Comment[ms]=Edit fail teks
Comment[nb]=Rediger tekstfiler
Comment[ne]=पाठ फाइललाई संशोधन गर्नुहोस्
Comment[nl]=Tekstbestanden bewerken
Comment[nn]=Rediger tekstfiler
Comment[no]=Rediger tekstfiler
Comment[or]=ପାଠ୍ଯ ଫାଇଲଗୁଡ଼ିକୁ ସମ୍ପାଦନ କରନ୍ତୁ
Comment[pa]=ਪਾਠ ਫਾਇਲਾਂ ਸੰਪਾਦਨ
Comment[pl]=Edytor plików tekstowych
Comment[pt]=Editar ficheiros de texto
Comment[pt_BR]=Edite arquivos de texto
Comment[ro]=Editare fişiere text
Comment[ru]=Редактирование текстовых файлов
Comment[sk]=Úprava textových súborov
Comment[sl]=Urejanje datotek z besedili
Comment[sq]=Përpuno files teksti
Comment[sr]=Уређујте текст фајлове
Comment[sr@Latn]=Izmeni tekstualne datoteke
Comment[sv]=Redigera textfiler
Comment[ta]=உரை கோப்புகளை தொகுக்கவும்
Comment[th]=แก้ไขแฟ้มข้อความ
Comment[tk]=Metin faýllary editle
Comment[tr]=Metin dosyaları düzenleyin
Comment[uk]=Редактор текстових файлів
Comment[vi]=Soạn thảo tập tin văn bản
Comment[wa]=Asspougnî des fitchîs tecses
Comment[zh_CN]=编辑文本文件
Comment[zh_TW]=編輯文字檔
TryExec=hx
Exec=hx %F
Terminal=true
Type=Application
Keywords=Text;editor;
Keywords[fr]=Texte;éditeur;
Keywords[ru]=текст;текстовый редактор;
Keywords[sr]=Текст;едитор;
Keywords[tr]=Metin;düzenleyici;
Icon=helix
Categories=Utility;TextEditor;
StartupNotify=false
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# Bash completion script for Helix editor
_hx() {
# $1 command name
# $2 word being completed
# $3 word preceding
COMPREPLY=()
case "$3" in
-g | --grammar)
COMPREPLY=($(compgen -W "fetch build" -- $2))
;;
--health)
local languages=$(hx --health |tail -n '+7' |awk '{print $1}' |sed 's/\x1b\[[0-9;]*m//g')
COMPREPLY=($(compgen -W "$languages" -- $2))
;;
*)
COMPREPLY=($(compgen -fd -W "-h --help --tutor -V --version -v -vv -vvv --health -g --grammar --vsplit --hsplit -c --config" -- $2))
;;
esac
} && complete -F _hx hx

49
contrib/completion/hx.elv Normal file
View File

@@ -0,0 +1,49 @@
# You can move it here ~/.config/elvish/lib/hx.elv
# Or add `eval (slurp < ~/$REPOS/helix/contrib/completion/hx.elv)`
# Be sure to replace `$REPOS` with something that makes sense for you!
### Renders a pretty completion candidate
var candidate = { | _stem _desc |
edit:complex-candidate $_stem &display=(styled $_stem bold)(styled " "$_desc dim)
}
### These commands will invalidate further input (i.e. not react to them)
var skips = [ "--tutor" "--help" "--version" "-V" "--health" ]
### Grammar commands
var grammar = [ "--grammar" "-g" ]
### Config commands
var config = [ "--config" "-c" ]
### Set an arg-completer for the `hx` binary
set edit:completion:arg-completer[hx] = {|@args|
var n = (count $args)
if (>= $n 3) {
# Stop completions if passed arg will take presedence
# and invalidate further input
if (has-value $skips $args[-2]) {
return
}
# If the previous arg == --grammar, then only suggest:
if (has-value $grammar $args[-2]) {
$candidate "fetch" "Fetch the tree-sitter grammars"
$candidate "build" "Build the tree-sitter grammars"
return
}
# When we have --config, we need a file
if (has-values $config $args[-2]) {
edit:complete-filename $args[-1] | each { |v| put $v[stem] }
return
}
}
edit:complete-filename $args[-1] | each { |v| put $v[stem]}
$candidate "--help" "(Prints help information)"
$candidate "--version" "(Prints version information)"
$candidate "--tutor" "(Loads the tutorial)"
$candidate "--health" "(Checks for errors in editor setup)"
$candidate "--grammar" "(Fetch or build the tree-sitter grammars)"
$candidate "--vsplit" "(Splits all given files vertically)"
$candidate "--hsplit" "(Splits all given files horizontally)"
$candidate "--config" "(Specifies a file to use for configuration)"
}

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env fish
# Fish completion script for Helix editor
set -l langs (hx --health |tail -n '+7' |awk '{print $1}' |sed 's/\x1b\[[0-9;]*m//g')
complete -c hx -s h -l help -d "Prints help information"
complete -c hx -l tutor -d "Loads the tutorial"
complete -c hx -l health -x -a "$langs" -d "Checks for errors in editor setup"
complete -c hx -s g -l grammar -x -a "fetch build" -d "Fetches or builds tree-sitter grammars"
complete -c hx -s v -o vv -o vvv -d "Increases logging verbosity"
complete -c hx -s V -l version -d "Prints version information"
complete -c hx -l vsplit -d "Splits all given files vertically into different windows"
complete -c hx -l hsplit -d "Splits all given files horizontally into different windows"
complete -c hx -s c -l config -d "Specifies a file to use for completion"

33
contrib/completion/hx.zsh Normal file
View File

@@ -0,0 +1,33 @@
#compdef _hx hx
# Zsh completion script for Helix editor
_hx() {
_arguments -C \
"-h[Prints help information]" \
"--help[Prints help information]" \
"-v[Increase logging verbosity]" \
"-vv[Increase logging verbosity]" \
"-vvv[Increase logging verbosity]" \
"-V[Prints version information]" \
"--version[Prints version information]" \
"--tutor[Loads the tutorial]" \
"--health[Checks for errors in editor setup]:language:->health" \
"-g[Fetches or builds tree-sitter grammars]:action:->grammar" \
"--grammar[Fetches or builds tree-sitter grammars]:action:->grammar" \
"--vsplit[Splits all given files vertically into different windows]" \
"--hsplit[Splits all given files horizontally into different windows]" \
"-c[Specifies a file to use for configuration]" \
"--config[Specifies a file to use for configuration]" \
"*:file:_files"
case "$state" in
health)
local languages=($(hx --health |tail -n '+7' |awk '{print $1}' |sed 's/\x1b\[[0-9;]*m//g'))
_values 'language' $languages
;;
grammar)
_values 'action' fetch build
;;
esac
}

BIN
contrib/helix.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

8
default.nix Normal file
View File

@@ -0,0 +1,8 @@
# Flake's default package for non-flake-enabled nix instances
let
compat = builtins.fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/b4a34015c698c7793d592d66adbab377907a2be8.tar.gz";
sha256 = "sha256:1qc703yg0babixi6wshn5wm2kgl5y1drcswgszh4xxzbrwkk9sv7";
};
in
(import compat {src = ./.;}).defaultNix.default

45
docs/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,45 @@
# Contributing
Contributors are very welcome! **No contribution is too small and all contributions are valued.**
Some suggestions to get started:
- You can look at the [good first issue][good-first-issue] label on the issue tracker.
- Help with packaging on various distributions needed!
- To use print debugging to the [Helix log file][log-file], you must:
* Print using `log::info!`, `warn!`, or `error!`. (`log::info!("helix!")`)
* Pass the appropriate verbosity level option for the desired log level. (`hx -v <file>` for info, more `v`s for higher severity inclusive)
- If your preferred language is missing, integrating a tree-sitter grammar for
it and defining syntax highlight queries for it is straight forward and
doesn't require much knowledge of the internals.
We provide an [architecture.md][architecture.md] that should give you
a good overview of the internals.
# Auto generated documentation
Some parts of [the book][docs] are autogenerated from the code itself,
like the list of `:commands` and supported languages. To generate these
files, run
```shell
cargo xtask docgen
```
inside the project. We use [xtask][xtask] as an ad-hoc task runner and
thus do not require any dependencies other than `cargo` (You don't have
to `cargo install` anything either).
# Integration tests
Integration tests for helix-term can be run with `cargo integration-test`. Code
contributors are strongly encouraged to write integration tests for their code.
Existing tests can be used as examples. Helpers can be found in
[helpers.rs][helpers.rs]
[good-first-issue]: https://github.com/helix-editor/helix/labels/E-easy
[log-file]: https://github.com/helix-editor/helix/wiki/FAQ#access-the-log-file
[architecture.md]: ./architecture.md
[docs]: https://docs.helix-editor.com/
[xtask]: https://github.com/matklad/cargo-xtask
[helpers.rs]: ../helix-term/tests/test/helpers.rs

View File

@@ -1,12 +1,13 @@
| Crate | Description |
| ----------- | ----------- |
| helix-core | Core editing primitives, functional. |
| helix-syntax | Tree-sitter grammars |
| helix-lsp | Language server client |
| helix-view | UI abstractions for use in backends, imperative shell. |
| helix-term | Terminal UI |
| helix-tui | TUI primitives, forked from tui-rs, inspired by Cursive |
| Crate | Description |
| ----------- | ----------- |
| helix-core | Core editing primitives, functional. |
| helix-lsp | Language server client |
| helix-dap | Debug Adapter Protocol (DAP) client |
| helix-loader | Functions for building, fetching, and loading external resources |
| helix-view | UI abstractions for use in backends, imperative shell. |
| helix-term | Terminal UI |
| helix-tui | TUI primitives, forked from tui-rs, inspired by Cursive |
This document contains a high-level overview of Helix internals.
@@ -31,7 +32,7 @@ represented by a `Selection`. Each `Range` in the selection consists of a moving
a selection with a single range, with the head and the anchor in the same
position.
Ropes are modified by constructing an OT-like `Transaction`. It's represents
Ropes are modified by constructing an OT-like `Transaction`. It represents
a single coherent change to the document and can be applied to the rope.
A transaction can be inverted to produce an undo. Selections and marks can be
mapped over a transaction to translate to a position in the new text state after
@@ -41,7 +42,7 @@ applying the transaction.
> interface used to generate text edits.
`Syntax` is the interface used to interact with tree-sitter ASTs for syntax
highling and other features.
highlighting and other features.
## View
@@ -54,15 +55,40 @@ A `Document` ties together the `Rope`, `Selection`(s), `Syntax`, document
file.
A `View` represents an open split in the UI. It holds the currently open
document ID and other related state.
document ID and other related state. Views encapsulate the gutter, status line,
diagnostics, and the inner area where the code is displayed.
> NOTE: Multiple views are able to display the same document, so the document
> contains selections for each view. To retrieve, `document.selection()` takes
> a `ViewId`.
`Info` is the autoinfo box that shows hints when awaiting another key with bindings
like `g` and `m`. It is attached to the viewport as a whole.
`Surface` is like a buffer to which widgets draw themselves to, and the
surface is then rendered on the screen on each cycle.
`Rect`s are areas (simply an x and y coordinate with the origin at the
screen top left and then a height and width) which are part of a
`Surface`. They can be used to limit the area to which a `Component` can
render. For example if we wrap a `Markdown` component in a `Popup`
(think the documentation popup with space+k), Markdown's render method
will get a Rect that is the exact size of the popup.
Widgets are called `Component`s internally, and you can see most of them
in `helix-term/src/ui`. Some components like `Popup` and `Overlay` can take
other components as children.
`Layer`s are how multiple components are displayed, and is simply a
`Vec<Component>`. Layers are managed by the `Compositor`. On each top
level render call, the compositor renders each component in the order
they were pushed into the stack. This makes multiple components "layer"
on top of one another. Hence we get a file picker displayed over the
editor, etc.
The `Editor` holds the global state: all the open documents, a tree
representation of all the view splits, and a registry of language servers. To
open or close files, interact with the editor.
representation of all the view splits, the configuration, and a registry of
language servers. To open or close files, interact with the editor.
## LSP

59
docs/releases.md Normal file
View File

@@ -0,0 +1,59 @@
## Checklist
Helix releases are versioned in the Calendar Versioning scheme:
`YY.0M(.MICRO)`, for example `22.05` for May of 2022. In these instructions
we'll use `<tag>` as a placeholder for the tag being published.
* Merge the changelog PR
* Tag and push
* `git tag -s -m "<tag>" -a <tag> && git push`
* Make sure to switch to master and pull first
* Edit the `VERSION` file and change the date to the next planned release
* Releases are planned to happen every two months, so `22.05` would change to `22.07`
* Wait for the Release CI to finish
* It will automatically turn the git tag into a GitHub release when it uploads artifacts
* Edit the new release
* Use `<tag>` as the title
* Link to the changelog and release notes
* Merge the release notes PR
* Download the macos and linux binaries and update the `sha256`s in the [homebrew formula]
* Use `sha256sum` on the downloaded `.tar.xz` files to determine the hash
* Link to the release notes in this-week-in-rust
* [Example PR](https://github.com/rust-lang/this-week-in-rust/pull/3300)
* Post to reddit
* [Example post](https://www.reddit.com/r/rust/comments/uzp5ze/helix_editor_2205_released/)
[homebrew formula]: https://github.com/Homebrew/homebrew-core/blob/master/Formula/helix.rb
## Changelog Curation
The changelog is currently created manually by reading through commits in the
log since the last release. GitHub's compare view is a nice way to approach
this. For example when creating the 22.07 release notes, this compare link
may be used
```
https://github.com/helix-editor/helix/compare/22.05...master
```
Either side of the triple-dot may be replaced with an exact revision, so if
you wish to incrementally compile the changelog, you can tackle a weeks worth
or so, record the revision where you stopped, and use that as a starting point
next week:
```
https://github.com/helix-editor/helix/compare/7706a4a0d8b67b943c31d0c5f7b00d357b5d838d...master
```
A work-in-progress commit for a changelog might look like
[this example](https://github.com/helix-editor/helix/commit/831adfd4c709ca16b248799bfef19698d5175e55).
Not every PR or commit needs a blurb in the changelog. Each release section
tends to have a blurb that links to a GitHub comparison between release
versions for convenience:
> As usual, the following is a summary of each of the changes since the last
> release. For the full log, check out the git log.
Typically, small changes like dependencies or documentation updates, refactors,
or meta changes like GitHub Actions work are left out.

142
flake.lock generated
View File

@@ -1,12 +1,29 @@
{
"nodes": {
"devshell": {
"crane": {
"flake": false,
"locked": {
"lastModified": 1632436039,
"narHash": "sha256-OtITeVWcKXn1SpVEnImpTGH91FycCskGBPqmlxiykv4=",
"lastModified": 1654444508,
"narHash": "sha256-4OBvQ4V7jyt7afs6iKUvRzJ1u/9eYnKzVQbeQdiamuY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "db5482bf225acc3160899124a1df5a617cfa27b5",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"devshell": {
"flake": false,
"locked": {
"lastModified": 1655976588,
"narHash": "sha256-VreHyH6ITkf/1EX/8h15UqhddJnUleb0HgbC3gMkAEQ=",
"owner": "numtide",
"repo": "devshell",
"rev": "7a7a7aa0adebe5488e5abaec688fd9ae0f8ea9c6",
"rev": "899ca4629020592a13a46783587f6e674179d1db",
"type": "github"
},
"original": {
@@ -15,13 +32,67 @@
"type": "github"
}
},
"dream2nix": {
"inputs": {
"alejandra": [
"nixCargoIntegration",
"nixpkgs"
],
"crane": "crane",
"devshell": [
"nixCargoIntegration",
"devshell"
],
"flake-utils-pre-commit": [
"nixCargoIntegration",
"nixpkgs"
],
"gomod2nix": [
"nixCargoIntegration",
"nixpkgs"
],
"mach-nix": [
"nixCargoIntegration",
"nixpkgs"
],
"nixpkgs": [
"nixCargoIntegration",
"nixpkgs"
],
"node2nix": [
"nixCargoIntegration",
"nixpkgs"
],
"poetry2nix": [
"nixCargoIntegration",
"nixpkgs"
],
"pre-commit-hooks": [
"nixCargoIntegration",
"nixpkgs"
]
},
"locked": {
"lastModified": 1655975833,
"narHash": "sha256-g8sdfuglIZ24oWVbntVzniNTJW+Z3n9DNL9w9Tt+UCE=",
"owner": "nix-community",
"repo": "dream2nix",
"rev": "4e75e665ec3a1cddae5266bed0dd72fce0b74a23",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "dream2nix",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1623875721,
"narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=",
"lastModified": 1637014545,
"narHash": "sha256-26IZAc5yzlD9FlDT54io1oqG/bBoyka+FJk5guaX4x4=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "f7e004a55b120c02ecb6219596820fcd32ca8772",
"rev": "bba5dcc8e0b20ab664967ad83d24d64cb64ec4f4",
"type": "github"
},
"original": {
@@ -30,38 +101,23 @@
"type": "github"
}
},
"flakeCompat": {
"flake": false,
"locked": {
"lastModified": 1627913399,
"narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"nixCargoIntegration": {
"inputs": {
"devshell": "devshell",
"dream2nix": "dream2nix",
"nixpkgs": [
"nixpkgs"
],
"rustOverlay": [
"rust-overlay": [
"rust-overlay"
]
},
"locked": {
"lastModified": 1634796585,
"narHash": "sha256-CW4yx6omk5qCXUIwXHp/sztA7u0SpyLq9NEACPnkiz8=",
"lastModified": 1656453541,
"narHash": "sha256-ZCPVnS6zJOZJvIlwU3rKR8MBVm6A3F4/0mA7G1lQ3D0=",
"owner": "yusdacra",
"repo": "nix-cargo-integration",
"rev": "a84a2137a396f303978f1d48341e0390b0e16a8b",
"rev": "9eb74345b30cd2e536d9dac9d4435d3c475605c7",
"type": "github"
},
"original": {
@@ -72,11 +128,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1634782485,
"narHash": "sha256-psfh4OQSokGXG0lpq3zKFbhOo3QfoeudRcaUnwMRkQo=",
"lastModified": 1655624069,
"narHash": "sha256-7g1zwTdp35GMTERnSzZMWJ7PG3QdDE8VOX3WsnOkAtM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "34ad3ffe08adfca17fcb4e4a47bb5f3b113687be",
"rev": "0d68d7c857fe301d49cdcd56130e0beea4ecd5aa",
"type": "github"
},
"original": {
@@ -86,24 +142,8 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1628186154,
"narHash": "sha256-r2d0wvywFnL9z4iptztdFMhaUIAaGzrSs7kSok0PgmE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "06552b72346632b6943c8032e57e702ea12413bf",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flakeCompat": "flakeCompat",
"nixCargoIntegration": "nixCargoIntegration",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
@@ -112,14 +152,16 @@
"rust-overlay": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_2"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1634869268,
"narHash": "sha256-RVAcEFlFU3877Mm4q/nbXGEYTDg/wQNhzmXGMTV6wBs=",
"lastModified": 1655779671,
"narHash": "sha256-6feeiGa6fb7ZPVHR71uswkmN1701TAJpwYQA8QffmRk=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "c02c2d86354327317546501af001886fbb53d374",
"rev": "8159585609a772b041cce6019d5c21d240709244",
"type": "github"
},
"original": {

177
flake.nix
View File

@@ -3,73 +3,136 @@
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
nixCargoIntegration = {
url = "github:yusdacra/nix-cargo-integration";
inputs.nixpkgs.follows = "nixpkgs";
inputs.rustOverlay.follows = "rust-overlay";
};
flakeCompat = {
url = "github:edolstra/flake-compat";
flake = false;
inputs.rust-overlay.follows = "rust-overlay";
};
};
outputs = inputs@{ self, nixCargoIntegration, ... }:
nixCargoIntegration.lib.makeOutputs {
root = ./.;
buildPlatform = "crate2nix";
renameOutputs = { "helix-term" = "helix"; };
# Set default app to hx (binary is from helix-term release build)
# Set default package to helix-term release build
defaultOutputs = { app = "hx"; package = "helix"; };
overrides = {
crateOverrides = common: _: {
helix-term = prev: {
# link languages and theme toml files since helix-term expects them (for tests)
preConfigure = "ln -s ${common.root}/{languages.toml,theme.toml} ..";
buildInputs = (prev.buildInputs or [ ]) ++ [ common.cCompiler.cc.lib ];
};
# link languages and theme toml files since helix-view expects them
helix-view = _: { preConfigure = "ln -s ${common.root}/{languages.toml,theme.toml} .."; };
helix-syntax = _prev: {
preConfigure = "mkdir -p ../runtime/grammars";
postInstall = "cp -r ../runtime $out/runtime";
};
outputs = inputs @ {
nixpkgs,
nixCargoIntegration,
...
}: let
outputs = config:
nixCargoIntegration.lib.makeOutputs {
root = ./.;
renameOutputs = {"helix-term" = "helix";};
# Set default app to hx (binary is from helix-term release build)
# Set default package to helix-term release build
defaultOutputs = {
app = "hx";
package = "helix";
};
mainBuild = common: prev:
let
inherit (common) pkgs lib;
helixSyntax = lib.buildCrate {
root = self;
memberName = "helix-syntax";
defaultCrateOverrides = {
helix-syntax = common.crateOverrides.helix-syntax;
overrides = {
cCompiler = common:
with common.pkgs;
if stdenv.isLinux
then gcc
else clang;
crateOverrides = common: _: {
helix-term = prev: let
inherit (common) pkgs;
mkRootPath = rel:
builtins.path {
path = "${common.root}/${rel}";
name = rel;
};
grammars = pkgs.callPackage ./grammars.nix config;
runtimeDir = pkgs.runCommandNoCC "helix-runtime" {} ''
mkdir -p $out
ln -s ${mkRootPath "runtime"}/* $out
rm -r $out/grammars
ln -s ${grammars} $out/grammars
'';
overridedAttrs = {
# disable fetching and building of tree-sitter grammars in the helix-term build.rs
HELIX_DISABLE_AUTO_GRAMMAR_BUILD = "1";
# link languages and theme toml files since helix-term expects them (for tests)
preConfigure =
pkgs.lib.concatMapStringsSep
"\n"
(path: "ln -sf ${mkRootPath path} ..")
["languages.toml" "theme.toml" "base16_theme.toml"];
buildInputs = (prev.buildInputs or []) ++ [common.cCompiler.cc.lib];
nativeBuildInputs = [pkgs.makeWrapper];
postFixup = ''
if [ -f "$out/bin/hx" ]; then
wrapProgram "$out/bin/hx" ''${makeWrapperArgs[@]} --set HELIX_RUNTIME "${runtimeDir}"
fi
'';
};
release = false;
};
runtimeDir = pkgs.runCommand "helix-runtime" { } ''
mkdir -p $out
ln -s ${common.root}/runtime/* $out
ln -sf ${helixSyntax}/runtime/grammars $out
'';
in
lib.optionalAttrs (common.memberName == "helix-term") {
nativeBuildInputs = [ pkgs.makeWrapper ];
postFixup = ''
if [ -f "$out/bin/hx" ]; then
wrapProgram "$out/bin/hx" --set HELIX_RUNTIME "${runtimeDir}"
fi
'';
in
overridedAttrs
// (
pkgs.lib.optionalAttrs
(config ? makeWrapperArgs)
{inherit (config) makeWrapperArgs;}
);
};
shell = common: prev: {
packages =
prev.packages
++ (
with common.pkgs;
[lld_13 lldb cargo-flamegraph rust-analyzer] ++
(lib.optional (stdenv.isx86_64 && stdenv.isLinux) cargo-tarpaulin)
);
env =
prev.env
++ [
{
name = "HELIX_RUNTIME";
eval = "$PWD/runtime";
}
{
name = "RUST_BACKTRACE";
value = "1";
}
{
name = "RUSTFLAGS";
value =
if common.pkgs.stdenv.isLinux
then "-C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment"
else "";
}
];
};
shell = common: prev: {
packages = prev.packages ++ (with common.pkgs; [ lld_12 lldb cargo-tarpaulin ]);
env = prev.env ++ [
{ name = "HELIX_RUNTIME"; eval = "$PWD/runtime"; }
{ name = "RUST_BACKTRACE"; value = "1"; }
{ name = "RUSTFLAGS"; value = "-C link-arg=-fuse-ld=lld -C target-cpu=native"; }
];
};
};
defaultOutputs = outputs {};
makeOverridableHelix = system: old:
old
// {
override = args:
makeOverridableHelix
system
(outputs args).packages.${system}.helix;
};
in
defaultOutputs
// {
packages =
nixpkgs.lib.mapAttrs
(
system: packages:
packages
// rec {
default = helix;
helix = makeOverridableHelix system packages.helix;
}
)
defaultOutputs.packages;
};
nixConfig = {
extra-substituters = ["https://helix.cachix.org"];
extra-trusted-public-keys = ["helix.cachix.org-1:ejp9KQpR1FBI2onstMQ34yogDm4OgU2ru6lIwPvuCVs="];
};
}

121
grammars.nix Normal file
View File

@@ -0,0 +1,121 @@
{
stdenv,
lib,
runCommandLocal,
runCommandNoCC,
yj,
includeGrammarIf ? _: true,
...
}: let
# HACK: nix < 2.6 has a bug in the toml parser, so we convert to JSON
# before parsing
languages-json = runCommandLocal "languages-toml-to-json" {} ''
${yj}/bin/yj -t < ${./languages.toml} > $out
'';
languagesConfig =
if lib.versionAtLeast builtins.nixVersion "2.6.0"
then builtins.fromTOML (builtins.readFile ./languages.toml)
else builtins.fromJSON (builtins.readFile (builtins.toPath languages-json));
isGitGrammar = grammar:
builtins.hasAttr "source" grammar
&& builtins.hasAttr "git" grammar.source
&& builtins.hasAttr "rev" grammar.source;
isGitHubGrammar = grammar: lib.hasPrefix "https://github.com" grammar.source.git;
toGitHubFetcher = url: let
match = builtins.match "https://github\.com/([^/]*)/([^/]*)/?" url;
in {
owner = builtins.elemAt match 0;
repo = builtins.elemAt match 1;
};
gitGrammars = builtins.filter isGitGrammar languagesConfig.grammar;
buildGrammar = grammar: let
gh = toGitHubFetcher grammar.source.git;
sourceGit = builtins.fetchTree {
type = "git";
url = grammar.source.git;
rev = grammar.source.rev;
ref = grammar.source.ref or "HEAD";
shallow = true;
};
sourceGitHub = builtins.fetchTree {
type = "github";
owner = gh.owner;
repo = gh.repo;
inherit (grammar.source) rev;
};
source =
if isGitHubGrammar grammar
then sourceGitHub
else sourceGit;
in
stdenv.mkDerivation rec {
# see https://github.com/NixOS/nixpkgs/blob/fbdd1a7c0bc29af5325e0d7dd70e804a972eb465/pkgs/development/tools/parsing/tree-sitter/grammar.nix
pname = "helix-tree-sitter-${grammar.name}";
version = grammar.source.rev;
src =
if builtins.hasAttr "subpath" grammar.source
then "${source}/${grammar.source.subpath}"
else source;
dontUnpack = true;
dontConfigure = true;
FLAGS = [
"-I${src}/src"
"-g"
"-O3"
"-fPIC"
"-fno-exceptions"
"-Wl,-z,relro,-z,now"
];
NAME = grammar.name;
buildPhase = ''
runHook preBuild
if [[ -e "$src/src/scanner.cc" ]]; then
$CXX -c "$src/src/scanner.cc" -o scanner.o $FLAGS
elif [[ -e "$src/src/scanner.c" ]]; then
$CC -c "$src/src/scanner.c" -o scanner.o $FLAGS
fi
$CC -c "$src/src/parser.c" -o parser.o $FLAGS
$CXX -shared -o $NAME.so *.o
ls -al
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir $out
mv $NAME.so $out/
runHook postInstall
'';
# Strip failed on darwin: strip: error: symbols referenced by indirect symbol table entries that can't be stripped
fixupPhase = lib.optionalString stdenv.isLinux ''
runHook preFixup
$STRIP $out/$NAME.so
runHook postFixup
'';
};
grammarsToBuild = builtins.filter includeGrammarIf gitGrammars;
builtGrammars =
builtins.map (grammar: {
inherit (grammar) name;
artifact = buildGrammar grammar;
})
grammarsToBuild;
grammarLinks =
builtins.map (grammar: "ln -s ${grammar.artifact}/${grammar.name}.so $out/${grammar.name}.so")
builtGrammars;
in
runCommandNoCC "consolidated-helix-grammars" {} ''
mkdir -p $out
${builtins.concatStringsSep "\n" grammarLinks}
''

View File

@@ -1,6 +1,6 @@
[package]
name = "helix-core"
version = "0.5.0"
version = "0.6.0"
authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
edition = "2021"
license = "MPL-2.0"
@@ -11,19 +11,22 @@ homepage = "https://helix-editor.com"
include = ["src/**/*", "README.md"]
[features]
unicode-lines = ["ropey/unicode_lines"]
integration = []
[dependencies]
helix-syntax = { version = "0.5", path = "../helix-syntax" }
helix-loader = { version = "0.6", path = "../helix-loader" }
ropey = "1.3"
smallvec = "1.7"
tendril = "0.4.2"
unicode-segmentation = "1.8"
ropey = { version = "1.5", default-features = false, features = ["simd"] }
smallvec = "1.9"
smartstring = "1.0.1"
unicode-segmentation = "1.9"
unicode-width = "0.1"
unicode-general-category = "0.4"
unicode-general-category = "0.5"
# slab = "0.4.2"
slotmap = "1.0"
tree-sitter = "0.20"
once_cell = "1.8"
once_cell = "1.13"
arc-swap = "1"
regex = "1"
@@ -32,9 +35,14 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
toml = "0.5"
similar = "2.1"
similar = "2.2"
etcetera = "0.3"
encoding_rs = "0.8"
chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] }
etcetera = "0.4"
textwrap = "0.15.0"
[dev-dependencies]
quickcheck = { version = "1", default-features = false }

File diff suppressed because it is too large Load Diff

View File

@@ -91,12 +91,14 @@ mod test {
#[test]
fn test_categorize() {
const EOL_TEST_CASE: &'static str = "\n\r\u{000B}\u{000C}\u{0085}\u{2028}\u{2029}";
const WORD_TEST_CASE: &'static str =
"_hello_world_あいうえおー1234567890";
const PUNCTUATION_TEST_CASE: &'static str =
#[cfg(not(feature = "unicode-lines"))]
const EOL_TEST_CASE: &str = "\n";
#[cfg(feature = "unicode-lines")]
const EOL_TEST_CASE: &str = "\n\u{000B}\u{000C}\u{0085}\u{2028}\u{2029}";
const WORD_TEST_CASE: &str = "_hello_world_あいうえおー1234567890";
const PUNCTUATION_TEST_CASE: &str =
"!\"#$%&\'()*+,-./:;<=>?@[\\]^`{|}~!”#$%&’()*+、。:;<=>?@「」^`{|}~";
const WHITESPACE_TEST_CASE: &'static str = "  ";
const WHITESPACE_TEST_CASE: &str = "  ";
for ch in EOL_TEST_CASE.chars() {
assert_eq!(CharCategory::Eol, categorize_char(ch));

View File

@@ -63,7 +63,7 @@ pub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&st
let token = token.unwrap_or("//");
let comment = Tendril::from(format!("{} ", token));
let mut lines: Vec<usize> = Vec::new();
let mut lines: Vec<usize> = Vec::with_capacity(selection.len());
let mut min_next_line = 0;
for selection in selection {
@@ -72,7 +72,7 @@ pub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&st
let end = (end + 1).min(text.len_lines());
lines.extend(start..end);
min_next_line = end + 1;
min_next_line = end;
}
let (commented, to_change, min, margin) = find_line_comment(token, text, lines);

10
helix-core/src/config.rs Normal file
View File

@@ -0,0 +1,10 @@
/// Syntax configuration loader based on built-in languages.toml.
pub fn default_syntax_loader() -> crate::syntax::Configuration {
helix_loader::config::default_lang_config()
.try_into()
.expect("Could not serialize built-in languages.toml")
}
/// Syntax configuration loader based on user configured languages.toml.
pub fn user_syntax_loader() -> Result<crate::syntax::Configuration, toml::de::Error> {
helix_loader::config::user_lang_config()?.try_into()
}

View File

@@ -1,26 +1,40 @@
//! LSP diagnostic utility types.
use serde::{Deserialize, Serialize};
/// Describes the severity level of a [`Diagnostic`].
#[derive(Debug, Eq, PartialEq)]
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub enum Severity {
Error,
Warning,
Info,
Hint,
Info,
Warning,
Error,
}
impl Default for Severity {
fn default() -> Self {
Self::Hint
}
}
/// A range of `char`s within the text.
#[derive(Debug)]
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
pub struct Range {
pub start: usize,
pub end: usize,
}
#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]
pub enum NumberOrString {
Number(i32),
String(String),
}
/// Corresponds to [`lsp_types::Diagnostic`](https://docs.rs/lsp-types/0.91.0/lsp_types/struct.Diagnostic.html)
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Diagnostic {
pub range: Range,
pub line: usize,
pub message: String,
pub severity: Option<Severity>,
pub code: Option<NumberOrString>,
}

View File

@@ -11,10 +11,6 @@ pub fn compare_ropes(old: &Rope, new: &Rope) -> Transaction {
// A timeout is set so after 1 seconds, the algorithm will start
// approximating. This is especially important for big `Rope`s or
// `Rope`s that are extremely dissimilar to each other.
//
// Note: Ignore the clippy warning, as the trait bounds of
// `Transaction::change()` require an iterator implementing
// `ExactIterator`.
let mut config = similar::TextDiff::configure();
config.timeout(std::time::Duration::from_secs(1));
@@ -62,7 +58,7 @@ mod tests {
let mut old = Rope::from(a);
let new = Rope::from(b);
compare_ropes(&old, &new).apply(&mut old);
old.to_string() == new.to_string()
old == new
}
}
}

View File

@@ -1,6 +1,6 @@
//! Utility functions to traverse the unicode graphemes of a `Rope`'s text contents.
//!
//! Based on https://github.com/cessen/led/blob/c4fa72405f510b7fd16052f90a598c429b3104a6/src/graphemes.rs
//! Based on <https://github.com/cessen/led/blob/c4fa72405f510b7fd16052f90a598c429b3104a6/src/graphemes.rs>
use ropey::{iter::Chunks, str_utils::byte_to_char_idx, RopeSlice};
use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete};
use unicode_width::UnicodeWidthStr;
@@ -14,7 +14,7 @@ pub fn grapheme_width(g: &str) -> usize {
// Point 1: theoretically, ascii control characters should have zero
// width, but in our case we actually want them to have width: if they
// show up in text, we want to treat them as textual elements that can
// be editied. So we can get away with making all ascii single width
// be edited. So we can get away with making all ascii single width
// here.
// Point 2: we're only examining the first codepoint here, which means
// we're ignoring graphemes formed with combining characters. However,
@@ -120,6 +120,43 @@ pub fn nth_next_grapheme_boundary(slice: RopeSlice, char_idx: usize, n: usize) -
chunk_char_idx + tmp
}
#[must_use]
pub fn nth_next_grapheme_boundary_byte(slice: RopeSlice, mut byte_idx: usize, n: usize) -> usize {
// Bounds check
debug_assert!(byte_idx <= slice.len_bytes());
// Get the chunk with our byte index in it.
let (mut chunk, mut chunk_byte_idx, mut _chunk_char_idx, _) = slice.chunk_at_byte(byte_idx);
// Set up the grapheme cursor.
let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);
// Find the nth next grapheme cluster boundary.
for _ in 0..n {
loop {
match gc.next_boundary(chunk, chunk_byte_idx) {
Ok(None) => return slice.len_bytes(),
Ok(Some(n)) => {
byte_idx = n;
break;
}
Err(GraphemeIncomplete::NextChunk) => {
chunk_byte_idx += chunk.len();
let (a, _, _c, _) = slice.chunk_at_byte(chunk_byte_idx);
chunk = a;
// chunk_char_idx = c;
}
Err(GraphemeIncomplete::PreContext(n)) => {
let ctx_chunk = slice.chunk_at_byte(n - 1).0;
gc.provide_context(ctx_chunk, n - ctx_chunk.len());
}
_ => unreachable!(),
}
}
}
byte_idx
}
/// Finds the next grapheme boundary after the given char position.
#[must_use]
#[inline(always)]
@@ -127,6 +164,13 @@ pub fn next_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> usize {
nth_next_grapheme_boundary(slice, char_idx, 1)
}
/// Finds the next grapheme boundary after the given byte position.
#[must_use]
#[inline(always)]
pub fn next_grapheme_boundary_byte(slice: RopeSlice, byte_idx: usize) -> usize {
nth_next_grapheme_boundary_byte(slice, byte_idx, 1)
}
/// Returns the passed char index if it's already a grapheme boundary,
/// or the next grapheme boundary char index if not.
#[must_use]
@@ -151,6 +195,23 @@ pub fn ensure_grapheme_boundary_prev(slice: RopeSlice, char_idx: usize) -> usize
}
}
/// Returns the passed byte index if it's already a grapheme boundary,
/// or the next grapheme boundary byte index if not.
#[must_use]
#[inline]
pub fn ensure_grapheme_boundary_next_byte(slice: RopeSlice, byte_idx: usize) -> usize {
if byte_idx == 0 {
byte_idx
} else {
// TODO: optimize so we're not constructing grapheme cursor twice
if is_grapheme_boundary_byte(slice, byte_idx) {
byte_idx
} else {
next_grapheme_boundary_byte(slice, byte_idx)
}
}
}
/// Returns whether the given char position is a grapheme boundary.
#[must_use]
pub fn is_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> bool {
@@ -179,6 +240,31 @@ pub fn is_grapheme_boundary(slice: RopeSlice, char_idx: usize) -> bool {
}
}
/// Returns whether the given byte position is a grapheme boundary.
#[must_use]
pub fn is_grapheme_boundary_byte(slice: RopeSlice, byte_idx: usize) -> bool {
// Bounds check
debug_assert!(byte_idx <= slice.len_bytes());
// Get the chunk with our byte index in it.
let (chunk, chunk_byte_idx, _, _) = slice.chunk_at_byte(byte_idx);
// Set up the grapheme cursor.
let mut gc = GraphemeCursor::new(byte_idx, slice.len_bytes(), true);
// Determine if the given position is a grapheme cluster boundary.
loop {
match gc.is_boundary(chunk, chunk_byte_idx) {
Ok(n) => return n,
Err(GraphemeIncomplete::PreContext(n)) => {
let (ctx_chunk, ctx_byte_start, _, _) = slice.chunk_at_byte(n - 1);
gc.provide_context(ctx_chunk, ctx_byte_start);
}
Err(_) => unreachable!(),
}
}
}
/// An iterator over the graphemes of a `RopeSlice`.
#[derive(Clone)]
pub struct RopeGraphemes<'a> {
@@ -247,10 +333,7 @@ impl<'a> Iterator for RopeGraphemes<'a> {
}
if a < self.cur_chunk_start {
let a_char = self.text.byte_to_char(a);
let b_char = self.text.byte_to_char(b);
Some(self.text.slice(a_char..b_char))
Some(self.text.byte_slice(a..b))
} else {
let a2 = a - self.cur_chunk_start;
let b2 = b - self.cur_chunk_start;

View File

@@ -1,4 +1,4 @@
use crate::{ChangeSet, Rope, State, Transaction};
use crate::{Assoc, ChangeSet, Range, Rope, State, Transaction};
use once_cell::sync::Lazy;
use regex::Regex;
use std::num::NonZeroUsize;
@@ -22,10 +22,10 @@ use std::time::{Duration, Instant};
///
/// The current revision is the one currently displayed in the buffer.
///
/// Commiting a new revision to the history will update the last child of the
/// Committing a new revision to the history will update the last child of the
/// current revision, and push a new revision to the end of the vector.
///
/// Revisions are commited with a timestamp. :earlier and :later can be used
/// Revisions are committed with a timestamp. :earlier and :later can be used
/// to jump to the closest revision to a moment in time relative to the timestamp
/// of the current revision plus (:later) or minus (:earlier) the duration
/// given to the command. If a single integer is given, the editor will instead
@@ -33,14 +33,14 @@ use std::time::{Duration, Instant};
///
/// Limitations:
/// * Changes in selections currently don't commit history changes. The selection
/// will only be updated to the state after a commited buffer change.
/// will only be updated to the state after a committed buffer change.
/// * The vector of history revisions is currently unbounded. This might
/// cause the memory consumption to grow significantly large during long
/// editing sessions.
/// * Because delete transactions currently don't store the text that they
/// delete, we also store an inversion of the transaction.
///
/// Using time to navigate the history: https://github.com/helix-editor/helix/pull/194
/// Using time to navigate the history: <https://github.com/helix-editor/helix/pull/194>
#[derive(Debug)]
pub struct History {
revisions: Vec<Revision>,
@@ -133,6 +133,32 @@ impl History {
Some(&self.revisions[last_child.get()].transaction)
}
// Get the position of last change
pub fn last_edit_pos(&self) -> Option<usize> {
if self.current == 0 {
return None;
}
let current_revision = &self.revisions[self.current];
let primary_selection = current_revision
.inversion
.selection()
.expect("inversion always contains a selection")
.primary();
let (_from, to, _fragment) = current_revision
.transaction
.changes_iter()
// find a change that matches the primary selection
.find(|(from, to, _fragment)| Range::new(*from, *to).overlaps(&primary_selection))
// or use the first change
.or_else(|| current_revision.transaction.changes_iter().next())
.unwrap();
let pos = current_revision
.transaction
.changes()
.map_pos(to, Assoc::After);
Some(pos)
}
fn lowest_common_ancestor(&self, mut a: usize, mut b: usize) -> usize {
use std::collections::HashSet;
let mut a_path_set = HashSet::new();
@@ -151,7 +177,7 @@ impl History {
}
}
/// List of nodes on the way from `n` to 'a`. Doesn`t include `a`.
/// List of nodes on the way from `n` to 'a`. Doesn't include `a`.
/// Includes `n` unless `a == n`. `a` must be an ancestor of `n`.
fn path_up(&self, mut n: usize, a: usize) -> Vec<usize> {
let mut path = Vec::new();
@@ -256,13 +282,13 @@ impl History {
}
/// Whether to undo by a number of edits or a duration of time.
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum UndoKind {
Steps(usize),
TimePeriod(std::time::Duration),
}
/// A subset of sytemd.time time span syntax units.
/// A subset of systemd.time time span syntax units.
const TIME_UNITS: &[(&[&str], &str, u64)] = &[
(&["seconds", "second", "sec", "s"], "seconds", 1),
(&["minutes", "minute", "min", "m"], "minutes", 60),
@@ -422,8 +448,8 @@ mod test {
change: crate::transaction::Change,
instant: Instant,
) {
let txn = Transaction::change(&state.doc, vec![change.clone()].into_iter());
history.commit_revision_at_timestamp(&txn, &state, instant);
let txn = Transaction::change(&state.doc, vec![change].into_iter());
history.commit_revision_at_timestamp(&txn, state, instant);
txn.apply(&mut state.doc);
}
@@ -520,8 +546,8 @@ mod test {
// Units are validated.
assert_eq!(
"1 millenium".parse::<UndoKind>(),
Err("incorrect time unit: millenium".to_string())
"1 millennium".parse::<UndoKind>(),
Err("incorrect time unit: millennium".to_string())
);
// Units can't be specified twice.

View File

@@ -0,0 +1,491 @@
use chrono::{Datelike, Duration, NaiveDate, NaiveDateTime, NaiveTime, Timelike};
use once_cell::sync::Lazy;
use regex::Regex;
use ropey::RopeSlice;
use std::borrow::Cow;
use std::cmp;
use std::fmt::Write;
use super::Increment;
use crate::{Range, Tendril};
#[derive(Debug, PartialEq, Eq)]
pub struct DateTimeIncrementor {
date_time: NaiveDateTime,
range: Range,
fmt: &'static str,
field: DateField,
}
impl DateTimeIncrementor {
pub fn from_range(text: RopeSlice, range: Range) -> Option<DateTimeIncrementor> {
let range = if range.is_empty() {
if range.anchor < text.len_chars() {
// Treat empty range as a cursor range.
range.put_cursor(text, range.anchor + 1, true)
} else {
// The range is empty and at the end of the text.
return None;
}
} else {
range
};
FORMATS.iter().find_map(|format| {
let from = range.from().saturating_sub(format.max_len);
let to = (range.from() + format.max_len).min(text.len_chars());
let (from_in_text, to_in_text) = (range.from() - from, range.to() - from);
let text: Cow<str> = text.slice(from..to).into();
let captures = format.regex.captures(&text)?;
if captures.len() - 1 != format.fields.len() {
return None;
}
let date_time = captures.get(0)?;
let offset = range.from() - from_in_text;
let range = Range::new(date_time.start() + offset, date_time.end() + offset);
let field = captures
.iter()
.skip(1)
.enumerate()
.find_map(|(i, capture)| {
let capture = capture?;
let capture_range = capture.range();
if capture_range.contains(&from_in_text)
&& capture_range.contains(&(to_in_text - 1))
{
Some(format.fields[i])
} else {
None
}
})?;
let has_date = format.fields.iter().any(|f| f.unit.is_date());
let has_time = format.fields.iter().any(|f| f.unit.is_time());
let date_time = &text[date_time.start()..date_time.end()];
let date_time = match (has_date, has_time) {
(true, true) => NaiveDateTime::parse_from_str(date_time, format.fmt).ok()?,
(true, false) => {
let date = NaiveDate::parse_from_str(date_time, format.fmt).ok()?;
date.and_hms(0, 0, 0)
}
(false, true) => {
let time = NaiveTime::parse_from_str(date_time, format.fmt).ok()?;
NaiveDate::from_ymd(0, 1, 1).and_time(time)
}
(false, false) => return None,
};
Some(DateTimeIncrementor {
date_time,
range,
fmt: format.fmt,
field,
})
})
}
}
impl Increment for DateTimeIncrementor {
fn increment(&self, amount: i64) -> (Range, Tendril) {
let date_time = match self.field.unit {
DateUnit::Years => add_years(self.date_time, amount),
DateUnit::Months => add_months(self.date_time, amount),
DateUnit::Days => add_duration(self.date_time, Duration::days(amount)),
DateUnit::Hours => add_duration(self.date_time, Duration::hours(amount)),
DateUnit::Minutes => add_duration(self.date_time, Duration::minutes(amount)),
DateUnit::Seconds => add_duration(self.date_time, Duration::seconds(amount)),
DateUnit::AmPm => toggle_am_pm(self.date_time),
}
.unwrap_or(self.date_time);
(self.range, date_time.format(self.fmt).to_string().into())
}
}
static FORMATS: Lazy<Vec<Format>> = Lazy::new(|| {
vec![
Format::new("%Y-%m-%d %H:%M:%S"), // 2021-11-24 07:12:23
Format::new("%Y/%m/%d %H:%M:%S"), // 2021/11/24 07:12:23
Format::new("%Y-%m-%d %H:%M"), // 2021-11-24 07:12
Format::new("%Y/%m/%d %H:%M"), // 2021/11/24 07:12
Format::new("%Y-%m-%d"), // 2021-11-24
Format::new("%Y/%m/%d"), // 2021/11/24
Format::new("%a %b %d %Y"), // Wed Nov 24 2021
Format::new("%d-%b-%Y"), // 24-Nov-2021
Format::new("%Y %b %d"), // 2021 Nov 24
Format::new("%b %d, %Y"), // Nov 24, 2021
Format::new("%-I:%M:%S %P"), // 7:21:53 am
Format::new("%-I:%M %P"), // 7:21 am
Format::new("%-I:%M:%S %p"), // 7:21:53 AM
Format::new("%-I:%M %p"), // 7:21 AM
Format::new("%H:%M:%S"), // 23:24:23
Format::new("%H:%M"), // 23:24
]
});
#[derive(Debug)]
struct Format {
fmt: &'static str,
fields: Vec<DateField>,
regex: Regex,
max_len: usize,
}
impl Format {
fn new(fmt: &'static str) -> Self {
let mut remaining = fmt;
let mut fields = Vec::new();
let mut regex = String::new();
let mut max_len = 0;
while let Some(i) = remaining.find('%') {
let after = &remaining[i + 1..];
let mut chars = after.chars();
let c = chars.next().unwrap();
let spec_len = if c == '-' {
1 + chars.next().unwrap().len_utf8()
} else {
c.len_utf8()
};
let specifier = &after[..spec_len];
let field = DateField::from_specifier(specifier).unwrap();
fields.push(field);
max_len += field.max_len + remaining[..i].len();
regex += &remaining[..i];
write!(regex, "({})", field.regex).unwrap();
remaining = &after[spec_len..];
}
let regex = Regex::new(&regex).unwrap();
Self {
fmt,
fields,
regex,
max_len,
}
}
}
impl PartialEq for Format {
fn eq(&self, other: &Self) -> bool {
self.fmt == other.fmt && self.fields == other.fields && self.max_len == other.max_len
}
}
impl Eq for Format {}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct DateField {
regex: &'static str,
unit: DateUnit,
max_len: usize,
}
impl DateField {
fn from_specifier(specifier: &str) -> Option<Self> {
match specifier {
"Y" => Some(Self {
regex: r"\d{4}",
unit: DateUnit::Years,
max_len: 5,
}),
"y" => Some(Self {
regex: r"\d\d",
unit: DateUnit::Years,
max_len: 2,
}),
"m" => Some(Self {
regex: r"[0-1]\d",
unit: DateUnit::Months,
max_len: 2,
}),
"d" => Some(Self {
regex: r"[0-3]\d",
unit: DateUnit::Days,
max_len: 2,
}),
"-d" => Some(Self {
regex: r"[1-3]?\d",
unit: DateUnit::Days,
max_len: 2,
}),
"a" => Some(Self {
regex: r"Sun|Mon|Tue|Wed|Thu|Fri|Sat",
unit: DateUnit::Days,
max_len: 3,
}),
"A" => Some(Self {
regex: r"Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday",
unit: DateUnit::Days,
max_len: 9,
}),
"b" | "h" => Some(Self {
regex: r"Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",
unit: DateUnit::Months,
max_len: 3,
}),
"B" => Some(Self {
regex: r"January|February|March|April|May|June|July|August|September|October|November|December",
unit: DateUnit::Months,
max_len: 9,
}),
"H" => Some(Self {
regex: r"[0-2]\d",
unit: DateUnit::Hours,
max_len: 2,
}),
"M" => Some(Self {
regex: r"[0-5]\d",
unit: DateUnit::Minutes,
max_len: 2,
}),
"S" => Some(Self {
regex: r"[0-5]\d",
unit: DateUnit::Seconds,
max_len: 2,
}),
"I" => Some(Self {
regex: r"[0-1]\d",
unit: DateUnit::Hours,
max_len: 2,
}),
"-I" => Some(Self {
regex: r"1?\d",
unit: DateUnit::Hours,
max_len: 2,
}),
"P" => Some(Self {
regex: r"am|pm",
unit: DateUnit::AmPm,
max_len: 2,
}),
"p" => Some(Self {
regex: r"AM|PM",
unit: DateUnit::AmPm,
max_len: 2,
}),
_ => None,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum DateUnit {
Years,
Months,
Days,
Hours,
Minutes,
Seconds,
AmPm,
}
impl DateUnit {
fn is_date(self) -> bool {
matches!(self, DateUnit::Years | DateUnit::Months | DateUnit::Days)
}
fn is_time(self) -> bool {
matches!(
self,
DateUnit::Hours | DateUnit::Minutes | DateUnit::Seconds
)
}
}
fn ndays_in_month(year: i32, month: u32) -> u32 {
// The first day of the next month...
let (y, m) = if month == 12 {
(year + 1, 1)
} else {
(year, month + 1)
};
let d = NaiveDate::from_ymd(y, m, 1);
// ...is preceded by the last day of the original month.
d.pred().day()
}
fn add_months(date_time: NaiveDateTime, amount: i64) -> Option<NaiveDateTime> {
let month = (date_time.month0() as i64).checked_add(amount)?;
let year = date_time.year() + i32::try_from(month / 12).ok()?;
let year = if month.is_negative() { year - 1 } else { year };
// Normalize month
let month = month % 12;
let month = if month.is_negative() {
month + 12
} else {
month
} as u32
+ 1;
let day = cmp::min(date_time.day(), ndays_in_month(year, month));
Some(NaiveDate::from_ymd(year, month, day).and_time(date_time.time()))
}
fn add_years(date_time: NaiveDateTime, amount: i64) -> Option<NaiveDateTime> {
let year = i32::try_from((date_time.year() as i64).checked_add(amount)?).ok()?;
let ndays = ndays_in_month(year, date_time.month());
if date_time.day() > ndays {
let d = NaiveDate::from_ymd(year, date_time.month(), ndays);
Some(d.succ().and_time(date_time.time()))
} else {
date_time.with_year(year)
}
}
fn add_duration(date_time: NaiveDateTime, duration: Duration) -> Option<NaiveDateTime> {
date_time.checked_add_signed(duration)
}
fn toggle_am_pm(date_time: NaiveDateTime) -> Option<NaiveDateTime> {
if date_time.hour() < 12 {
add_duration(date_time, Duration::hours(12))
} else {
add_duration(date_time, Duration::hours(-12))
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Rope;
#[test]
fn test_increment_date_times() {
let tests = [
// (original, cursor, amount, expected)
("2020-02-28", 0, 1, "2021-02-28"),
("2020-02-29", 0, 1, "2021-03-01"),
("2020-01-31", 5, 1, "2020-02-29"),
("2020-01-20", 5, 1, "2020-02-20"),
("2021-01-01", 5, -1, "2020-12-01"),
("2021-01-31", 5, -2, "2020-11-30"),
("2020-02-28", 8, 1, "2020-02-29"),
("2021-02-28", 8, 1, "2021-03-01"),
("2021-02-28", 0, -1, "2020-02-28"),
("2021-03-01", 0, -1, "2020-03-01"),
("2020-02-29", 5, -1, "2020-01-29"),
("2020-02-20", 5, -1, "2020-01-20"),
("2020-02-29", 8, -1, "2020-02-28"),
("2021-03-01", 8, -1, "2021-02-28"),
("1980/12/21", 8, 100, "1981/03/31"),
("1980/12/21", 8, -100, "1980/09/12"),
("1980/12/21", 8, 1000, "1983/09/17"),
("1980/12/21", 8, -1000, "1978/03/27"),
("2021-11-24 07:12:23", 0, 1, "2022-11-24 07:12:23"),
("2021-11-24 07:12:23", 5, 1, "2021-12-24 07:12:23"),
("2021-11-24 07:12:23", 8, 1, "2021-11-25 07:12:23"),
("2021-11-24 07:12:23", 11, 1, "2021-11-24 08:12:23"),
("2021-11-24 07:12:23", 14, 1, "2021-11-24 07:13:23"),
("2021-11-24 07:12:23", 17, 1, "2021-11-24 07:12:24"),
("2021/11/24 07:12:23", 0, 1, "2022/11/24 07:12:23"),
("2021/11/24 07:12:23", 5, 1, "2021/12/24 07:12:23"),
("2021/11/24 07:12:23", 8, 1, "2021/11/25 07:12:23"),
("2021/11/24 07:12:23", 11, 1, "2021/11/24 08:12:23"),
("2021/11/24 07:12:23", 14, 1, "2021/11/24 07:13:23"),
("2021/11/24 07:12:23", 17, 1, "2021/11/24 07:12:24"),
("2021-11-24 07:12", 0, 1, "2022-11-24 07:12"),
("2021-11-24 07:12", 5, 1, "2021-12-24 07:12"),
("2021-11-24 07:12", 8, 1, "2021-11-25 07:12"),
("2021-11-24 07:12", 11, 1, "2021-11-24 08:12"),
("2021-11-24 07:12", 14, 1, "2021-11-24 07:13"),
("2021/11/24 07:12", 0, 1, "2022/11/24 07:12"),
("2021/11/24 07:12", 5, 1, "2021/12/24 07:12"),
("2021/11/24 07:12", 8, 1, "2021/11/25 07:12"),
("2021/11/24 07:12", 11, 1, "2021/11/24 08:12"),
("2021/11/24 07:12", 14, 1, "2021/11/24 07:13"),
("Wed Nov 24 2021", 0, 1, "Thu Nov 25 2021"),
("Wed Nov 24 2021", 4, 1, "Fri Dec 24 2021"),
("Wed Nov 24 2021", 8, 1, "Thu Nov 25 2021"),
("Wed Nov 24 2021", 11, 1, "Thu Nov 24 2022"),
("24-Nov-2021", 0, 1, "25-Nov-2021"),
("24-Nov-2021", 3, 1, "24-Dec-2021"),
("24-Nov-2021", 7, 1, "24-Nov-2022"),
("2021 Nov 24", 0, 1, "2022 Nov 24"),
("2021 Nov 24", 5, 1, "2021 Dec 24"),
("2021 Nov 24", 9, 1, "2021 Nov 25"),
("Nov 24, 2021", 0, 1, "Dec 24, 2021"),
("Nov 24, 2021", 4, 1, "Nov 25, 2021"),
("Nov 24, 2021", 8, 1, "Nov 24, 2022"),
("7:21:53 am", 0, 1, "8:21:53 am"),
("7:21:53 am", 3, 1, "7:22:53 am"),
("7:21:53 am", 5, 1, "7:21:54 am"),
("7:21:53 am", 8, 1, "7:21:53 pm"),
("7:21:53 AM", 0, 1, "8:21:53 AM"),
("7:21:53 AM", 3, 1, "7:22:53 AM"),
("7:21:53 AM", 5, 1, "7:21:54 AM"),
("7:21:53 AM", 8, 1, "7:21:53 PM"),
("7:21 am", 0, 1, "8:21 am"),
("7:21 am", 3, 1, "7:22 am"),
("7:21 am", 5, 1, "7:21 pm"),
("7:21 AM", 0, 1, "8:21 AM"),
("7:21 AM", 3, 1, "7:22 AM"),
("7:21 AM", 5, 1, "7:21 PM"),
("23:24:23", 1, 1, "00:24:23"),
("23:24:23", 3, 1, "23:25:23"),
("23:24:23", 6, 1, "23:24:24"),
("23:24", 1, 1, "00:24"),
("23:24", 3, 1, "23:25"),
];
for (original, cursor, amount, expected) in tests {
let rope = Rope::from_str(original);
let range = Range::new(cursor, cursor + 1);
assert_eq!(
DateTimeIncrementor::from_range(rope.slice(..), range)
.unwrap()
.increment(amount)
.1,
Tendril::from(expected)
);
}
}
#[test]
fn test_invalid_date_times() {
let tests = [
"0000-00-00",
"1980-2-21",
"1980-12-1",
"12345",
"2020-02-30",
"1999-12-32",
"19-12-32",
"1-2-3",
"0000/00/00",
"1980/2/21",
"1980/12/1",
"12345",
"2020/02/30",
"1999/12/32",
"19/12/32",
"1/2/3",
"123:456:789",
"11:61",
"2021-55-12 08:12:54",
];
for invalid in tests {
let rope = Rope::from_str(invalid);
let range = Range::new(0, 1);
assert_eq!(DateTimeIncrementor::from_range(rope.slice(..), range), None)
}
}
}

View File

@@ -0,0 +1,8 @@
pub mod date_time;
pub mod number;
use crate::{Range, Tendril};
pub trait Increment {
fn increment(&self, amount: i64) -> (Range, Tendril);
}

View File

@@ -0,0 +1,507 @@
use std::borrow::Cow;
use ropey::RopeSlice;
use super::Increment;
use crate::{
textobject::{textobject_word, TextObject},
Range, Tendril,
};
#[derive(Debug, PartialEq, Eq)]
pub struct NumberIncrementor<'a> {
value: i64,
radix: u32,
range: Range,
text: RopeSlice<'a>,
}
impl<'a> NumberIncrementor<'a> {
/// Return information about number under rang if there is one.
pub fn from_range(text: RopeSlice, range: Range) -> Option<NumberIncrementor> {
// If the cursor is on the minus sign of a number we want to get the word textobject to the
// right of it.
let range = if range.to() < text.len_chars()
&& range.to() - range.from() <= 1
&& text.char(range.from()) == '-'
{
Range::new(range.from() + 1, range.to() + 1)
} else {
range
};
let range = textobject_word(text, range, TextObject::Inside, 1, false);
// If there is a minus sign to the left of the word object, we want to include it in the range.
let range = if range.from() > 0 && text.char(range.from() - 1) == '-' {
range.extend(range.from() - 1, range.from())
} else {
range
};
let word: String = text
.slice(range.from()..range.to())
.chars()
.filter(|&c| c != '_')
.collect();
let (radix, prefixed) = if word.starts_with("0x") {
(16, true)
} else if word.starts_with("0o") {
(8, true)
} else if word.starts_with("0b") {
(2, true)
} else {
(10, false)
};
let number = if prefixed { &word[2..] } else { &word };
let value = i128::from_str_radix(number, radix).ok()?;
if (value.is_positive() && value.leading_zeros() < 64)
|| (value.is_negative() && value.leading_ones() < 64)
{
return None;
}
let value = value as i64;
Some(NumberIncrementor {
range,
value,
radix,
text,
})
}
}
impl<'a> Increment for NumberIncrementor<'a> {
fn increment(&self, amount: i64) -> (Range, Tendril) {
let old_text: Cow<str> = self.text.slice(self.range.from()..self.range.to()).into();
let old_length = old_text.len();
let new_value = self.value.wrapping_add(amount);
// Get separator indexes from right to left.
let separator_rtl_indexes: Vec<usize> = old_text
.chars()
.rev()
.enumerate()
.filter_map(|(i, c)| if c == '_' { Some(i) } else { None })
.collect();
let format_length = if self.radix == 10 {
match (self.value.is_negative(), new_value.is_negative()) {
(true, false) => old_length - 1,
(false, true) => old_length + 1,
_ => old_text.len(),
}
} else {
old_text.len() - 2
} - separator_rtl_indexes.len();
let mut new_text = match self.radix {
2 => format!("0b{:01$b}", new_value, format_length),
8 => format!("0o{:01$o}", new_value, format_length),
10 if old_text.starts_with('0') || old_text.starts_with("-0") => {
format!("{:01$}", new_value, format_length)
}
10 => format!("{}", new_value),
16 => {
let (lower_count, upper_count): (usize, usize) =
old_text.chars().skip(2).fold((0, 0), |(lower, upper), c| {
(
lower + c.is_ascii_lowercase().then(|| 1).unwrap_or(0),
upper + c.is_ascii_uppercase().then(|| 1).unwrap_or(0),
)
});
if upper_count > lower_count {
format!("0x{:01$X}", new_value, format_length)
} else {
format!("0x{:01$x}", new_value, format_length)
}
}
_ => unimplemented!("radix not supported: {}", self.radix),
};
// Add separators from original number.
for &rtl_index in &separator_rtl_indexes {
if rtl_index < new_text.len() {
let new_index = new_text.len() - rtl_index;
new_text.insert(new_index, '_');
}
}
// Add in additional separators if necessary.
if new_text.len() > old_length && !separator_rtl_indexes.is_empty() {
let spacing = match separator_rtl_indexes.as_slice() {
[.., b, a] => a - b - 1,
_ => separator_rtl_indexes[0],
};
let prefix_length = if self.radix == 10 { 0 } else { 2 };
if let Some(mut index) = new_text.find('_') {
while index - prefix_length > spacing {
index -= spacing;
new_text.insert(index, '_');
}
}
}
(self.range, new_text.into())
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::Rope;
#[test]
fn test_decimal_at_point() {
let rope = Rope::from_str("Test text 12345 more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 15),
value: 12345,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_uppercase_hexadecimal_at_point() {
let rope = Rope::from_str("Test text 0x123ABCDEF more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 21),
value: 0x123ABCDEF,
radix: 16,
text: rope.slice(..),
})
);
}
#[test]
fn test_lowercase_hexadecimal_at_point() {
let rope = Rope::from_str("Test text 0xfa3b4e more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 18),
value: 0xfa3b4e,
radix: 16,
text: rope.slice(..),
})
);
}
#[test]
fn test_octal_at_point() {
let rope = Rope::from_str("Test text 0o1074312 more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 19),
value: 0o1074312,
radix: 8,
text: rope.slice(..),
})
);
}
#[test]
fn test_binary_at_point() {
let rope = Rope::from_str("Test text 0b10111010010101 more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 26),
value: 0b10111010010101,
radix: 2,
text: rope.slice(..),
})
);
}
#[test]
fn test_negative_decimal_at_point() {
let rope = Rope::from_str("Test text -54321 more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 16),
value: -54321,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_decimal_with_leading_zeroes_at_point() {
let rope = Rope::from_str("Test text 000045326 more text.");
let range = Range::point(12);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 19),
value: 45326,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_negative_decimal_cursor_on_minus_sign() {
let rope = Rope::from_str("Test text -54321 more text.");
let range = Range::point(10);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(10, 16),
value: -54321,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_number_under_range_start_of_rope() {
let rope = Rope::from_str("100");
let range = Range::point(0);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(0, 3),
value: 100,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_number_under_range_end_of_rope() {
let rope = Rope::from_str("100");
let range = Range::point(2);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(0, 3),
value: 100,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_number_surrounded_by_punctuation() {
let rope = Rope::from_str(",100;");
let range = Range::point(1);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range),
Some(NumberIncrementor {
range: Range::new(1, 4),
value: 100,
radix: 10,
text: rope.slice(..),
})
);
}
#[test]
fn test_not_a_number_point() {
let rope = Rope::from_str("Test text 45326 more text.");
let range = Range::point(6);
assert_eq!(NumberIncrementor::from_range(rope.slice(..), range), None);
}
#[test]
fn test_number_too_large_at_point() {
let rope = Rope::from_str("Test text 0xFFFFFFFFFFFFFFFFF more text.");
let range = Range::point(12);
assert_eq!(NumberIncrementor::from_range(rope.slice(..), range), None);
}
#[test]
fn test_number_cursor_one_right_of_number() {
let rope = Rope::from_str("100 ");
let range = Range::point(3);
assert_eq!(NumberIncrementor::from_range(rope.slice(..), range), None);
}
#[test]
fn test_number_cursor_one_left_of_number() {
let rope = Rope::from_str(" 100");
let range = Range::point(0);
assert_eq!(NumberIncrementor::from_range(rope.slice(..), range), None);
}
#[test]
fn test_increment_basic_decimal_numbers() {
let tests = [
("100", 1, "101"),
("100", -1, "99"),
("99", 1, "100"),
("100", 1000, "1100"),
("100", -1000, "-900"),
("-1", 1, "0"),
("-1", 2, "1"),
("1", -1, "0"),
("1", -2, "-1"),
];
for (original, amount, expected) in tests {
let rope = Rope::from_str(original);
let range = Range::point(0);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range)
.unwrap()
.increment(amount)
.1,
Tendril::from(expected)
);
}
}
#[test]
fn test_increment_basic_hexadecimal_numbers() {
let tests = [
("0x0100", 1, "0x0101"),
("0x0100", -1, "0x00ff"),
("0x0001", -1, "0x0000"),
("0x0000", -1, "0xffffffffffffffff"),
("0xffffffffffffffff", 1, "0x0000000000000000"),
("0xffffffffffffffff", 2, "0x0000000000000001"),
("0xffffffffffffffff", -1, "0xfffffffffffffffe"),
("0xABCDEF1234567890", 1, "0xABCDEF1234567891"),
("0xabcdef1234567890", 1, "0xabcdef1234567891"),
];
for (original, amount, expected) in tests {
let rope = Rope::from_str(original);
let range = Range::point(0);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range)
.unwrap()
.increment(amount)
.1,
Tendril::from(expected)
);
}
}
#[test]
fn test_increment_basic_octal_numbers() {
let tests = [
("0o0107", 1, "0o0110"),
("0o0110", -1, "0o0107"),
("0o0001", -1, "0o0000"),
("0o7777", 1, "0o10000"),
("0o1000", -1, "0o0777"),
("0o0107", 10, "0o0121"),
("0o0000", -1, "0o1777777777777777777777"),
("0o1777777777777777777777", 1, "0o0000000000000000000000"),
("0o1777777777777777777777", 2, "0o0000000000000000000001"),
("0o1777777777777777777777", -1, "0o1777777777777777777776"),
];
for (original, amount, expected) in tests {
let rope = Rope::from_str(original);
let range = Range::point(0);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range)
.unwrap()
.increment(amount)
.1,
Tendril::from(expected)
);
}
}
#[test]
fn test_increment_basic_binary_numbers() {
let tests = [
("0b00000100", 1, "0b00000101"),
("0b00000100", -1, "0b00000011"),
("0b00000100", 2, "0b00000110"),
("0b00000100", -2, "0b00000010"),
("0b00000001", -1, "0b00000000"),
("0b00111111", 10, "0b01001001"),
("0b11111111", 1, "0b100000000"),
("0b10000000", -1, "0b01111111"),
(
"0b0000",
-1,
"0b1111111111111111111111111111111111111111111111111111111111111111",
),
(
"0b1111111111111111111111111111111111111111111111111111111111111111",
1,
"0b0000000000000000000000000000000000000000000000000000000000000000",
),
(
"0b1111111111111111111111111111111111111111111111111111111111111111",
2,
"0b0000000000000000000000000000000000000000000000000000000000000001",
),
(
"0b1111111111111111111111111111111111111111111111111111111111111111",
-1,
"0b1111111111111111111111111111111111111111111111111111111111111110",
),
];
for (original, amount, expected) in tests {
let rope = Rope::from_str(original);
let range = Range::point(0);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range)
.unwrap()
.increment(amount)
.1,
Tendril::from(expected)
);
}
}
#[test]
fn test_increment_with_separators() {
let tests = [
("999_999", 1, "1_000_000"),
("1_000_000", -1, "999_999"),
("-999_999", -1, "-1_000_000"),
("0x0000_0000_0001", 0x1_ffff_0000, "0x0001_ffff_0001"),
("0x0000_0000_0001", 0x1_ffff_0000, "0x0001_ffff_0001"),
("0x0000_0000_0001", 0x1_ffff_0000, "0x0001_ffff_0001"),
("0x0000_0000", -1, "0xffff_ffff_ffff_ffff"),
("0x0000_0000_0000", -1, "0xffff_ffff_ffff_ffff"),
("0b01111111_11111111", 1, "0b10000000_00000000"),
("0b11111111_11111111", 1, "0b1_00000000_00000000"),
];
for (original, amount, expected) in tests {
let rope = Rope::from_str(original);
let range = Range::point(0);
assert_eq!(
NumberIncrementor::from_range(rope.slice(..), range)
.unwrap()
.increment(amount)
.1,
Tendril::from(expected)
);
}
}
}

View File

@@ -1,7 +1,10 @@
use std::collections::HashMap;
use tree_sitter::{Query, QueryCursor, QueryPredicateArg};
use crate::{
chars::{char_is_line_ending, char_is_whitespace},
find_first_non_whitespace_char,
syntax::{IndentQuery, LanguageConfiguration, Syntax},
syntax::{LanguageConfiguration, RopeProvider, Syntax},
tree_sitter::Node,
Rope, RopeSlice,
};
@@ -174,8 +177,7 @@ pub fn auto_detect_indent_style(document_text: &Rope) -> Option<IndentStyle> {
/// To determine indentation of a newly inserted line, figure out the indentation at the last col
/// of the previous line.
#[allow(dead_code)]
fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize {
pub fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize {
let mut len = 0;
for ch in line.chars() {
match ch {
@@ -188,129 +190,405 @@ fn indent_level_for_line(line: RopeSlice, tab_width: usize) -> usize {
len / tab_width
}
/// Find the highest syntax node at position.
/// This is to identify the column where this node (e.g., an HTML closing tag) ends.
fn get_highest_syntax_node_at_bytepos(syntax: &Syntax, pos: usize) -> Option<Node> {
let tree = syntax.tree();
// named_descendant
let mut node = match tree.root_node().descendant_for_byte_range(pos, pos) {
Some(node) => node,
None => return None,
};
while let Some(parent) = node.parent() {
if parent.start_byte() == node.start_byte() {
node = parent
/// Computes for node and all ancestors whether they are the first node on their line.
/// The first entry in the return value represents the root node, the last one the node itself
fn get_first_in_line(mut node: Node, byte_pos: usize, new_line: bool) -> Vec<bool> {
let mut first_in_line = Vec::new();
loop {
if let Some(prev) = node.prev_sibling() {
// If we insert a new line, the first node at/after the cursor is considered to be the first in its line
let first = prev.end_position().row != node.start_position().row
|| (new_line && node.start_byte() >= byte_pos && prev.start_byte() < byte_pos);
first_in_line.push(Some(first));
} else {
// Nodes that have no previous siblings are first in their line if and only if their parent is
// (which we don't know yet)
first_in_line.push(None);
}
if let Some(parent) = node.parent() {
node = parent;
} else {
break;
}
}
Some(node)
}
fn calculate_indentation(query: &IndentQuery, node: Option<Node>, newline: bool) -> usize {
// NOTE: can't use contains() on query because of comparing Vec<String> and &str
// https://doc.rust-lang.org/std/vec/struct.Vec.html#method.contains
let mut increment: isize = 0;
let mut node = match node {
Some(node) => node,
None => return 0,
};
let mut prev_start = node.start_position().row;
// if we're calculating indentation for a brand new line then the current node will become the
// parent node. We need to take it's indentation level into account too.
let node_kind = node.kind();
if newline && query.indent.contains(node_kind) {
increment += 1;
}
while let Some(parent) = node.parent() {
let parent_kind = parent.kind();
let start = parent.start_position().row;
// detect deeply nested indents in the same line
// .map(|a| { <-- ({ is two scopes
// let len = 1; <-- indents one level
// }) <-- }) is two scopes
let starts_same_line = start == prev_start;
if query.outdent.contains(node.kind()) && !starts_same_line {
// we outdent by skipping the rules for the current level and jumping up
// node = parent;
increment -= 1;
// continue;
let mut result = Vec::with_capacity(first_in_line.len());
let mut parent_is_first = true; // The root node is by definition the first node in its line
for first in first_in_line.into_iter().rev() {
if let Some(first) = first {
result.push(first);
parent_is_first = first;
} else {
result.push(parent_is_first);
}
if query.indent.contains(parent_kind) // && not_first_or_last_sibling
&& !starts_same_line
{
// println!("is_scope {}", parent_kind);
prev_start = start;
increment += 1
}
// if last_scope && increment > 0 && ...{ ignore }
node = parent;
}
increment.max(0) as usize
result
}
#[allow(dead_code)]
fn suggested_indent_for_line(
language_config: &LanguageConfiguration,
syntax: Option<&Syntax>,
text: RopeSlice,
line_num: usize,
_tab_width: usize,
) -> usize {
if let Some(start) = find_first_non_whitespace_char(text.line(line_num)) {
return suggested_indent_for_pos(
Some(language_config),
syntax,
text,
start + text.line_to_char(line_num),
false,
);
};
// if the line is blank, indent should be zero
0
/// The total indent for some line of code.
/// This is usually constructed in one of 2 ways:
/// - Successively add indent captures to get the (added) indent from a single line
/// - Successively add the indent results for each line
#[derive(Default)]
struct Indentation {
/// The total indent (the number of indent levels) is defined as max(0, indent-outdent).
/// The string that this results in depends on the indent style (spaces or tabs, etc.)
indent: usize,
outdent: usize,
}
impl Indentation {
/// Add some other [IndentResult] to this.
/// The added indent should be the total added indent from one line
fn add_line(&mut self, added: &Indentation) {
if added.indent > 0 && added.outdent == 0 {
self.indent += 1;
} else if added.outdent > 0 && added.indent == 0 {
self.outdent += 1;
}
}
/// Add an indent capture to this indent.
/// All the captures that are added in this way should be on the same line.
fn add_capture(&mut self, added: IndentCaptureType) {
match added {
IndentCaptureType::Indent => {
self.indent = 1;
}
IndentCaptureType::Outdent => {
self.outdent = 1;
}
}
}
fn as_string(&self, indent_style: &IndentStyle) -> String {
let indent_level = if self.indent >= self.outdent {
self.indent - self.outdent
} else {
log::warn!("Encountered more outdent than indent nodes while calculating indentation: {} outdent, {} indent", self.outdent, self.indent);
0
};
indent_style.as_str().repeat(indent_level)
}
}
// TODO: two usecases: if we are triggering this for a new, blank line:
// - it should return 0 when mass indenting stuff
// - it should look up the wrapper node and count it too when we press o/O
pub fn suggested_indent_for_pos(
language_config: Option<&LanguageConfiguration>,
syntax: Option<&Syntax>,
/// An indent definition which corresponds to a capture from the indent query
struct IndentCapture {
capture_type: IndentCaptureType,
scope: IndentScope,
}
#[derive(Clone, Copy)]
enum IndentCaptureType {
Indent,
Outdent,
}
impl IndentCaptureType {
fn default_scope(&self) -> IndentScope {
match self {
IndentCaptureType::Indent => IndentScope::Tail,
IndentCaptureType::Outdent => IndentScope::All,
}
}
}
/// This defines which part of a node an [IndentCapture] applies to.
/// Each [IndentCaptureType] has a default scope, but the scope can be changed
/// with `#set!` property declarations.
#[derive(Clone, Copy)]
enum IndentScope {
/// The indent applies to the whole node
All,
/// The indent applies to everything except for the first line of the node
Tail,
}
/// Execute the indent query.
/// Returns for each node (identified by its id) a list of indent captures for that node.
fn query_indents(
query: &Query,
syntax: &Syntax,
cursor: &mut QueryCursor,
text: RopeSlice,
range: std::ops::Range<usize>,
// Position of the (optional) newly inserted line break.
// Given as (line, byte_pos)
new_line_break: Option<(usize, usize)>,
) -> HashMap<usize, Vec<IndentCapture>> {
let mut indent_captures: HashMap<usize, Vec<IndentCapture>> = HashMap::new();
cursor.set_byte_range(range);
// Iterate over all captures from the query
for m in cursor.matches(query, syntax.tree().root_node(), RopeProvider(text)) {
// Skip matches where not all custom predicates are fulfilled
if !query.general_predicates(m.pattern_index).iter().all(|pred| {
match pred.operator.as_ref() {
"not-kind-eq?" => match (pred.args.get(0), pred.args.get(1)) {
(
Some(QueryPredicateArg::Capture(capture_idx)),
Some(QueryPredicateArg::String(kind)),
) => {
let node = m.nodes_for_capture_index(*capture_idx).next();
match node {
Some(node) => node.kind()!=kind.as_ref(),
_ => true,
}
}
_ => {
panic!("Invalid indent query: Arguments to \"not-kind-eq?\" must be a capture and a string");
}
},
"same-line?" | "not-same-line?" => {
match (pred.args.get(0), pred.args.get(1)) {
(
Some(QueryPredicateArg::Capture(capt1)),
Some(QueryPredicateArg::Capture(capt2))
) => {
let get_line_num = |node: Node| {
let mut node_line = node.start_position().row;
// Adjust for the new line that will be inserted
if let Some((line, byte)) = new_line_break {
if node_line==line && node.start_byte()>=byte {
node_line += 1;
}
}
node_line
};
let n1 = m.nodes_for_capture_index(*capt1).next();
let n2 = m.nodes_for_capture_index(*capt2).next();
match (n1, n2) {
(Some(n1), Some(n2)) => {
let same_line = get_line_num(n1)==get_line_num(n2);
same_line==(pred.operator.as_ref()=="same-line?")
}
_ => true,
}
}
_ => {
panic!("Invalid indent query: Arguments to \"{}\" must be 2 captures", pred.operator);
}
}
}
_ => {
panic!(
"Invalid indent query: Unknown predicate (\"{}\")",
pred.operator
);
}
}
}) {
continue;
}
for capture in m.captures {
let capture_type = query.capture_names()[capture.index as usize].as_str();
let capture_type = match capture_type {
"indent" => IndentCaptureType::Indent,
"outdent" => IndentCaptureType::Outdent,
_ => {
// Ignore any unknown captures (these may be needed for predicates such as #match?)
continue;
}
};
let scope = capture_type.default_scope();
let mut indent_capture = IndentCapture {
capture_type,
scope,
};
// Apply additional settings for this capture
for property in query.property_settings(m.pattern_index) {
match property.key.as_ref() {
"scope" => {
indent_capture.scope = match property.value.as_deref() {
Some("all") => IndentScope::All,
Some("tail") => IndentScope::Tail,
Some(s) => {
panic!("Invalid indent query: Unknown value for \"scope\" property (\"{}\")", s);
}
None => {
panic!(
"Invalid indent query: Missing value for \"scope\" property"
);
}
}
}
_ => {
panic!(
"Invalid indent query: Unknown property \"{}\"",
property.key
);
}
}
}
indent_captures
.entry(capture.node.id())
// Most entries only need to contain a single IndentCapture
.or_insert_with(|| Vec::with_capacity(1))
.push(indent_capture);
}
}
indent_captures
}
/// Use the syntax tree to determine the indentation for a given position.
/// This can be used in 2 ways:
///
/// - To get the correct indentation for an existing line (new_line=false), not necessarily equal to the current indentation.
/// - In this case, pos should be inside the first tree-sitter node on that line.
/// In most cases, this can just be the first non-whitespace on that line.
/// - To get the indentation for a new line (new_line=true). This behaves like the first usecase if the part of the current line
/// after pos were moved to a new line.
///
/// The indentation is determined by traversing all the tree-sitter nodes containing the position.
/// Each of these nodes produces some [AddedIndent] for:
///
/// - The line of the (beginning of the) node. This is defined by the scope `all` if this is the first node on its line.
/// - The line after the node. This is defined by:
/// - The scope `tail`.
/// - The scope `all` if this node is not the first node on its line.
/// Intuitively, `all` applies to everything contained in this node while `tail` applies to everything except for the first line of the node.
/// The indents from different nodes for the same line are then combined.
/// The [IndentResult] is simply the sum of the [AddedIndent] for all lines.
///
/// Specifying which line exactly an [AddedIndent] applies to is important because indents on the same line combine differently than indents on different lines:
/// ```ignore
/// some_function(|| {
/// // Both the function parameters as well as the contained block should be indented.
/// // Because they are on the same line, this only yields one indent level
/// });
/// ```
///
/// ```ignore
/// some_function(
/// param1,
/// || {
/// // Here we get 2 indent levels because the 'parameters' and the 'block' node begin on different lines
/// },
/// );
/// ```
pub fn treesitter_indent_for_pos(
query: &Query,
syntax: &Syntax,
indent_style: &IndentStyle,
text: RopeSlice,
line: usize,
pos: usize,
new_line: bool,
) -> usize {
) -> Option<String> {
let byte_pos = text.char_to_byte(pos);
let mut node = syntax
.tree()
.root_node()
.descendant_for_byte_range(byte_pos, byte_pos)?;
let mut first_in_line = get_first_in_line(node, byte_pos, new_line);
let new_line_break = if new_line {
Some((line, byte_pos))
} else {
None
};
let query_result = crate::syntax::PARSER.with(|ts_parser| {
let mut ts_parser = ts_parser.borrow_mut();
let mut cursor = ts_parser.cursors.pop().unwrap_or_else(QueryCursor::new);
let query_result = query_indents(
query,
syntax,
&mut cursor,
text,
byte_pos..byte_pos + 1,
new_line_break,
);
ts_parser.cursors.push(cursor);
query_result
});
let mut result = Indentation::default();
// We always keep track of all the indent changes on one line, in order to only indent once
// even if there are multiple "indent" nodes on the same line
let mut indent_for_line = Indentation::default();
let mut indent_for_line_below = Indentation::default();
loop {
// This can safely be unwrapped because `first_in_line` contains
// one entry for each ancestor of the node (which is what we iterate over)
let is_first = *first_in_line.last().unwrap();
// Apply all indent definitions for this node
if let Some(definitions) = query_result.get(&node.id()) {
for definition in definitions {
match definition.scope {
IndentScope::All => {
if is_first {
indent_for_line.add_capture(definition.capture_type);
} else {
indent_for_line_below.add_capture(definition.capture_type);
}
}
IndentScope::Tail => {
indent_for_line_below.add_capture(definition.capture_type);
}
}
}
}
if let Some(parent) = node.parent() {
let mut node_line = node.start_position().row;
let mut parent_line = parent.start_position().row;
if node_line == line && new_line {
// Also consider the line that will be inserted
if node.start_byte() >= byte_pos {
node_line += 1;
}
if parent.start_byte() >= byte_pos {
parent_line += 1;
}
};
if node_line != parent_line {
if node_line < line + (new_line as usize) {
// Don't add indent for the line below the line of the query
result.add_line(&indent_for_line_below);
}
if node_line == parent_line + 1 {
indent_for_line_below = indent_for_line;
} else {
result.add_line(&indent_for_line);
indent_for_line_below = Indentation::default();
}
indent_for_line = Indentation::default();
}
node = parent;
first_in_line.pop();
} else {
result.add_line(&indent_for_line_below);
result.add_line(&indent_for_line);
break;
}
}
Some(result.as_string(indent_style))
}
/// Returns the indentation for a new line.
/// This is done either using treesitter, or if that's not available by copying the indentation from the current line
#[allow(clippy::too_many_arguments)]
pub fn indent_for_newline(
language_config: Option<&LanguageConfiguration>,
syntax: Option<&Syntax>,
indent_style: &IndentStyle,
tab_width: usize,
text: RopeSlice,
line_before: usize,
line_before_end_pos: usize,
current_line: usize,
) -> String {
if let (Some(query), Some(syntax)) = (
language_config.and_then(|config| config.indent_query()),
syntax,
) {
let byte_start = text.char_to_byte(pos);
let node = get_highest_syntax_node_at_bytepos(syntax, byte_start);
// let config = load indentation query config from Syntax(should contain language_config)
// TODO: special case for comments
// TODO: if preserve_leading_whitespace
calculate_indentation(query, node, new_line)
} else {
// TODO: heuristics for non-tree sitter grammars
0
if let Some(indent) = treesitter_indent_for_pos(
query,
syntax,
indent_style,
text,
line_before,
line_before_end_pos,
true,
) {
return indent;
};
}
let indent_level = indent_level_for_line(text.line(current_line), tab_width);
indent_style.as_str().repeat(indent_level)
}
pub fn get_scopes(syntax: Option<&Syntax>, text: RopeSlice, pos: usize) -> Vec<&'static str> {
@@ -354,141 +632,4 @@ mod test {
let line = Rope::from("\t \tfn new"); // 1 tab, 4 spaces, tab
assert_eq!(indent_level_for_line(line.slice(..), tab_width), 3);
}
#[test]
fn test_suggested_indent_for_line() {
let doc = Rope::from(
"
use std::{
io::{self, stdout, Stdout, Write},
path::PathBuf,
sync::Arc,
time::Duration,
}
mod test {
fn hello_world() {
1 + 1;
let does_indentation_work = 1;
let test_function = function_with_param(this_param,
that_param
);
let test_function = function_with_param(
this_param,
that_param
);
let test_function = function_with_proper_indent(param1,
param2,
);
let selection = Selection::new(
changes
.clone()
.map(|(start, end, text): (usize, usize, Option<Tendril>)| {
let len = text.map(|text| text.len()).unwrap() - 1; // minus newline
let pos = start + len;
Range::new(pos, pos)
})
.collect(),
0,
);
return;
}
}
impl<A, D> MyTrait<A, D> for YourType
where
A: TraitB + TraitC,
D: TraitE + TraitF,
{
}
#[test]
//
match test {
Some(a) => 1,
None => {
unimplemented!()
}
}
std::panic::set_hook(Box::new(move |info| {
hook(info);
}));
{ { {
1
}}}
pub fn change<I>(document: &Document, changes: I) -> Self
where
I: IntoIterator<Item = Change> + ExactSizeIterator,
{
[
1,
2,
3,
];
(
1,
2
);
true
}
",
);
let doc = Rope::from(doc);
use crate::syntax::{
Configuration, IndentationConfiguration, LanguageConfiguration, Loader,
};
use once_cell::sync::OnceCell;
let loader = Loader::new(Configuration {
language: vec![LanguageConfiguration {
scope: "source.rust".to_string(),
file_types: vec!["rs".to_string()],
language_id: "Rust".to_string(),
highlight_config: OnceCell::new(),
config: None,
//
injection_regex: None,
roots: vec![],
comment_token: None,
auto_format: false,
language_server: None,
indent: Some(IndentationConfiguration {
tab_width: 4,
unit: String::from(" "),
}),
indent_query: OnceCell::new(),
textobject_query: OnceCell::new(),
}],
});
// set runtime path so we can find the queries
let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
runtime.push("../runtime");
std::env::set_var("HELIX_RUNTIME", runtime.to_str().unwrap());
let language_config = loader.language_config_for_scope("source.rust").unwrap();
let highlight_config = language_config.highlight_config(&[]).unwrap();
let syntax = Syntax::new(&doc, highlight_config.clone());
let text = doc.slice(..);
let tab_width = 4;
for i in 0..doc.len_lines() {
let line = text.line(i);
let indent = indent_level_for_line(line, tab_width);
assert_eq!(
suggested_indent_for_line(&language_config, Some(&syntax), text, i, tab_width),
indent,
"line {}: {}",
i,
line
);
}
}
}

View File

@@ -1,10 +1,14 @@
pub use encoding_rs as encoding;
pub mod auto_pairs;
pub mod chars;
pub mod comment;
pub mod config;
pub mod diagnostic;
pub mod diff;
pub mod graphemes;
pub mod history;
pub mod increment;
pub mod indent;
pub mod line_ending;
pub mod macros;
@@ -16,11 +20,14 @@ mod position;
pub mod register;
pub mod search;
pub mod selection;
pub mod shellwords;
mod state;
pub mod surround;
pub mod syntax;
pub mod test;
pub mod textobject;
mod transaction;
pub mod wrap;
pub mod unicode {
pub use unicode_general_category as category;
@@ -28,174 +35,39 @@ pub mod unicode {
pub use unicode_width as width;
}
static RUNTIME_DIR: once_cell::sync::Lazy<std::path::PathBuf> =
once_cell::sync::Lazy::new(runtime_dir);
pub fn find_first_non_whitespace_char(line: RopeSlice) -> Option<usize> {
line.chars().position(|ch| !ch.is_whitespace())
}
pub fn find_root(root: Option<&str>) -> Option<std::path::PathBuf> {
let current_dir = std::env::current_dir().expect("unable to determine current directory");
let root = match root {
Some(root) => {
let root = std::path::Path::new(root);
if root.is_absolute() {
root.to_path_buf()
} else {
current_dir.join(root)
}
}
None => current_dir,
};
for ancestor in root.ancestors() {
// TODO: also use defined roots if git isn't found
if ancestor.join(".git").is_dir() {
return Some(ancestor.to_path_buf());
}
}
None
/// Find project root.
///
/// Order of detection:
/// * Top-most folder containing a root marker in current git repository
/// * Git repository root if no marker detected
/// * Top-most folder containing a root marker if not git repository detected
/// * Current working directory as fallback
pub fn find_root(root: Option<&str>, root_markers: &[String]) -> Option<std::path::PathBuf> {
helix_loader::find_root_impl(root, root_markers)
.first()
.cloned()
}
pub fn runtime_dir() -> std::path::PathBuf {
if let Ok(dir) = std::env::var("HELIX_RUNTIME") {
return dir.into();
}
pub use ropey::{str_utils, Rope, RopeBuilder, RopeSlice};
const RT_DIR: &str = "runtime";
let conf_dir = config_dir().join(RT_DIR);
if conf_dir.exists() {
return conf_dir;
}
// pub use tendril::StrTendril as Tendril;
pub use smartstring::SmartString;
if let Ok(dir) = std::env::var("CARGO_MANIFEST_DIR") {
// this is the directory of the crate being run by cargo, we need the workspace path so we take the parent
return std::path::PathBuf::from(dir).parent().unwrap().join(RT_DIR);
}
// fallback to location of the executable being run
std::env::current_exe()
.ok()
.and_then(|path| path.parent().map(|path| path.to_path_buf().join(RT_DIR)))
.unwrap()
}
pub fn config_dir() -> std::path::PathBuf {
// TODO: allow env var override
let strategy = choose_base_strategy().expect("Unable to find the config directory!");
let mut path = strategy.config_dir();
path.push("helix");
path
}
pub fn cache_dir() -> std::path::PathBuf {
// TODO: allow env var override
let strategy = choose_base_strategy().expect("Unable to find the config directory!");
let mut path = strategy.cache_dir();
path.push("helix");
path
}
// right overrides left
pub fn merge_toml_values(left: toml::Value, right: toml::Value) -> toml::Value {
use toml::Value;
fn get_name(v: &Value) -> Option<&str> {
v.get("name").and_then(Value::as_str)
}
match (left, right) {
(Value::Array(mut left_items), Value::Array(right_items)) => {
left_items.reserve(right_items.len());
for rvalue in right_items {
let lvalue = get_name(&rvalue)
.and_then(|rname| left_items.iter().position(|v| get_name(v) == Some(rname)))
.map(|lpos| left_items.remove(lpos));
let mvalue = match lvalue {
Some(lvalue) => merge_toml_values(lvalue, rvalue),
None => rvalue,
};
left_items.push(mvalue);
}
Value::Array(left_items)
}
(Value::Table(mut left_map), Value::Table(right_map)) => {
for (rname, rvalue) in right_map {
match left_map.remove(&rname) {
Some(lvalue) => {
let merged_value = merge_toml_values(lvalue, rvalue);
left_map.insert(rname, merged_value);
}
None => {
left_map.insert(rname, rvalue);
}
}
}
Value::Table(left_map)
}
// Catch everything else we didn't handle, and use the right value
(_, value) => value,
}
}
#[cfg(test)]
mod merge_toml_tests {
use super::merge_toml_values;
#[test]
fn language_tomls() {
use toml::Value;
const USER: &str = "
[[language]]
name = \"nix\"
test = \"bbb\"
indent = { tab-width = 4, unit = \" \", test = \"aaa\" }
";
let base: Value = toml::from_slice(include_bytes!("../../languages.toml"))
.expect("Couldn't parse built-in langauges config");
let user: Value = toml::from_str(USER).unwrap();
let merged = merge_toml_values(base, user);
let languages = merged.get("language").unwrap().as_array().unwrap();
let nix = languages
.iter()
.find(|v| v.get("name").unwrap().as_str().unwrap() == "nix")
.unwrap();
let nix_indent = nix.get("indent").unwrap();
// We changed tab-width and unit in indent so check them if they are the new values
assert_eq!(
nix_indent.get("tab-width").unwrap().as_integer().unwrap(),
4
);
assert_eq!(nix_indent.get("unit").unwrap().as_str().unwrap(), " ");
// We added a new keys, so check them
assert_eq!(nix.get("test").unwrap().as_str().unwrap(), "bbb");
assert_eq!(nix_indent.get("test").unwrap().as_str().unwrap(), "aaa");
// We didn't change comment-token so it should be same
assert_eq!(nix.get("comment-token").unwrap().as_str().unwrap(), "#");
}
}
pub use etcetera::home_dir;
use etcetera::base_strategy::{choose_base_strategy, BaseStrategy};
pub use ropey::{Rope, RopeBuilder, RopeSlice};
pub use tendril::StrTendril as Tendril;
pub type Tendril = SmartString<smartstring::LazyCompact>;
#[doc(inline)]
pub use {regex, tree_sitter};
pub use graphemes::RopeGraphemes;
pub use position::{coords_at_pos, pos_at_coords, Position};
pub use position::{
coords_at_pos, pos_at_coords, pos_at_visual_coords, visual_coords_at_pos, Position,
};
pub use selection::{Range, Selection};
pub use smallvec::SmallVec;
pub use smallvec::{smallvec, SmallVec};
pub use syntax::Syntax;
pub use diagnostic::Diagnostic;

View File

@@ -10,12 +10,18 @@ pub const DEFAULT_LINE_ENDING: LineEnding = LineEnding::LF;
pub enum LineEnding {
Crlf, // CarriageReturn followed by LineFeed
LF, // U+000A -- LineFeed
VT, // U+000B -- VerticalTab
FF, // U+000C -- FormFeed
CR, // U+000D -- CarriageReturn
Nel, // U+0085 -- NextLine
LS, // U+2028 -- Line Separator
PS, // U+2029 -- ParagraphSeparator
#[cfg(feature = "unicode-lines")]
VT, // U+000B -- VerticalTab
#[cfg(feature = "unicode-lines")]
FF, // U+000C -- FormFeed
#[cfg(feature = "unicode-lines")]
CR, // U+000D -- CarriageReturn
#[cfg(feature = "unicode-lines")]
Nel, // U+0085 -- NextLine
#[cfg(feature = "unicode-lines")]
LS, // U+2028 -- Line Separator
#[cfg(feature = "unicode-lines")]
PS, // U+2029 -- ParagraphSeparator
}
impl LineEnding {
@@ -32,11 +38,17 @@ impl LineEnding {
match self {
Self::Crlf => "\u{000D}\u{000A}",
Self::LF => "\u{000A}",
#[cfg(feature = "unicode-lines")]
Self::VT => "\u{000B}",
#[cfg(feature = "unicode-lines")]
Self::FF => "\u{000C}",
#[cfg(feature = "unicode-lines")]
Self::CR => "\u{000D}",
#[cfg(feature = "unicode-lines")]
Self::Nel => "\u{0085}",
#[cfg(feature = "unicode-lines")]
Self::LS => "\u{2028}",
#[cfg(feature = "unicode-lines")]
Self::PS => "\u{2029}",
}
}
@@ -45,11 +57,17 @@ impl LineEnding {
pub const fn from_char(ch: char) -> Option<LineEnding> {
match ch {
'\u{000A}' => Some(LineEnding::LF),
#[cfg(feature = "unicode-lines")]
'\u{000B}' => Some(LineEnding::VT),
#[cfg(feature = "unicode-lines")]
'\u{000C}' => Some(LineEnding::FF),
#[cfg(feature = "unicode-lines")]
'\u{000D}' => Some(LineEnding::CR),
#[cfg(feature = "unicode-lines")]
'\u{0085}' => Some(LineEnding::Nel),
#[cfg(feature = "unicode-lines")]
'\u{2028}' => Some(LineEnding::LS),
#[cfg(feature = "unicode-lines")]
'\u{2029}' => Some(LineEnding::PS),
// Not a line ending
_ => None,
@@ -65,11 +83,17 @@ impl LineEnding {
match g {
"\u{000D}\u{000A}" => Some(LineEnding::Crlf),
"\u{000A}" => Some(LineEnding::LF),
#[cfg(feature = "unicode-lines")]
"\u{000B}" => Some(LineEnding::VT),
#[cfg(feature = "unicode-lines")]
"\u{000C}" => Some(LineEnding::FF),
#[cfg(feature = "unicode-lines")]
"\u{000D}" => Some(LineEnding::CR),
#[cfg(feature = "unicode-lines")]
"\u{0085}" => Some(LineEnding::Nel),
#[cfg(feature = "unicode-lines")]
"\u{2028}" => Some(LineEnding::LS),
#[cfg(feature = "unicode-lines")]
"\u{2029}" => Some(LineEnding::PS),
// Not a line ending
_ => None,
@@ -95,13 +119,20 @@ pub fn str_is_line_ending(s: &str) -> bool {
LineEnding::from_str(s).is_some()
}
#[inline]
pub fn rope_is_line_ending(r: RopeSlice) -> bool {
r.chunks().all(str_is_line_ending)
}
/// Attempts to detect what line ending the passed document uses.
pub fn auto_detect_line_ending(doc: &Rope) -> Option<LineEnding> {
// Return first matched line ending. Not all possible line endings
// are being matched, as they might be special-use only
for line in doc.lines().take(100) {
match get_line_ending(&line) {
None | Some(LineEnding::VT) | Some(LineEnding::FF) | Some(LineEnding::PS) => {}
None => {}
#[cfg(feature = "unicode-lines")]
Some(LineEnding::VT) | Some(LineEnding::FF) | Some(LineEnding::PS) => {}
ending => return ending,
}
}
@@ -128,6 +159,19 @@ pub fn get_line_ending(line: &RopeSlice) -> Option<LineEnding> {
LineEnding::from_str(g2).or_else(|| LineEnding::from_str(g1))
}
#[cfg(not(feature = "unicode-lines"))]
/// Returns the passed line's line ending, if any.
pub fn get_line_ending_of_str(line: &str) -> Option<LineEnding> {
if line.ends_with("\u{000D}\u{000A}") {
Some(LineEnding::Crlf)
} else if line.ends_with('\u{000A}') {
Some(LineEnding::LF)
} else {
None
}
}
#[cfg(feature = "unicode-lines")]
/// Returns the passed line's line ending, if any.
pub fn get_line_ending_of_str(line: &str) -> Option<LineEnding> {
if line.ends_with("\u{000D}\u{000A}") {
@@ -211,6 +255,7 @@ mod line_ending_tests {
#[test]
fn str_to_line_ending() {
#[cfg(feature = "unicode-lines")]
assert_eq!(LineEnding::from_str("\r"), Some(LineEnding::CR));
assert_eq!(LineEnding::from_str("\n"), Some(LineEnding::LF));
assert_eq!(LineEnding::from_str("\r\n"), Some(LineEnding::Crlf));
@@ -220,6 +265,7 @@ mod line_ending_tests {
#[test]
fn rope_slice_to_line_ending() {
let r = Rope::from_str("hello\r\n");
#[cfg(feature = "unicode-lines")]
assert_eq!(
LineEnding::from_rope_slice(&r.slice(5..6)),
Some(LineEnding::CR)
@@ -238,6 +284,7 @@ mod line_ending_tests {
#[test]
fn get_line_ending_rope_slice() {
let r = Rope::from_str("Hello\rworld\nhow\r\nare you?");
#[cfg(feature = "unicode-lines")]
assert_eq!(get_line_ending(&r.slice(..6)), Some(LineEnding::CR));
assert_eq!(get_line_ending(&r.slice(..12)), Some(LineEnding::LF));
assert_eq!(get_line_ending(&r.slice(..17)), Some(LineEnding::Crlf));
@@ -247,19 +294,28 @@ mod line_ending_tests {
#[test]
fn get_line_ending_str() {
let text = "Hello\rworld\nhow\r\nare you?";
#[cfg(feature = "unicode-lines")]
assert_eq!(get_line_ending_of_str(&text[..6]), Some(LineEnding::CR));
assert_eq!(get_line_ending_of_str(&text[..12]), Some(LineEnding::LF));
assert_eq!(get_line_ending_of_str(&text[..17]), Some(LineEnding::Crlf));
assert_eq!(get_line_ending_of_str(&text[..]), None);
assert_eq!(get_line_ending_of_str(text), None);
}
#[test]
fn line_end_char_index_rope_slice() {
let r = Rope::from_str("Hello\rworld\nhow\r\nare you?");
let s = &r.slice(..);
assert_eq!(line_end_char_index(s, 0), 5);
assert_eq!(line_end_char_index(s, 1), 11);
assert_eq!(line_end_char_index(s, 2), 15);
assert_eq!(line_end_char_index(s, 3), 25);
#[cfg(not(feature = "unicode-lines"))]
{
assert_eq!(line_end_char_index(s, 0), 11);
assert_eq!(line_end_char_index(s, 1), 15);
assert_eq!(line_end_char_index(s, 2), 25);
}
#[cfg(feature = "unicode-lines")]
{
assert_eq!(line_end_char_index(s, 0), 5);
assert_eq!(line_end_char_index(s, 1), 11);
assert_eq!(line_end_char_index(s, 2), 15);
}
}
}

View File

@@ -1,48 +1,92 @@
use tree_sitter::Node;
use crate::{Rope, Syntax};
const PAIRS: &[(char, char)] = &[('(', ')'), ('{', '}'), ('[', ']'), ('<', '>')];
// limit matching pairs to only ( ) { } [ ] < >
const PAIRS: &[(char, char)] = &[
('(', ')'),
('{', '}'),
('[', ']'),
('<', '>'),
('\'', '\''),
('\"', '\"'),
];
// limit matching pairs to only ( ) { } [ ] < > ' ' " "
// Returns the position of the matching bracket under cursor.
//
// If the cursor is one the opening bracket, the position of
// the closing bracket is returned. If the cursor in the closing
// bracket, the position of the opening bracket is returned.
//
// If the cursor is not on a bracket, `None` is returned.
#[must_use]
pub fn find(syntax: &Syntax, doc: &Rope, pos: usize) -> Option<usize> {
let tree = syntax.tree();
let byte_pos = doc.char_to_byte(pos);
// most naive implementation: find the innermost syntax node, if we're at the edge of a node,
// return the other edge.
let node = match tree
.root_node()
.named_descendant_for_byte_range(byte_pos, byte_pos)
{
Some(node) => node,
None => return None,
};
if node.is_error() {
pub fn find_matching_bracket(syntax: &Syntax, doc: &Rope, pos: usize) -> Option<usize> {
if pos >= doc.len_chars() || !is_valid_bracket(doc.char(pos)) {
return None;
}
find_pair(syntax, doc, pos, false)
}
// Returns the position of the bracket that is closing the current scope.
//
// If the cursor is on an opening or closing bracket, the function
// behaves equivalent to [`find_matching_bracket`].
//
// If the cursor position is within a scope, the function searches
// for the surrounding scope that is surrounded by brackets and
// returns the position of the closing bracket for that scope.
//
// If no surrounding scope is found, the function returns `None`.
#[must_use]
pub fn find_matching_bracket_fuzzy(syntax: &Syntax, doc: &Rope, pos: usize) -> Option<usize> {
find_pair(syntax, doc, pos, true)
}
fn find_pair(syntax: &Syntax, doc: &Rope, pos: usize, traverse_parents: bool) -> Option<usize> {
let tree = syntax.tree();
let pos = doc.char_to_byte(pos);
let mut node = tree.root_node().named_descendant_for_byte_range(pos, pos)?;
loop {
let (start_byte, end_byte) = surrounding_bytes(doc, &node)?;
let (start_char, end_char) = (doc.byte_to_char(start_byte), doc.byte_to_char(end_byte));
if is_valid_pair(doc, start_char, end_char) {
if end_byte == pos {
return Some(start_char);
}
// We return the end char if the cursor is either on the start char
// or at some arbitrary position between start and end char.
return Some(end_char);
}
if traverse_parents {
node = node.parent()?;
} else {
return None;
}
}
}
fn is_valid_bracket(c: char) -> bool {
PAIRS.iter().any(|(l, r)| *l == c || *r == c)
}
fn is_valid_pair(doc: &Rope, start_char: usize, end_char: usize) -> bool {
PAIRS.contains(&(doc.char(start_char), doc.char(end_char)))
}
fn surrounding_bytes(doc: &Rope, node: &Node) -> Option<(usize, usize)> {
let len = doc.len_bytes();
let start_byte = node.start_byte();
let end_byte = node.end_byte().saturating_sub(1); // it's end exclusive
let end_byte = node.end_byte().saturating_sub(1);
if start_byte >= len || end_byte >= len {
return None;
}
let start_char = doc.byte_to_char(start_byte);
let end_char = doc.byte_to_char(end_byte);
if PAIRS.contains(&(doc.char(start_char), doc.char(end_char))) {
if start_byte == byte_pos {
return Some(end_char);
}
if end_byte == byte_pos {
return Some(start_char);
}
}
None
Some((start_byte, end_byte))
}

View File

@@ -1,15 +1,19 @@
use std::iter;
use ropey::iter::Chars;
use tree_sitter::{Node, QueryCursor};
use crate::{
chars::{categorize_char, char_is_line_ending, CharCategory},
coords_at_pos,
graphemes::{
next_grapheme_boundary, nth_next_grapheme_boundary, nth_prev_grapheme_boundary,
prev_grapheme_boundary,
},
pos_at_coords, Position, Range, RopeSlice,
line_ending::rope_is_line_ending,
pos_at_visual_coords,
syntax::LanguageConfiguration,
textobject::TextObject,
visual_coords_at_pos, Position, Range, RopeSlice,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -30,6 +34,7 @@ pub fn move_horizontally(
dir: Direction,
count: usize,
behaviour: Movement,
_: usize,
) -> Range {
let pos = range.cursor(slice);
@@ -49,11 +54,12 @@ pub fn move_vertically(
dir: Direction,
count: usize,
behaviour: Movement,
tab_width: usize,
) -> Range {
let pos = range.cursor(slice);
// Compute the current position's 2d coordinates.
let Position { row, col } = coords_at_pos(slice, pos);
let Position { row, col } = visual_coords_at_pos(slice, pos, tab_width);
let horiz = range.horiz.unwrap_or(col as u32);
// Compute the new position.
@@ -62,7 +68,7 @@ pub fn move_vertically(
Direction::Backward => row.saturating_sub(count),
};
let new_col = col.max(horiz as usize);
let new_pos = pos_at_coords(slice, Position::new(new_row, new_col), true);
let new_pos = pos_at_visual_coords(slice, Position::new(new_row, new_col), tab_width);
// Special-case to avoid moving to the end of the last non-empty line.
if behaviour == Movement::Extend && slice.line(new_row).len_chars() == 0 {
@@ -141,6 +147,88 @@ fn word_move(slice: RopeSlice, range: Range, count: usize, target: WordMotionTar
})
}
pub fn move_prev_paragraph(
slice: RopeSlice,
range: Range,
count: usize,
behavior: Movement,
) -> Range {
let mut line = range.cursor_line(slice);
let first_char = slice.line_to_char(line) == range.cursor(slice);
let prev_line_empty = rope_is_line_ending(slice.line(line.saturating_sub(1)));
let curr_line_empty = rope_is_line_ending(slice.line(line));
let prev_empty_to_line = prev_line_empty && !curr_line_empty;
// skip character before paragraph boundary
if prev_empty_to_line && !first_char {
line += 1;
}
let mut lines = slice.lines_at(line);
lines.reverse();
let mut lines = lines.map(rope_is_line_ending).peekable();
for _ in 0..count {
while lines.next_if(|&e| e).is_some() {
line -= 1;
}
while lines.next_if(|&e| !e).is_some() {
line -= 1;
}
}
let head = slice.line_to_char(line);
let anchor = if behavior == Movement::Move {
// exclude first character after paragraph boundary
if prev_empty_to_line && first_char {
range.cursor(slice)
} else {
range.head
}
} else {
range.put_cursor(slice, head, true).anchor
};
Range::new(anchor, head)
}
pub fn move_next_paragraph(
slice: RopeSlice,
range: Range,
count: usize,
behavior: Movement,
) -> Range {
let mut line = range.cursor_line(slice);
let last_char =
prev_grapheme_boundary(slice, slice.line_to_char(line + 1)) == range.cursor(slice);
let curr_line_empty = rope_is_line_ending(slice.line(line));
let next_line_empty =
rope_is_line_ending(slice.line(slice.len_lines().saturating_sub(1).min(line + 1)));
let curr_empty_to_line = curr_line_empty && !next_line_empty;
// skip character after paragraph boundary
if curr_empty_to_line && last_char {
line += 1;
}
let mut lines = slice.lines_at(line).map(rope_is_line_ending).peekable();
for _ in 0..count {
while lines.next_if(|&e| !e).is_some() {
line += 1;
}
while lines.next_if(|&e| e).is_some() {
line += 1;
}
}
let head = slice.line_to_char(line);
let anchor = if behavior == Movement::Move {
if curr_empty_to_line && last_char {
range.head
} else {
range.cursor(slice)
}
} else {
range.put_cursor(slice, head, true).anchor
};
Range::new(anchor, head)
}
// ---- util ------------
#[inline]
@@ -164,7 +252,7 @@ pub fn backwards_skip_while<F>(slice: RopeSlice, pos: usize, fun: F) -> Option<u
where
F: Fn(char) -> bool,
{
let mut chars_starting_from_next = slice.chars_at(pos + 1);
let mut chars_starting_from_next = slice.chars_at(pos);
let mut backwards = iter::from_fn(|| chars_starting_from_next.prev()).enumerate();
backwards.find_map(|(i, c)| {
if !fun(c) {
@@ -301,12 +389,62 @@ fn reached_target(target: WordMotionTarget, prev_ch: char, next_ch: char) -> boo
}
}
pub fn goto_treesitter_object(
slice: RopeSlice,
range: Range,
object_name: &str,
dir: Direction,
slice_tree: Node,
lang_config: &LanguageConfiguration,
count: usize,
) -> Range {
let get_range = move |range: Range| -> Option<Range> {
let byte_pos = slice.char_to_byte(range.cursor(slice));
let cap_name = |t: TextObject| format!("{}.{}", object_name, t);
let mut cursor = QueryCursor::new();
let nodes = lang_config.textobject_query()?.capture_nodes_any(
&[
&cap_name(TextObject::Movement),
&cap_name(TextObject::Around),
&cap_name(TextObject::Inside),
],
slice_tree,
slice,
&mut cursor,
)?;
let node = match dir {
Direction::Forward => nodes
.filter(|n| n.start_byte() > byte_pos)
.min_by_key(|n| n.start_byte())?,
Direction::Backward => nodes
.filter(|n| n.start_byte() < byte_pos)
.max_by_key(|n| n.start_byte())?,
};
let len = slice.len_bytes();
let start_byte = node.start_byte();
let end_byte = node.end_byte();
if start_byte >= len || end_byte >= len {
return None;
}
let start_char = slice.byte_to_char(start_byte);
let end_char = slice.byte_to_char(end_byte);
// head of range should be at beginning
Some(Range::new(end_char, start_char))
};
(0..count).fold(range, |range, _| get_range(range).unwrap_or(range))
}
#[cfg(test)]
mod test {
use std::array::{self, IntoIter};
use ropey::Rope;
use crate::{coords_at_pos, pos_at_coords};
use super::*;
const SINGLE_LINE_SAMPLE: &str = "This is a simple alphabetic line";
@@ -333,7 +471,7 @@ mod test {
assert_eq!(
coords_at_pos(
slice,
move_vertically(slice, range, Direction::Forward, 1, Movement::Move).head
move_vertically(slice, range, Direction::Forward, 1, Movement::Move, 4).head
),
(1, 3).into()
);
@@ -356,8 +494,8 @@ mod test {
((Direction::Backward, 999usize), (0, 0)), // |This is a simple alphabetic line
];
for ((direction, amount), coordinates) in IntoIter::new(moves_and_expected_coordinates) {
range = move_horizontally(slice, range, direction, amount, Movement::Move);
for ((direction, amount), coordinates) in moves_and_expected_coordinates {
range = move_horizontally(slice, range, direction, amount, Movement::Move, 0);
assert_eq!(coords_at_pos(slice, range.head), coordinates.into())
}
}
@@ -370,7 +508,7 @@ mod test {
let mut range = Range::point(position);
let moves_and_expected_coordinates = IntoIter::new([
let moves_and_expected_coordinates = [
((Direction::Forward, 11usize), (1, 1)), // Multiline\nt|ext sample\n...
((Direction::Backward, 1usize), (1, 0)), // Multiline\n|text sample\n...
((Direction::Backward, 5usize), (0, 5)), // Multi|line\ntext sample\n...
@@ -380,10 +518,10 @@ mod test {
((Direction::Backward, 0usize), (0, 3)), // Mul|tiline\ntext sample\n...
((Direction::Forward, 999usize), (5, 0)), // ...and whitespaced\n|
((Direction::Forward, 999usize), (5, 0)), // ...and whitespaced\n|
]);
];
for ((direction, amount), coordinates) in moves_and_expected_coordinates {
range = move_horizontally(slice, range, direction, amount, Movement::Move);
range = move_horizontally(slice, range, direction, amount, Movement::Move, 0);
assert_eq!(coords_at_pos(slice, range.head), coordinates.into());
assert_eq!(range.head, range.anchor);
}
@@ -398,14 +536,14 @@ mod test {
let mut range = Range::point(position);
let original_anchor = range.anchor;
let moves = IntoIter::new([
let moves = [
(Direction::Forward, 1usize),
(Direction::Forward, 5usize),
(Direction::Backward, 3usize),
]);
];
for (direction, amount) in moves {
range = move_horizontally(slice, range, direction, amount, Movement::Extend);
range = move_horizontally(slice, range, direction, amount, Movement::Extend, 0);
assert_eq!(range.anchor, original_anchor);
}
}
@@ -416,7 +554,7 @@ mod test {
let slice = text.slice(..);
let position = pos_at_coords(slice, (0, 0).into(), true);
let mut range = Range::point(position);
let moves_and_expected_coordinates = IntoIter::new([
let moves_and_expected_coordinates = [
((Direction::Forward, 1usize), (1, 0)),
((Direction::Forward, 2usize), (3, 0)),
((Direction::Forward, 1usize), (4, 0)),
@@ -426,10 +564,10 @@ mod test {
((Direction::Backward, 0usize), (4, 0)),
((Direction::Forward, 5), (5, 0)),
((Direction::Forward, 999usize), (5, 0)),
]);
];
for ((direction, amount), coordinates) in moves_and_expected_coordinates {
range = move_vertically(slice, range, direction, amount, Movement::Move);
range = move_vertically(slice, range, direction, amount, Movement::Move, 4);
assert_eq!(coords_at_pos(slice, range.head), coordinates.into());
assert_eq!(range.head, range.anchor);
}
@@ -446,7 +584,7 @@ mod test {
H,
V,
}
let moves_and_expected_coordinates = IntoIter::new([
let moves_and_expected_coordinates = [
// Places cursor at the end of line
((Axis::H, Direction::Forward, 8usize), (0, 8)),
// First descent preserves column as the target line is wider
@@ -459,12 +597,12 @@ mod test {
((Axis::V, Direction::Backward, 999usize), (0, 8)),
((Axis::V, Direction::Forward, 4usize), (4, 8)),
((Axis::V, Direction::Forward, 999usize), (5, 0)),
]);
];
for ((axis, direction, amount), coordinates) in moves_and_expected_coordinates {
range = match axis {
Axis::H => move_horizontally(slice, range, direction, amount, Movement::Move),
Axis::V => move_vertically(slice, range, direction, amount, Movement::Move),
Axis::H => move_horizontally(slice, range, direction, amount, Movement::Move, 0),
Axis::V => move_vertically(slice, range, direction, amount, Movement::Move, 4),
};
assert_eq!(coords_at_pos(slice, range.head), coordinates.into());
assert_eq!(range.head, range.anchor);
@@ -485,21 +623,21 @@ mod test {
H,
V,
}
let moves_and_expected_coordinates = IntoIter::new([
let moves_and_expected_coordinates = [
// Places cursor at the fourth kana.
((Axis::H, Direction::Forward, 4), (0, 4)),
// Descent places cursor at the 4th character.
((Axis::V, Direction::Forward, 1usize), (1, 4)),
// Moving back 1 character.
((Axis::H, Direction::Backward, 1usize), (1, 3)),
// Descent places cursor at the 8th character.
((Axis::V, Direction::Forward, 1usize), (1, 8)),
// Moving back 2 characters.
((Axis::H, Direction::Backward, 2usize), (1, 6)),
// Jumping back up 1 line.
((Axis::V, Direction::Backward, 1usize), (0, 3)),
]);
];
for ((axis, direction, amount), coordinates) in moves_and_expected_coordinates {
range = match axis {
Axis::H => move_horizontally(slice, range, direction, amount, Movement::Move),
Axis::V => move_vertically(slice, range, direction, amount, Movement::Move),
Axis::H => move_horizontally(slice, range, direction, amount, Movement::Move, 0),
Axis::V => move_vertically(slice, range, direction, amount, Movement::Move, 4),
};
assert_eq!(coords_at_pos(slice, range.head), coordinates.into());
assert_eq!(range.head, range.anchor);
@@ -526,7 +664,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_start_of_next_words() {
let tests = array::IntoIter::new([
let tests = [
("Basic forward motion stops at the first space",
vec![(1, Range::new(0, 0), Range::new(0, 6))]),
(" Starting from a boundary advances the anchor",
@@ -600,7 +738,7 @@ mod test {
vec![
(1, Range::new(0, 0), Range::new(0, 6)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -612,7 +750,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_start_of_next_long_words() {
let tests = array::IntoIter::new([
let tests = [
("Basic forward motion stops at the first space",
vec![(1, Range::new(0, 0), Range::new(0, 6))]),
(" Starting from a boundary advances the anchor",
@@ -684,7 +822,7 @@ mod test {
vec![
(1, Range::new(0, 0), Range::new(0, 8)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -696,7 +834,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_start_of_previous_words() {
let tests = array::IntoIter::new([
let tests = [
("Basic backward motion from the middle of a word",
vec![(1, Range::new(3, 3), Range::new(4, 0))]),
@@ -769,7 +907,7 @@ mod test {
vec![
(1, Range::new(0, 6), Range::new(6, 0)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -781,7 +919,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_start_of_previous_long_words() {
let tests = array::IntoIter::new([
let tests = [
(
"Basic backward motion from the middle of a word",
vec![(1, Range::new(3, 3), Range::new(4, 0))],
@@ -866,7 +1004,7 @@ mod test {
vec![
(1, Range::new(0, 8), Range::new(8, 0)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -878,7 +1016,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_end_of_next_words() {
let tests = array::IntoIter::new([
let tests = [
("Basic forward motion from the start of a word to the end of it",
vec![(1, Range::new(0, 0), Range::new(0, 5))]),
("Basic forward motion from the end of a word to the end of the next",
@@ -950,7 +1088,7 @@ mod test {
vec![
(1, Range::new(0, 0), Range::new(0, 5)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -962,7 +1100,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_end_of_previous_words() {
let tests = array::IntoIter::new([
let tests = [
("Basic backward motion from the middle of a word",
vec![(1, Range::new(9, 9), Range::new(10, 5))]),
("Starting from after boundary retreats the anchor",
@@ -1032,7 +1170,7 @@ mod test {
vec![
(1, Range::new(0, 10), Range::new(10, 4)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -1044,7 +1182,7 @@ mod test {
#[test]
fn test_behaviour_when_moving_to_end_of_next_long_words() {
let tests = array::IntoIter::new([
let tests = [
("Basic forward motion from the start of a word to the end of it",
vec![(1, Range::new(0, 0), Range::new(0, 5))]),
("Basic forward motion from the end of a word to the end of the next",
@@ -1114,7 +1252,7 @@ mod test {
vec![
(1, Range::new(0, 0), Range::new(0, 7)),
]),
]);
];
for (sample, scenario) in tests {
for (count, begin, expected_end) in scenario.into_iter() {
@@ -1123,4 +1261,172 @@ mod test {
}
}
}
#[test]
fn test_behaviour_when_moving_to_prev_paragraph_single() {
let tests = [
("#[|]#", "#[|]#"),
("#[s|]#tart at\nfirst char\n", "#[|s]#tart at\nfirst char\n"),
("start at\nlast char#[\n|]#", "#[|start at\nlast char\n]#"),
(
"goto\nfirst\n\n#[p|]#aragraph",
"#[|goto\nfirst\n\n]#paragraph",
),
(
"goto\nfirst\n#[\n|]#paragraph",
"#[|goto\nfirst\n\n]#paragraph",
),
(
"goto\nsecond\n\np#[a|]#ragraph",
"goto\nsecond\n\n#[|pa]#ragraph",
),
(
"here\n\nhave\nmultiple\nparagraph\n\n\n\n\n#[|]#",
"here\n\n#[|have\nmultiple\nparagraph\n\n\n\n\n]#",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection =
selection.transform(|r| move_prev_paragraph(text.slice(..), r, 1, Movement::Move));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_behaviour_when_moving_to_prev_paragraph_double() {
let tests = [
(
"on#[e|]#\n\ntwo\n\nthree\n\n",
"#[|one]#\n\ntwo\n\nthree\n\n",
),
(
"one\n\ntwo\n\nth#[r|]#ee\n\n",
"one\n\n#[|two\n\nthr]#ee\n\n",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection =
selection.transform(|r| move_prev_paragraph(text.slice(..), r, 2, Movement::Move));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_behaviour_when_moving_to_prev_paragraph_extend() {
let tests = [
(
"one\n\n#[|two\n\n]#three\n\n",
"#[|one\n\ntwo\n\n]#three\n\n",
),
(
"#[|one\n\ntwo\n\n]#three\n\n",
"#[|one\n\ntwo\n\n]#three\n\n",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection = selection
.transform(|r| move_prev_paragraph(text.slice(..), r, 1, Movement::Extend));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_behaviour_when_moving_to_next_paragraph_single() {
let tests = [
("#[|]#", "#[|]#"),
("#[s|]#tart at\nfirst char\n", "#[start at\nfirst char\n|]#"),
("start at\nlast char#[\n|]#", "start at\nlast char#[\n|]#"),
(
"a\nb\n\n#[g|]#oto\nthird\n\nparagraph",
"a\nb\n\n#[goto\nthird\n\n|]#paragraph",
),
(
"a\nb\n#[\n|]#goto\nthird\n\nparagraph",
"a\nb\n\n#[goto\nthird\n\n|]#paragraph",
),
(
"a\nb#[\n|]#\ngoto\nsecond\n\nparagraph",
"a\nb#[\n\n|]#goto\nsecond\n\nparagraph",
),
(
"here\n\nhave\n#[m|]#ultiple\nparagraph\n\n\n\n\n",
"here\n\nhave\n#[multiple\nparagraph\n\n\n\n\n|]#",
),
(
"#[t|]#ext\n\n\nafter two blank lines\n\nmore text\n",
"#[text\n\n\n|]#after two blank lines\n\nmore text\n",
),
(
"#[text\n\n\n|]#after two blank lines\n\nmore text\n",
"text\n\n\n#[after two blank lines\n\n|]#more text\n",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection =
selection.transform(|r| move_next_paragraph(text.slice(..), r, 1, Movement::Move));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_behaviour_when_moving_to_next_paragraph_double() {
let tests = [
(
"one\n\ntwo\n\nth#[r|]#ee\n\n",
"one\n\ntwo\n\nth#[ree\n\n|]#",
),
(
"on#[e|]#\n\ntwo\n\nthree\n\n",
"on#[e\n\ntwo\n\n|]#three\n\n",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection =
selection.transform(|r| move_next_paragraph(text.slice(..), r, 2, Movement::Move));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_behaviour_when_moving_to_next_paragraph_extend() {
let tests = [
(
"one\n\n#[two\n\n|]#three\n\n",
"one\n\n#[two\n\nthree\n\n|]#",
),
(
"one\n\n#[two\n\nthree\n\n|]#",
"one\n\n#[two\n\nthree\n\n|]#",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection = selection
.transform(|r| move_next_paragraph(text.slice(..), r, 1, Movement::Extend));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
}

View File

@@ -1,26 +1,71 @@
use crate::{Range, RopeSlice, Selection, Syntax};
use tree_sitter::Node;
// TODO: to contract_selection we'd need to store the previous ranges before expand.
// Maybe just contract to the first child node?
pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: &Selection) -> Selection {
pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
select_node_impl(syntax, text, selection, |mut node, from, to| {
while node.start_byte() == from && node.end_byte() == to {
node = node.parent()?;
}
Some(node)
})
}
pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
select_node_impl(syntax, text, selection, |descendant, _from, _to| {
descendant.child(0).or(Some(descendant))
})
}
pub fn select_sibling<F>(
syntax: &Syntax,
text: RopeSlice,
selection: Selection,
sibling_fn: &F,
) -> Selection
where
F: Fn(Node) -> Option<Node>,
{
select_node_impl(syntax, text, selection, |descendant, _from, _to| {
find_sibling_recursive(descendant, sibling_fn)
})
}
fn find_sibling_recursive<F>(node: Node, sibling_fn: F) -> Option<Node>
where
F: Fn(Node) -> Option<Node>,
{
sibling_fn(node).or_else(|| {
node.parent()
.and_then(|node| find_sibling_recursive(node, sibling_fn))
})
}
fn select_node_impl<F>(
syntax: &Syntax,
text: RopeSlice,
selection: Selection,
select_fn: F,
) -> Selection
where
F: Fn(Node, usize, usize) -> Option<Node>,
{
let tree = syntax.tree();
selection.clone().transform(|range| {
selection.transform(|range| {
let from = text.char_to_byte(range.from());
let to = text.char_to_byte(range.to());
// find parent of a descendant that matches the range
let parent = match tree
let node = match tree
.root_node()
.descendant_for_byte_range(from, to)
.and_then(|node| node.parent())
.and_then(|node| select_fn(node, from, to))
{
Some(parent) => parent,
Some(node) => node,
None => return range,
};
let from = text.byte_to_char(parent.start_byte());
let to = text.byte_to_char(parent.end_byte());
let from = text.byte_to_char(node.start_byte());
let to = text.byte_to_char(node.end_byte());
if range.head < range.anchor {
Range::new(to, from)

View File

@@ -1,26 +1,26 @@
use etcetera::home_dir;
use std::path::{Component, Path, PathBuf};
/// Replaces users home directory from `path` with tilde `~` if the directory
/// is available, otherwise returns the path unchanged.
pub fn fold_home_dir(path: &Path) -> PathBuf {
if let Ok(home) = super::home_dir() {
if path.starts_with(&home) {
// it's ok to unwrap, the path starts with home dir
return PathBuf::from("~").join(path.strip_prefix(&home).unwrap());
if let Ok(home) = home_dir() {
if let Ok(stripped) = path.strip_prefix(&home) {
return PathBuf::from("~").join(stripped);
}
}
path.to_path_buf()
}
/// Expands tilde `~` into users home directory if avilable, otherwise returns the path
/// Expands tilde `~` into users home directory if available, otherwise returns the path
/// unchanged. The tilde will only be expanded when present as the first component of the path
/// and only slash follows it.
pub fn expand_tilde(path: &Path) -> PathBuf {
let mut components = path.components().peekable();
if let Some(Component::Normal(c)) = components.peek() {
if c == &"~" {
if let Ok(home) = super::home_dir() {
if let Ok(home) = home_dir() {
// it's ok to unwrap, the path starts with `~`
return home.join(path.strip_prefix("~").unwrap());
}
@@ -40,7 +40,6 @@ pub fn expand_tilde(path: &Path) -> PathBuf {
/// needs to improve on.
/// Copied from cargo: <https://github.com/rust-lang/cargo/blob/070e459c2d8b79c5b2ac5218064e7603329c92ae/crates/cargo-util/src/paths.rs#L81>
pub fn get_normalized_path(path: &Path) -> PathBuf {
let path = expand_tilde(path);
let mut components = path.components().peekable();
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
components.next();
@@ -72,10 +71,11 @@ pub fn get_normalized_path(path: &Path) -> PathBuf {
/// This function is used instead of `std::fs::canonicalize` because we don't want to verify
/// here if the path exists, just normalize it's components.
pub fn get_canonicalized_path(path: &Path) -> std::io::Result<PathBuf> {
let path = expand_tilde(path);
let path = if path.is_relative() {
std::env::current_dir().map(|current_dir| current_dir.join(path))?
} else {
path.to_path_buf()
path
};
Ok(get_normalized_path(path.as_path()))
@@ -90,3 +90,54 @@ pub fn get_relative_path(path: &Path) -> PathBuf {
};
fold_home_dir(path)
}
/// Returns a truncated filepath where the basepart of the path is reduced to the first
/// char of the folder and the whole filename appended.
///
/// Also strip the current working directory from the beginning of the path.
/// Note that this function does not check if the truncated path is unambiguous.
///
/// ```
/// use helix_core::path::get_truncated_path;
/// use std::path::Path;
///
/// assert_eq!(
/// get_truncated_path("/home/cnorris/documents/jokes.txt").as_path(),
/// Path::new("/h/c/d/jokes.txt")
/// );
/// assert_eq!(
/// get_truncated_path("jokes.txt").as_path(),
/// Path::new("jokes.txt")
/// );
/// assert_eq!(
/// get_truncated_path("/jokes.txt").as_path(),
/// Path::new("/jokes.txt")
/// );
/// assert_eq!(
/// get_truncated_path("/h/c/d/jokes.txt").as_path(),
/// Path::new("/h/c/d/jokes.txt")
/// );
/// assert_eq!(get_truncated_path("").as_path(), Path::new(""));
/// ```
///
pub fn get_truncated_path<P: AsRef<Path>>(path: P) -> PathBuf {
let cwd = std::env::current_dir().unwrap_or_default();
let path = path
.as_ref()
.strip_prefix(cwd)
.unwrap_or_else(|_| path.as_ref());
let file = path.file_name().unwrap_or_default();
let base = path.parent().unwrap_or_else(|| Path::new(""));
let mut ret = PathBuf::new();
for d in base {
ret.push(
d.to_string_lossy()
.chars()
.next()
.unwrap_or_default()
.to_string(),
);
}
ret.push(file);
ret
}

View File

@@ -1,6 +1,8 @@
use std::borrow::Cow;
use crate::{
chars::char_is_line_ending,
graphemes::{ensure_grapheme_boundary_prev, RopeGraphemes},
graphemes::{ensure_grapheme_boundary_prev, grapheme_width, RopeGraphemes},
line_ending::line_end_char_index,
RopeSlice,
};
@@ -54,11 +56,8 @@ impl From<Position> for tree_sitter::Point {
}
/// Convert a character index to (line, column) coordinates.
///
/// TODO: this should be split into two methods: one for visual
/// row/column, and one for "objective" row/column (possibly with
/// the column specified in `char`s). The former would be used
/// for cursor movement, and the latter would be used for e.g. the
/// row:column display in the status line.
/// column in `char` count which can be used for row:column display in
/// status line. See [`visual_coords_at_pos`] for a visual one.
pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position {
let line = text.char_to_line(pos);
@@ -69,6 +68,31 @@ pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position {
Position::new(line, col)
}
/// Convert a character index to (line, column) coordinates visually.
///
/// Takes \t, double-width characters (CJK) into account as well as text
/// not in the document in the future.
/// See [`coords_at_pos`] for an "objective" one.
pub fn visual_coords_at_pos(text: RopeSlice, pos: usize, tab_width: usize) -> Position {
let line = text.char_to_line(pos);
let line_start = text.line_to_char(line);
let pos = ensure_grapheme_boundary_prev(text, pos);
let mut col = 0;
for grapheme in RopeGraphemes::new(text.slice(line_start..pos)) {
if grapheme == "\t" {
col += tab_width - (col % tab_width);
} else {
let grapheme = Cow::from(grapheme);
col += grapheme_width(&grapheme);
}
}
Position::new(line, col)
}
/// Convert (line, column) coordinates to a character index.
///
/// If the `line` coordinate is beyond the end of the file, the EOF
@@ -85,11 +109,11 @@ pub fn coords_at_pos(text: RopeSlice, pos: usize) -> Position {
/// with left-side block-cursor positions, as this prevents the the block cursor
/// from jumping to the next line. Otherwise you typically want it to be `false`,
/// such as when dealing with raw anchor/head positions.
///
/// TODO: this should be changed to work in terms of visual row/column, not
/// graphemes.
pub fn pos_at_coords(text: RopeSlice, coords: Position, limit_before_line_ending: bool) -> usize {
let Position { row, col } = coords;
let Position { mut row, col } = coords;
if limit_before_line_ending {
row = row.min(text.len_lines() - 1);
};
let line_start = text.line_to_char(row);
let line_end = if limit_before_line_ending {
line_end_char_index(&text, row)
@@ -108,6 +132,43 @@ pub fn pos_at_coords(text: RopeSlice, coords: Position, limit_before_line_ending
line_start + col_char_offset
}
/// Convert visual (line, column) coordinates to a character index.
///
/// If the `line` coordinate is beyond the end of the file, the EOF
/// position will be returned.
///
/// If the `column` coordinate is past the end of the given line, the
/// line-end position (in this case, just before the line ending
/// character) will be returned.
pub fn pos_at_visual_coords(text: RopeSlice, coords: Position, tab_width: usize) -> usize {
let Position { mut row, col } = coords;
row = row.min(text.len_lines() - 1);
let line_start = text.line_to_char(row);
let line_end = line_end_char_index(&text, row);
let mut col_char_offset = 0;
let mut cols_remaining = col;
for grapheme in RopeGraphemes::new(text.slice(line_start..line_end)) {
let grapheme_width = if grapheme == "\t" {
tab_width - ((col - cols_remaining) % tab_width)
} else {
let grapheme = Cow::from(grapheme);
grapheme_width(&grapheme)
};
// If pos is in the middle of a wider grapheme (tab for example)
// return the starting offset.
if grapheme_width > cols_remaining {
break;
}
cols_remaining -= grapheme_width;
col_char_offset += grapheme.chars().count();
}
line_start + col_char_offset
}
#[cfg(test)]
mod test {
use super::*;
@@ -130,7 +191,6 @@ mod test {
assert_eq!(coords_at_pos(slice, 10), (1, 4).into()); // position on d
// Test with wide characters.
// TODO: account for character width.
let text = Rope::from("今日はいい\n");
let slice = text.slice(..);
assert_eq!(coords_at_pos(slice, 0), (0, 0).into());
@@ -151,7 +211,6 @@ mod test {
assert_eq!(coords_at_pos(slice, 9), (1, 0).into());
// Test with wide-character grapheme clusters.
// TODO: account for character width.
let text = Rope::from("किमपि\n");
let slice = text.slice(..);
assert_eq!(coords_at_pos(slice, 0), (0, 0).into());
@@ -161,7 +220,6 @@ mod test {
assert_eq!(coords_at_pos(slice, 6), (1, 0).into());
// Test with tabs.
// Todo: account for tab stops.
let text = Rope::from("\tHello\n");
let slice = text.slice(..);
assert_eq!(coords_at_pos(slice, 0), (0, 0).into());
@@ -169,6 +227,54 @@ mod test {
assert_eq!(coords_at_pos(slice, 2), (0, 2).into());
}
#[test]
fn test_visual_coords_at_pos() {
let text = Rope::from("ḧëḷḷö\nẅöṛḷḋ");
let slice = text.slice(..);
assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());
assert_eq!(visual_coords_at_pos(slice, 5, 8), (0, 5).into()); // position on \n
assert_eq!(visual_coords_at_pos(slice, 6, 8), (1, 0).into()); // position on w
assert_eq!(visual_coords_at_pos(slice, 7, 8), (1, 1).into()); // position on o
assert_eq!(visual_coords_at_pos(slice, 10, 8), (1, 4).into()); // position on d
// Test with wide characters.
let text = Rope::from("今日はいい\n");
let slice = text.slice(..);
assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());
assert_eq!(visual_coords_at_pos(slice, 1, 8), (0, 2).into());
assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 4).into());
assert_eq!(visual_coords_at_pos(slice, 3, 8), (0, 6).into());
assert_eq!(visual_coords_at_pos(slice, 4, 8), (0, 8).into());
assert_eq!(visual_coords_at_pos(slice, 5, 8), (0, 10).into());
assert_eq!(visual_coords_at_pos(slice, 6, 8), (1, 0).into());
// Test with grapheme clusters.
let text = Rope::from("a̐éö̲\r\n");
let slice = text.slice(..);
assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());
assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 1).into());
assert_eq!(visual_coords_at_pos(slice, 4, 8), (0, 2).into());
assert_eq!(visual_coords_at_pos(slice, 7, 8), (0, 3).into());
assert_eq!(visual_coords_at_pos(slice, 9, 8), (1, 0).into());
// Test with wide-character grapheme clusters.
// TODO: account for cluster.
let text = Rope::from("किमपि\n");
let slice = text.slice(..);
assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());
assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 2).into());
assert_eq!(visual_coords_at_pos(slice, 3, 8), (0, 3).into());
assert_eq!(visual_coords_at_pos(slice, 5, 8), (0, 5).into());
assert_eq!(visual_coords_at_pos(slice, 6, 8), (1, 0).into());
// Test with tabs.
let text = Rope::from("\tHello\n");
let slice = text.slice(..);
assert_eq!(visual_coords_at_pos(slice, 0, 8), (0, 0).into());
assert_eq!(visual_coords_at_pos(slice, 1, 8), (0, 8).into());
assert_eq!(visual_coords_at_pos(slice, 2, 8), (0, 9).into());
}
#[test]
fn test_pos_at_coords() {
let text = Rope::from("ḧëḷḷö\nẅöṛḷḋ");
@@ -225,5 +331,78 @@ mod test {
assert_eq!(pos_at_coords(slice, (0, 0).into(), false), 0);
assert_eq!(pos_at_coords(slice, (0, 1).into(), false), 1);
assert_eq!(pos_at_coords(slice, (0, 2).into(), false), 2);
// Test out of bounds.
let text = Rope::new();
let slice = text.slice(..);
assert_eq!(pos_at_coords(slice, (10, 0).into(), true), 0);
assert_eq!(pos_at_coords(slice, (0, 10).into(), true), 0);
assert_eq!(pos_at_coords(slice, (10, 10).into(), true), 0);
}
#[test]
fn test_pos_at_visual_coords() {
let text = Rope::from("ḧëḷḷö\nẅöṛḷḋ");
let slice = text.slice(..);
assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 5).into(), 4), 5); // position on \n
assert_eq!(pos_at_visual_coords(slice, (0, 6).into(), 4), 5); // position after \n
assert_eq!(pos_at_visual_coords(slice, (1, 0).into(), 4), 6); // position on w
assert_eq!(pos_at_visual_coords(slice, (1, 1).into(), 4), 7); // position on o
assert_eq!(pos_at_visual_coords(slice, (1, 4).into(), 4), 10); // position on d
// Test with wide characters.
let text = Rope::from("今日はいい\n");
let slice = text.slice(..);
assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 1);
assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 1);
assert_eq!(pos_at_visual_coords(slice, (0, 4).into(), 4), 2);
assert_eq!(pos_at_visual_coords(slice, (0, 5).into(), 4), 2);
assert_eq!(pos_at_visual_coords(slice, (0, 6).into(), 4), 3);
assert_eq!(pos_at_visual_coords(slice, (0, 7).into(), 4), 3);
assert_eq!(pos_at_visual_coords(slice, (0, 8).into(), 4), 4);
assert_eq!(pos_at_visual_coords(slice, (0, 9).into(), 4), 4);
// assert_eq!(pos_at_visual_coords(slice, (0, 10).into(), 4, false), 5);
// assert_eq!(pos_at_visual_coords(slice, (0, 10).into(), 4, true), 5);
assert_eq!(pos_at_visual_coords(slice, (1, 0).into(), 4), 6);
// Test with grapheme clusters.
let text = Rope::from("a̐éö̲\r\n");
let slice = text.slice(..);
assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 2);
assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 4);
assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 7); // \r\n is one char here
assert_eq!(pos_at_visual_coords(slice, (0, 4).into(), 4), 7);
assert_eq!(pos_at_visual_coords(slice, (1, 0).into(), 4), 9);
// Test with wide-character grapheme clusters.
let text = Rope::from("किमपि");
// 2 - 1 - 2 codepoints
// TODO: delete handling as per https://news.ycombinator.com/item?id=20058454
let slice = text.slice(..);
assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 2);
assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 3);
// Test with tabs.
let text = Rope::from("\tHello\n");
let slice = text.slice(..);
assert_eq!(pos_at_visual_coords(slice, (0, 0).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 1).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 2).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 3).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 4).into(), 4), 1);
assert_eq!(pos_at_visual_coords(slice, (0, 5).into(), 4), 2);
// Test out of bounds.
let text = Rope::new();
let slice = text.slice(..);
assert_eq!(pos_at_visual_coords(slice, (10, 0).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (0, 10).into(), 4), 0);
assert_eq!(pos_at_visual_coords(slice, (10, 10).into(), 4), 0);
}
}

View File

@@ -15,7 +15,11 @@ impl Register {
}
pub fn new_with_values(name: char, values: Vec<String>) -> Self {
Self { name, values }
if name == '_' {
Self::new(name)
} else {
Self { name, values }
}
}
pub const fn name(&self) -> char {
@@ -27,11 +31,15 @@ impl Register {
}
pub fn write(&mut self, values: Vec<String>) {
self.values = values;
if self.name != '_' {
self.values = values;
}
}
pub fn push(&mut self, value: String) {
self.values.push(value);
if self.name != '_' {
self.values.push(value);
}
}
}
@@ -60,4 +68,16 @@ impl Registers {
pub fn read(&self, name: char) -> Option<&[String]> {
self.get(name).map(|reg| reg.read())
}
pub fn first(&self, name: char) -> Option<&String> {
self.read(name).and_then(|entries| entries.first())
}
pub fn last(&self, name: char) -> Option<&String> {
self.read(name).and_then(|entries| entries.last())
}
pub fn inner(&self) -> &HashMap<char, Register> {
&self.inner
}
}

View File

@@ -1,6 +1,28 @@
use crate::RopeSlice;
pub fn find_nth_next(text: RopeSlice, ch: char, mut pos: usize, n: usize) -> Option<usize> {
// TODO: switch to std::str::Pattern when it is stable.
pub trait CharMatcher {
fn char_match(&self, ch: char) -> bool;
}
impl CharMatcher for char {
fn char_match(&self, ch: char) -> bool {
*self == ch
}
}
impl<F: Fn(&char) -> bool> CharMatcher for F {
fn char_match(&self, ch: char) -> bool {
(*self)(&ch)
}
}
pub fn find_nth_next<M: CharMatcher>(
text: RopeSlice,
char_matcher: M,
mut pos: usize,
n: usize,
) -> Option<usize> {
if pos >= text.len_chars() || n == 0 {
return None;
}
@@ -13,7 +35,7 @@ pub fn find_nth_next(text: RopeSlice, ch: char, mut pos: usize, n: usize) -> Opt
pos += 1;
if c == ch {
if char_matcher.char_match(c) {
break;
}
}

View File

@@ -7,7 +7,8 @@ use crate::{
ensure_grapheme_boundary_next, ensure_grapheme_boundary_prev, next_grapheme_boundary,
prev_grapheme_boundary,
},
Assoc, ChangeSet, RopeSlice,
movement::Direction,
Assoc, ChangeSet, RopeGraphemes, RopeSlice,
};
use smallvec::{smallvec, SmallVec};
use std::borrow::Cow;
@@ -82,6 +83,13 @@ impl Range {
std::cmp::max(self.anchor, self.head)
}
/// Total length of the range.
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.to() - self.from()
}
/// The (inclusive) range of lines that the range overlaps.
#[inline]
#[must_use]
@@ -102,6 +110,27 @@ impl Range {
self.anchor == self.head
}
/// `Direction::Backward` when head < anchor.
/// `Direction::Backward` otherwise.
#[inline]
#[must_use]
pub fn direction(&self) -> Direction {
if self.head < self.anchor {
Direction::Backward
} else {
Direction::Forward
}
}
// flips the direction of the selection
pub fn flip(&self) -> Self {
Self {
anchor: self.head,
head: self.anchor,
horiz: self.horiz,
}
}
/// Check two ranges for overlap.
#[must_use]
pub fn overlaps(&self, other: &Self) -> bool {
@@ -111,6 +140,11 @@ impl Range {
self.from() == other.from() || (self.to() > other.from() && other.to() > self.from())
}
#[inline]
pub fn contains_range(&self, other: &Self) -> bool {
self.from() <= other.from() && self.to() >= other.to()
}
pub fn contains(&self, pos: usize) -> bool {
self.from() <= pos && pos < self.to()
}
@@ -188,9 +222,23 @@ impl Range {
// groupAt
/// Returns the text inside this range given the text of the whole buffer.
///
/// The returned `Cow` is a reference if the range of text is inside a single
/// chunk of the rope. Otherwise a copy of the text is returned. Consider
/// using `slice` instead if you do not need a `Cow` or `String` to avoid copying.
#[inline]
pub fn fragment<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> Cow<'b, str> {
text.slice(self.from()..self.to()).into()
self.slice(text).into()
}
/// Returns the text inside this range given the text of the whole buffer.
///
/// The returned value is a reference to the passed slice. This method never
/// copies any contents.
#[inline]
pub fn slice<'a, 'b: 'a>(&'a self, text: RopeSlice<'b>) -> RopeSlice<'b> {
text.slice(self.from()..self.to())
}
//--------------------------------
@@ -305,13 +353,21 @@ impl Range {
pub fn cursor_line(&self, text: RopeSlice) -> usize {
text.char_to_line(self.cursor(text))
}
/// Returns true if this Range covers a single grapheme in the given text
pub fn is_single_grapheme(&self, doc: RopeSlice) -> bool {
let mut graphemes = RopeGraphemes::new(doc.slice(self.from()..self.to()));
let first = graphemes.next();
let second = graphemes.next();
first.is_some() && second.is_none()
}
}
impl From<(usize, usize)> for Range {
fn from(tuple: (usize, usize)) -> Self {
fn from((anchor, head): (usize, usize)) -> Self {
Self {
anchor: tuple.0,
head: tuple.1,
anchor,
head,
horiz: None,
}
}
@@ -360,8 +416,13 @@ impl Selection {
self.normalize()
}
/// Adds a new range to the selection and makes it the primary range.
/// Removes a range from the selection.
pub fn remove(mut self, index: usize) -> Self {
assert!(
self.ranges.len() > 1,
"can't remove the last range from a selection!"
);
self.ranges.remove(index);
if index < self.primary_index || self.primary_index == self.ranges.len() {
self.primary_index -= 1;
@@ -369,6 +430,12 @@ impl Selection {
self
}
/// Replace a range in the selection with a new range.
pub fn replace(mut self, index: usize, range: Range) -> Self {
self.ranges[index] = range;
self.normalize()
}
/// Map selections over a set of changes. Useful for adjusting the selection position after
/// applying changes to a document.
pub fn map(self, changes: &ChangeSet) -> Self {
@@ -495,6 +562,10 @@ impl Selection {
self.ranges.iter().map(move |range| range.fragment(text))
}
pub fn slices<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator<Item = RopeSlice> + 'a {
self.ranges.iter().map(move |range| range.slice(text))
}
#[inline(always)]
pub fn iter(&self) -> std::slice::Iter<'_, Range> {
self.ranges.iter()
@@ -504,6 +575,39 @@ impl Selection {
pub fn len(&self) -> usize {
self.ranges.len()
}
// returns true if self ⊇ other
pub fn contains(&self, other: &Selection) -> bool {
// can't contain other if it is larger
if other.len() > self.len() {
return false;
}
let (mut iter_self, mut iter_other) = (self.iter(), other.iter());
let (mut ele_self, mut ele_other) = (iter_self.next(), iter_other.next());
loop {
match (ele_self, ele_other) {
(Some(ra), Some(rb)) => {
if !ra.contains_range(rb) {
// `self` doesn't contain next element from `other`, advance `self`, we need to match all from `other`
ele_self = iter_self.next();
} else {
// matched element from `other`, advance `other`
ele_other = iter_other.next();
};
}
(None, Some(_)) => {
// exhausted `self`, we can't match the reminder of `other`
return false;
}
(_, None) => {
// no elements from `other` left to match, `self` contains `other`
return true;
}
}
}
}
}
impl<'a> IntoIterator for &'a Selection {
@@ -517,14 +621,15 @@ impl<'a> IntoIterator for &'a Selection {
// TODO: checkSelection -> check if valid for doc length && sorted
pub fn keep_matches(
pub fn keep_or_remove_matches(
text: RopeSlice,
selection: &Selection,
regex: &crate::regex::Regex,
remove: bool,
) -> Option<Selection> {
let result: SmallVec<_> = selection
.iter()
.filter(|range| regex.is_match(&range.fragment(text)))
.filter(|range| regex.is_match(&range.fragment(text)) ^ remove)
.copied()
.collect();
@@ -554,7 +659,13 @@ pub fn select_on_matches(
let start = text.byte_to_char(start_byte + mat.start());
let end = text.byte_to_char(start_byte + mat.end());
result.push(Range::new(start, end));
let range = Range::new(start, end);
// Make sure the match is not right outside of the selection.
// These invalid matches can come from using RegEx anchors like `^`, `$`
if range != Range::point(sel.to()) {
result.push(range);
}
}
}
@@ -687,16 +798,16 @@ mod test {
fn test_contains() {
let range = Range::new(10, 12);
assert_eq!(range.contains(9), false);
assert_eq!(range.contains(10), true);
assert_eq!(range.contains(11), true);
assert_eq!(range.contains(12), false);
assert_eq!(range.contains(13), false);
assert!(!range.contains(9));
assert!(range.contains(10));
assert!(range.contains(11));
assert!(!range.contains(12));
assert!(!range.contains(13));
let range = Range::new(9, 6);
assert_eq!(range.contains(9), false);
assert_eq!(range.contains(7), true);
assert_eq!(range.contains(6), true);
assert!(!range.contains(9));
assert!(range.contains(7));
assert!(range.contains(6));
}
#[test]
@@ -751,7 +862,7 @@ mod test {
}
#[test]
fn test_graphem_aligned() {
fn test_grapheme_aligned() {
let r = Rope::from_str("\r\nHi\r\n");
let s = r.slice(..);
@@ -824,6 +935,76 @@ mod test {
assert_eq!(Range::new(6, 5).min_width_1(s), Range::new(6, 5));
}
#[test]
fn test_select_on_matches() {
use crate::regex::{Regex, RegexBuilder};
let r = Rope::from_str("Nobody expects the Spanish inquisition");
let s = r.slice(..);
let selection = Selection::single(0, r.len_chars());
assert_eq!(
select_on_matches(s, &selection, &Regex::new(r"[A-Z][a-z]*").unwrap()),
Some(Selection::new(
smallvec![Range::new(0, 6), Range::new(19, 26)],
0
))
);
let r = Rope::from_str("This\nString\n\ncontains multiple\nlines");
let s = r.slice(..);
let start_of_line = RegexBuilder::new(r"^").multi_line(true).build().unwrap();
let end_of_line = RegexBuilder::new(r"$").multi_line(true).build().unwrap();
// line without ending
assert_eq!(
select_on_matches(s, &Selection::single(0, 4), &start_of_line),
Some(Selection::single(0, 0))
);
assert_eq!(
select_on_matches(s, &Selection::single(0, 4), &end_of_line),
None
);
// line with ending
assert_eq!(
select_on_matches(s, &Selection::single(0, 5), &start_of_line),
Some(Selection::single(0, 0))
);
assert_eq!(
select_on_matches(s, &Selection::single(0, 5), &end_of_line),
Some(Selection::single(4, 4))
);
// line with start of next line
assert_eq!(
select_on_matches(s, &Selection::single(0, 6), &start_of_line),
Some(Selection::new(
smallvec![Range::point(0), Range::point(5)],
0
))
);
assert_eq!(
select_on_matches(s, &Selection::single(0, 6), &end_of_line),
Some(Selection::single(4, 4))
);
// multiple lines
assert_eq!(
select_on_matches(
s,
&Selection::single(0, s.len_chars()),
&RegexBuilder::new(r"^[a-z ]*$")
.multi_line(true)
.build()
.unwrap()
),
Some(Selection::new(
smallvec![Range::point(12), Range::new(13, 30), Range::new(31, 36)],
0
))
);
}
#[test]
fn test_line_range() {
let r = Rope::from_str("\r\nHi\r\nthere!");
@@ -941,4 +1122,30 @@ mod test {
&["", "abcd", "efg", "rs", "xyz"]
);
}
#[test]
fn test_selection_contains() {
fn contains(a: Vec<(usize, usize)>, b: Vec<(usize, usize)>) -> bool {
let sela = Selection::new(a.iter().map(|a| Range::new(a.0, a.1)).collect(), 0);
let selb = Selection::new(b.iter().map(|b| Range::new(b.0, b.1)).collect(), 0);
sela.contains(&selb)
}
// exact match
assert!(contains(vec!((1, 1)), vec!((1, 1))));
// larger set contains smaller
assert!(contains(vec!((1, 1), (2, 2), (3, 3)), vec!((2, 2))));
// multiple matches
assert!(contains(vec!((1, 1), (2, 2)), vec!((1, 1), (2, 2))));
// smaller set can't contain bigger
assert!(!contains(vec!((1, 1)), vec!((1, 1), (2, 2))));
assert!(contains(
vec!((1, 1), (2, 4), (5, 6), (7, 9), (10, 13)),
vec!((3, 4), (7, 9))
));
assert!(!contains(vec!((1, 1), (5, 6)), vec!((1, 6))));
}
}

View File

@@ -0,0 +1,198 @@
use std::borrow::Cow;
/// Get the vec of escaped / quoted / doublequoted filenames from the input str
pub fn shellwords(input: &str) -> Vec<Cow<'_, str>> {
enum State {
Normal,
NormalEscaped,
Quoted,
QuoteEscaped,
Dquoted,
DquoteEscaped,
}
use State::*;
let mut state = Normal;
let mut args: Vec<Cow<str>> = Vec::new();
let mut escaped = String::with_capacity(input.len());
let mut start = 0;
let mut end = 0;
for (i, c) in input.char_indices() {
state = match state {
Normal => match c {
'\\' => {
if cfg!(unix) {
escaped.push_str(&input[start..i]);
start = i + 1;
NormalEscaped
} else {
Normal
}
}
'"' => {
end = i;
Dquoted
}
'\'' => {
end = i;
Quoted
}
c if c.is_ascii_whitespace() => {
end = i;
Normal
}
_ => Normal,
},
NormalEscaped => Normal,
Quoted => match c {
'\\' => {
if cfg!(unix) {
escaped.push_str(&input[start..i]);
start = i + 1;
QuoteEscaped
} else {
Quoted
}
}
'\'' => {
end = i;
Normal
}
_ => Quoted,
},
QuoteEscaped => Quoted,
Dquoted => match c {
'\\' => {
if cfg!(unix) {
escaped.push_str(&input[start..i]);
start = i + 1;
DquoteEscaped
} else {
Dquoted
}
}
'"' => {
end = i;
Normal
}
_ => Dquoted,
},
DquoteEscaped => Dquoted,
};
if i >= input.len() - 1 && end == 0 {
end = i + 1;
}
if end > 0 {
let esc_trim = escaped.trim();
let inp = &input[start..end];
if !(esc_trim.is_empty() && inp.trim().is_empty()) {
if esc_trim.is_empty() {
args.push(inp.into());
} else {
args.push([escaped, inp.into()].concat().into());
escaped = "".to_string();
}
}
start = i + 1;
end = 0;
}
}
args
}
#[cfg(test)]
mod test {
use super::*;
#[test]
#[cfg(windows)]
fn test_normal() {
let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
let result = shellwords(input);
let expected = vec![
Cow::from(":o"),
Cow::from("single_word"),
Cow::from("twó"),
Cow::from("wörds"),
Cow::from("\\three\\"),
Cow::from("\\"),
Cow::from("with\\ escaping\\\\"),
];
// TODO test is_owned and is_borrowed, once they get stabilized.
assert_eq!(expected, result);
}
#[test]
#[cfg(unix)]
fn test_normal() {
let input = r#":o single_word twó wörds \three\ \"with\ escaping\\"#;
let result = shellwords(input);
let expected = vec![
Cow::from(":o"),
Cow::from("single_word"),
Cow::from("twó"),
Cow::from("wörds"),
Cow::from(r#"three "with escaping\"#),
];
// TODO test is_owned and is_borrowed, once they get stabilized.
assert_eq!(expected, result);
}
#[test]
#[cfg(unix)]
fn test_quoted() {
let quoted =
r#":o 'single_word' 'twó wörds' '' ' ''\three\' \"with\ escaping\\' 'quote incomplete"#;
let result = shellwords(quoted);
let expected = vec![
Cow::from(":o"),
Cow::from("single_word"),
Cow::from("twó wörds"),
Cow::from(r#"three' "with escaping\"#),
Cow::from("quote incomplete"),
];
assert_eq!(expected, result);
}
#[test]
#[cfg(unix)]
fn test_dquoted() {
let dquoted = r#":o "single_word" "twó wörds" "" " ""\three\' \"with\ escaping\\" "dquote incomplete"#;
let result = shellwords(dquoted);
let expected = vec![
Cow::from(":o"),
Cow::from("single_word"),
Cow::from("twó wörds"),
Cow::from(r#"three' "with escaping\"#),
Cow::from("dquote incomplete"),
];
assert_eq!(expected, result);
}
#[test]
#[cfg(unix)]
fn test_mixed() {
let dquoted = r#":o single_word 'twó wörds' "\three\' \"with\ escaping\\""no space before"'and after' $#%^@ "%^&(%^" ')(*&^%''a\\\\\b' '"#;
let result = shellwords(dquoted);
let expected = vec![
Cow::from(":o"),
Cow::from("single_word"),
Cow::from("twó wörds"),
Cow::from("three' \"with escaping\\"),
Cow::from("no space before"),
Cow::from("and after"),
Cow::from("$#%^@"),
Cow::from("%^&(%^"),
Cow::from(")(*&^%"),
Cow::from(r#"a\\b"#),
//last ' just changes to quoted but since we dont have anything after it, it should be ignored
];
assert_eq!(expected, result);
}
}

View File

@@ -1,4 +1,6 @@
use crate::{search, Selection};
use std::fmt::Display;
use crate::{search, Range, Selection};
use ropey::RopeSlice;
pub const PAIRS: &[(char, char)] = &[
@@ -11,6 +13,27 @@ pub const PAIRS: &[(char, char)] = &[
('', ''),
];
#[derive(Debug, PartialEq)]
pub enum Error {
PairNotFound,
CursorOverlap,
RangeExceedsText,
CursorOnAmbiguousPair,
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match *self {
Error::PairNotFound => "Surround pair not found around all cursors",
Error::CursorOverlap => "Cursors overlap for a single surround pair range",
Error::RangeExceedsText => "Cursor range exceeds text length",
Error::CursorOnAmbiguousPair => "Cursor on ambiguous surround pair",
})
}
}
type Result<T> = std::result::Result<T, Error>;
/// Given any char in [PAIRS], return the open and closing chars. If not found in
/// [PAIRS] return (ch, ch).
///
@@ -29,45 +52,83 @@ pub fn get_pair(ch: char) -> (char, char) {
.unwrap_or((ch, ch))
}
pub fn find_nth_closest_pairs_pos(
text: RopeSlice,
range: Range,
n: usize,
) -> Result<(usize, usize)> {
let is_open_pair = |ch| PAIRS.iter().any(|(open, _)| *open == ch);
let is_close_pair = |ch| PAIRS.iter().any(|(_, close)| *close == ch);
let mut stack = Vec::with_capacity(2);
let pos = range.cursor(text);
for ch in text.chars_at(pos) {
if is_open_pair(ch) {
// Track open pairs encountered so that we can step over
// the corresponding close pairs that will come up further
// down the loop. We want to find a lone close pair whose
// open pair is before the cursor position.
stack.push(ch);
continue;
} else if is_close_pair(ch) {
let (open, _) = get_pair(ch);
if stack.last() == Some(&open) {
stack.pop();
continue;
} else {
// In the ideal case the stack would be empty here and the
// current character would be the close pair that we are
// looking for. It could also be the case that the pairs
// are unbalanced and we encounter a close pair that doesn't
// close the last seen open pair. In either case use this
// char as the auto-detected closest pair.
return find_nth_pairs_pos(text, ch, range, n);
}
}
}
Err(Error::PairNotFound)
}
/// Find the position of surround pairs of `ch` which can be either a closing
/// or opening pair. `n` will skip n - 1 pairs (eg. n=2 will discard (only)
/// the first pair found and keep looking)
pub fn find_nth_pairs_pos(
text: RopeSlice,
ch: char,
pos: usize,
range: Range,
n: usize,
) -> Option<(usize, usize)> {
) -> Result<(usize, usize)> {
if text.len_chars() < 2 {
return Err(Error::PairNotFound);
}
if range.to() >= text.len_chars() {
return Err(Error::RangeExceedsText);
}
let (open, close) = get_pair(ch);
let pos = range.cursor(text);
if text.len_chars() < 2 || pos >= text.len_chars() {
return None;
}
if open == close {
let (open, close) = if open == close {
if Some(open) == text.get_char(pos) {
// Special case: cursor is directly on a matching char.
match pos {
0 => Some((pos, search::find_nth_next(text, close, pos + 1, n)?)),
_ if (pos + 1) == text.len_chars() => {
Some((search::find_nth_prev(text, open, pos, n)?, pos))
}
// We return no match because there's no way to know which
// side of the char we should be searching on.
_ => None,
}
} else {
Some((
search::find_nth_prev(text, open, pos, n)?,
search::find_nth_next(text, close, pos, n)?,
))
// Cursor is directly on match char. We return no match
// because there's no way to know which side of the char
// we should be searching on.
return Err(Error::CursorOnAmbiguousPair);
}
(
search::find_nth_prev(text, open, pos, n),
search::find_nth_next(text, close, pos, n),
)
} else {
Some((
find_nth_open_pair(text, open, close, pos, n)?,
find_nth_close_pair(text, open, close, pos, n)?,
))
}
(
find_nth_open_pair(text, open, close, pos, n),
find_nth_close_pair(text, open, close, pos, n),
)
};
Option::zip(open, close).ok_or(Error::PairNotFound)
}
fn find_nth_open_pair(
@@ -151,23 +212,28 @@ fn find_nth_close_pair(
/// Find position of surround characters around every cursor. Returns None
/// if any positions overlap. Note that the positions are in a flat Vec.
/// Use get_surround_pos().chunks(2) to get matching pairs of surround positions.
/// `ch` can be either closing or opening pair.
/// `ch` can be either closing or opening pair. If `ch` is None, surround pairs
/// are automatically detected around each cursor (note that this may result
/// in them selecting different surround characters for each selection).
pub fn get_surround_pos(
text: RopeSlice,
selection: &Selection,
ch: char,
ch: Option<char>,
skip: usize,
) -> Option<Vec<usize>> {
) -> Result<Vec<usize>> {
let mut change_pos = Vec::new();
for range in selection {
let (open_pos, close_pos) = find_nth_pairs_pos(text, ch, range.head, skip)?;
for &range in selection {
let (open_pos, close_pos) = match ch {
Some(ch) => find_nth_pairs_pos(text, ch, range, skip)?,
None => find_nth_closest_pairs_pos(text, range, skip)?,
};
if change_pos.contains(&open_pos) || change_pos.contains(&close_pos) {
return None;
return Err(Error::CursorOverlap);
}
change_pos.extend_from_slice(&[open_pos, close_pos]);
}
Some(change_pos)
Ok(change_pos)
}
#[cfg(test)]
@@ -178,67 +244,92 @@ mod test {
use ropey::Rope;
use smallvec::SmallVec;
#[test]
fn test_find_nth_pairs_pos() {
let doc = Rope::from("some (text) here");
#[allow(clippy::type_complexity)]
fn check_find_nth_pair_pos(
text: &str,
cases: Vec<(usize, char, usize, Result<(usize, usize)>)>,
) {
let doc = Rope::from(text);
let slice = doc.slice(..);
// cursor on [t]ext
assert_eq!(find_nth_pairs_pos(slice, '(', 6, 1), Some((5, 10)));
assert_eq!(find_nth_pairs_pos(slice, ')', 6, 1), Some((5, 10)));
// cursor on so[m]e
assert_eq!(find_nth_pairs_pos(slice, '(', 2, 1), None);
// cursor on bracket itself
assert_eq!(find_nth_pairs_pos(slice, '(', 5, 1), Some((5, 10)));
assert_eq!(find_nth_pairs_pos(slice, '(', 10, 1), Some((5, 10)));
for (cursor_pos, ch, n, expected_range) in cases {
let range = find_nth_pairs_pos(slice, ch, (cursor_pos, cursor_pos + 1).into(), n);
assert_eq!(
range, expected_range,
"Expected {:?}, got {:?}",
expected_range, range
);
}
}
#[test]
fn test_find_nth_pairs_pos() {
check_find_nth_pair_pos(
"some (text) here",
vec![
// cursor on [t]ext
(6, '(', 1, Ok((5, 10))),
(6, ')', 1, Ok((5, 10))),
// cursor on so[m]e
(2, '(', 1, Err(Error::PairNotFound)),
// cursor on bracket itself
(5, '(', 1, Ok((5, 10))),
(10, '(', 1, Ok((5, 10))),
],
);
}
#[test]
fn test_find_nth_pairs_pos_skip() {
let doc = Rope::from("(so (many (good) text) here)");
let slice = doc.slice(..);
// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 2), Some((4, 21)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 3), Some((0, 27)));
check_find_nth_pair_pos(
"(so (many (good) text) here)",
vec![
// cursor on go[o]d
(13, '(', 1, Ok((10, 15))),
(13, '(', 2, Ok((4, 21))),
(13, '(', 3, Ok((0, 27))),
],
);
}
#[test]
fn test_find_nth_pairs_pos_same() {
let doc = Rope::from("'so 'many 'good' text' here'");
let slice = doc.slice(..);
// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 2), Some((4, 21)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 3), Some((0, 27)));
// cursor on the quotes
assert_eq!(find_nth_pairs_pos(slice, '\'', 10, 1), None);
// this is the best we can do since opening and closing pairs are same
assert_eq!(find_nth_pairs_pos(slice, '\'', 0, 1), Some((0, 4)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 27, 1), Some((21, 27)));
check_find_nth_pair_pos(
"'so 'many 'good' text' here'",
vec![
// cursor on go[o]d
(13, '\'', 1, Ok((10, 15))),
(13, '\'', 2, Ok((4, 21))),
(13, '\'', 3, Ok((0, 27))),
// cursor on the quotes
(10, '\'', 1, Err(Error::CursorOnAmbiguousPair)),
],
)
}
#[test]
fn test_find_nth_pairs_pos_step() {
let doc = Rope::from("((so)((many) good (text))(here))");
let slice = doc.slice(..);
// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '(', 15, 1), Some((5, 24)));
assert_eq!(find_nth_pairs_pos(slice, '(', 15, 2), Some((0, 31)));
check_find_nth_pair_pos(
"((so)((many) good (text))(here))",
vec![
// cursor on go[o]d
(15, '(', 1, Ok((5, 24))),
(15, '(', 2, Ok((0, 31))),
],
)
}
#[test]
fn test_find_nth_pairs_pos_mixed() {
let doc = Rope::from("(so [many {good} text] here)");
let slice = doc.slice(..);
// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '{', 13, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '[', 13, 1), Some((4, 21)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 1), Some((0, 27)));
check_find_nth_pair_pos(
"(so [many {good} text] here)",
vec![
// cursor on go[o]d
(13, '{', 1, Ok((10, 15))),
(13, '[', 1, Ok((4, 21))),
(13, '(', 1, Ok((0, 27))),
],
)
}
#[test]
@@ -252,7 +343,7 @@ mod test {
// cursor on s[o]me, c[h]ars, newl[i]ne
assert_eq!(
get_surround_pos(slice, &selection, '(', 1)
get_surround_pos(slice, &selection, Some('('), 1)
.unwrap()
.as_slice(),
&[0, 5, 7, 13, 15, 23]
@@ -266,11 +357,10 @@ mod test {
let selection =
Selection::new(SmallVec::from_slice(&[Range::point(2), Range::point(9)]), 0);
// cursor on s[o]me, c[h]ars
assert_eq!(
get_surround_pos(slice, &selection, '(', 1),
None // different surround chars
get_surround_pos(slice, &selection, Some('('), 1),
Err(Error::PairNotFound) // different surround chars
);
let selection = Selection::new(
@@ -279,8 +369,16 @@ mod test {
);
// cursor on [x]x, newli[n]e
assert_eq!(
get_surround_pos(slice, &selection, '(', 1),
None // overlapping surround chars
get_surround_pos(slice, &selection, Some('('), 1),
Err(Error::PairNotFound) // overlapping surround chars
);
let selection =
Selection::new(SmallVec::from_slice(&[Range::point(2), Range::point(3)]), 0);
// cursor on s[o][m]e
assert_eq!(
get_surround_pos(slice, &selection, Some('['), 1),
Err(Error::CursorOverlap)
);
}
}

File diff suppressed because it is too large Load Diff

143
helix-core/src/test.rs Normal file
View File

@@ -0,0 +1,143 @@
//! Test helpers.
use crate::{Range, Selection};
use smallvec::SmallVec;
use std::cmp::Reverse;
/// Convert annotated test string to test string and selection.
///
/// `#[|` for primary selection with head before anchor followed by `]#`.
/// `#(|` for secondary selection with head before anchor followed by `)#`.
/// `#[` for primary selection with head after anchor followed by `|]#`.
/// `#(` for secondary selection with head after anchor followed by `|)#`.
///
/// # Examples
///
/// ```
/// use helix_core::{Range, Selection, test::print};
/// use smallvec::smallvec;
///
/// assert_eq!(
/// print("#[a|]#b#(|c)#"),
/// ("abc".to_owned(), Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0))
/// );
/// ```
///
/// # Panics
///
/// Panics when missing primary or appeared more than once.
/// Panics when missing head or anchor.
/// Panics when head come after head or anchor come after anchor.
pub fn print(s: &str) -> (String, Selection) {
let mut primary_idx = None;
let mut ranges = SmallVec::new();
let mut iter = s.chars().peekable();
let mut left = String::with_capacity(s.len());
'outer: while let Some(c) = iter.next() {
let start = left.len();
if c != '#' {
left.push(c);
continue;
}
let (is_primary, close_pair) = match iter.next() {
Some('[') => (true, ']'),
Some('(') => (false, ')'),
Some(ch) => {
left.push('#');
left.push(ch);
continue;
}
None => break,
};
if is_primary && primary_idx.is_some() {
panic!("primary `#[` already appeared {:?} {:?}", left, s);
}
let head_at_beg = iter.next_if_eq(&'|').is_some();
while let Some(c) = iter.next() {
if !(c == close_pair && iter.peek() == Some(&'#')) {
left.push(c);
continue;
}
if !head_at_beg {
let prev = left.pop().unwrap();
if prev != '|' {
left.push(prev);
left.push(c);
continue;
}
}
iter.next(); // skip "#"
if is_primary {
primary_idx = Some(ranges.len());
}
let (anchor, head) = match head_at_beg {
true => (left.len(), start),
false => (start, left.len()),
};
ranges.push(Range::new(anchor, head));
continue 'outer;
}
if head_at_beg {
panic!("missing end `{}#` {:?} {:?}", close_pair, left, s);
} else {
panic!("missing end `|{}#` {:?} {:?}", close_pair, left, s);
}
}
let primary = match primary_idx {
Some(i) => i,
None => panic!("missing primary `#[|]#` {:?}", s),
};
let selection = Selection::new(ranges, primary);
(left, selection)
}
/// Convert test string and selection to annotated test string.
///
/// `#[|` for primary selection with head before anchor followed by `]#`.
/// `#(|` for secondary selection with head before anchor followed by `)#`.
/// `#[` for primary selection with head after anchor followed by `|]#`.
/// `#(` for secondary selection with head after anchor followed by `|)#`.
///
/// # Examples
///
/// ```
/// use helix_core::{Range, Selection, test::plain};
/// use smallvec::smallvec;
///
/// assert_eq!(
/// plain("abc", Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0)),
/// "#[a|]#b#(|c)#".to_owned()
/// );
/// ```
pub fn plain(s: &str, selection: Selection) -> String {
let primary = selection.primary_index();
let mut out = String::with_capacity(s.len() + 5 * selection.len());
out.push_str(s);
let mut insertion: Vec<_> = selection
.iter()
.enumerate()
.flat_map(|(i, range)| {
// sort like this before reversed so anchor < head later
match (range.anchor < range.head, i == primary) {
(true, true) => [(range.anchor, "#["), (range.head, "|]#")],
(true, false) => [(range.anchor, "#("), (range.head, "|)#")],
(false, true) => [(range.anchor, "]#"), (range.head, "#[|")],
(false, false) => [(range.anchor, ")#"), (range.head, "#(|")],
}
})
.collect();
// insert in reverse order
insertion.sort_unstable_by_key(|k| Reverse(k.0));
for (i, s) in insertion {
out.insert_str(i, s);
}
out
}

View File

@@ -4,13 +4,14 @@ use ropey::RopeSlice;
use tree_sitter::{Node, QueryCursor};
use crate::chars::{categorize_char, char_is_whitespace, CharCategory};
use crate::graphemes::next_grapheme_boundary;
use crate::graphemes::{next_grapheme_boundary, prev_grapheme_boundary};
use crate::line_ending::rope_is_line_ending;
use crate::movement::Direction;
use crate::surround;
use crate::syntax::LanguageConfiguration;
use crate::Range;
fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction) -> usize {
fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction, long: bool) -> usize {
use CharCategory::{Eol, Whitespace};
let iter = match direction {
@@ -33,7 +34,7 @@ fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction) ->
match categorize_char(ch) {
Eol | Whitespace => return pos,
category => {
if category != prev_category && pos != 0 && pos != slice.len_chars() {
if !long && category != prev_category && pos != 0 && pos != slice.len_chars() {
return pos;
} else {
match direction {
@@ -53,6 +54,8 @@ fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction) ->
pub enum TextObject {
Around,
Inside,
/// Used for moving between objects.
Movement,
}
impl Display for TextObject {
@@ -60,6 +63,7 @@ impl Display for TextObject {
f.write_str(match self {
Self::Around => "around",
Self::Inside => "inside",
Self::Movement => "movement",
})
}
}
@@ -70,13 +74,14 @@ pub fn textobject_word(
range: Range,
textobject: TextObject,
_count: usize,
long: bool,
) -> Range {
let pos = range.cursor(slice);
let word_start = find_word_boundary(slice, pos, Direction::Backward);
let word_start = find_word_boundary(slice, pos, Direction::Backward, long);
let word_end = match slice.get_char(pos).map(categorize_char) {
None | Some(CharCategory::Whitespace | CharCategory::Eol) => pos,
_ => find_word_boundary(slice, pos + 1, Direction::Forward),
_ => find_word_boundary(slice, pos + 1, Direction::Forward, long),
};
// Special case.
@@ -103,20 +108,132 @@ pub fn textobject_word(
Range::new(word_start - whitespace_count_left, word_end)
}
}
TextObject::Movement => unreachable!(),
}
}
pub fn textobject_surround(
pub fn textobject_paragraph(
slice: RopeSlice,
range: Range,
textobject: TextObject,
count: usize,
) -> Range {
let mut line = range.cursor_line(slice);
let prev_line_empty = rope_is_line_ending(slice.line(line.saturating_sub(1)));
let curr_line_empty = rope_is_line_ending(slice.line(line));
let next_line_empty = rope_is_line_ending(slice.line(line.saturating_sub(1)));
let last_char =
prev_grapheme_boundary(slice, slice.line_to_char(line + 1)) == range.cursor(slice);
let prev_empty_to_line = prev_line_empty && !curr_line_empty;
let curr_empty_to_line = curr_line_empty && !next_line_empty;
// skip character before paragraph boundary
let mut line_back = line; // line but backwards
if prev_empty_to_line || curr_empty_to_line {
line_back += 1;
}
// do not include current paragraph on paragraph end (include next)
if !(curr_empty_to_line && last_char) {
let mut lines = slice.lines_at(line_back);
lines.reverse();
let mut lines = lines.map(rope_is_line_ending).peekable();
while lines.next_if(|&e| e).is_some() {
line_back -= 1;
}
while lines.next_if(|&e| !e).is_some() {
line_back -= 1;
}
}
// skip character after paragraph boundary
if curr_empty_to_line && last_char {
line += 1;
}
let mut lines = slice.lines_at(line).map(rope_is_line_ending).peekable();
let mut count_done = 0; // count how many non-whitespace paragraphs done
for _ in 0..count {
let mut done = false;
while lines.next_if(|&e| !e).is_some() {
line += 1;
done = true;
}
while lines.next_if(|&e| e).is_some() {
line += 1;
}
count_done += done as usize;
}
// search one paragraph backwards for last paragraph
// makes `map` at the end of the paragraph with trailing newlines useful
let last_paragraph = count_done != count && lines.peek().is_none();
if last_paragraph {
let mut lines = slice.lines_at(line_back);
lines.reverse();
let mut lines = lines.map(rope_is_line_ending).peekable();
while lines.next_if(|&e| e).is_some() {
line_back -= 1;
}
while lines.next_if(|&e| !e).is_some() {
line_back -= 1;
}
}
// handle last whitespaces part separately depending on textobject
match textobject {
TextObject::Around => {}
TextObject::Inside => {
// remove last whitespace paragraph
let mut lines = slice.lines_at(line);
lines.reverse();
let mut lines = lines.map(rope_is_line_ending).peekable();
while lines.next_if(|&e| e).is_some() {
line -= 1;
}
}
TextObject::Movement => unreachable!(),
}
let anchor = slice.line_to_char(line_back);
let head = slice.line_to_char(line);
Range::new(anchor, head)
}
pub fn textobject_pair_surround(
slice: RopeSlice,
range: Range,
textobject: TextObject,
ch: char,
count: usize,
) -> Range {
surround::find_nth_pairs_pos(slice, ch, range.head, count)
textobject_pair_surround_impl(slice, range, textobject, Some(ch), count)
}
pub fn textobject_pair_surround_closest(
slice: RopeSlice,
range: Range,
textobject: TextObject,
count: usize,
) -> Range {
textobject_pair_surround_impl(slice, range, textobject, None, count)
}
fn textobject_pair_surround_impl(
slice: RopeSlice,
range: Range,
textobject: TextObject,
ch: Option<char>,
count: usize,
) -> Range {
let pair_pos = match ch {
Some(ch) => surround::find_nth_pairs_pos(slice, ch, range, count),
// Automatically find the closest surround pairs
None => surround::find_nth_closest_pairs_pos(slice, range, count),
};
pair_pos
.map(|(anchor, head)| match textobject {
TextObject::Inside => Range::new(next_grapheme_boundary(slice, anchor), head),
TextObject::Around => Range::new(anchor, next_grapheme_boundary(slice, head)),
TextObject::Movement => unreachable!(),
})
.unwrap_or(range)
}
@@ -169,7 +286,7 @@ mod test {
#[test]
fn test_textobject_word() {
// (text, [(cursor position, textobject, final range), ...])
// (text, [(char position, textobject, final range), ...])
let tests = &[
(
"cursor at beginning of doc",
@@ -268,7 +385,9 @@ mod test {
let slice = doc.slice(..);
for &case in scenario {
let (pos, objtype, expected_range) = case;
let result = textobject_word(slice, Range::point(pos), objtype, 1);
// cursor is a single width selection
let range = Range::new(pos, pos + 1);
let result = textobject_word(slice, range, objtype, 1, false);
assert_eq!(
result,
expected_range.into(),
@@ -280,9 +399,94 @@ mod test {
}
}
#[test]
fn test_textobject_paragraph_inside_single() {
let tests = [
("#[|]#", "#[|]#"),
("firs#[t|]#\n\nparagraph\n\n", "#[first\n|]#\nparagraph\n\n"),
(
"second\n\npa#[r|]#agraph\n\n",
"second\n\n#[paragraph\n|]#\n",
),
("#[f|]#irst char\n\n", "#[first char\n|]#\n"),
("last char\n#[\n|]#", "#[last char\n|]#\n"),
(
"empty to line\n#[\n|]#paragraph boundary\n\n",
"empty to line\n\n#[paragraph boundary\n|]#\n",
),
(
"line to empty\n\n#[p|]#aragraph boundary\n\n",
"line to empty\n\n#[paragraph boundary\n|]#\n",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection = selection
.transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 1));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_textobject_paragraph_inside_double() {
let tests = [
(
"last two\n\n#[p|]#aragraph\n\nwithout whitespaces\n\n",
"last two\n\n#[paragraph\n\nwithout whitespaces\n|]#\n",
),
(
"last two\n#[\n|]#paragraph\n\nwithout whitespaces\n\n",
"last two\n\n#[paragraph\n\nwithout whitespaces\n|]#\n",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection = selection
.transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 2));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_textobject_paragraph_around_single() {
let tests = [
("#[|]#", "#[|]#"),
("firs#[t|]#\n\nparagraph\n\n", "#[first\n\n|]#paragraph\n\n"),
(
"second\n\npa#[r|]#agraph\n\n",
"second\n\n#[paragraph\n\n|]#",
),
("#[f|]#irst char\n\n", "#[first char\n\n|]#"),
("last char\n#[\n|]#", "#[last char\n\n|]#"),
(
"empty to line\n#[\n|]#paragraph boundary\n\n",
"empty to line\n\n#[paragraph boundary\n\n|]#",
),
(
"line to empty\n\n#[p|]#aragraph boundary\n\n",
"line to empty\n\n#[paragraph boundary\n\n|]#",
),
];
for (before, expected) in tests {
let (s, selection) = crate::test::print(before);
let text = Rope::from(s.as_str());
let selection = selection
.transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Around, 1));
let actual = crate::test::plain(&s, selection);
assert_eq!(actual, expected, "\nbefore: `{:?}`", before);
}
}
#[test]
fn test_textobject_surround() {
// (text, [(cursor position, textobject, final range, count), ...])
// (text, [(cursor position, textobject, final range, surround char, count), ...])
let tests = &[
(
"simple (single) surround pairs",
@@ -358,7 +562,7 @@ mod test {
let slice = doc.slice(..);
for &case in scenario {
let (pos, objtype, expected_range, ch, count) = case;
let result = textobject_surround(slice, Range::point(pos), objtype, ch, count);
let result = textobject_pair_surround(slice, Range::point(pos), objtype, ch, count);
assert_eq!(
result,
expected_range.into(),

View File

@@ -21,8 +21,7 @@ pub enum Assoc {
After,
}
// ChangeSpec = Change | ChangeSet | Vec<Change>
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ChangeSet {
pub(crate) changes: Vec<Operation>,
/// The required document length. Will refuse to apply changes unless it matches.
@@ -30,16 +29,6 @@ pub struct ChangeSet {
len_after: usize,
}
impl Default for ChangeSet {
fn default() -> Self {
Self {
changes: Vec::new(),
len: 0,
len_after: 0,
}
}
}
impl ChangeSet {
pub fn with_capacity(capacity: usize) -> Self {
Self {
@@ -60,7 +49,6 @@ impl ChangeSet {
}
// TODO: from iter
//
#[doc(hidden)] // used by lsp to convert to LSP changes
pub fn changes(&self) -> &[Operation] {
@@ -95,7 +83,7 @@ impl ChangeSet {
let new_last = match self.changes.as_mut_slice() {
[.., Insert(prev)] | [.., Insert(prev), Delete(_)] => {
prev.push_tendril(&fragment);
prev.push_str(&fragment);
return;
}
[.., last @ Delete(_)] => std::mem::replace(last, Insert(fragment)),
@@ -199,7 +187,7 @@ impl ChangeSet {
// TODO: cover this with a test
// figure out the byte index of the truncated string end
let (pos, _) = s.char_indices().nth(j).unwrap();
s.pop_front(pos as u32);
s.replace_range(0..pos, "");
head_a = Some(Insert(s));
head_b = changes_b.next();
}
@@ -221,9 +209,11 @@ impl ChangeSet {
Ordering::Greater => {
// figure out the byte index of the truncated string end
let (pos, _) = s.char_indices().nth(j).unwrap();
let pos = pos as u32;
changes.insert(s.subtendril(0, pos));
head_a = Some(Insert(s.subtendril(pos, s.len() as u32 - pos)));
let mut before = s;
let after = before.split_off(pos);
changes.insert(before);
head_a = Some(Insert(after));
head_b = changes_b.next();
}
}
@@ -287,7 +277,7 @@ impl ChangeSet {
}
Delete(n) => {
let text = Cow::from(original_doc.slice(pos..pos + *n));
changes.insert(Tendril::from_slice(&text));
changes.insert(Tendril::from(text.as_ref()));
pos += n;
}
Insert(s) => {
@@ -330,7 +320,7 @@ impl ChangeSet {
/// `true` when the set is empty.
#[inline]
pub fn is_empty(&self) -> bool {
self.changes.is_empty()
self.changes.is_empty() || self.changes == [Operation::Retain(self.len)]
}
/// Map a position through the changes.
@@ -419,12 +409,10 @@ impl ChangeSet {
/// Transaction represents a single undoable unit of changes. Several changes can be grouped into
/// a single transaction.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Transaction {
changes: ChangeSet,
selection: Option<Selection>,
// effects, annotations
// scroll_into_view
}
impl Transaction {
@@ -448,14 +436,12 @@ impl Transaction {
/// Returns true if applied successfully.
pub fn apply(&self, doc: &mut Rope) -> bool {
if !self.changes.is_empty() {
// apply changes to the document
if !self.changes.apply(doc) {
return false;
}
if self.changes.is_empty() {
return true;
}
true
// apply changes to the document
self.changes.apply(doc)
}
/// Generate a transaction that reverts this one.
@@ -483,7 +469,7 @@ impl Transaction {
/// Generate a transaction from a set of changes.
pub fn change<I>(doc: &Rope, changes: I) -> Self
where
I: IntoIterator<Item = Change> + Iterator,
I: Iterator<Item = Change>,
{
let len = doc.len_chars();
@@ -491,12 +477,11 @@ impl Transaction {
let size = upper.unwrap_or(lower);
let mut changeset = ChangeSet::with_capacity(2 * size + 1); // rough estimate
// TODO: verify ranges are ordered and not overlapping or change will panic.
// TODO: test for (pos, pos, None) to factor out as nothing
let mut last = 0;
for (from, to, tendril) in changes {
// Verify ranges are ordered and not overlapping
debug_assert!(last <= from);
// Retain from last "to" to current "from"
changeset.retain(from - last);
let span = to - from;
@@ -702,7 +687,7 @@ mod test {
let mut doc = Rope::from("hello world!\ntest 123");
let transaction = Transaction::change(
&doc,
// (1, 1, None) is a useless 0-width delete
// (1, 1, None) is a useless 0-width delete that gets factored out
vec![(1, 1, None), (6, 11, Some("void".into())), (12, 17, None)].into_iter(),
);
transaction.apply(&mut doc);
@@ -720,19 +705,19 @@ mod test {
#[test]
fn optimized_composition() {
let mut state = State::new("".into());
let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('h'));
let t1 = Transaction::insert(&state.doc, &state.selection, Tendril::from("h"));
t1.apply(&mut state.doc);
state.selection = state.selection.clone().map(t1.changes());
let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('e'));
let t2 = Transaction::insert(&state.doc, &state.selection, Tendril::from("e"));
t2.apply(&mut state.doc);
state.selection = state.selection.clone().map(t2.changes());
let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
let t3 = Transaction::insert(&state.doc, &state.selection, Tendril::from("l"));
t3.apply(&mut state.doc);
state.selection = state.selection.clone().map(t3.changes());
let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('l'));
let t4 = Transaction::insert(&state.doc, &state.selection, Tendril::from("l"));
t4.apply(&mut state.doc);
state.selection = state.selection.clone().map(t4.changes());
let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from_char('o'));
let t5 = Transaction::insert(&state.doc, &state.selection, Tendril::from("o"));
t5.apply(&mut state.doc);
state.selection = state.selection.clone().map(t5.changes());
@@ -771,7 +756,7 @@ mod test {
#[test]
fn combine_with_utf8() {
const TEST_CASE: &'static str = "Hello, これはヘリックスエディターです!";
const TEST_CASE: &str = "Hello, これはヘリックスエディターです!";
let empty = Rope::from("");
let a = ChangeSet::new(&empty);

7
helix-core/src/wrap.rs Normal file
View File

@@ -0,0 +1,7 @@
use smartstring::{LazyCompact, SmartString};
/// Given a slice of text, return the text re-wrapped to fit it
/// within the given width.
pub fn reflow_hard_wrap(text: &str, max_line_len: usize) -> SmartString<LazyCompact> {
textwrap::refill(text, max_line_len).into()
}

View File

@@ -0,0 +1 @@
../../../src/indent.rs

View File

@@ -0,0 +1,13 @@
# This languages.toml should contain definitions for all languages for which we have indent tests
[[language]]
name = "rust"
scope = "source.rust"
injection-regex = "rust"
file-types = ["rs"]
comment-token = "//"
roots = ["Cargo.toml", "Cargo.lock"]
indent = { tab-width = 4, unit = " " }
[[grammar]]
name = "rust"
source = { git = "https://github.com/tree-sitter/tree-sitter-rust", rev = "a360da0a29a19c281d08295a35ecd0544d2da211" }

View File

@@ -0,0 +1,105 @@
use std::{
io::{self, stdout, Stdout, Write},
path::PathBuf,
sync::Arc,
time::Duration,
};
mod test {
fn hello_world() {
1 + 1;
let does_indentation_work = 1;
let mut really_long_variable_name_using_up_the_line =
really_long_fn_that_should_definitely_go_on_the_next_line();
really_long_variable_name_using_up_the_line =
really_long_fn_that_should_definitely_go_on_the_next_line();
really_long_variable_name_using_up_the_line |=
really_long_fn_that_should_definitely_go_on_the_next_line();
let (
a_long_variable_name_in_this_tuple,
b_long_variable_name_in_this_tuple,
c_long_variable_name_in_this_tuple,
d_long_variable_name_in_this_tuple,
e_long_variable_name_in_this_tuple,
): (usize, usize, usize, usize, usize) =
if really_long_fn_that_should_definitely_go_on_the_next_line() {
(
03294239434,
1213412342314,
21231234134,
834534234549898789,
9879234234543853457,
)
} else {
(0, 1, 2, 3, 4)
};
let test_function = function_with_param(this_param,
that_param
);
let test_function = function_with_param(
this_param,
that_param
);
let test_function = function_with_proper_indent(param1,
param2,
);
let selection = Selection::new(
changes
.clone()
.map(|(start, end, text): (usize, usize, Option<Tendril>)| {
let len = text.map(|text| text.len()).unwrap() - 1; // minus newline
let pos = start + len;
Range::new(pos, pos)
})
.collect(),
0,
);
return;
}
}
impl<A, D> MyTrait<A, D> for YourType
where
A: TraitB + TraitC,
D: TraitE + TraitF,
{
}
#[test]
//
match test {
Some(a) => 1,
None => {
unimplemented!()
}
}
std::panic::set_hook(Box::new(move |info| {
hook(info);
}));
{ { {
1
}}}
pub fn change<I>(document: &Document, changes: I) -> Self
where
I: IntoIterator<Item = Change> + ExactSizeIterator,
{
[
1,
2,
3,
];
(
1,
2
);
true
}

View File

@@ -0,0 +1,68 @@
use helix_core::{
indent::{treesitter_indent_for_pos, IndentStyle},
syntax::Loader,
Syntax,
};
use std::path::PathBuf;
#[test]
fn test_treesitter_indent_rust() {
test_treesitter_indent("rust.rs", "source.rust");
}
#[test]
fn test_treesitter_indent_rust_2() {
test_treesitter_indent("indent.rs", "source.rust");
// TODO Use commands.rs as indentation test.
// Currently this fails because we can't align the parameters of a closure yet
// test_treesitter_indent("commands.rs", "source.rust");
}
fn test_treesitter_indent(file_name: &str, lang_scope: &str) {
let mut test_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
test_dir.push("tests/data/indent");
let mut test_file = test_dir.clone();
test_file.push(file_name);
let test_file = std::fs::File::open(test_file).unwrap();
let doc = ropey::Rope::from_reader(test_file).unwrap();
let mut config_file = test_dir;
config_file.push("languages.toml");
let config = std::fs::read(config_file).unwrap();
let config = toml::from_slice(&config).unwrap();
let loader = Loader::new(config);
// set runtime path so we can find the queries
let mut runtime = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
runtime.push("../runtime");
std::env::set_var("HELIX_RUNTIME", runtime.to_str().unwrap());
let language_config = loader.language_config_for_scope(lang_scope).unwrap();
let highlight_config = language_config.highlight_config(&[]).unwrap();
let syntax = Syntax::new(&doc, highlight_config, std::sync::Arc::new(loader));
let indent_query = language_config.indent_query().unwrap();
let text = doc.slice(..);
for i in 0..doc.len_lines() {
let line = text.line(i);
if let Some(pos) = helix_core::find_first_non_whitespace_char(line) {
let suggested_indent = treesitter_indent_for_pos(
indent_query,
&syntax,
&IndentStyle::Spaces(4),
text,
i,
text.line_to_char(i) + pos,
false,
)
.unwrap();
assert!(
line.get_slice(..pos).map_or(false, |s| s == suggested_indent),
"Wrong indentation on line {}:\n\"{}\" (original line)\n\"{}\" (suggested indentation)\n",
i+1,
line.slice(..line.len_chars()-1),
suggested_indent,
);
}
}
}

25
helix-dap/Cargo.toml Normal file
View File

@@ -0,0 +1,25 @@
[package]
name = "helix-dap"
version = "0.6.0"
authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
edition = "2018"
license = "MPL-2.0"
description = "DAP client implementation for Helix project"
categories = ["editor"]
repository = "https://github.com/helix-editor/helix"
homepage = "https://helix-editor.com"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
helix-core = { version = "0.6", path = "../helix-core" }
anyhow = "1.0"
log = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "net", "sync"] }
which = "4.2"
[dev-dependencies]
fern = "0.6"

480
helix-dap/src/client.rs Normal file
View File

@@ -0,0 +1,480 @@
use crate::{
transport::{Payload, Request, Response, Transport},
types::*,
Error, Result, ThreadId,
};
use helix_core::syntax::DebuggerQuirks;
use serde_json::Value;
use anyhow::anyhow;
pub use log::{error, info};
use std::{
collections::HashMap,
future::Future,
net::{IpAddr, Ipv4Addr, SocketAddr},
path::PathBuf,
process::Stdio,
sync::atomic::{AtomicU64, Ordering},
};
use tokio::{
io::{AsyncBufRead, AsyncWrite, BufReader, BufWriter},
net::TcpStream,
process::{Child, Command},
sync::mpsc::{channel, unbounded_channel, UnboundedReceiver, UnboundedSender},
time,
};
#[derive(Debug)]
pub struct Client {
id: usize,
_process: Option<Child>,
server_tx: UnboundedSender<Payload>,
request_counter: AtomicU64,
pub caps: Option<DebuggerCapabilities>,
// thread_id -> frames
pub stack_frames: HashMap<ThreadId, Vec<StackFrame>>,
pub thread_states: ThreadStates,
pub thread_id: Option<ThreadId>,
/// Currently active frame for the current thread.
pub active_frame: Option<usize>,
pub quirks: DebuggerQuirks,
}
impl Client {
// Spawn a process and communicate with it by either TCP or stdio
pub async fn process(
transport: &str,
command: &str,
args: Vec<&str>,
port_arg: Option<&str>,
id: usize,
) -> Result<(Self, UnboundedReceiver<Payload>)> {
if command.is_empty() {
return Result::Err(Error::Other(anyhow!("Command not provided")));
}
if transport == "tcp" && port_arg.is_some() {
Self::tcp_process(command, args, port_arg.unwrap(), id).await
} else if transport == "stdio" {
Self::stdio(command, args, id)
} else {
Result::Err(Error::Other(anyhow!("Incorrect transport {}", transport)))
}
}
pub fn streams(
rx: Box<dyn AsyncBufRead + Unpin + Send>,
tx: Box<dyn AsyncWrite + Unpin + Send>,
err: Option<Box<dyn AsyncBufRead + Unpin + Send>>,
id: usize,
process: Option<Child>,
) -> Result<(Self, UnboundedReceiver<Payload>)> {
let (server_rx, server_tx) = Transport::start(rx, tx, err, id);
let (client_rx, client_tx) = unbounded_channel();
let client = Self {
id,
_process: process,
server_tx,
request_counter: AtomicU64::new(0),
caps: None,
//
stack_frames: HashMap::new(),
thread_states: HashMap::new(),
thread_id: None,
active_frame: None,
quirks: DebuggerQuirks::default(),
};
tokio::spawn(Self::recv(server_rx, client_rx));
Ok((client, client_tx))
}
pub async fn tcp(
addr: std::net::SocketAddr,
id: usize,
) -> Result<(Self, UnboundedReceiver<Payload>)> {
let stream = TcpStream::connect(addr).await?;
let (rx, tx) = stream.into_split();
Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), None, id, None)
}
pub fn stdio(
cmd: &str,
args: Vec<&str>,
id: usize,
) -> Result<(Self, UnboundedReceiver<Payload>)> {
// Resolve path to the binary
let cmd = which::which(cmd).map_err(|err| anyhow::anyhow!(err))?;
let process = Command::new(cmd)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
// make sure the process is reaped on drop
.kill_on_drop(true)
.spawn();
let mut process = process?;
// TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
let errors = process.stderr.take().map(BufReader::new);
Self::streams(
Box::new(BufReader::new(reader)),
Box::new(writer),
// errors.map(|errors| Box::new(BufReader::new(errors))),
match errors {
Some(errors) => Some(Box::new(BufReader::new(errors))),
None => None,
},
id,
Some(process),
)
}
async fn get_port() -> Option<u16> {
Some(
tokio::net::TcpListener::bind(SocketAddr::new(
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
0,
))
.await
.ok()?
.local_addr()
.ok()?
.port(),
)
}
pub async fn tcp_process(
cmd: &str,
args: Vec<&str>,
port_format: &str,
id: usize,
) -> Result<(Self, UnboundedReceiver<Payload>)> {
let port = Self::get_port().await.unwrap();
let process = Command::new(cmd)
.args(args)
.args(port_format.replace("{}", &port.to_string()).split(' '))
// silence messages
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
// Do not kill debug adapter when leaving, it should exit automatically
.spawn()?;
// Wait for adapter to become ready for connection
time::sleep(time::Duration::from_millis(500)).await;
let stream = TcpStream::connect(SocketAddr::new(
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
port,
))
.await?;
let (rx, tx) = stream.into_split();
Self::streams(
Box::new(BufReader::new(rx)),
Box::new(tx),
None,
id,
Some(process),
)
}
async fn recv(mut server_rx: UnboundedReceiver<Payload>, client_tx: UnboundedSender<Payload>) {
while let Some(msg) = server_rx.recv().await {
match msg {
Payload::Event(ev) => {
client_tx.send(Payload::Event(ev)).expect("Failed to send");
}
Payload::Response(_) => unreachable!(),
Payload::Request(req) => {
client_tx
.send(Payload::Request(req))
.expect("Failed to send");
}
}
}
}
pub fn id(&self) -> usize {
self.id
}
fn next_request_id(&self) -> u64 {
self.request_counter.fetch_add(1, Ordering::Relaxed)
}
// Internal, called by specific DAP commands when resuming
pub fn resume_application(&mut self) {
if let Some(thread_id) = self.thread_id {
self.thread_states.insert(thread_id, "running".to_string());
self.stack_frames.remove(&thread_id);
}
self.active_frame = None;
self.thread_id = None;
}
/// Execute a RPC request on the debugger.
pub fn call<R: crate::types::Request>(
&self,
arguments: R::Arguments,
) -> impl Future<Output = Result<Value>>
where
R::Arguments: serde::Serialize,
{
let server_tx = self.server_tx.clone();
let id = self.next_request_id();
async move {
use std::time::Duration;
use tokio::time::timeout;
let arguments = Some(serde_json::to_value(arguments)?);
let (callback_tx, mut callback_rx) = channel(1);
let req = Request {
back_ch: Some(callback_tx),
seq: id,
command: R::COMMAND.to_string(),
arguments,
};
server_tx
.send(Payload::Request(req))
.map_err(|e| Error::Other(e.into()))?;
// TODO: specifiable timeout, delay other calls until initialize success
timeout(Duration::from_secs(20), callback_rx.recv())
.await
.map_err(|_| Error::Timeout)? // return Timeout
.ok_or(Error::StreamClosed)?
.map(|response| response.body.unwrap_or_default())
// TODO: check response.success
}
}
pub async fn request<R: crate::types::Request>(&self, params: R::Arguments) -> Result<R::Result>
where
R::Arguments: serde::Serialize,
R::Result: core::fmt::Debug, // TODO: temporary
{
// a future that resolves into the response
let json = self.call::<R>(params).await?;
let response = serde_json::from_value(json)?;
Ok(response)
}
pub fn reply(
&self,
request_seq: u64,
command: &str,
result: core::result::Result<Value, Error>,
) -> impl Future<Output = Result<()>> {
let server_tx = self.server_tx.clone();
let command = command.to_string();
async move {
let response = match result {
Ok(result) => Response {
request_seq,
command,
success: true,
message: None,
body: Some(result),
},
Err(error) => Response {
request_seq,
command,
success: false,
message: Some(error.to_string()),
body: None,
},
};
server_tx
.send(Payload::Response(response))
.map_err(|e| Error::Other(e.into()))?;
Ok(())
}
}
pub fn capabilities(&self) -> &DebuggerCapabilities {
self.caps.as_ref().expect("debugger not yet initialized!")
}
pub async fn initialize(&mut self, adapter_id: String) -> Result<()> {
let args = requests::InitializeArguments {
client_id: Some("hx".to_owned()),
client_name: Some("helix".to_owned()),
adapter_id,
locale: Some("en-us".to_owned()),
lines_start_at_one: Some(true),
columns_start_at_one: Some(true),
path_format: Some("path".to_owned()),
supports_variable_type: Some(true),
supports_variable_paging: Some(false),
supports_run_in_terminal_request: Some(true),
supports_memory_references: Some(false),
supports_progress_reporting: Some(false),
supports_invalidated_event: Some(false),
};
let response = self.request::<requests::Initialize>(args).await?;
self.caps = Some(response);
Ok(())
}
pub fn disconnect(&self) -> impl Future<Output = Result<Value>> {
self.call::<requests::Disconnect>(())
}
pub fn launch(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
self.call::<requests::Launch>(args)
}
pub fn attach(&self, args: serde_json::Value) -> impl Future<Output = Result<Value>> {
self.call::<requests::Attach>(args)
}
pub async fn set_breakpoints(
&self,
file: PathBuf,
breakpoints: Vec<SourceBreakpoint>,
) -> Result<Option<Vec<Breakpoint>>> {
let args = requests::SetBreakpointsArguments {
source: Source {
path: Some(file),
name: None,
source_reference: None,
presentation_hint: None,
origin: None,
sources: None,
adapter_data: None,
checksums: None,
},
breakpoints: Some(breakpoints),
source_modified: Some(false),
};
let response = self.request::<requests::SetBreakpoints>(args).await?;
Ok(response.breakpoints)
}
pub async fn configuration_done(&self) -> Result<()> {
self.request::<requests::ConfigurationDone>(()).await
}
pub fn continue_thread(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {
let args = requests::ContinueArguments { thread_id };
self.call::<requests::Continue>(args)
}
pub async fn stack_trace(
&self,
thread_id: ThreadId,
) -> Result<(Vec<StackFrame>, Option<usize>)> {
let args = requests::StackTraceArguments {
thread_id,
start_frame: None,
levels: None,
format: None,
};
let response = self.request::<requests::StackTrace>(args).await?;
Ok((response.stack_frames, response.total_frames))
}
pub fn threads(&self) -> impl Future<Output = Result<Value>> {
self.call::<requests::Threads>(())
}
pub async fn scopes(&self, frame_id: usize) -> Result<Vec<Scope>> {
let args = requests::ScopesArguments { frame_id };
let response = self.request::<requests::Scopes>(args).await?;
Ok(response.scopes)
}
pub async fn variables(&self, variables_reference: usize) -> Result<Vec<Variable>> {
let args = requests::VariablesArguments {
variables_reference,
filter: None,
start: None,
count: None,
format: None,
};
let response = self.request::<requests::Variables>(args).await?;
Ok(response.variables)
}
pub fn step_in(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {
let args = requests::StepInArguments {
thread_id,
target_id: None,
granularity: None,
};
self.call::<requests::StepIn>(args)
}
pub fn step_out(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {
let args = requests::StepOutArguments {
thread_id,
granularity: None,
};
self.call::<requests::StepOut>(args)
}
pub fn next(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {
let args = requests::NextArguments {
thread_id,
granularity: None,
};
self.call::<requests::Next>(args)
}
pub fn pause(&self, thread_id: ThreadId) -> impl Future<Output = Result<Value>> {
let args = requests::PauseArguments { thread_id };
self.call::<requests::Pause>(args)
}
pub async fn eval(
&self,
expression: String,
frame_id: Option<usize>,
) -> Result<requests::EvaluateResponse> {
let args = requests::EvaluateArguments {
expression,
frame_id,
context: None,
format: None,
};
self.request::<requests::Evaluate>(args).await
}
pub fn set_exception_breakpoints(
&self,
filters: Vec<String>,
) -> impl Future<Output = Result<Value>> {
let args = requests::SetExceptionBreakpointsArguments { filters };
self.call::<requests::SetExceptionBreakpoints>(args)
}
}

24
helix-dap/src/lib.rs Normal file
View File

@@ -0,0 +1,24 @@
mod client;
mod transport;
mod types;
pub use client::Client;
pub use events::Event;
pub use transport::{Payload, Response, Transport};
pub use types::*;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("failed to parse: {0}")]
Parse(#[from] serde_json::Error),
#[error("IO Error: {0}")]
IO(#[from] std::io::Error),
#[error("request timed out")]
Timeout,
#[error("server closed the stream")]
StreamClosed,
#[error(transparent)]
Other(#[from] anyhow::Error),
}
pub type Result<T> = core::result::Result<T, Error>;

280
helix-dap/src/transport.rs Normal file
View File

@@ -0,0 +1,280 @@
use crate::{Error, Event, Result};
use anyhow::Context;
use log::{error, info, warn};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::{
io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWrite, AsyncWriteExt},
sync::{
mpsc::{unbounded_channel, Sender, UnboundedReceiver, UnboundedSender},
Mutex,
},
};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Request {
#[serde(skip)]
pub back_ch: Option<Sender<Result<Response>>>,
pub seq: u64,
pub command: String,
pub arguments: Option<Value>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
pub struct Response {
// seq is omitted as unused and is not sent by some implementations
pub request_seq: u64,
pub success: bool,
pub command: String,
pub message: Option<String>,
pub body: Option<Value>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Payload {
// type = "event"
Event(Box<Event>),
// type = "response"
Response(Response),
// type = "request"
Request(Request),
}
#[derive(Debug)]
pub struct Transport {
#[allow(unused)]
id: usize,
pending_requests: Mutex<HashMap<u64, Sender<Result<Response>>>>,
}
impl Transport {
pub fn start(
server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,
server_stdin: Box<dyn AsyncWrite + Unpin + Send>,
server_stderr: Option<Box<dyn AsyncBufRead + Unpin + Send>>,
id: usize,
) -> (UnboundedReceiver<Payload>, UnboundedSender<Payload>) {
let (client_tx, rx) = unbounded_channel();
let (tx, client_rx) = unbounded_channel();
let transport = Self {
id,
pending_requests: Mutex::new(HashMap::default()),
};
let transport = Arc::new(transport);
tokio::spawn(Self::recv(transport.clone(), server_stdout, client_tx));
tokio::spawn(Self::send(transport, server_stdin, client_rx));
if let Some(stderr) = server_stderr {
tokio::spawn(Self::err(stderr));
}
(rx, tx)
}
async fn recv_server_message(
reader: &mut Box<dyn AsyncBufRead + Unpin + Send>,
buffer: &mut String,
) -> Result<Payload> {
let mut content_length = None;
loop {
buffer.truncate(0);
if reader.read_line(buffer).await? == 0 {
return Err(Error::StreamClosed);
};
if buffer == "\r\n" {
// look for an empty CRLF line
break;
}
let header = buffer.trim();
let parts = header.split_once(": ");
match parts {
Some(("Content-Length", value)) => {
content_length = Some(value.parse().context("invalid content length")?);
}
Some((_, _)) => {}
None => {
// Workaround: Some non-conformant language servers will output logging and other garbage
// into the same stream as JSON-RPC messages. This can also happen from shell scripts that spawn
// the server. Skip such lines and log a warning.
// warn!("Failed to parse header: {:?}", header);
}
}
}
let content_length = content_length.context("missing content length")?;
//TODO: reuse vector
let mut content = vec![0; content_length];
reader.read_exact(&mut content).await?;
let msg = std::str::from_utf8(&content).context("invalid utf8 from server")?;
info!("<- DAP {}", msg);
// try parsing as output (server response) or call (server request)
let output: serde_json::Result<Payload> = serde_json::from_str(msg);
Ok(output?)
}
async fn recv_server_error(
err: &mut (impl AsyncBufRead + Unpin + Send),
buffer: &mut String,
) -> Result<()> {
buffer.truncate(0);
if err.read_line(buffer).await? == 0 {
return Err(Error::StreamClosed);
};
error!("err <- {}", buffer);
Ok(())
}
async fn send_payload_to_server(
&self,
server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,
mut payload: Payload,
) -> Result<()> {
if let Payload::Request(request) = &mut payload {
if let Some(back) = request.back_ch.take() {
self.pending_requests.lock().await.insert(request.seq, back);
}
}
let json = serde_json::to_string(&payload)?;
self.send_string_to_server(server_stdin, json).await
}
async fn send_string_to_server(
&self,
server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,
request: String,
) -> Result<()> {
info!("-> DAP {}", request);
// send the headers
server_stdin
.write_all(format!("Content-Length: {}\r\n\r\n", request.len()).as_bytes())
.await?;
// send the body
server_stdin.write_all(request.as_bytes()).await?;
server_stdin.flush().await?;
Ok(())
}
fn process_response(res: Response) -> Result<Response> {
if res.success {
info!("<- DAP success in response to {}", res.request_seq);
Ok(res)
} else {
error!(
"<- DAP error {:?} ({:?}) for command #{} {}",
res.message, res.body, res.request_seq, res.command
);
Err(Error::Other(anyhow::format_err!("{:?}", res.body)))
}
}
async fn process_server_message(
&self,
client_tx: &UnboundedSender<Payload>,
msg: Payload,
) -> Result<()> {
match msg {
Payload::Response(res) => {
let request_seq = res.request_seq;
let tx = self.pending_requests.lock().await.remove(&request_seq);
match tx {
Some(tx) => match tx.send(Self::process_response(res)).await {
Ok(_) => (),
Err(_) => error!(
"Tried sending response into a closed channel (id={:?}), original request likely timed out",
request_seq
),
}
None => {
warn!("Response to nonexistent request #{}", res.request_seq);
client_tx.send(Payload::Response(res)).expect("Failed to send");
}
}
Ok(())
}
Payload::Request(Request {
ref command,
ref seq,
..
}) => {
info!("<- DAP request {} #{}", command, seq);
client_tx.send(msg).expect("Failed to send");
Ok(())
}
Payload::Event(ref event) => {
info!("<- DAP event {:?}", event);
client_tx.send(msg).expect("Failed to send");
Ok(())
}
}
}
async fn recv(
transport: Arc<Self>,
mut server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,
client_tx: UnboundedSender<Payload>,
) {
let mut recv_buffer = String::new();
loop {
match Self::recv_server_message(&mut server_stdout, &mut recv_buffer).await {
Ok(msg) => {
transport
.process_server_message(&client_tx, msg)
.await
.unwrap();
}
Err(err) => {
error!("err: <- {:?}", err);
break;
}
}
}
}
async fn send(
transport: Arc<Self>,
mut server_stdin: Box<dyn AsyncWrite + Unpin + Send>,
mut client_rx: UnboundedReceiver<Payload>,
) {
while let Some(payload) = client_rx.recv().await {
transport
.send_payload_to_server(&mut server_stdin, payload)
.await
.unwrap()
}
}
async fn err(mut server_stderr: Box<dyn AsyncBufRead + Unpin + Send>) {
let mut recv_buffer = String::new();
loop {
match Self::recv_server_error(&mut server_stderr, &mut recv_buffer).await {
Ok(_) => {}
Err(err) => {
error!("err: <- {:?}", err);
break;
}
}
}
}
}

870
helix-dap/src/types.rs Normal file
View File

@@ -0,0 +1,870 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(
Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize,
)]
pub struct ThreadId(isize);
impl std::fmt::Display for ThreadId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
pub type ThreadStates = HashMap<ThreadId, String>;
pub trait Request {
type Arguments: serde::de::DeserializeOwned + serde::Serialize;
type Result: serde::de::DeserializeOwned + serde::Serialize;
const COMMAND: &'static str;
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ColumnDescriptor {
pub attribute_name: String,
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<String>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub ty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<usize>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ExceptionBreakpointsFilter {
pub filter: String,
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_condition: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub condition_description: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DebuggerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_configuration_done_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_function_breakpoints: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_conditional_breakpoints: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_hit_conditional_breakpoints: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_evaluate_for_hovers: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_step_back: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_set_variable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_restart_frame: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_goto_targets_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_step_in_targets_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_completions_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_modules_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_restart_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_exception_options: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_value_formatting_options: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_exception_info_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub support_terminate_debuggee: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub support_suspend_debuggee: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_delayed_stack_trace_loading: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_loaded_sources_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_log_points: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_terminate_threads_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_set_expression: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_terminate_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_data_breakpoints: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_read_memory_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_write_memory_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_disassemble_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_cancel_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_breakpoint_locations_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_clipboard_context: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_stepping_granularity: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_instruction_breakpoints: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_exception_filter_options: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exception_breakpoint_filters: Option<Vec<ExceptionBreakpointsFilter>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_trigger_characters: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub additional_module_columns: Option<Vec<ColumnDescriptor>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supported_checksum_algorithms: Option<Vec<String>>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Checksum {
pub algorithm: String,
pub checksum: String,
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Source {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<PathBuf>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_reference: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub presentation_hint: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sources: Option<Vec<Source>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub adapter_data: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub checksums: Option<Vec<Checksum>>,
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SourceBreakpoint {
pub line: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub column: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hit_condition: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub log_message: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Breakpoint {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<usize>,
pub verified: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<Source>,
#[serde(skip_serializing_if = "Option::is_none")]
pub line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub column: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_column: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub instruction_reference: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<usize>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StackFrameFormat {
#[serde(skip_serializing_if = "Option::is_none")]
pub parameters: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parameter_types: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parameter_names: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parameter_values: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub line: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub module: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub include_all: Option<bool>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StackFrame {
pub id: usize,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<Source>,
pub line: usize,
pub column: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_column: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub can_restart: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub instruction_pointer_reference: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub module_id: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub presentation_hint: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Thread {
pub id: ThreadId,
pub name: String,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Scope {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub presentation_hint: Option<String>,
pub variables_reference: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub named_variables: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub indexed_variables: Option<usize>,
pub expensive: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<Source>,
#[serde(skip_serializing_if = "Option::is_none")]
pub line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub column: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_column: Option<usize>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ValueFormat {
#[serde(skip_serializing_if = "Option::is_none")]
pub hex: Option<bool>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VariablePresentationHint {
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attributes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub visibility: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Variable {
pub name: String,
pub value: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub ty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub presentation_hint: Option<VariablePresentationHint>,
#[serde(skip_serializing_if = "Option::is_none")]
pub evaluate_name: Option<String>,
pub variables_reference: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub named_variables: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub indexed_variables: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory_reference: Option<String>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Module {
pub id: String, // TODO: || number
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<PathBuf>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_optimized: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_user_code: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol_status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol_file_path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub date_time_stamp: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub address_range: Option<String>,
}
pub mod requests {
use super::*;
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeArguments {
#[serde(rename = "clientID", skip_serializing_if = "Option::is_none")]
pub client_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_name: Option<String>,
#[serde(rename = "adapterID")]
pub adapter_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub locale: Option<String>,
#[serde(rename = "linesStartAt1", skip_serializing_if = "Option::is_none")]
pub lines_start_at_one: Option<bool>,
#[serde(rename = "columnsStartAt1", skip_serializing_if = "Option::is_none")]
pub columns_start_at_one: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path_format: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_variable_type: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_variable_paging: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_run_in_terminal_request: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_memory_references: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_progress_reporting: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub supports_invalidated_event: Option<bool>,
}
#[derive(Debug)]
pub enum Initialize {}
impl Request for Initialize {
type Arguments = InitializeArguments;
type Result = DebuggerCapabilities;
const COMMAND: &'static str = "initialize";
}
#[derive(Debug)]
pub enum Launch {}
impl Request for Launch {
type Arguments = Value;
type Result = Value;
const COMMAND: &'static str = "launch";
}
#[derive(Debug)]
pub enum Attach {}
impl Request for Attach {
type Arguments = Value;
type Result = Value;
const COMMAND: &'static str = "attach";
}
#[derive(Debug)]
pub enum Disconnect {}
impl Request for Disconnect {
type Arguments = ();
type Result = ();
const COMMAND: &'static str = "disconnect";
}
#[derive(Debug)]
pub enum ConfigurationDone {}
impl Request for ConfigurationDone {
type Arguments = ();
type Result = ();
const COMMAND: &'static str = "configurationDone";
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SetBreakpointsArguments {
pub source: Source,
#[serde(skip_serializing_if = "Option::is_none")]
pub breakpoints: Option<Vec<SourceBreakpoint>>,
// lines is deprecated
#[serde(skip_serializing_if = "Option::is_none")]
pub source_modified: Option<bool>,
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SetBreakpointsResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub breakpoints: Option<Vec<Breakpoint>>,
}
#[derive(Debug)]
pub enum SetBreakpoints {}
impl Request for SetBreakpoints {
type Arguments = SetBreakpointsArguments;
type Result = SetBreakpointsResponse;
const COMMAND: &'static str = "setBreakpoints";
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ContinueArguments {
pub thread_id: ThreadId,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ContinueResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub all_threads_continued: Option<bool>,
}
#[derive(Debug)]
pub enum Continue {}
impl Request for Continue {
type Arguments = ContinueArguments;
type Result = ContinueResponse;
const COMMAND: &'static str = "continue";
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StackTraceArguments {
pub thread_id: ThreadId,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_frame: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub levels: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<StackFrameFormat>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StackTraceResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub total_frames: Option<usize>,
pub stack_frames: Vec<StackFrame>,
}
#[derive(Debug)]
pub enum StackTrace {}
impl Request for StackTrace {
type Arguments = StackTraceArguments;
type Result = StackTraceResponse;
const COMMAND: &'static str = "stackTrace";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadsResponse {
pub threads: Vec<Thread>,
}
#[derive(Debug)]
pub enum Threads {}
impl Request for Threads {
type Arguments = ();
type Result = ThreadsResponse;
const COMMAND: &'static str = "threads";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ScopesArguments {
pub frame_id: usize,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ScopesResponse {
pub scopes: Vec<Scope>,
}
#[derive(Debug)]
pub enum Scopes {}
impl Request for Scopes {
type Arguments = ScopesArguments;
type Result = ScopesResponse;
const COMMAND: &'static str = "scopes";
}
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VariablesArguments {
pub variables_reference: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub count: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<ValueFormat>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VariablesResponse {
pub variables: Vec<Variable>,
}
#[derive(Debug)]
pub enum Variables {}
impl Request for Variables {
type Arguments = VariablesArguments;
type Result = VariablesResponse;
const COMMAND: &'static str = "variables";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StepInArguments {
pub thread_id: ThreadId,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_id: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub granularity: Option<String>,
}
#[derive(Debug)]
pub enum StepIn {}
impl Request for StepIn {
type Arguments = StepInArguments;
type Result = ();
const COMMAND: &'static str = "stepIn";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StepOutArguments {
pub thread_id: ThreadId,
#[serde(skip_serializing_if = "Option::is_none")]
pub granularity: Option<String>,
}
#[derive(Debug)]
pub enum StepOut {}
impl Request for StepOut {
type Arguments = StepOutArguments;
type Result = ();
const COMMAND: &'static str = "stepOut";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NextArguments {
pub thread_id: ThreadId,
#[serde(skip_serializing_if = "Option::is_none")]
pub granularity: Option<String>,
}
#[derive(Debug)]
pub enum Next {}
impl Request for Next {
type Arguments = NextArguments;
type Result = ();
const COMMAND: &'static str = "next";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PauseArguments {
pub thread_id: ThreadId,
}
#[derive(Debug)]
pub enum Pause {}
impl Request for Pause {
type Arguments = PauseArguments;
type Result = ();
const COMMAND: &'static str = "pause";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EvaluateArguments {
pub expression: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub frame_id: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub format: Option<ValueFormat>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EvaluateResponse {
pub result: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub ty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub presentation_hint: Option<VariablePresentationHint>,
pub variables_reference: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub named_variables: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub indexed_variables: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub memory_reference: Option<String>,
}
#[derive(Debug)]
pub enum Evaluate {}
impl Request for Evaluate {
type Arguments = EvaluateArguments;
type Result = EvaluateResponse;
const COMMAND: &'static str = "evaluate";
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SetExceptionBreakpointsArguments {
pub filters: Vec<String>,
// pub filterOptions: Option<Vec<ExceptionFilterOptions>>, // needs capability
// pub exceptionOptions: Option<Vec<ExceptionOptions>>, // needs capability
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SetExceptionBreakpointsResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub breakpoints: Option<Vec<Breakpoint>>,
}
#[derive(Debug)]
pub enum SetExceptionBreakpoints {}
impl Request for SetExceptionBreakpoints {
type Arguments = SetExceptionBreakpointsArguments;
type Result = SetExceptionBreakpointsResponse;
const COMMAND: &'static str = "setExceptionBreakpoints";
}
// Reverse Requests
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RunInTerminalResponse {
#[serde(skip_serializing_if = "Option::is_none")]
pub process_id: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub shell_process_id: Option<u32>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RunInTerminalArguments {
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
pub cwd: String,
pub args: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub env: Option<HashMap<String, Option<String>>>,
}
#[derive(Debug)]
pub enum RunInTerminal {}
impl Request for RunInTerminal {
type Arguments = RunInTerminalArguments;
type Result = RunInTerminalResponse;
const COMMAND: &'static str = "runInTerminal";
}
}
// Events
pub mod events {
use super::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "event", content = "body")]
// seq is omitted as unused and is not sent by some implementations
pub enum Event {
Initialized,
Stopped(Stopped),
Continued(Continued),
Exited(Exited),
Terminated(Option<Terminated>),
Thread(Thread),
Output(Output),
Breakpoint(Breakpoint),
Module(Module),
LoadedSource(LoadedSource),
Process(Process),
Capabilities(Capabilities),
// ProgressStart(),
// ProgressUpdate(),
// ProgressEnd(),
// Invalidated(),
Memory(Memory),
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Stopped {
pub reason: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub thread_id: Option<ThreadId>,
#[serde(skip_serializing_if = "Option::is_none")]
pub preserve_focus_hint: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub all_threads_stopped: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hit_breakpoint_ids: Option<Vec<usize>>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Continued {
pub thread_id: ThreadId,
#[serde(skip_serializing_if = "Option::is_none")]
pub all_threads_continued: Option<bool>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Exited {
pub exit_code: usize,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Terminated {
#[serde(skip_serializing_if = "Option::is_none")]
pub restart: Option<Value>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Thread {
pub reason: String,
pub thread_id: ThreadId,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Output {
pub output: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub line: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub column: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub variables_reference: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<Source>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Breakpoint {
pub reason: String,
pub breakpoint: super::Breakpoint,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Module {
pub reason: String,
pub module: super::Module,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct LoadedSource {
pub reason: String,
pub source: super::Source,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Process {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub system_process_id: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_local_process: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_method: Option<String>, // TODO: use enum
#[serde(skip_serializing_if = "Option::is_none")]
pub pointer_size: Option<usize>,
}
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Capabilities {
pub capabilities: super::DebuggerCapabilities,
}
// #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
// #[serde(rename_all = "camelCase")]
// pub struct Invalidated {
// pub areas: Vec<InvalidatedArea>,
// pub thread_id: Option<ThreadId>,
// pub stack_frame_id: Option<usize>,
// }
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Memory {
pub memory_reference: String,
pub offset: usize,
pub count: usize,
}
}

32
helix-loader/Cargo.toml Normal file
View File

@@ -0,0 +1,32 @@
[package]
name = "helix-loader"
version = "0.6.0"
description = "A post-modern text editor."
authors = ["Blaž Hrastnik <blaz@mxxn.io>"]
edition = "2021"
license = "MPL-2.0"
categories = ["editor"]
repository = "https://github.com/helix-editor/helix"
homepage = "https://helix-editor.com"
[[bin]]
name = "hx-loader"
path = "src/main.rs"
[dependencies]
anyhow = "1"
serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
etcetera = "0.4"
tree-sitter = "0.20"
once_cell = "1.13"
log = "0.4"
# TODO: these two should be on !wasm32 only
# cloning/compiling tree-sitter grammars
cc = { version = "1" }
threadpool = { version = "1.0" }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
libloading = "0.7"

6
helix-loader/build.rs Normal file
View File

@@ -0,0 +1,6 @@
fn main() {
println!(
"cargo:rustc-env=BUILD_TARGET={}",
std::env::var("TARGET").unwrap()
);
}

View File

@@ -0,0 +1,42 @@
/// Default built-in languages.toml.
pub fn default_lang_config() -> toml::Value {
toml::from_slice(include_bytes!("../../languages.toml"))
.expect("Could not parse built-in languages.toml to valid toml")
}
/// User configured languages.toml file, merged with the default config.
pub fn user_lang_config() -> Result<toml::Value, toml::de::Error> {
let config = crate::local_config_dirs()
.into_iter()
.chain([crate::config_dir()].into_iter())
.map(|path| path.join("languages.toml"))
.filter_map(|file| {
std::fs::read(&file)
.map(|config| toml::from_slice(&config))
.ok()
})
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.chain([default_lang_config()].into_iter())
.fold(toml::Value::Table(toml::value::Table::default()), |a, b| {
// combines for example
// b:
// [[language]]
// name = "toml"
// language-server = { command = "taplo", args = ["lsp", "stdio"] }
//
// a:
// [[language]]
// language-server = { command = "/usr/bin/taplo" }
//
// into:
// [[language]]
// name = "toml"
// language-server = { command = "/usr/bin/taplo" }
//
// thus it overrides the third depth-level of b with values of a if they exist, but otherwise merges their values
crate::merge_toml_values(b, a, 3)
});
Ok(config)
}

Some files were not shown because too many files have changed in this diff Show More