* Fix#6092
Cause were some incorrect assumptions that missed an edge case in the
`Selection.contains()` calculation. Tests were added accordingly.
* Fix Selection.contains() edge-case handling.
Removing the len check short-circuit was the only thing needed as
pointed out by @dead10ck.
Repeating completions currently crates a savepoint when a completion
popup was triggered (so after the request completed). Just like for
normal completions the savepoint must be created at the request.
The occurrence of the completion request was previously not saved in
`last_insert`. To that end a new `InsertEvent::RequestCompletion`
variant has been added. When replayed this event creates a snapshot
that is "actived" by the `TriggerCompletion` event and subsequently
used during any `InsertEvent::CompletiuonApply` events.
Completion requests are computed asynchronously to avoid common micro
freezes while editing. This means that once a completion request
completes, the state of the editor might have changed. Currently,
there is a check to ensure we are still in insert mode. However,
we also need to ensure that the view and document hasn't changed
to avoid accidentally using a savepoint with the wrong view/document.
Furthermore, the editor might request a new completion while the
previous completion request hasn't complemented yet. This can
lead to weird flickering or an outdated completion request replacing
a newer completion that has already completed (the LSP server
is not required to process completion requests in order). This change
also needed to ensure determinism/linear ordering so that completion
popup always correspond to the last completion request.
Fixing autocomplete required moving the document savepoint before the
asynchronous completion request. However, this in turn causes new bugs:
If the completion popup is open, the savepoint is restored when the
popup closes (or another entry is selected). However, at that point
a new completion request might already have been created which
would have replaced the new savepoint (therefore leading to incorrectly
applied complies).
This commit fixes that bug by allowing in arbitrary number of
savepoints to be tracked on the document. The savepoints are reference
counted and therefore remain valid as long as any reference to them
remains. Weak reference are stored on the document and any reference
that can not be upgraded anymore (hence no strong reference remain)
are automatically discarded.
Currently, the selection is not saved/restored when completion
checkpoints are applied. This is usually fine because undoing changes
usually restores maps selections back in insert mode. But this is not
always the case and especially problematic in the presence of
multi-cursor completions (since completions are applied relative to
the selection/cursor) and snippets (which can change the selection)
* LSP: Support textDocument/prepareRename
'textDocument/prepareRename' can be used by the client to ask the
server the range of the symbol under the cursor which would be changed
by a subsequent call to 'textDocument/rename' with that position.
We can use this information to fill the prompt with an accurate prefill
which can improve the UX for renaming symbols when the symbol doesn't
align with the "word" textobject. (We currently use the "word"
textobject as a default value for the prompt.)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* clippy fixes
* rustfmt
* Update helix-term/src/commands/lsp.rs
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* Update helix-term/src/commands/lsp.rs
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* fix clippy from suggestions
* Update helix-term/src/commands/lsp.rs
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
---------
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* use max_line_width + 1 during softwrap to account for newline char
Helix softwrap implementation always wraps lines so that the newline
character doesn't get cut off so he line wraps one chars earlier then
in other editors. This is necessary, because newline chars are always
selecatble in helix and must never be hidden.
However That means that `max_line_width` currently wraps one char
earlier than expected. The typical definition of line width does not
include the newline character and other helix commands like `:reflow`
also don't count the newline character here.
This commit makes softwrap use `max_line_width + 1` instead of
`max_line_width` to correct the impedance missmatch.
* fix typos
Co-authored-by: Jonathan Lebon <jonathan@jlebon.com>
* Add text-width to config.toml
* text-width: update setting documentation
* rename leftover config item
* remove leftover max-line-length occurrences
* Make `text-width` optional in editor config
When it was only used for `:reflow` it made sense to have a default
value set to `80`, but now that soft-wrapping uses this setting, keeping
a default set to `80` would make soft-wrapping behave more aggressively.
* Allow softwrapping to ignore `text-width`
Softwrapping wraps by default to the viewport width or a configured
`text-width` (whichever's smaller). In some cases we only want to set
`text-width` to use for hard-wrapping and let longer lines flow if they
have enough space. This setting allows that.
* Revert "Make `text-width` optional in editor config"
This reverts commit b247d526d69adf41434b6fd9c4983369c785aa22.
* soft-wrap: allow per-language overrides
* Update book/src/configuration.md
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
* Update book/src/languages.md
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
* Update book/src/configuration.md
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
---------
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
Co-authored-by: Jonathan Lebon <jonathan@jlebon.com>
Co-authored-by: Alex Boehm <alexb@ozrunways.com>
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
* Do not add intermediate lines to jumplist with :<linenum> command.
* Revert jumplist index changes.
* Reduce calculations during update cycle.
* Use jumplist for undo, set jumplist before preview.
* remove some debug logging
* Revert "remove some debug logging"
This reverts commit 5772c4327e7121c53ea0726a4d7333ae1c413ffb.
* Revert "Use jumplist for undo, set jumplist before preview."
This reverts commit f73a1b29824feaf16477b9df547fb28d9db81923.
* Add last_selection, update implementation.
* @pascalkuthe initial feedback
* Ensure ":goto 123" keybinding works as expected.
* fix clippies, prefer expect() for expect last_selection state
This fixes blank row text in a DynamicPicker which is initially given
no options. This can happen for language servers which respond to
the workspace symbol request for an empty query with an empty list
of symbols, and that behavior is somewhat common since returning all
symbols as the spec suggests is very expensive.
For empty options, `Picker::new` calculated the widths of each column
as 0. We can recalculate the column widths when the new options are
set to fix this. This refactor is also a good opportunity to formalize
setting new options on a picker: besides setting the new options and
calculating column widths we also want to reset the cursor and rescore
the options.
Previously we did not respond to malformed or unhandled LSP requests.
The JSONRPC spec says that all non-notification requests must have
responses:
> When a rpc call is made, the Server MUST reply with a Response,
> except for in the case of Notifications
(Note that Helix is the "Server" in this case. Also from the spec:
"The Server is defined as the origin of Response objects and the
handler of Request objects.")
So this change sends error replies for requests which can't be parsed
or handled. Request IDs are also now added to the log messages for
unhandled requests.
This moves the `Application::claim_term` and
`helix-term::application::restore_term` functions into the helix-tui
crate. How the terminal should be claimed and restored is a TUI concern
and is implemented differently through different TUI backends.
This cleans out a lot of crossterm and TUI code in Application and
makes it easier to modify claim/restore based on information we query
from the terminal host. The child commit will take advantage of this
to cache the check for whether the host terminal supports the keyboard
enhancement protocol. Without this change, caching that information
takes much more code which is not easily reusable for anything else.
The code to restore the terminal is somewhat duplicated by this patch:
we want to restore the terminal in cases of panics. Panic handler hooks
must live for `'static` and the Application's terminal does not.
This refactors the snippet logic to be largely unaware of the rest of
the document. The completion application logic is moved into
generate_transaction_from_snippet which is extended to support
dynamically computing replacement text.
When accepting a snippet completion we automatically delete the
placeholders for now as doing so manual is quite cumbersome. In the
future we should keep these as a mark + virtual text that is
automatically removed once the cursor moves there.
Add a restart debug session command, which would issue a
[Restart Request][1], if the debugger supports it and a session is
running. It uses the same arguments and requests used to start the
initial session, when recreating it.
It builds upon #5532, making use of the changes to the termination
workflow of a session.
[1]: https://microsoft.github.io/debug-adapter-protocol/specification#Requests_RestartCloses: #5594
Signed-off-by: Filip Dutescu <filip.dutescu@gmail.com>
* Fix lack of space for popup crash
* Fix saturating -> wrapping
* Fix wrapping -> saturating (I am an idiot)
* Remove useless "mut" in helix-tui/src/buffer.rs
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
* Remove redundant bound-check
* Return bound-check back
* Add bound-check for set_style
* Remove set_style bound-check
* Revert bound-check
---------
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
This is a workaround for a freeze when suspending Helix with C-z on
non-Windows systems. The check for the keyboard enhancement protocol
locks up crossterm's internal event reading/polling system by trying to
set up multiple concurrent readers. `input_stream.next()` sets up one
reader looking for regular crossterm events while the
`supports_keyboard_enhancement` query sets up another looking for
internal events. The latter hangs for two seconds or until the former
yields an event. By handling signals first we don't lock up the mutex
by trying to read keyboard events.
Since crossterm 0.26.x, we receive press/release keyboard events on
Windows always. We can ignore the release events though to emulate
the behavior of keyboard input on Windows on crossterm 0.25.x.
When the Kitty Keyboard Protocol is enabled, S-backspace is
distinguished from backspace with no modifiers. This is awkward when
typing because it's very easy to accidentally hold shift and press
backspace temporarily when typing capital letters.
Kakoune (which is also a Kitty Keyboard Protocol application) treats
S-backspace as backspace too:
3150e9b3cd/src/input_handler.cc (L1275)
Check if the stack frames contain the thread id and the frame before
trying to get the frame id. If case any of the two fails to be
found, provide the user with messages to inform them of the issue and
gracefully return.
Closes: #5625
Signed-off-by: Filip Dutescu <filip.dutescu@gmail.com>
Send a `Disconnect` DAP request if the `Terminated` event is received.
According to the specification, if the debugging session was started by
as `launch`, the debuggee should be terminated alongside the session. If
instead the session was started as `attach`, it should not be disposed of.
This default behaviour can be overriden if the `supportTerminateDebuggee`
capability is supported by the adapter, through the `Disconnect` request
`terminateDebuggee` argument, as described in
[the specification][discon-spec].
This also implies saving the starting command for a debug sessions, in
order to decide which behaviour should be used, as well as validating the
capabilities of the adapter, in order to decide what the disconnect should
do.
An additional change made is handling of the `Exited` event, showing a
message if the exit code is different than `0`, for the user to be aware
off the termination failure.
[discon-spec]: https://microsoft.github.io/debug-adapter-protocol/specification#Requests_DisconnectCloses: #4674
Signed-off-by: Filip Dutescu <filip.dutescu@gmail.com>
The completion component has a separate branch for handling the
Escape key but it can use the `ignore_escape_key` helper added for
signature-help instead.
This should not cause a behavior change - it's just cleaning up the
completion component.
* feat(ui): deprecated completions
Mark deprecated completions using strike-through
(CROSSED_OUT modifier). The deprection information
is taken either from the `deprecated` field of the
completion item or from the completion tags.
The field seems to be the older way of passing
the deprecated information and it was already
marked as deprecated for Symbol. In completion
item the field is still valid but it seems that
the LSP is moving in the general direction of using
tags for this kind of information and as such
relying on tags as well seems reasonable and
future-proof.