We clone this type very often in LSP pickers, for example diagnostics
and symbols. We can use a single Arc in many cases to avoid the
unnecessary clones.
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.
Whenever a document is changed helix maps various positions like the
cursor or diagnostics through the `ChangeSet` applied to the document.
Currently, this mapping handles replacements as follows:
* Move position to the left for `Assoc::Before` (start of selection)
* Move position to the right for `Assoc::After` (end of selection)
However, when text is exactly replaced this can produce weird results
where the cursor is moved when it shouldn't. For example if `foo` is
selected and a separate cursor is placed on each character (`s.<ret>`)
and the text is replaced (for example `rx`) then the cursors are moved
to the side instead of remaining in place.
This change adds a special case to the mapping code of replacements:
If the deleted and inserted text have the same (char) length then
the position is returned as if the replacement doesn't exist.
only keep selections invariant under replacement
Keeping selections unchanged if they are inside an exact replacement
is intuitive. However, for diagnostics this is not desirable as
helix would otherwise fail to remove diagnostics if replacing parts
of the document.
The `take_while` should limit the layers to those that can match the
input range so we don't always scan the entire `injection_layers`. We
can limit `depth == 1` layers to those that start before the search
`end`. Deeper layers overlap with shallower layers though so we need
to allow those layers as well in the `take_while`.
For example
```vue
<script setup lang="ts">
const foo = 'bar'.match(/foo/);
const bar = foo;
</script>
```
L2 and L3 are a typescript layer and the `/foo/` part is a small regex
layer. If you used `A-o` before the regex layer you would select the
entire typescript layer. The search in `layer_id_containing_byte_range`
would not consider the typescript layer since the regex layer comes
earlier in `injection_ranges` and that layer's start is after `end`.
The regex layer has a depth of `2` though so the change in this commit
allows scanning through that layer.
Co-authored-by: Pascal Kuthe <pascalkuthe@pm.me>
* feat(languages): update `just` grammar and queries
Bump the
* refactor(syntax): inject shebang by id not name
---------
Co-authored-by: Trevor Gross <tmgross@umich.edu>
The line annotation as implemented in #5420 had two shortcomings:
* It required the height of virtual text lines to be known ahead time
* It checked for line anchors at every grapheme
The first problem made the API impractical to use in practice because
almost all virtual text needs to be softwrapped. For example inline
diagnostics should be softwrapped to avoid cutting off the diagnostic
message (as no scrolling is possible). While more complex virtual text
like side by side diffs must dynamically calculate the number of empty
lines two align two documents (which requires taking account both
softwrap and virtual text). To address this, the API has been
refactored to use a trait.
The second issue caused some performance overhead and unnecessarily
complicated the `DocumentFormatter`. It was addressed by only calling
the trait mentioned above at line breaks (instead of always). This
allows offers additional flexibility to annotations as it offers
the flexibility to align lines (needed for side by side diffs).
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>