Call as bytes before slicing, that way you can take bytes that aren't
aligned to chars. Should technically also be slightly faster since you
don't have to check alignment...
* Fix next/prev tree-sitter inconsistency
Before there where different results going to next or previous due to
sorting not dealing with multiple captures that start/end at the same
pos. I chose to prefer longer matches.
* Revert unnecessary change
* Add command for merging non-consecutive ranges
* Add `merge_selections` command to book
* Simplify `merge_ranges`
Heeded the advice of @the-mikedavis to stop iterating over all ranges and simply merge the first and the last range, as the invariants of `Selection` guarantee that the list of ranges is always sorted and never empty.
* Clarify doc comment of `merge_ranges`
Language Servers are now configured in a separate table in `languages.toml`:
```toml
[langauge-server.mylang-lsp]
command = "mylang-lsp"
args = ["--stdio"]
config = { provideFormatter = true }
[language-server.efm-lsp-prettier]
command = "efm-langserver"
[language-server.efm-lsp-prettier.config]
documentFormatting = true
languages = { typescript = [ { formatCommand ="prettier --stdin-filepath ${INPUT}", formatStdin = true } ] }
```
The language server for a language is configured like this (`typescript-language-server` is configured by default):
```toml
[[language]]
name = "typescript"
language-servers = [ { name = "efm-lsp-prettier", only-features = [ "format" ] }, "typescript-language-server" ]
```
or equivalent:
```toml
[[language]]
name = "typescript"
language-servers = [ { name = "typescript-language-server", except-features = [ "format" ] }, "efm-lsp-prettier" ]
```
Each requested LSP feature is priorized in the order of the `language-servers` array.
For example the first `goto-definition` supported language server (in this case `typescript-language-server`) will be taken for the relevant LSP request (command `goto_definition`).
If no `except-features` or `only-features` is given all features for the language server are enabled, as long as the language server supports these. If it doesn't the next language server which supports the feature is tried.
The list of supported features are:
- `format`
- `goto-definition`
- `goto-declaration`
- `goto-type-definition`
- `goto-reference`
- `goto-implementation`
- `signature-help`
- `hover`
- `document-highlight`
- `completion`
- `code-action`
- `workspace-command`
- `document-symbols`
- `workspace-symbols`
- `diagnostics`
- `rename-symbol`
- `inlay-hints`
Another side-effect/difference that comes with this PR, is that only one language server instance is started if different languages use the same language server.
Currently, when forward deleting (`delete_char_forward` bound to `del`,
`delete_word_forward`, `kill_to_line_end`) the cursor is moved to the
left in append mode (or generally when the cursor is at the end of the
selection). For example in a document `|abc|def` (|indicates selection)
if enter append mode the cursor is moved to `c` and the selection
becomes: `|abcd|ef`. When deleting forward (`del`) `d` is deleted. The
expectation would be that the selection doesn't shrink so that `del`
again deletes `e` and then `f`. This would look as follows:
`|abcd|ef`
`|abce|f`
`|abcf|`
`|abc |`
This is inline with how other editors like kakoune work.
However, helix currently moves the selection backwards leading to the
following behavior:
`|abcd|ef`
`|abc|ef`
`|ab|ef`
`ef`
This means that `delete_char_forward` essentially acts like
`delete_char_backward` after deleting the first character in append
mode.
To fix the problem the cursor must be moved to the right while deleting
forward (first fix in this commit). Furthermore, when the EOF char is
reached a newline char must be inserted (just like when entering
appendmode) to prevent the cursor from moving to the right
Some deletion operations (especially those that use indentation)
can generate overlapping deletion ranges when using multiple cursors.
To fix that problem a new `Transaction::delete` and
`Transaction:delete_by_selection` function were added. These functions
merge overlapping deletion ranges instead of generating an invalid
transaction. This merging of changes is only possible for deletions
and not for other changes and therefore require its own function.
The function has been used in all commands that currently delete
text by using `Transaction::change_by_selection`.
* inject language based on file extension
Nodes can now be captured with "injection.filename". If this capture
contains a valid file extension known to Helix, then the content will
be highlighted as that language.
* inject language by shebang
Nodes can now be captured with "injection.shebang". If this capture
contains a valid shebang line known to Helix, then the content will
be highlighted as the language the shebang calls for.
* add documentation for language injection
* nix: fix highlights
The `@` is now highlighted properly on either side of the function arg.
Also, extending the phases with `buildPhase = prev.buildPhase + ''''`
is now highlighted properly.
Fix highlighting of `''$` style escapes (requires tree-sitter-nix bump)
Fix `inherit` highlighting.
* simplify injection_for_match
Split out injection pair logic into its own method to make the overall
flow easier to follow.
Also transform the top-level function into a method on a
HighlightConfiguration.
* markdown: add shebang injection query
char_idx_at_visual_row_offset asssumed that a single line/block break
always corresponded to a vertical offset of 1. However conceal can hide
the line break (in which case the certical offset would be 0) and line
annotations (or softwrapped inlay hints at the end of the line) can insert
addtional vertical lines.
To correctly account for these cases we simply compute the visual offset
of the start of the next block from the previous block instead of the
visual offset of the block end. This means that the line breaks at the
end of the block (however many there may be) are automatically included
and we don't need to manually add 1 to the `row_offset` anymore.
Using `partition_point` ensures we always find the first entry.
With binary search it is "random" (deterministic but implementation
specific) which index is retruned if there are multiple equal elements.
`partition_point` was added to the standard library to cover extactly
the usecase here.
The top of a view is marked by a char idx anchor. That char idx is
usually the first character of the visual line it's on. We use a char
index instead of a line index because the view may start in the middle
of a line with soft wrapping. However, it's possible to temporarily
endup in a state where this anchor is not the first character of the
first visual line. This is pretty rare because edits usually happen
inside/after the view. In most cases we handle this case correctly.
However, if the cursor is before the anchor (but still in view)
there can be crashes or visual artifacts. This is caused by the fact
that visual_offset_from_anchor (and the positioning code in view.rs)
incorrectly assumed that the (cursor) position is always after the
view anchor if the cursor is in view. But if the anchor is not the
first character of the first visual line this is not the case anymore.
In that case crashes and visual artifacts are possible. This commit
fixes that problem by changing `visual_offset_from_anchor` (and
callsites) to properly consider that case.
* build(deps): bump bitflags from 1.3.2 to 2.0.2
Bumps [bitflags](https://github.com/bitflags/bitflags) from 1.3.2 to 2.0.2.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/1.3.2...2.0.2)
---
updated-dependencies:
- dependency-name: bitflags
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot] <support@github.com>
* deps: Resolve bitflags 2.0 breaking changes
Bitflags 2.0 release made some breaking changes requiring some small
changes to the Helix codebase.
Almost all of the necessary changes are to manually `#[derive(..)]`
trait implementations which are no longer automatically derived for
all bitflags. All of these were previously automatically derived:
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy]
I have derived the minimum traits for each bitflag type.
The other change was to the `.bits` field. This is now a `.bits()`
method so the usage of this has been updated in the `Borders` type.
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
The current test DSL currently has no way to express being at the end of
a line, save for putting an explicit LF or CRLF inside the `#[|]#`. The
problem with this approach is that it can add unintended extra new lines
if used in conjunction with raw strings, which insert newlines for you.
This is a simple attempt to mitigate this problem. If there is an
explicit newline character at the end of the selection, and then it
is immediately followed by the same newline character at the right end
of the selection, this following newline is removed. This way, one can
express a cursor at the end of a line explicitly.
* misc: missing inline, outdated link
* doc: Add new theme keys and config option to book
* fix: don't panic in Tree::try_get(view_id)
Necessary for later, where we could be receiving an LSP response
for a closed window, in which case we don't want to crash while
checking for its existence
* fix: reset idle timer on all mouse events
* refacto: Introduce Overlay::new and InlineAnnotation::new
* refacto: extract make_job_callback from Context::callback
* feat: add LSP display_inlay_hint option to config
* feat: communicate inlay hints support capabilities of helix to LSP server
* feat: Add function to request range of inlay hint from LSP
* feat: Save inlay hints in document, per view
* feat: Update inlay hints on document changes
* feat: Compute inlay hints on idle timeout
* nit: Add todo's about inlay hints for later
* fix: compute text annotations for current view in view.rs, not document.rs
* doc: Improve Document::text_annotations() description
* nit: getters don't use 'get_' in front
* fix: Drop inlay hints annotations on config refresh if necessary
* fix: padding theming for LSP inlay hints
* fix: tracking of outdated inlay hints should not be dependant on document revision (because of undos and such)
* fix: follow LSP spec and don't highlight padding as virtual text
* config: add some LSP inlay hint configs
This commit adds new functions to `Transaction` that allow creating
edits that might potentially overlap. Any change that overlaps
previous changes is ignored. Furthermore, a utility method is added
that also drops selections associated with dropped changes (for
transactions that are created from a selection).
This is needed to avoid crashes when applying multicursor
autocompletions, as the edit from a previous cursor may overlap
with the next cursor/edit.