Previously we removed selections for a closed view on only the
currently focused document. A view might have selections in other
documents though, so the view needs to be removed from all documents.
* Add a test case for updating jumplists across windows
* Apply transactions to all views on history changes
This ensures that jumplist selections follow changes in documents, even
when there are multiple views (for example a split where both windows
edit the same document).
* Leave TODOs for cleaning up View::apply
* Use Iterator::reduce to compose history transactions
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Previously, jumplists could grow unchecked. Every transaction is
applied to jumplist selections to ensure that they are up to date
and within document bounds, so this would cause every edit to become
more expensive as jumplist lengths increased throughout a session.
Setting a maximum number of entries limits the cost.
Vim and Neovim limit their jumplists:
* b298fe6cba/src/structs.h (L141)
* e8cc489acc/src/nvim/mark_defs.h (L57)
Notably, Kakoune does not. In Kakoune, changes are applied to jumplist
entries lazily as you hit `<C-o>`/`<C-i>` though, so Kakoune doesn't
have the same growing cost concerns. Kakoune also does not have a
concept of a View which limits the cost further.
Vim and Neovim limit to 100. This seems unreasonably high to me so I've
set this to 30 to start. We can increase if this is problematically
low.
There is some common code between Editor::focus_next and Editor::focus
that can be eliminated by refactoring Tree::focus_next into a function
that only returns the next ViewId.
* dynamically resize line number gutter width
* removing digits lower-bound, permitting spacer
* removing max line num char limit; adding notes; qualified successors; notes
* updating tests to use new line number width when testing views
* linenr width based on document line count
* using min width of 2 so line numbers relative is useful
* lint rolling; removing unnecessary type parameter lifetime
* merge change resolution
* reformat code
* rename row_styler to style; add int_log resource
* adding spacer to gutters default; updating book config entry
* adding view.inner_height(), swap for loop for iterator
* reverting change of current! to view! now that doc is not needed
* Clamp highlighting range to be within document
This fixes a panic possible when two vsplits of the same document
exist and enough lines are deleted from the document so that one of
the windows focuses past the end of the document.
* Ensure cursor is in view on window change
If two windows are editing the same document, one may delete enough of
the document so that the other window is pointing at a blank page (past
the document end). In this change we ensure that the cursor is within
view whenever we switch to a new window (for example with `<C-w>w`).
* Update helix-term/src/ui/editor.rs
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Most commands that accept an argument show their current value if no
argument is specified. The `:theme` command previously displayed an
error message in the status bar if not provided with an argument:
```
Theme name not provided
```
It now shows the current theme name in the status bar if no argument is
specified.
Signed-off-by: James O. D. Hunt <jamesodhunt@gmail.com>
Signed-off-by: James O. D. Hunt <jamesodhunt@gmail.com>
* Autosave all when the terminal loses focus
* Correct comment on focus config
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
* Need a block_try_flush_writes in all quit_all paths
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
* Fix test::print for Unicode
The print function was not generating correct translations when
the input has Unicode (non-ASCII) in it. This is due to its use of
String::len, which gives the length in bytes, not chars.
* Fix multi-code point auto pairs
The current code for auto pairs is counting offsets by summing the
length of the open and closing chars with char::len_utf8. Unfortunately,
this gives back bytes, and the offset needs to be in chars.
Additionally, it was discovered that there was a preexisting bug where
the selection was not computed correctly in the case that the cursor
was:
1. a single grapheme in width
2. this grapheme was more than one char
3. the direction of the cursor is backwards
4. a secondary range
In this case, the offset was not being added into the anchor. This was
fixed.
* migrate auto pairs tests to integration
* review comments
This was not distinguishing the error types when trying a receive on an empty
receiver, which was erroneously causing the sender to be closed when trying to
flush the writes when there were none
If a document is written with a new path, currently, in the event that
the write fails, the document still gets its path changed. This fixes
it so that the path is not updated unless the write succeeds.
The way that document writes are handled are by submitting them to the
async job pool, which are all executed opportunistically out of order. It
was discovered that this can lead to write inconsistencies when there
are multiple writes to the same file in quick succession.
This seeks to fix this problem by removing document writes from the
general pool of jobs and into its own specialized event. Now when a
user submits a write with one of the write commands, a request is simply
queued up in a new mpsc channel that each Document makes to handle its own
writes. This way, if multiple writes are submitted on the same document,
they are executed in order, while still allowing concurrent writes for
different documents.
Undo/redo/earlier/later call `Document::apply_impl` which applies
transactions to the document. These transactions also need to be
applied to the view as in 0aedef0.
It is easy to forget to call `Document::apply` and/or `View::apply` in
the correct order. This commit introduces a helper function which
closes over both calls.
This change adds View::apply calls for all Document::apply call-sites,
ensuring that changes to a document do not leave invalid entries in
the View's jumplist.
Applying a transaction to a View adjusts the ranges in the jumplist
to ensure that they remain within the text of the document and follow
regular selection invariants (for example, must be have a width of at
least one).
* Implement cursorcolumn
* Add documentation
* Separate column style from line with fallback
* Fallback to cursorcolumn first
* Switch to non-fallback try_get_exact
Add new function `try_get_exact`, which doesn't perform fallback,
and use that instead because the fallback behaviour is being handled
manually.
This change automatically tracks pending text for for commands which use
on-next-key callbacks. For example, `t` will await the next key event
and "t" will be shown in the bottom right-hand corner to show that we're
in a pending state.
Previously, the text for these on-next-key commands needed to be
hard-coded into the command definition which had some drawbacks:
* It was easy to forget to write and clear the pending text.
* If a command was remapped in a custom config, the pending text would
still show the old key.
With this change, pending text is automatically tracked based on the
key events that lead to the command being executed. This works even
when the command is remapped in config and when the on-next-key
callback is nested under some key sequence (for example `mi`).
* Change focus to modified docs on quit
When quitting with modified documents, automatically switch focus to
one of them.
* Update helix-term/src/commands/typed.rs
Co-authored-by: Poliorcetics <poliorcetics@users.noreply.github.com>
* Make it work with buffer-close-all and the like
* Cleanup
Use Cow instead of String, and rename DoesntExist -> DoesNotExist
Co-authored-by: Poliorcetics <poliorcetics@users.noreply.github.com>
* Add option to skip the first indent guide
* reorder skip_first option
* change indent-guides.skip_first to a number
* rename skip -> skip_levels
* add skip_levels to the book
* Update book/src/configuration.md
Co-authored-by: A-Walrus <58790821+A-Walrus@users.noreply.github.com>
* Update helix-term/src/ui/editor.rs
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
Co-authored-by: Robin <robinvandijk@klippa.com>
Co-authored-by: A-Walrus <58790821+A-Walrus@users.noreply.github.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* Add RawTheme to handle inheritance with theme palette
* Add a intermediate step in theme loading
it uses RawTheme struct to load the original ThemePalette, so we can merge it with the inherited one.
* Load default themes via RawThemes, remove Theme deserialization
* Allow naming custom theme same as inherited one
* Remove RawTheme and use toml::Value directly
* Resolve all review changes resulting in a cleaner code
* Simplify return for Loader::load
* Add implementation to avoid extra step for loading of base themes
Underline styles are mutally exclusive and overwrite each other.
Therefore implementing as an modifier lead to incorrect behaviour
when the underline style is overwritten.
For backwards compatability the "underline" modified is retained (but
deprecated). Instead the "underline_style" and "underline_color"
optios should be used to style underlines.
Applying document-change transactions to diagnostic ranges is not stable
with respect to the ordering of diagnostics. This can cause diagnostics
to become temporarily unordered with some edits to a document, which can
eventually break some invariants/assumptions in syntax::merge.
With this change, Document::diagnostics are always sorted.
Currently it is not possible to save a file with a language that
has an external formatter configuration unless the external
formatter is installed, even if the language has a Language Server
configuration capable of auto-format. This change checks that the
external formatter exists before using it to create a formatting
callback.
* 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.
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>