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%.
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.
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.
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.
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.
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.
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.
* 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>
* 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
* 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
* 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>
* 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?
* 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>
* 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
* 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>'
* 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
* 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
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.
* 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>
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).
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%.
* 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
* add show_subtree command for viewing tree-sitter subtree in Popup
* remove '.slice(..)' from show_subtree command
* name docs and subtree Popups 'hover'
* 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
* 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
* 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
* 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.
* 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
* 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
* 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
* 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`
* 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
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.
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.
* 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
* 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>
* 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>
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)
* 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
* Add typable `goto` command
* Support `:<line-number>` on prompt
* Rename function according to convention
* Directly call into goto_line_number function
* 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>
* 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
* 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
* 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
* 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 cb47f946d7fb62ceda68e7d1692a3914d0be7762.
* 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!
* 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
* 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>
* 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>
* 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`
* 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>
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.
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.
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.