Commit graph

134 commits

Author SHA1 Message Date
Michael Davis
cbea11947d
Move LSP inlay hints to the event system 2025-03-27 10:51:39 -04:00
Michael Davis
7e7a98560e
LSP: Eagerly decode request results in the client
Previously the `call` helper (and its related functions) returned a
`serde_json::Value` which was then decoded either later in the client
(see signature help and hover) or by the client's caller. This led to
some unnecessary boilerplate in the client:

    let resp = self.call::<MyRequest>(params);
    Some(async move { Ok(serde_json::from_value(resp.await?)?) })

and in the caller. It also allowed for mistakes with the types. The
workspace symbol request's calling code for example mistakenly decoded a
`lsp::WorkspaceSymbolResponse` as `Vec<lsp::SymbolInformation>` - one of
the untagged enum members (so it parsed successfully) but not the
correct type.

With this change, the `call` helper eagerly decodes the response to a
request as the `lsp::request::Request::Result` trait item. This is
similar to the old helper `request` (which has become redundant and has
been eliminated) but all work is done within the same async block which
avoids some awkward lifetimes. The return types of functions like
`Client::text_document_range_inlay_hints` are now more verbose but it is
no longer possible to accidentally decode as an incorrect type.

Additionally `Client::resolve_code_action` now uses the `call_with_ref`
helper to avoid an unnecessary clone.
2025-03-22 14:40:29 -04:00
Michael Davis
683fac65e7
Refactor DiagnosticProvider as an enum
This resolves a TODO in the core diagnostic module to refactor this
type. It was originally an alias of `LanguageServerId` for simplicity.
Refactoring as an enum is a necessary step towards introducing
"internal" diagnostics - diagnostics emitted by core features such as
a spell checker. Fully supporting this use-case will require further
larger changes to the diagnostic type, but the change to the provider
can be made first.

Note that `Copy` is not derived for `DiagnosticProvider` (as it was
previously because `LanguageServerId` is `Copy`). In the child commits
we will add the `identifier` used in LSP pull diagnostics which is a
string - not `Copy`.
2025-03-22 09:25:29 -04:00
Michael Davis
14cab4ba62
LSP: Gracefully handle partial failures in multi-server LSP requests
This is the same change as 1c9a5bd366 but for:

* document symbols
* workspace symbols
* goto definition/declaration/.../references
* hover

Instead of bailing when one server fails, we log an error and continue
gathering items from the other responses.
2025-03-22 08:54:22 -04:00
Ian Hobson
1c9a5bd366
Show successfully requested code actions after a failed request (#13156)
When requesting code actions from multiple LSP servers,
rather than bailing as soon as an error is encountered,
instead log the error and then keep going so that successful
requests can be presented to the user.
2025-03-21 09:10:24 -05:00
Michael Davis
33c17d48ff
minor: Move 'execute_lsp_command' helper into helix-view
This is a minor move that will make future refactors of code actions
simpler. We should be able to move nearly all code action functionality
into `helix-view`, save UI stuff like the `menu::Item` implementation
and dealings with the compositor.
2025-03-19 09:41:18 -04:00
Michael Davis
fbc0f956b3
minor: Move json deserialization into text_document_hover future
This follows a pattern used in the signature help request for example.
Moving the json deserialization into the return future of
`text_document_hover` makes the types easier for callers to work with.
2025-03-04 12:01:07 -05:00
David Vogt
c98302a543
feat(lsp): add container name as a column in the symbol pickers (#12930) 2025-02-26 17:28:34 -06:00
Michael Davis
d285a8a9e5
LSP: Fix option handling in goto definition/references commands
The language server may return `None` for a definition/reference
request. The parent commits introduced a regression for these commands
when a server did not provide locations. With this change a server may
respond with `null` and its locations will instead not be considered.

Fixes #12732
2025-01-30 11:59:02 -05:00
Michael Davis
1a821ac726
LSP: Support multiple langauge servers for goto references
This refactors goto_reference like the parent commit to query all
language servers supporting the feature.
2025-01-30 10:37:01 -05:00
Michael Davis
f7394d53fd
LSP: Support multiple language servers for goto definition
This covers all goto-definition-like commands: declaration, definition,
type definition and implementation.

Closes #11689

Co-authored-by: j <junglerobba@jngl.one>
2025-01-30 10:36:03 -05:00
Michael Davis
ba116b47a0
LSP commands: Move offset encoding onto the Location type
<https://github.com/helix-editor/helix/pull/11486> introduced a Location
type in the LSP commands module which unified helpers like
`jump_to_location`. This change moves `OffsetEncoding` onto that type.

`SymbolInformationItem` and `PickerDiagnostic` already had fields for
carrying the offset encoding. We would want a similar setup for goto
definition/references as well (for supporting multiple language servers
with that feature) but those use the `Location` type. By moving
`OffsetEncoding` onto `Location` we make future changes to allow
mulitple language servers possible for goto definition/references
features and also simplify some calls for symbols and diagnostics.
2025-01-29 17:25:12 -05:00
kyfanc
9829ac0c02
Cycle through hover results from multiple language servers (#10122)
Co-authored-by: Vladyslav Karasov <36513243+cotneit@users.noreply.github.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2025-01-26 11:24:50 -06:00
Rolo
c1d382a532 fix(lints): clippy 1.84 2025-01-23 15:18:16 -05:00
Michael Davis
606b957172
Replace uses of lsp::Location with a custom Location type
The lsp location type has the lsp's URI type and a range. We can replace
that with a custom type private to the lsp commands module that uses the
core URI type instead.

We can't entirely replace the type with a new Location type in core.
That type might look like:

    pub struct Location {
        uri: crate::Uri,
        range: crate::Range,
    }

But we can't convert every `lsp::Location` to this type because for
definitions, references and diagnostics language servers send documents
which we haven't opened yet, so we don't have the information to convert
an `lsp::Range` (line+col) to a `helix_core::Range` (char indexing).

This cleans up the picker definitions in this file so that they can all
use helpers like `jump_to_location` and `location_to_file_location` for
the picker preview. It also removes the only use of the deprecated
`PathOrId::from_path_buf` function, allowing us to drop the owned
variant of that type in the child commit.
2024-09-03 09:48:32 -04:00
RoloEdits
86aecc96a1
chore: clean up clippy lints (#11377)
Using clippy 1.80.0. Also cleans up some that were windows only.
2024-08-01 06:39:46 +09:00
Pascal Kuthe
8e041c99df
stable sort lsp edits (#11357) 2024-07-29 06:22:28 +09:00
Ingrid
1d0a3d49d3
Consistently maintain view position (#10559)
* replicate t-monaghan's changes

* remove View.offset in favour of Document.view_data.view_position

* improve access patterns for Document.view_data

* better borrow checker wrangling with doc_mut!()

* reintroduce ensure_cursor_in_view in handle_config_events

since we sorted out the borrow checker issues using partial borrows,
there's nothing stopping us from going back to the simpler implementation

* introduce helper functions on Document .view_offset, set_view_offset

* fix rebase breakage
2024-07-23 19:54:00 +02:00
Pascal Kuthe
7283ef881f
only show inline diagnostics after a delay 2024-07-15 16:36:29 +02:00
Michael Davis
a7777b3c11
Accept 'IntoIterator<Item = Column<T, D>>' for picker columns
This allows us to replace any `vec![..]`s of columns where all columns
are static with static slices `[..]`.
2024-07-15 09:31:33 -04:00
Michael Davis
8555248b01
Accept 'IntoIterator<Item = T>' for Picker::new options
`Picker::new` loops through the input options to inject each of them, so
there's no need to collect into an intermediary Vec. This removes some
unnecessary collections. Also, pickers that start with no initial
options can now pass an empty slice instead of an empty Vec.

Co-authored-by: Luis Useche <useche@gmail.com>
2024-07-15 09:31:33 -04:00
Michael Davis
3906f6605f
Avoid allocations in Picker file preview callback
The `FileLocation` and `PathOrId` types can borrow paths rather than
requiring them to be owned. This takes a refactor of the preview
functions and preview internals within `Picker`. With this change we
avoid an unnecessary `PathBuf` clone per render for any picker with a
file preview function (i.e. most pickers).

This refactor is not fully complete. The `PathOrId` is _sometimes_ an
owned `PathBuf`. This is for pragmatic reasons rather than technical
ones. We need a further refactor to introduce more core types like
`Location` in order to eliminate the Cow and only use `&Path`s within
`PathOrId`. This is left for future work as it will be a larger refactor
almost entirely fitting into the LSP commands module and helix-core -
i.e. mostly unrelated to refactoring the `Picker` code itself.

Co-authored-by: Pascal Kuthe <pascalkuthe@pm.me>
2024-07-15 09:31:33 -04:00
Michael Davis
f4a433f855
Convert LSP URIs into custom URIs
This introduces a custom URI type in core meant to be extended later
if we want to support other schemes. For now it's just a wrapper over a
PathBuf. We use this new URI type to firewall `lsp::Url`. This was
previously done in 8141a4a but using a custom URI type is more flexible
and will improve the way Pickers handle paths for previews in the child
commit(s).

Co-authored-by: soqb <cb.setho@gmail.com>
2024-07-15 09:31:33 -04:00
Michael Davis
5622db6798
Remove sym_picker helper fun
The parent commit split out the workspace symbol picker to an inline
definition so the `workspace` parameter is never passed as `true`. We
should consolidate this picker definition into the symbol_picker
function.
2024-07-15 09:31:32 -04:00
Michael Davis
9e31ba5475
Consolidate DynamicPicker into Picker
DynamicPicker is a thin wrapper over Picker that holds some additional
state, similar to the old FilePicker type. Like with FilePicker, we want
to fold the two types together, having Picker optionally hold that
extra state.

The DynamicPicker is a little more complicated than FilePicker was
though - it holds a query callback and current query string in state and
provides some debounce for queries using the IdleTimeout event.
We can move all of that state and debounce logic into an AsyncHook
implementation, introduced here as `DynamicQueryHandler`. The hook
receives updates to the primary query and debounces those events so
that once a query has been idle for a short time (275ms) we re-run
the query.

A standard Picker created through `new` for example can be promoted into
a Dynamic picker by chaining the new `with_dynamic_query` function, very
similar to FilePicker's replacement `with_preview`.

The workspace symbol picker has been migrated to the new way of writing
dynamic pickers as an example. The child commit will promote global
search into a dynamic Picker as well.
2024-07-15 09:31:32 -04:00
Michael Davis
385b398808
Add column configurations for existing pickers
This removes the menu::Item implementations for picker item types and
adds `Vec<Column<T, D>>` configurations.
2024-07-15 09:31:32 -04:00
Michael Davis
f40fca88e0
Refactor Picker in terms of columns
`menu::Item` is replaced with column configurations for each picker
which control how a column is displayed and whether it is passed to
nucleo for filtering. (This is used for dynamic pickers so that we can
filter those items with the dynamic picker callback rather than nucleo.)

The picker has a new lucene-like syntax that can be used to filter the
picker only on certain criteria. If a filter is not specified, the text
in the prompt applies to the picker's configured "primary" column.

Adding column configurations for each picker is left for the child
commit.
2024-07-15 09:31:31 -04:00
Sebastian Poeplau
62655e97f1
Optional history for rename_symbol (#10932)
Fix #10560 by accepting an optional history register for the
rename_symbol command.
2024-06-12 16:44:47 +02:00
Pascal Kuthe
2d6d876a23 fix popup size calculation
Co-authored-by: ath3 <ha05190@protonmail.com>
2024-04-28 11:21:50 -04:00
Pascal Kuthe
b834806dbc use newtype parttern for langauge server id 2024-04-22 12:27:47 +09:00
Evgeniy Tatarkin
07cb24abdd
Respect lsp definition order for code actions (#9590) 2024-04-09 09:28:54 -05:00
Pascal Kuthe
69e07ab61e use slices instead of Rc for virtual text 2024-03-23 15:35:25 +09:00
Michael Davis
8141a4a1ab LSP: Key diagnostics off file path instead of URI
URIs need to be normalized to be comparable. For example a language
server could send a URI for a path containing '+' as '%2B' but we might
encode this in something like 'Document::url' as just '+'. We can
normalize the URI straight into a PathBuf though since this is the only
value we compare these diagnostics URIs against. This also covers
edge-cases like windows drive letter capitalization.
2024-02-26 00:12:43 +09:00
Pascal Kuthe
87a720c3a1
make path changes LSP spec conform (#8949)
Currently, helix implements operations which change the paths of files
incorrectly and inconsistently. This PR ensures that we do the following
whenever a buffer is renamed (`:move` and workspace edits)

* always send did_open/did_close notifications
* send will_rename/did_rename requests correctly
  * send them to all LSP servers not just those that are active for a
    buffer
  * also send these requests for paths that are not yet open in a buffer (if
    triggered from workspace edit).
  * only send these if the server registered interests in the path
* autodetect language, indent, line ending, ..

This PR also centralizes the infrastructure for path setting and
therefore `:w <path>` benefits from similar fixed (but without didRename)
2024-01-29 01:34:45 +09:00
Nick
d8b8d2fda6
Fix error message shown for goto references (#9382) 2024-01-25 14:11:12 +09:00
Pascal Kuthe
8e592a151f refactor completion and signature help using hooks 2024-01-23 11:20:19 +09:00
Michael Davis
1f916e65cf Create helix-stdx crate for stdlib extensions
helix-stdx is meant to carry extensions to the stdlib or low-level
dependencies that are useful in all other crates. This commit starts
with all of the path functions from helix-core and the CWD tracking that
lived in helix-loader.

The CWD tracking in helix-loader was previously unable to call the
canonicalization functions in helix-core. Switching to our custom
canonicalization code should make no noticeable difference though
since `std::env::current_dir` returns a canonicalized path with
symlinks resolved (at least on unix).
2024-01-18 10:57:53 +09:00
Gabriel Dinner-David
84e24b33dc
make sure to sync views when applying edits to unfocused views (#9173) 2024-01-09 10:21:16 +09:00
Michael Davis
0cbd8d3df1
Check for rename support before showing LSP rename prompt (#9277) 2024-01-09 09:55:11 +09:00
ath3
9ba691cd3a
Support drawing popup frame (#4313)
Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
2023-12-19 10:17:12 +09:00
Cole Helbling
8b0ae3d279
bump MSRV to 1.70.0 (#8877)
* rust-toolchain.toml: bump MSRV to 1.70.0

With Firefox 120 released on 21 November 2023, the MSRV is now 1.70.0.

* Fix cargo fmt with Rust 1.70.0

* Fix cargo clippy with Rust 1.70.0

* Fix cargo doc with Rust 1.70.0

* rust-toolchain.toml: add clippy component

* .github: bump dtolnay/rust-toolchain to 1.70

* helix-term: bump rust-version to 1.70

* helix-view/gutter: use checked_ilog10 to count digits

* helix-core/syntax: use MAIN_SEPARATOR_STR constant

* helix-view/handlers/dap: use Display impl for displaying process spawn error

* WIP: helix-term/commands: use checked math to assert ranges cannot overlap
2023-11-25 13:55:49 +01:00
woojiq
aa4d84a0b3
Align view for background buffer opened with alt-ret (#7691)
* fix(picker): `alt-ret' changes cursor pos of current file, not new one

Closes #7673

* fix other pickers

* symbol pickers
* diagnostick pickers

This is done using the already patched `jump_to_location` method.

* fix global and jumplist pickers

* use `view` as old_id; make `align_view` method of `Action`

* test(picker): basic <alt-ret> functionality

* fix: picker integrational test

* fix nit

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

---------

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2023-08-08 15:17:29 +02:00
Philipp Mildenberger
8a28f30593
Reformat with nightly rustfmt for better let-else formatting (#7721) 2023-07-27 11:57:19 +09:00
sigmaSd
8977123f25
feat: resolve code action (#7677) 2023-07-21 14:50:08 -05:00
Yomain
8afc0282f2
Fix crash when cwd is deleted (#7185) 2023-07-11 19:51:04 +02:00
Gokul Soumya
f18acadbd0
Completely remove old Picker and rename FilePicker to Picker 2023-06-18 12:28:26 -05:00
Michael Davis
545acfda88
Make file preview callback optional
When Picker and FilePicker are merged, not all Pickers will be able to
show a preview.

Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
2023-06-18 12:28:16 -05:00
Michael Davis
d4427125eb
Bail if no language servers support workspace symbols (#7286) 2023-06-08 09:48:11 +09:00
Matthew Toohey
207829eefe
Fix off-by-one in select symbol references (#7132) 2023-05-25 14:01:56 +02:00
Philipp Mildenberger
2b746ea6fa Some minor clarity/cosmetic improvements
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
2023-05-18 22:04:49 +02:00