Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Completion #5728

Merged
merged 6 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ signal to the Helix process on Unix operating systems, such as by using the comm
| `auto-save` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal | `false` |
| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant | `400` |
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `completion-replace` | Set to `true` to make completions always replace the entire word and not just the part before the cursor | `false` |
| `auto-info` | Whether to display info boxes | `true` |
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative | `false` |
| `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file | `[]` |
Expand Down
9 changes: 9 additions & 0 deletions helix-core/src/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,15 @@ impl<'a> IntoIterator for &'a Selection {
}
}

impl IntoIterator for Selection {
type Item = Range;
type IntoIter = smallvec::IntoIter<[Range; 1]>;

fn into_iter(self) -> smallvec::IntoIter<[Range; 1]> {
self.ranges.into_iter()
}
}

// TODO: checkSelection -> check if valid for doc length && sorted

pub fn keep_or_remove_matches(
Expand Down
67 changes: 67 additions & 0 deletions helix-core/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use smallvec::SmallVec;

use crate::{Range, Rope, Selection, Tendril};
use std::borrow::Cow;

Expand Down Expand Up @@ -466,6 +468,33 @@ impl Transaction {
self
}

/// Generate a transaction from a set of potentially overlapping changes. The `change_ranges`
/// iterator yield the range (of removed text) in the old document for each edit. If any change
/// overlaps with a range overlaps with a previous range then that range is ignored.
///
/// The `process_change` callback is called for each edit that is not ignored (in the order
/// yielded by `changes`) and should return the new text that the associated range will be
/// replaced with.
///
/// To make this function more flexible the iterator can yield additional data for each change
/// that is passed to `process_change`
pub fn change_ignore_overlapping<T>(
doc: &Rope,
change_ranges: impl Iterator<Item = (usize, usize, T)>,
mut process_change: impl FnMut(usize, usize, T) -> Option<Tendril>,
) -> Self {
let mut last = 0;
let changes = change_ranges.filter_map(|(from, to, data)| {
if from < last {
return None;
}
let tendril = process_change(from, to, data);
last = to;
Some((from, to, tendril))
});
Self::change(doc, changes)
}

/// Generate a transaction from a set of changes.
pub fn change<I>(doc: &Rope, changes: I) -> Self
where
Expand Down Expand Up @@ -513,6 +542,44 @@ impl Transaction {
Self::change(doc, selection.iter().map(f))
}

pub fn change_by_selection_ignore_overlapping(
doc: &Rope,
selection: &Selection,
mut change_range: impl FnMut(&Range) -> (usize, usize),
mut create_tendril: impl FnMut(usize, usize) -> Option<Tendril>,
) -> (Transaction, Selection) {
let mut last_selection_idx = None;
let mut new_primary_idx = None;
let mut ranges: SmallVec<[Range; 1]> = SmallVec::new();
let process_change = |change_start, change_end, (idx, range): (usize, &Range)| {
// update the primary idx
if idx == selection.primary_index() {
new_primary_idx = Some(idx);
} else if new_primary_idx.is_none() {
if idx > selection.primary_index() {
new_primary_idx = last_selection_idx;
} else {
last_selection_idx = Some(idx);
}
}
ranges.push(*range);
create_tendril(change_start, change_end)
};
let transaction = Self::change_ignore_overlapping(
doc,
selection.iter().enumerate().map(|range| {
let (change_start, change_end) = change_range(range.1);
(change_start, change_end, range)
}),
process_change,
);

(
transaction,
Selection::new(ranges, new_primary_idx.unwrap_or(0)),
pascalkuthe marked this conversation as resolved.
Show resolved Hide resolved
)
}

/// Insert text at each selection head.
pub fn insert(doc: &Rope, selection: &Selection, text: Tendril) -> Self {
Self::change_by_selection(doc, selection, |range| {
Expand Down
Loading