aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src
diff options
context:
space:
mode:
authorNathan Vegdahl2021-07-19 05:02:12 +0000
committerNathan Vegdahl2021-07-19 05:02:12 +0000
commite462f32723bb61899a390f438d7d856d87fb7614 (patch)
treee97a9afbf07e2735ba96d62dd5e8f71e1a241fe1 /helix-core/src
parent6c038bb0151c6aeb43fc94bd2dc3d516a71d346c (diff)
parent5292fe0f7df9f1a420744007aa9dd67e7a5a6610 (diff)
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
Diffstat (limited to 'helix-core/src')
-rw-r--r--helix-core/src/comment.rs10
-rw-r--r--helix-core/src/diff.rs56
-rw-r--r--helix-core/src/indent.rs2
-rw-r--r--helix-core/src/syntax.rs2
-rw-r--r--helix-core/src/transaction.rs6
5 files changed, 40 insertions, 36 deletions
diff --git a/helix-core/src/comment.rs b/helix-core/src/comment.rs
index 07f685d8..5d564055 100644
--- a/helix-core/src/comment.rs
+++ b/helix-core/src/comment.rs
@@ -38,18 +38,18 @@ fn find_line_comment(
}
#[must_use]
-pub fn toggle_line_comments(doc: &Rope, selection: &Selection) -> Transaction {
+pub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&str>) -> Transaction {
let text = doc.slice(..);
let mut changes: Vec<Change> = Vec::new();
- let token = "//";
+ let token = token.unwrap_or("//");
let comment = Tendril::from(format!("{} ", token));
for selection in selection {
let start = text.char_to_line(selection.from());
let end = text.char_to_line(selection.to());
let lines = start..end + 1;
- let (commented, skipped, min) = find_line_comment(token, text, lines.clone());
+ let (commented, skipped, min) = find_line_comment(&token, text, lines.clone());
changes.reserve((end - start).saturating_sub(skipped.len()));
@@ -95,14 +95,14 @@ mod test {
assert_eq!(res, (false, vec![1], 2));
// comment
- let transaction = toggle_line_comments(&state.doc, &state.selection);
+ let transaction = toggle_line_comments(&state.doc, &state.selection, None);
transaction.apply(&mut state.doc);
state.selection = state.selection.clone().map(transaction.changes());
assert_eq!(state.doc, " // 1\n\n // 2\n // 3");
// uncomment
- let transaction = toggle_line_comments(&state.doc, &state.selection);
+ let transaction = toggle_line_comments(&state.doc, &state.selection, None);
transaction.apply(&mut state.doc);
state.selection = state.selection.clone().map(transaction.changes());
assert_eq!(state.doc, " 1\n\n 2\n 3");
diff --git a/helix-core/src/diff.rs b/helix-core/src/diff.rs
index 9c1fc999..a83db333 100644
--- a/helix-core/src/diff.rs
+++ b/helix-core/src/diff.rs
@@ -1,6 +1,4 @@
-use ropey::Rope;
-
-use crate::{Change, Transaction};
+use crate::{Rope, Transaction};
/// Compares `old` and `new` to generate a [`Transaction`] describing
/// the steps required to get from `old` to `new`.
@@ -25,34 +23,34 @@ pub fn compare_ropes(old: &Rope, new: &Rope) -> Transaction {
// The current position of the change needs to be tracked to
// construct the `Change`s.
let mut pos = 0;
- let changes: Vec<Change> = diff
- .ops()
- .iter()
- .map(|op| op.as_tag_tuple())
- .filter_map(|(tag, old_range, new_range)| {
- // `old_pos..pos` is equivalent to `start..end` for where
- // the change should be applied.
- let old_pos = pos;
- pos += old_range.end - old_range.start;
+ Transaction::change(
+ old,
+ diff.ops()
+ .iter()
+ .map(|op| op.as_tag_tuple())
+ .filter_map(|(tag, old_range, new_range)| {
+ // `old_pos..pos` is equivalent to `start..end` for where
+ // the change should be applied.
+ let old_pos = pos;
+ pos += old_range.end - old_range.start;
- match tag {
- // Semantically, inserts and replacements are the same thing.
- similar::DiffTag::Insert | similar::DiffTag::Replace => {
- // This is the text from the `new` rope that should be
- // inserted into `old`.
- let text: &str = {
- let start = new.char_to_byte(new_range.start);
- let end = new.char_to_byte(new_range.end);
- &new_converted[start..end]
- };
- Some((old_pos, pos, Some(text.into())))
+ match tag {
+ // Semantically, inserts and replacements are the same thing.
+ similar::DiffTag::Insert | similar::DiffTag::Replace => {
+ // This is the text from the `new` rope that should be
+ // inserted into `old`.
+ let text: &str = {
+ let start = new.char_to_byte(new_range.start);
+ let end = new.char_to_byte(new_range.end);
+ &new_converted[start..end]
+ };
+ Some((old_pos, pos, Some(text.into())))
+ }
+ similar::DiffTag::Delete => Some((old_pos, pos, None)),
+ similar::DiffTag::Equal => None,
}
- similar::DiffTag::Delete => Some((old_pos, pos, None)),
- similar::DiffTag::Equal => None,
- }
- })
- .collect();
- Transaction::change(old, changes.into_iter())
+ }),
+ )
}
#[cfg(test)]
diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs
index 1b36db7b..0ca05fb3 100644
--- a/helix-core/src/indent.rs
+++ b/helix-core/src/indent.rs
@@ -262,8 +262,10 @@ where
file_types: vec!["rs".to_string()],
language_id: "Rust".to_string(),
highlight_config: OnceCell::new(),
+ config: None,
//
roots: vec![],
+ comment_token: None,
auto_format: false,
language_server: None,
indent: Some(IndentationConfiguration {
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index d9bfc16f..dfd7aec3 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -35,6 +35,8 @@ pub struct LanguageConfiguration {
pub scope: String, // source.rust
pub file_types: Vec<String>, // filename ends_with? <Gemfile, rb, etc>
pub roots: Vec<String>, // these indicate project roots <.git, Cargo.toml>
+ pub comment_token: Option<String>,
+ pub config: Option<String>,
#[serde(default)]
pub auto_format: bool,
diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs
index 048839b3..e20e550f 100644
--- a/helix-core/src/transaction.rs
+++ b/helix-core/src/transaction.rs
@@ -473,11 +473,13 @@ impl Transaction {
/// Generate a transaction from a set of changes.
pub fn change<I>(doc: &Rope, changes: I) -> Self
where
- I: IntoIterator<Item = Change> + ExactSizeIterator,
+ I: IntoIterator<Item = Change> + Iterator,
{
let len = doc.len_chars();
- let mut changeset = ChangeSet::with_capacity(2 * changes.len() + 1); // rough estimate
+ let (lower, upper) = changes.size_hint();
+ let size = upper.unwrap_or(lower);
+ let mut changeset = ChangeSet::with_capacity(2 * size + 1); // rough estimate
// TODO: verify ranges are ordered and not overlapping or change will panic.