Commit Graph

769 Commits

Author SHA1 Message Date
Mike Trinkala
9267343830
Fix panic when using surround_replace/delete (#9796)
1. Create a document containing `{A}`
1. C-w v # vsplit
1. gl    # goto_line_end
1. b     # move_prev_word_start
1. `     # switch_to_lowercase
1. mrm(  # surround replace
1. C-w v # vsplit

In the debug build surround_replace/delete will immedately assert with
`assertion failed: last <= from', transaction.rs:597:13`. The splits and
lowercase conversion are not needed to trigger the bug.

In the release build the surround becomes `)a(` and the last vsplit
causes the transaction to panic.
`internal error: entered unreachable code:
(Some(Retain(18446744073709551573)))', transaction.rs:185:46`

Since the selection direction is backwards get_surround_pos returns the
pairs reversed but the downstream code assumes they are in the forward
direction.
2024-03-03 18:55:09 +01:00
Pascal Kuthe
1143f47954
fix split_on_newline (#9756) 2024-02-29 10:47:41 +09:00
Gabriel Dinner-David
26b3dc29be
toggling of block comments (#4718) 2024-02-27 22:36:25 +09:00
Pascal Kuthe
cd02976fa3
switch to regex-cursor (#9422) 2024-02-26 16:45:20 +09:00
kyfanc
fe869e5dc7
fix lsp config reload (#9415)
`syn_loader` was replaced rather than interior value being replace,
old value was still being referenced and not updated after `:config-refresh`.
By using `ArcSwap` like for `config`, each `.load()` call will return the most
updated value.

Co-authored-by: kyfan <kyfan@email>
2024-02-13 11:58:53 +01:00
ontley
6a90166d0a
Add required-root-patterns for situational lsp activation (#8696)
* Added required-root-patterns for situational lsp activation using globbing

* Replaced filter_map with flatten

* updated book to include required-root-patterns option

* fixed wrong function name for path

* Added globset to helix-core. Moved globset building to config parsing.

* Normalize implements AsRef

* cargo fmt

* Revert "cargo fmt"

This reverts commit ca8ce123e8.
2024-02-12 02:35:25 +01:00
Galen Abell
581a1ebf5d
Add glob file type support (#8006)
* Replace FileType::Suffix with FileType::Glob

Suffix is rather limited and cannot be used to match files which have
semantic meaning based on location + file type (for example, Github
Action workflow files). This patch adds support for a Glob FileType to
replace Suffix, which encompasses the existing behavior & adds
additional file matching functionality.

Globs are standard Unix-style path globs, which are matched against the
absolute path of the file. If the configured glob for a language is a
relative glob (that is, it isn't an absolute path or already starts with
a glob pattern), a glob pattern will be prepended to allow matching
relative paths from any directory.

The order of file type matching is also updated to first match on globs
and then on extension. This is necessary as most cases where
glob-matching is useful will have already been matched by an extension
if glob matching is done last.

* Convert file-types suffixes to globs

* Use globs for filename matching

Trying to match the file-type raw strings against both filename and
extension leads to files with the same name as the extension having the
incorrect syntax.

* Match dockerfiles with suffixes

It's common practice to add a suffix to dockerfiles based on their
context, e.g. `Dockerfile.dev`, `Dockerfile.prod`, etc.

* Make env filetype matching more generic

Match on `.env` or any `.env.*` files.

* Update docs

* Use GlobSet to match all file type globs at once

* Update todo.txt glob patterns

* Consolidate language Configuration and Loader creation

This is a refactor that improves the error handling for creating
the `helix_core::syntax::Loader` from the default and user language
configuration.

* Fix integration tests

* Add additional starlark file-type glob

---------

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2024-02-11 18:24:20 +01:00
Michael Davis
035b8eabdb Respect injections in movement::move_parent_node_end 2024-01-28 18:13:33 +09:00
Michael Davis
5e0b3cc28b Use injection syntax trees for bracket matching
Previously we used the root syntax tree for bracket matching. We can use
the new functionality in `Syntax` for finding the correct syntax tree
for a given byte range though so we use the correct syntax tree within
injections. This improves bracket matching behavior within HTML
injections like script or style tags for example.
2024-01-28 18:13:33 +09:00
Michael Davis
cda8ea991e
highlighting: Gate multiple captures behind #is-not? local predicates (#9390) 2024-01-25 14:10:58 +09:00
Matthew Toohey
f5f08becef
Fix typo in string representation of GotoReference (#9395) 2024-01-22 23:06:20 +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
Michael Davis
eca3ccff76
Select subtree within injections in :tree-sitter-subtree (#9309)
`:tree-sitter-subtree` could previously only print subtrees of nodes
in the root injection layer. We can improve on that by finding the layer
that contains the given byte range and printing the subtree within that
layer. That gives more useful results when a selection is within an
injection layer.
2024-01-15 15:34:38 +09:00
Michael Davis
3011df4f35
Bump tree-sitter to latest master (#9317)
* query capture names now return `&str`s rather than `String`s
* the `#any-of?` predicate is now supported
2024-01-15 15:33:26 +09:00
Pascal Kuthe
445f7a273a ignore empty TS nodes in match bracket 2024-01-15 15:32:07 +09:00
Pascal Kuthe
2fb7e50b54 don't crash in plaintext bracket match (mm) on empty file 2024-01-15 15:32:07 +09:00
woojiq
3f88a3f4e6
Change path normalization strategy to not resolve symlinks (#9330) 2024-01-14 08:46:32 -06:00
Philipp Mildenberger
41ca46cf8c
Initialize diagnostics when opening a document (#8873) 2024-01-09 10:01:04 +09:00
Pascal Kuthe
515ef17207 make diagnostics stick to word boundaries
Diagnostics are currently extended if text is inserted at their end. This is
desirable when inserting text after an identifier. For example consider:

let foo = 2;
    --- unused variable

Renaming the identifier should extend the diagnostic:

let foobar = 2;
    ------ unused variable

This is currently implemented in helix but as a consequence adding whitespaces
or a type hint also extends the diagnostic:

let foo      = 2;
    -------- unused variable
let foo: Bar = 2;
    -------- unused variable

In these cases the diagnostic should remain unchanged:

let foo      = 2;
    --- unused variable
let foo: Bar = 2;
    --- unused variable

As a heuristic helix will now only extend diagnostics that end on a word char
if new chars are appended to the word (so not for punctuation/ whitespace).
The idea for this mapping was inspired for the word level tracking vscode uses
for many positions. While VSCode doesn't currently update diagnostics after
receiving publishDiagnostic it does use this system for inlay hints for example.
Similarly, the new association mechanism implemented here can be used for word
level tracking of inlay hints.

A similar mapping function is implemented for word starts. Together
these can be used to make a diagnostic stick to a word. If that word
is removed that diagnostic is automatically removed too. This is the exact
same behavior VSCode inlay hints eixibit.
2023-12-27 15:28:14 +09:00
Pascal Kuthe
8653e1b02f Add config to mark diagnostic sources as persistent 2023-12-27 15:28:14 +09:00
TornaxO7
914c83420b
fix :indent-style crash (#9087)
* removing unreachable statement in `:indent-style`

* update checks when setting indent line and update docs

* `cargo xtask docgen`
2023-12-15 19:05:04 +01:00
Daniel Ebert
723a132bdf Simplify implementation of add_indent_level.
Increase hybrid indent heuristic attempt limit to 4.
Clarify the fallback logic in indent heuristic docs.
2023-12-15 15:59:54 +09:00
Daniel Ebert
938a710904 Make the indent heuristic configurable 2023-12-15 15:59:54 +09:00
Daniel Ebert
559bfc1f5e Improve relative indent computation.
Add tests to ensure that relative & absolute indent computation are consistent.
2023-12-15 15:59:54 +09:00
Daniel Ebert
d29a66f267 Implement relative indent queries,
i.e. also take into account the indentation of a previous
line when computing the indentation for a new line.
2023-12-15 15:59:54 +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
Michael Davis
8b2d97eb56 Default 'roots' field of language config
Previously roots needed to be specified by every language and `[]` was
used as an explicit default. Root files don't make sense for every
language (for example TOML) so I think we should allow languages to
not explicitly mention the key and have the `[]` default automatically.
2023-11-14 11:56:53 +09:00
Triton171
ef0c31db02
Fix precedence order of @align captures in indent computation (#8659)
precedence when multiple occur on the same line in an indent query.
2023-10-29 17:48:58 +01:00
Blaž Hrastnik
5ce1c30f77
Revert "Pin tree-sitter to the 0.20.10 release (#8396)"
We only reverted so that the latest release would use a stable
tree-sitter version hosted on crates.io. We do want the improvements
on nightly.

This reverts commit 2ebcc4dbeb.
2023-10-26 15:58:10 +09:00
Michael Davis
2ebcc4dbeb
Pin tree-sitter to the 0.20.10 release (#8396) 2023-10-26 01:08:46 +09:00
Stephen Seo
31f50bf5bf
don't break on hyphen with :reflow (#8569) 2023-10-21 07:58:36 -05:00
Alexis Mousset
83ac53a109
Fix various typos (#8233) 2023-09-10 15:31:12 -05:00
Pascal Kuthe
e6cdc5f9d3
Don't use word splitting during fuzzy matching (#8192) 2023-09-06 23:03:48 +09:00
Pascal Kuthe
0cb595e226
transition to nucleo for fuzzy matching (#7814)
* transition to nucleo for fuzzy matching

* drop flakey test case

since the picker streams in results now any test that relies
on the picker containing results is potentially flakely

* use crates.io version of nucleo

* Fix typo in commands.rs

Co-authored-by: Skyler Hawthorne <skyler@dead10ck.com>

---------

Co-authored-by: Skyler Hawthorne <skyler@dead10ck.com>
2023-08-30 13:26:21 +09:00
nkitsaini
22f4f313f1
Remove unnecessary Err from get_canonicalized_path (#8009)
Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2023-08-20 21:11:32 +02:00
Michael Davis
01a1e5ec2a
Update tree-sitter to latest master (#7998) 2023-08-20 00:21:18 +09:00
Dillard Robertson
01776e6851
Prevent GraphemeStrs created from Strings from leaking (#7920) 2023-08-12 20:13:06 -05:00
Daniel Ebert
eab0d4fa4b Implement @align (and @anchor) indent query. 2023-08-11 23:44:02 +09:00
Skyler Hawthorne
7078e84007 Fix YAML auto indent
YAML indents queries are tweaked to fix auto indent behavior.

A new capture type `indent.always` is introduced to address use cases
where combining indent captures on a single line is desired.

Fixes #6661
2023-08-11 06:22:22 +09:00
Skyler Hawthorne
93acb53812 add node boundary movement 2023-08-01 09:41:42 -05:00
Michael Davis
baceb02a09 Use refactored Registers type
This is an unfortunately noisy change: we need to update virtually all
callsites that access the registers. For reads this means passing in the
Editor and for writes this means handling potential failure when we
can't write to a clipboard register.
2023-07-31 15:05:38 +09:00
Michael Davis
da2afe7353 Add '#' and '.' special registers
These come from Kakoune:

* '#' is the selection index register. It's read-only and produces the
  selection index numbers, 1-indexed.
* '.' is the selection contents register. It is also read-only and
  mirrors the contents of the current selections when read.

We switch the iterators returned from Selection's `fragments` and
`slices` methods to ExactSizeIterators because:

* The selection contents register can simply return the fragments
  iterator.
* ExactSizeIterator is already implemented for iterators over Vecs, so
  it's essentially free.
* The `len` method can be useful on its own.
2023-07-31 15:05:38 +09:00
Philipp Mildenberger
8a28f30593
Reformat with nightly rustfmt for better let-else formatting (#7721) 2023-07-27 11:57:19 +09:00
Michael Davis
98ef05d768 Prefer RopeSlice to &Rope in helix_core::syntax
Pascal and I discussed this and we think it's generally better to
take a 'RopeSlice' rather than a '&Rope'. The code block rendering
function in the markdown component module is a good example for how
this can be useful: we can remove an allocation of a rope and instead
directly turn a '&str' into a 'RopeSlice' which is very cheap.

A change to prefer 'RopeSlice' to '&Rope' whenever the rope isn't
modified would be nice, but it would be a very large diff (around 500+
500-). Starting off with just the syntax functions seems like a nice
middle-ground, and we can remove a Rope allocation because of it.

Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
2023-07-27 11:50:19 +09:00
Pascal Kuthe
68a98ac36b use a single query for injections
In the past we used two separate queries for combined and normal injections. There was no real reason for this (except historical/slightly easier implementation). Instead, we now use a single query and simply check if an injection corresponds to a combined injection or not.
2023-07-17 14:08:50 +09:00
Pascal Kuthe
2d5ff9ec8f fix crash when encountering overlapping injections 2023-07-17 14:08:50 +09:00
Yomain
8afc0282f2
Fix crash when cwd is deleted (#7185) 2023-07-11 19:51:04 +02:00
Pascal Kuthe
1adb19464f
search buffer contents during global search (#5652) 2023-07-11 21:26:11 +09:00
Pascal Kuthe
4a2337d828
correctly map unsorted positions (#7471)
* correctly map unsorted positions

* Fix typo

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

---------

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2023-06-28 23:35:31 +09:00
Pascal Kuthe
b33516fb16 move normalize fastpath into normalize function 2023-06-26 01:32:31 +09:00
Pascal Kuthe
d491e234f4 map positions through changes in O(N) 2023-06-26 01:32:31 +09:00
Scott Driggers
93ac706844
Allow any indent size from 1 to 16 (#7429) 2023-06-23 23:36:02 +09:00
Pascal Kuthe
a0359f7f22 make TS matching fallback to plaintext 2023-06-22 16:00:08 +09:00
Pascal Kuthe
5dba649d81 Avoid false positives in non-fuzzy bracket match 2023-06-22 16:00:08 +09:00
Pascal Kuthe
37058e0401 match pairs which don't form a standalone TS node 2023-06-22 16:00:08 +09:00
A-Walrus
eb81cf3c01
Fix tree sitter chunking (#7417)
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...
2023-06-21 09:52:42 -05:00
Alex
3fb9fafb2a
Add config for default line ending (#5621) 2023-06-16 12:02:15 -05:00
A-Walrus
a4a86120e8
Fix next/prev tree-sitter inconsistency (#7332)
* 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
2023-06-13 16:04:11 +02:00
vwkd
352d1574a6
add move_prev_long_word_end and extend_prev_long_word_end (#6905) 2023-06-08 00:41:35 +02:00
Ilya Sovtsov
77e9a22aff
Add check for a non-zero value for tab width (#7178) 2023-06-07 17:51:29 +09:00
Alex Vinyals
a2b8cfdb8c
feat(core): add plaintext matching fallback to tree-sitter matching (#4288) 2023-06-05 23:13:00 +09:00
Ikko Eltociear Ashimine
349e2b5f0e
Fix typo in syntax.rs (#7114)
seperator -> separator
2023-05-26 10:45:15 +02:00
Szabin
70e4cdbd8e
Add command to merge non-consecutive ranges (#7053)
* 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`
2023-05-20 01:31:39 +02:00
Philipp Mildenberger
2eeac10755 Refactor doc language servers to a HashMap, and the config to use a Vec to retain order 2023-05-18 21:48:32 +02:00
Philipp Mildenberger
ec2f9091a0 Simplify Display implementation for LanguageServerFeature 2023-05-18 21:48:32 +02:00
Philipp Mildenberger
76b5cab524 Refactored doc.language_servers and doc.language_servers_with_feature to return an iterator and refactor LanguageServerFeature handling to a HashMap (language server name maps to features)
Co-authored-by: Pascal Kuthe <pascal.kuthe@semimod.de>
2023-05-18 21:48:32 +02:00
Philipp Mildenberger
19f88fc577 Simplify Display implementation of LanguageServerFeature
Co-authored-by: Ivan Tham <pickfire@riseup.net>
2023-05-18 21:48:32 +02:00
Philipp Mildenberger
71551d395b Adds support for multiple language servers per language.
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.
2023-05-18 21:48:30 +02:00
Pascal Kuthe
b0705337be automatically disable TS when parsing takes longer than 500ms 2023-05-18 15:23:37 +09:00
Pascal Kuthe
25d4ebe30d don't move cursor while forward deleting in append mode
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
2023-05-18 15:20:55 +09:00
Pascal Kuthe
f8225ed921 fix panic when deleting overlapping ranges
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`.
2023-05-18 15:20:55 +09:00
ZJPzjp
3b8c15618f
Fix warnings from clippy (#7013)
* Fix warnings from clippy

* revert MAIN_SEPARATOR_STR
2023-05-11 14:44:52 +09:00
Timothy DeHerrera
9c6c63a2be
inject language based on file extension & shebang (#3970)
* 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
2023-04-28 18:21:34 +09:00
jorge
204d1eba4b
feat(commands): add clear-register typable command (#5695)
Co-authored-by: Jorge <chorcheus@tutanota.com>
2023-04-27 21:57:05 +02:00
ymgyt
61ff2bc094
return early if soft wrap is invalid (#6856) 2023-04-23 08:24:17 -05:00
Blaž Hrastnik
58e457a4e1
Revert "Fix #6605: Remove soft-wrap.enable option wrapping. (#6656)"
This caused a bug that would ignore the global config.

This reverts commit af88a3c15c.
2023-04-08 21:52:34 +09:00
gibbz00
af88a3c15c
Fix #6605: Remove soft-wrap.enable option wrapping. (#6656)
Co-authored-by: gibbz00 <gabrielhansson@gmail.com>
2023-04-08 21:18:11 +09:00
Daniel Sedlak
e856906f76
Fix typos (#6643) 2023-04-07 23:10:38 +08:00
jazzfool
d04288e0f3
Canonicalize paths before stripping current dir as prefix (#6290)
Co-authored-by: jazzfool <shamoslover69@gmail.com>
2023-03-30 11:21:40 -05:00
Pascal Kuthe
2d10a429eb add workspace config and manual LSP root management
fixup documentation

Co-authored-by: LeoniePhiline <22329650+LeoniePhiline@users.noreply.github.com>

fixup typo

Co-authored-by: LeoniePhiline <22329650+LeoniePhiline@users.noreply.github.com>
2023-03-29 12:57:30 +09:00
Philipp Mildenberger
198ff2c3f9
Fix clippy lints (#6454) 2023-03-27 18:33:55 -05:00
Pascal Kuthe
2af14a24ab respect line annotations in char_idx_at_visual_row_offset
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.
2023-03-27 09:54:40 +09:00
Pascal Kuthe
7cf448eb5b use partition_point instead of binary_search_by
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.
2023-03-27 09:54:40 +09:00
Pascal Kuthe
72b9311678 fix view anchors not at start of a visual line
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.
2023-03-27 09:54:40 +09:00
dependabot[bot]
52ced7e85f
build(deps): bump bitflags from 1.3.2 to 2.0.2 (#6387)
* 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>
2023-03-22 08:12:08 +08:00
Skyler Hawthorne
d3b051d28e fix test::plain
test::plain uses char indices when it should use byte indices
2023-03-20 18:34:40 -05:00
Skyler Hawthorne
58ea193054 Allow explicit newlines in test DSL
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.
2023-03-20 18:34:40 -05:00
Stanisław Borowy
39052433ed
Fix indentation level calculation for lines mixing tabs and spaces (#6278) 2023-03-12 12:12:06 -05:00
Poliorcetics
bdcd4d9411
Feat: LSP Type Hints (#5934)
* 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
2023-03-11 11:32:14 +09:00
Pascal Kuthe
2b64a64d7e Add API to create a Transaction from potentially overlapping changes
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.
2023-03-10 16:54:17 +09:00
Pascal Kuthe
e91289fda1 Add IntoIterator implementation for Selection 2023-03-10 16:54:17 +09:00
gibbz00
2cf4ce2356
Fix shrink_selection with multiple cursors. (#6093)
* 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.
2023-03-09 13:08:28 +09:00
Kyle Smith
3849ca4c2a
Add test cases for existing pair matching logic. (#6027)
* Add test cases for existing pair matching logic.

* fix clippy
2023-03-08 11:10:55 +09:00
Clément Delafargue
8dd1ab4899
Softwrapping improvements (#5893)
* 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 b247d526d6.

* 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>
2023-03-08 11:02:11 +09:00
Urgau
ec6e575a40 Correctly handle multiple cursors with LSP snippets 2023-03-08 10:48:35 +09:00
Alexandr
8043959265
Doc string fix in selection.rs (#6077)
* Doc string fix

Delete duplicate `the`

* selection.rs doc string wording

* Remove extra whitespace at end of doc text

---------

Co-authored-by: Ivan Tham <pickfire@riseup.net>
2023-02-22 21:25:15 +08:00
Triton171
a1a6d5f334
Replace incorrect usages of tab_width with indent_width. (#5918) 2023-02-16 23:47:59 +09:00
Mike Trinkala
ef221abe83
Prevent a panic when uncommenting a line with only a comment token (#5933)
Open a new document `test.rs` and type the following:
`di//<esc><C-c>`

The margin calculation pushes the range out of bounds for the comment
marker when there are no characters (newline) after it.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value:
Char range out of bounds: char range 0..3,
Rope/RopeSlice char length 2', ropey-1.6.0/src/rope.rs:546:37

The debug build catches the error in the transaction: thread 'main'
panicked at 'attempt to subtract with overflow',
helix-core/src/transaction.rs:503:26
2023-02-12 13:13:22 -06:00
Daniel S Poulin
6929a12f29
Make m textobject look for pairs enclosing selections (#3344)
* Make `m` textobject look for pairs enclosing selections

Right now, this textobject only looks for pairs that surround the
cursor. This ensures that the pair found encloses each selection, which
is likely to be intuitively what is expected of this textobject.

* Simplification of match code

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

* Adjust logic for ensuring surround range encloses selection

Prior, it was missing the case where the start of the selection came
before the opening brace. We also had an off-by-one error where if the
end of the selection was on the closing brace it would not work.

* Refactor to search for the open pair specifically to avoid edge cases

* Adjust wording of autoinfo to reflect new functionality

* Implement tests for surround functionality in new integration style

* Fix handling of skip values

* Fix out of bounds error

* Add `ma` version of tests

* Fix formatting of tests

* Reduce indentation levels for readability, and update comments

* Preserve each selection's direction with enclosing pair surround

* Add test case for multiple cursors resulting in overlap

* Mark known failures as TODO

* Make tests multi-threaded or they fail

* Cargo fmt

* Fix typos in integration test comments

---------

Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
2023-02-10 13:52:57 -06:00
Pascal Kuthe
8a3ec443f1
Fix new clippy lints (#5892) 2023-02-09 16:27:08 -06:00