aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src')
-rw-r--r--helix-term/src/commands.rs571
1 files changed, 252 insertions, 319 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 5ac83d7b..8bde88a2 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -325,140 +325,111 @@ impl PartialEq for Command {
fn move_char_left(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_horizontally(
- doc.text().slice(..),
- range,
- Direction::Backward,
- count,
- Movement::Move,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_horizontally(text, range, Direction::Backward, count, Movement::Move)
+ });
+ doc.set_selection(view.id, selection);
}
fn move_char_right(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_horizontally(
- doc.text().slice(..),
- range,
- Direction::Forward,
- count,
- Movement::Move,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_horizontally(text, range, Direction::Forward, count, Movement::Move)
+ });
+ doc.set_selection(view.id, selection);
}
fn move_line_up(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_vertically(
- doc.text().slice(..),
- range,
- Direction::Backward,
- count,
- Movement::Move,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_vertically(text, range, Direction::Backward, count, Movement::Move)
+ });
+ doc.set_selection(view.id, selection);
}
fn move_line_down(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_vertically(
- doc.text().slice(..),
- range,
- Direction::Forward,
- count,
- Movement::Move,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_vertically(text, range, Direction::Forward, count, Movement::Move)
+ });
+ doc.set_selection(view.id, selection);
}
fn goto_line_end(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- let line = range.head_line(text);
+ let text = doc.text().slice(..);
- let mut pos = line_end_char_index(&text, line);
- if doc.mode != Mode::Select {
- pos = graphemes::prev_grapheme_boundary(text, pos);
- }
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ let line = range.head_line(text);
- pos = range.head.max(pos).max(text.line_to_char(line));
+ let mut pos = line_end_char_index(&text, line);
+ if doc.mode != Mode::Select {
+ pos = graphemes::prev_grapheme_boundary(text, pos);
+ }
- range.put(text, pos, doc.mode == Mode::Select)
- }),
- );
+ pos = range.head.max(pos).max(text.line_to_char(line));
+
+ range.put(text, pos, doc.mode == Mode::Select)
+ });
+ doc.set_selection(view.id, selection);
}
fn goto_line_end_newline(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- let line = range.head_line(text);
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ let line = range.head_line(text);
- let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
- if doc.mode != Mode::Select {
- pos = graphemes::prev_grapheme_boundary(text, pos);
- }
- range.put(text, pos, doc.mode == Mode::Select)
- }),
- );
+ let mut pos = text.line_to_char((line + 1).min(text.len_lines()));
+ if doc.mode != Mode::Select {
+ pos = graphemes::prev_grapheme_boundary(text, pos);
+ }
+ range.put(text, pos, doc.mode == Mode::Select)
+ });
+ doc.set_selection(view.id, selection);
}
fn goto_line_start(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- let line = range.head_line(text);
+ let text = doc.text().slice(..);
- // adjust to start of the line
- let pos = text.line_to_char(line);
- range.put(text, pos, doc.mode == Mode::Select)
- }),
- );
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ let line = range.head_line(text);
+
+ // adjust to start of the line
+ let pos = text.line_to_char(line);
+ range.put(text, pos, doc.mode == Mode::Select)
+ });
+ doc.set_selection(view.id, selection);
}
fn goto_first_nonwhitespace(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- let line = range.head_line(text);
+ let text = doc.text().slice(..);
- if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
- let pos = pos + text.line_to_char(line);
- range.put(text, pos, doc.mode == Mode::Select)
- } else {
- range
- }
- }),
- );
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ let line = range.head_line(text);
+
+ if let Some(pos) = find_first_non_whitespace_char(text.line(line)) {
+ let pos = pos + text.line_to_char(line);
+ range.put(text, pos, doc.mode == Mode::Select)
+ } else {
+ range
+ }
+ });
+ doc.set_selection(view.id, selection);
}
fn goto_window(cx: &mut Context, align: Align) {
@@ -499,80 +470,79 @@ fn goto_window_bottom(cx: &mut Context) {
fn move_next_word_start(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| movement::move_next_word_start(doc.text().slice(..), range, count)),
- );
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| movement::move_next_word_start(text, range, count));
+ doc.set_selection(view.id, selection);
}
fn move_prev_word_start(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| movement::move_prev_word_start(doc.text().slice(..), range, count)),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| movement::move_prev_word_start(text, range, count));
+ doc.set_selection(view.id, selection);
}
fn move_next_word_end(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| movement::move_next_word_end(doc.text().slice(..), range, count)),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| movement::move_next_word_end(text, range, count));
+ doc.set_selection(view.id, selection);
}
fn move_next_long_word_start(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| {
- movement::move_next_long_word_start(doc.text().slice(..), range, count)
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| movement::move_next_long_word_start(text, range, count));
+ doc.set_selection(view.id, selection);
}
fn move_prev_long_word_start(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| {
- movement::move_prev_long_word_start(doc.text().slice(..), range, count)
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| movement::move_prev_long_word_start(text, range, count));
+ doc.set_selection(view.id, selection);
}
fn move_next_long_word_end(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| {
- movement::move_next_long_word_end(doc.text().slice(..), range, count)
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| movement::move_next_long_word_end(text, range, count));
+ doc.set_selection(view.id, selection);
}
fn goto_file_start(cx: &mut Context) {
@@ -590,52 +560,52 @@ fn goto_file_end(cx: &mut Context) {
fn extend_next_word_start(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| {
- let text = doc.text().slice(..);
- let word = movement::move_next_word_start(text, range, count);
- let pos = word.head;
- range.put(text, pos, true)
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| {
+ let word = movement::move_next_word_start(text, range, count);
+ let pos = word.head;
+ range.put(text, pos, true)
+ });
+ doc.set_selection(view.id, selection);
}
fn extend_prev_word_start(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| {
- let text = doc.text().slice(..);
- let word = movement::move_prev_word_start(text, range, count);
- let pos = word.head;
- range.put(text, pos, true)
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| {
+ let word = movement::move_prev_word_start(text, range, count);
+ let pos = word.head;
+ range.put(text, pos, true)
+ });
+ doc.set_selection(view.id, selection);
}
fn extend_next_word_end(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .min_width_1(doc.text().slice(..))
- .transform(|range| {
- let text = doc.text().slice(..);
- let word = movement::move_next_word_end(text, range, count);
- let pos = word.head;
- range.put(text, pos, true)
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .min_width_1(text)
+ .transform(|range| {
+ let word = movement::move_next_word_end(text, range, count);
+ let pos = word.head;
+ range.put(text, pos, true)
+ });
+ doc.set_selection(view.id, selection);
}
#[inline]
@@ -678,15 +648,13 @@ where
};
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- search_fn(text, ch, range.head, count, inclusive)
- .map_or(range, |pos| range.put(text, pos, extend))
- }),
- );
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ search_fn(text, ch, range.head, count, inclusive)
+ .map_or(range, |pos| range.put(text, pos, extend))
+ });
+ doc.set_selection(view.id, selection);
})
}
@@ -939,69 +907,45 @@ fn half_page_down(cx: &mut Context) {
fn extend_char_left(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_horizontally(
- doc.text().slice(..),
- range,
- Direction::Backward,
- count,
- Movement::Extend,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_horizontally(text, range, Direction::Backward, count, Movement::Extend)
+ });
+ doc.set_selection(view.id, selection);
}
fn extend_char_right(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_horizontally(
- doc.text().slice(..),
- range,
- Direction::Forward,
- count,
- Movement::Extend,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_horizontally(text, range, Direction::Forward, count, Movement::Extend)
+ });
+ doc.set_selection(view.id, selection);
}
fn extend_line_up(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_vertically(
- doc.text().slice(..),
- range,
- Direction::Backward,
- count,
- Movement::Extend,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_vertically(text, range, Direction::Backward, count, Movement::Extend)
+ });
+ doc.set_selection(view.id, selection);
}
fn extend_line_down(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_vertically(
- doc.text().slice(..),
- range,
- Direction::Forward,
- count,
- Movement::Extend,
- )
- }),
- );
+ let text = doc.text().slice(..);
+
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ movement::move_vertically(text, range, Direction::Forward, count, Movement::Extend)
+ });
+ doc.set_selection(view.id, selection);
}
fn select_all(cx: &mut Context) {
@@ -1222,30 +1166,28 @@ fn change_selection(cx: &mut Context) {
fn collapse_selection(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let pos = if range.head > range.anchor {
- // For 1-width cursor semantics.
- graphemes::prev_grapheme_boundary(doc.text().slice(..), range.head)
- } else {
- range.head
- };
- Range::new(pos, pos)
- }),
- );
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ let pos = if range.head > range.anchor {
+ // For 1-width cursor semantics.
+ graphemes::prev_grapheme_boundary(text, range.head)
+ } else {
+ range.head
+ };
+ Range::new(pos, pos)
+ });
+ doc.set_selection(view.id, selection);
}
fn flip_selections(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .transform(|range| Range::new(range.head, range.anchor)),
- );
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .transform(|range| Range::new(range.head, range.anchor));
+ doc.set_selection(view.id, selection);
}
fn enter_insert_mode(doc: &mut Document) {
@@ -1257,12 +1199,11 @@ fn insert_mode(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
enter_insert_mode(doc);
- doc.set_selection(
- view.id,
- doc.selection(view.id)
- .clone()
- .transform(|range| Range::new(range.to(), range.from())),
- );
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .transform(|range| Range::new(range.to(), range.from()));
+ doc.set_selection(view.id, selection);
}
// inserts at the end of each selection
@@ -1286,15 +1227,13 @@ fn append_mode(cx: &mut Context) {
doc.apply(&transaction, view.id);
}
- doc.set_selection(
- view.id,
- selection.clone().transform(|range| {
- Range::new(
- range.from(),
- graphemes::next_grapheme_boundary(doc.text().slice(..), range.to()),
- )
- }),
- );
+ let selection = selection.transform(|range| {
+ Range::new(
+ range.from(),
+ graphemes::next_grapheme_boundary(doc.text().slice(..), range.to()),
+ )
+ });
+ doc.set_selection(view.id, selection);
}
mod cmd {
@@ -2200,15 +2139,13 @@ fn append_to_line(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
enter_insert_mode(doc);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- let line = range.head_line(text);
- let pos = line_end_char_index(&text, line);
- Range::new(pos, pos)
- }),
- );
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ let text = doc.text().slice(..);
+ let line = range.head_line(text);
+ let pos = line_end_char_index(&text, line);
+ Range::new(pos, pos)
+ });
+ doc.set_selection(view.id, selection);
}
/// Sometimes when applying formatting changes we want to mark the buffer as unmodified, for
@@ -2338,15 +2275,14 @@ fn normal_mode(cx: &mut Context) {
// if leaving append mode, move cursor back by 1
if doc.restore_cursor {
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- Range::new(
- range.from(),
- graphemes::prev_grapheme_boundary(doc.text().slice(..), range.to()),
- )
- }),
- );
+ let text = doc.text().slice(..);
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ Range::new(
+ range.from(),
+ graphemes::prev_grapheme_boundary(text, range.to()),
+ )
+ });
+ doc.set_selection(view.id, selection);
doc.restore_cursor = false;
}
@@ -2370,22 +2306,21 @@ fn goto_last_accessed_file(cx: &mut Context) {
fn select_mode(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
// Make sure all selections are at least 1-wide.
// (With the exception of being in an empty document, of course.)
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- if range.is_empty() && range.head == doc.text().len_chars() {
- Range::new(
- graphemes::prev_grapheme_boundary(doc.text().slice(..), range.anchor),
- range.head,
- )
- } else {
- range.min_width_1(doc.text().slice(..))
- }
- }),
- );
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ if range.is_empty() && range.head == text.len_chars() {
+ Range::new(
+ graphemes::prev_grapheme_boundary(text, range.anchor),
+ range.head,
+ )
+ } else {
+ range.min_width_1(text)
+ }
+ });
+ doc.set_selection(view.id, selection);
doc_mut!(cx.editor).mode = Mode::Select;
}
@@ -2964,13 +2899,13 @@ pub mod insert {
pub fn delete_word_backward(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- movement::move_prev_word_start(doc.text().slice(..), range, count)
- }),
- );
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .transform(|range| movement::move_prev_word_start(text, range, count));
+ doc.set_selection(view.id, selection);
delete_selection(cx)
}
}
@@ -3721,21 +3656,19 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
} = event
{
let (view, doc) = current!(cx.editor);
+ let text = doc.text().slice(..);
- doc.set_selection(
- view.id,
- doc.selection(view.id).clone().transform(|range| {
- let text = doc.text().slice(..);
- match ch {
- 'w' => textobject::textobject_word(text, range, objtype, count),
- // TODO: cancel new ranges if inconsistent surround matches across lines
- ch if !ch.is_ascii_alphanumeric() => {
- textobject::textobject_surround(text, range, objtype, ch, count)
- }
- _ => range,
+ let selection = doc.selection(view.id).clone().transform(|range| {
+ match ch {
+ 'w' => textobject::textobject_word(text, range, objtype, count),
+ // TODO: cancel new ranges if inconsistent surround matches across lines
+ ch if !ch.is_ascii_alphanumeric() => {
+ textobject::textobject_surround(text, range, objtype, ch, count)
}
- }),
- );
+ _ => range,
+ }
+ });
+ doc.set_selection(view.id, selection);
}
})
}