aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/commands.rs
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src/commands.rs')
-rw-r--r--helix-term/src/commands.rs277
1 files changed, 166 insertions, 111 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index fb1a4b38..5073651b 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -27,6 +27,7 @@ use helix_core::{
SmallVec, Tendril, Transaction,
};
use helix_view::{
+ apply_transaction,
clipboard::ClipboardType,
document::{FormatterError, Mode, SCRATCH_BUFFER_NAME},
editor::{Action, Motion},
@@ -273,8 +274,8 @@ impl MappableCommand {
diagnostics_picker, "Open diagnostic picker",
workspace_diagnostics_picker, "Open workspace diagnostic picker",
last_picker, "Open last picker",
- prepend_to_line, "Insert at start of line",
- append_to_line, "Append to end of line",
+ insert_at_line_start, "Insert at start of line",
+ insert_at_line_end, "Insert at end of line",
open_below, "Open new line below selection",
open_above, "Open new line above selection",
normal_mode, "Enter normal mode",
@@ -346,6 +347,7 @@ impl MappableCommand {
unindent, "Unindent selection",
format_selections, "Format selection",
join_selections, "Join lines inside selection",
+ join_selections_space, "Join lines inside selection and select spaces",
keep_selections, "Keep selections matching regex",
remove_selections, "Remove selections matching regex",
align_selections, "Align selections in column",
@@ -858,7 +860,7 @@ fn align_selections(cx: &mut Context) {
changes.sort_unstable_by_key(|(from, _, _)| *from);
let transaction = Transaction::change(doc.text(), changes.into_iter());
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
fn goto_window(cx: &mut Context, align: Align) {
@@ -885,8 +887,12 @@ fn goto_window(cx: &mut Context, align: Align) {
.min(last_line.saturating_sub(scrolloff));
let pos = doc.text().line_to_char(line);
-
- doc.set_selection(view.id, Selection::point(pos));
+ let text = doc.text().slice(..);
+ let selection = doc
+ .selection(view.id)
+ .clone()
+ .transform(|range| range.put_cursor(text, pos, cx.editor.mode == Mode::Select));
+ doc.set_selection(view.id, selection);
}
fn goto_window_top(cx: &mut Context) {
@@ -1284,7 +1290,7 @@ fn replace(cx: &mut Context) {
}
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
})
}
@@ -1301,7 +1307,7 @@ where
(range.from(), range.to(), Some(text))
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
fn switch_case(cx: &mut Context) {
@@ -1511,7 +1517,8 @@ fn select_regex(cx: &mut Context) {
"select:".into(),
Some(reg),
ui::completers::none,
- move |view, doc, regex, event| {
+ move |editor, regex, event| {
+ let (view, doc) = current!(editor);
if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
return;
}
@@ -1532,7 +1539,8 @@ fn split_selection(cx: &mut Context) {
"split:".into(),
Some(reg),
ui::completers::none,
- move |view, doc, regex, event| {
+ move |editor, regex, event| {
+ let (view, doc) = current!(editor);
if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
return;
}
@@ -1556,15 +1564,16 @@ fn split_selection_on_newline(cx: &mut Context) {
#[allow(clippy::too_many_arguments)]
fn search_impl(
- doc: &mut Document,
- view: &mut View,
+ editor: &mut Editor,
contents: &str,
regex: &Regex,
movement: Movement,
direction: Direction,
scrolloff: usize,
wrap_around: bool,
+ show_warnings: bool,
) {
+ let (view, doc) = current!(editor);
let text = doc.text().slice(..);
let selection = doc.selection(view.id);
@@ -1594,17 +1603,29 @@ fn search_impl(
Direction::Backward => regex.find_iter(&contents[..start]).last(),
};
- if wrap_around && mat.is_none() {
- mat = match direction {
- Direction::Forward => regex.find(contents),
- Direction::Backward => {
- offset = start;
- regex.find_iter(&contents[start..]).last()
+ if mat.is_none() {
+ if wrap_around {
+ mat = match direction {
+ Direction::Forward => regex.find(contents),
+ Direction::Backward => {
+ offset = start;
+ regex.find_iter(&contents[start..]).last()
+ }
+ };
+ }
+ if show_warnings {
+ if wrap_around && mat.is_some() {
+ editor.set_status("Wrapped around document");
+ } else {
+ editor.set_error("No more matches");
}
}
- // TODO: message on wraparound
}
+ let (view, doc) = current!(editor);
+ let text = doc.text().slice(..);
+ let selection = doc.selection(view.id);
+
if let Some(mat) = mat {
let start = text.byte_to_char(mat.start() + offset);
let end = text.byte_to_char(mat.end() + offset);
@@ -1680,19 +1701,19 @@ fn searcher(cx: &mut Context, direction: Direction) {
.map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
.collect()
},
- move |view, doc, regex, event| {
+ move |editor, regex, event| {
if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
return;
}
search_impl(
- doc,
- view,
+ editor,
&contents,
&regex,
Movement::Move,
direction,
scrolloff,
wrap_around,
+ false,
);
},
);
@@ -1702,7 +1723,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
let count = cx.count();
let config = cx.editor.config();
let scrolloff = config.scrolloff;
- let (view, doc) = current!(cx.editor);
+ let (_, doc) = current!(cx.editor);
let registers = &cx.editor.registers;
if let Some(query) = registers.read('/').and_then(|query| query.last()) {
let contents = doc.text().slice(..).to_string();
@@ -1720,14 +1741,14 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
{
for _ in 0..count {
search_impl(
- doc,
- view,
+ cx.editor,
&contents,
&regex,
movement,
direction,
scrolloff,
wrap_around,
+ true,
);
}
} else {
@@ -1825,7 +1846,7 @@ fn global_search(cx: &mut Context) {
.map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
.collect()
},
- move |_view, _doc, regex, event| {
+ move |_editor, regex, event| {
if event != PromptEvent::Validate {
return;
}
@@ -1844,10 +1865,15 @@ fn global_search(cx: &mut Context) {
.hidden(file_picker_config.hidden)
.parents(file_picker_config.parents)
.ignore(file_picker_config.ignore)
+ .follow_links(file_picker_config.follow_symlinks)
.git_ignore(file_picker_config.git_ignore)
.git_global(file_picker_config.git_global)
.git_exclude(file_picker_config.git_exclude)
.max_depth(file_picker_config.max_depth)
+ // We always want to ignore the .git directory, otherwise if
+ // `ignore` is turned off above, we end up with a lot of noise
+ // in our picker.
+ .filter_entry(|entry| entry.file_name() != ".git")
.build_parallel()
.run(|| {
let mut searcher = searcher.clone();
@@ -2092,7 +2118,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
(range.from(), range.to(), None)
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
match op {
Operation::Delete => {
@@ -2106,14 +2132,11 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
}
#[inline]
-fn delete_selection_insert_mode(doc: &mut Document, view: &View, selection: &Selection) {
- let view_id = view.id;
-
- // then delete
+fn delete_selection_insert_mode(doc: &mut Document, view: &mut View, selection: &Selection) {
let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
(range.from(), range.to(), None)
});
- doc.apply(&transaction, view_id);
+ apply_transaction(&transaction, doc, view);
}
fn delete_selection(cx: &mut Context) {
@@ -2161,10 +2184,7 @@ fn ensure_selections_forward(cx: &mut Context) {
let selection = doc
.selection(view.id)
.clone()
- .transform(|r| match r.direction() {
- Direction::Forward => r,
- Direction::Backward => r.flip(),
- });
+ .transform(|r| r.with_direction(Direction::Forward));
doc.set_selection(view.id, selection);
}
@@ -2207,12 +2227,12 @@ fn append_mode(cx: &mut Context) {
.iter()
.last()
.expect("selection should always have at least one range");
- if !last_range.is_empty() && last_range.head == end {
+ if !last_range.is_empty() && last_range.to() == end {
let transaction = Transaction::change(
doc.text(),
[(end, end, Some(doc.line_ending.as_str().into()))].into_iter(),
);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
let selection = doc.selection(view.id).clone().transform(|range| {
@@ -2410,12 +2430,12 @@ impl ui::menu::Item for MappableCommand {
match self {
MappableCommand::Typable { doc, name, .. } => match keymap.get(name as &String) {
- Some(bindings) => format!("{} ({})", doc, fmt_binding(bindings)).into(),
- None => doc.as_str().into(),
+ Some(bindings) => format!("{} ({}) [{}]", doc, fmt_binding(bindings), name).into(),
+ None => format!("{} [{}]", doc, name).into(),
},
MappableCommand::Static { doc, name, .. } => match keymap.get(*name) {
- Some(bindings) => format!("{} ({})", doc, fmt_binding(bindings)).into(),
- None => (*doc).into(),
+ Some(bindings) => format!("{} ({}) [{}]", doc, fmt_binding(bindings), name).into(),
+ None => format!("{} [{}]", doc, name).into(),
},
}
}
@@ -2465,13 +2485,13 @@ fn last_picker(cx: &mut Context) {
}
// I inserts at the first nonwhitespace character of each line with a selection
-fn prepend_to_line(cx: &mut Context) {
+fn insert_at_line_start(cx: &mut Context) {
goto_first_nonwhitespace(cx);
enter_insert_mode(cx);
}
// A inserts at the end of each line with a selection
-fn append_to_line(cx: &mut Context) {
+fn insert_at_line_end(cx: &mut Context) {
enter_insert_mode(cx);
let (view, doc) = current!(cx.editor);
@@ -2512,7 +2532,7 @@ async fn make_format_callback(
let doc = doc_mut!(editor, &doc_id);
let view = view_mut!(editor);
if doc.version() == doc_version {
- doc.apply(&format, view.id);
+ apply_transaction(&format, doc, view);
doc.append_changes_to_history(view.id);
doc.detect_indent_and_line_ending();
view.ensure_cursor_in_view(doc, scrolloff);
@@ -2599,7 +2619,7 @@ fn open(cx: &mut Context, open: Open) {
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
// o inserts a new line after each line with a selection
@@ -2620,7 +2640,7 @@ fn normal_mode(cx: &mut Context) {
cx.editor.mode = Mode::Normal;
let (view, doc) = current!(cx.editor);
- try_restore_indent(doc, view.id);
+ try_restore_indent(doc, view);
// if leaving append mode, move cursor back by 1
if doc.restore_cursor {
@@ -2637,7 +2657,7 @@ fn normal_mode(cx: &mut Context) {
}
}
-fn try_restore_indent(doc: &mut Document, view_id: ViewId) {
+fn try_restore_indent(doc: &mut Document, view: &mut View) {
use helix_core::chars::char_is_whitespace;
use helix_core::Operation;
@@ -2656,18 +2676,18 @@ fn try_restore_indent(doc: &mut Document, view_id: ViewId) {
let doc_changes = doc.changes().changes();
let text = doc.text().slice(..);
- let range = doc.selection(view_id).primary();
+ let range = doc.selection(view.id).primary();
let pos = range.cursor(text);
let line_end_pos = line_end_char_index(&text, range.cursor_line(text));
if inserted_a_new_blank_line(doc_changes, pos, line_end_pos) {
// Removes tailing whitespaces.
let transaction =
- Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| {
+ Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
let line_start_pos = text.line_to_char(range.cursor_line(text));
(line_start_pos, pos, None)
});
- doc.apply(&transaction, view_id);
+ apply_transaction(&transaction, doc, view);
}
}
@@ -2865,7 +2885,7 @@ pub mod insert {
/// Exclude the cursor in range.
fn exclude_cursor(text: RopeSlice, range: Range, cursor: Range) -> Range {
- if range.to() == cursor.to() {
+ if range.to() == cursor.to() && text.len_chars() != cursor.to() {
Range::new(
range.from(),
graphemes::prev_grapheme_boundary(text, cursor.to()),
@@ -2981,7 +3001,7 @@ pub mod insert {
let (view, doc) = current!(cx.editor);
if let Some(t) = transaction {
- doc.apply(&t, view.id);
+ apply_transaction(&t, doc, view);
}
// TODO: need a post insert hook too for certain triggers (autocomplete, signature help, etc)
@@ -3003,7 +3023,7 @@ pub mod insert {
&doc.selection(view.id).clone().cursors(doc.text().slice(..)),
indent,
);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
pub fn insert_newline(cx: &mut Context) {
@@ -3090,7 +3110,7 @@ pub mod insert {
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));
let (view, doc) = current!(cx.editor);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
pub fn delete_char_backward(cx: &mut Context) {
@@ -3184,7 +3204,7 @@ pub mod insert {
}
});
let (view, doc) = current!(cx.editor);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
lsp::signature_help_impl(cx, SignatureHelpInvoked::Automatic);
}
@@ -3202,7 +3222,7 @@ pub mod insert {
None,
)
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
lsp::signature_help_impl(cx, SignatureHelpInvoked::Automatic);
}
@@ -3243,7 +3263,7 @@ fn undo(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
for _ in 0..count {
- if !doc.undo(view.id) {
+ if !doc.undo(view) {
cx.editor.set_status("Already at oldest change");
break;
}
@@ -3254,7 +3274,7 @@ fn redo(cx: &mut Context) {
let count = cx.count();
let (view, doc) = current!(cx.editor);
for _ in 0..count {
- if !doc.redo(view.id) {
+ if !doc.redo(view) {
cx.editor.set_status("Already at newest change");
break;
}
@@ -3266,7 +3286,7 @@ fn earlier(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
for _ in 0..count {
// rather than doing in batch we do this so get error halfway
- if !doc.earlier(view.id, UndoKind::Steps(1)) {
+ if !doc.earlier(view, UndoKind::Steps(1)) {
cx.editor.set_status("Already at oldest change");
break;
}
@@ -3278,7 +3298,7 @@ fn later(cx: &mut Context) {
let (view, doc) = current!(cx.editor);
for _ in 0..count {
// rather than doing in batch we do this so get error halfway
- if !doc.later(view.id, UndoKind::Steps(1)) {
+ if !doc.later(view, UndoKind::Steps(1)) {
cx.editor.set_status("Already at newest change");
break;
}
@@ -3330,9 +3350,15 @@ fn yank_joined_to_clipboard_impl(
.map(Cow::into_owned)
.collect();
+ let clipboard_text = match clipboard_type {
+ ClipboardType::Clipboard => "system clipboard",
+ ClipboardType::Selection => "primary clipboard",
+ };
+
let msg = format!(
- "joined and yanked {} selection(s) to system clipboard",
+ "joined and yanked {} selection(s) to {}",
values.len(),
+ clipboard_text,
);
let joined = values.join(separator);
@@ -3361,6 +3387,11 @@ fn yank_main_selection_to_clipboard_impl(
let (view, doc) = current!(editor);
let text = doc.text().slice(..);
+ let message_text = match clipboard_type {
+ ClipboardType::Clipboard => "yanked main selection to system clipboard",
+ ClipboardType::Selection => "yanked main selection to primary clipboard",
+ };
+
let value = doc.selection(view.id).primary().fragment(text);
if let Err(e) = editor
@@ -3370,7 +3401,7 @@ fn yank_main_selection_to_clipboard_impl(
bail!("Couldn't set system clipboard content: {}", e);
}
- editor.set_status("yanked main selection to system clipboard");
+ editor.set_status(message_text);
Ok(())
}
@@ -3396,7 +3427,7 @@ enum Paste {
Cursor,
}
-fn paste_impl(values: &[String], doc: &mut Document, view: &View, action: Paste, count: usize) {
+fn paste_impl(values: &[String], doc: &mut Document, view: &mut View, action: Paste, count: usize) {
let repeat = std::iter::repeat(
values
.last()
@@ -3439,7 +3470,7 @@ fn paste_impl(values: &[String], doc: &mut Document, view: &View, action: Paste,
};
(pos, pos, values.next())
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
pub(crate) fn paste_bracketed_value(cx: &mut Context, contents: String) {
@@ -3531,7 +3562,7 @@ fn replace_with_yanked(cx: &mut Context) {
}
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
}
}
@@ -3554,7 +3585,7 @@ fn replace_selections_with_clipboard_impl(
)
});
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
doc.append_changes_to_history(view.id);
Ok(())
}
@@ -3624,7 +3655,7 @@ fn indent(cx: &mut Context) {
Some((pos, pos, Some(indent.clone())))
}),
);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
fn unindent(cx: &mut Context) {
@@ -3663,7 +3694,7 @@ fn unindent(cx: &mut Context) {
let transaction = Transaction::change(doc.text(), changes.into_iter());
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
fn format_selections(cx: &mut Context) {
@@ -3710,11 +3741,11 @@ fn format_selections(cx: &mut Context) {
// language_server.offset_encoding(),
// );
- // doc.apply(&transaction, view.id);
+ // apply_transaction(&transaction, doc, view);
}
}
-fn join_selections(cx: &mut Context) {
+fn join_selections_inner(cx: &mut Context, select_space: bool) {
use movement::skip_while;
let (view, doc) = current!(cx.editor);
let text = doc.text();
@@ -3749,11 +3780,23 @@ fn join_selections(cx: &mut Context) {
// TODO: joining multiple empty lines should be replaced by a single space.
// need to merge change ranges that touch
- let transaction = Transaction::change(doc.text(), changes.into_iter());
- // TODO: select inserted spaces
- // .with_selection(selection);
+ // select inserted spaces
+ let transaction = if select_space {
+ let ranges: SmallVec<_> = changes
+ .iter()
+ .scan(0, |offset, change| {
+ let range = Range::point(change.0 - *offset);
+ *offset += change.1 - change.0 - 1; // -1 because cursor is 0-sized
+ Some(range)
+ })
+ .collect();
+ let selection = Selection::new(ranges, 0);
+ Transaction::change(doc.text(), changes.into_iter()).with_selection(selection)
+ } else {
+ Transaction::change(doc.text(), changes.into_iter())
+ };
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
@@ -3764,7 +3807,8 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
if remove { "remove:" } else { "keep:" }.into(),
Some(reg),
ui::completers::none,
- move |view, doc, regex, event| {
+ move |editor, regex, event| {
+ let (view, doc) = current!(editor);
if !matches!(event, PromptEvent::Update | PromptEvent::Validate) {
return;
}
@@ -3779,6 +3823,14 @@ fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
)
}
+fn join_selections(cx: &mut Context) {
+ join_selections_inner(cx, false)
+}
+
+fn join_selections_space(cx: &mut Context) {
+ join_selections_inner(cx, true)
+}
+
fn keep_selections(cx: &mut Context) {
keep_or_remove_selections_impl(cx, false)
}
@@ -3897,7 +3949,7 @@ fn toggle_comments(cx: &mut Context) {
.map(|tc| tc.as_ref());
let transaction = comment::toggle_line_comments(doc.text(), doc.selection(view.id), token);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
exit_select_mode(cx);
}
@@ -3953,7 +4005,7 @@ fn rotate_selection_contents(cx: &mut Context, direction: Direction) {
.map(|(range, fragment)| (range.from(), range.to(), Some(fragment))),
);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
fn rotate_selection_contents_forward(cx: &mut Context) {
@@ -4268,7 +4320,7 @@ fn goto_ts_object_impl(cx: &mut Context, object: &'static str, direction: Direct
let root = syntax.tree().root_node();
let selection = doc.selection(view.id).clone().transform(|range| {
- movement::goto_treesitter_object(
+ let new_range = movement::goto_treesitter_object(
text,
range,
object,
@@ -4276,7 +4328,19 @@ fn goto_ts_object_impl(cx: &mut Context, object: &'static str, direction: Direct
root,
lang_config,
count,
- )
+ );
+
+ if editor.mode == Mode::Select {
+ let head = if new_range.head < range.anchor {
+ new_range.anchor
+ } else {
+ new_range.head
+ };
+
+ Range::new(range.anchor, head)
+ } else {
+ new_range.with_direction(direction)
+ }
});
doc.set_selection(view.id, selection);
@@ -4341,7 +4405,6 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
cx.on_next_key(move |cx, event| {
cx.editor.autoinfo = None;
- cx.editor.pseudo_pending = None;
if let Some(ch) = event.char() {
let textobject = move |editor: &mut Editor| {
let (view, doc) = current!(editor);
@@ -4390,33 +4453,25 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
}
});
- if let Some((title, abbrev)) = match objtype {
- textobject::TextObject::Inside => Some(("Match inside", "mi")),
- textobject::TextObject::Around => Some(("Match around", "ma")),
+ let title = match objtype {
+ textobject::TextObject::Inside => "Match inside",
+ textobject::TextObject::Around => "Match around",
_ => return,
- } {
- let help_text = [
- ("w", "Word"),
- ("W", "WORD"),
- ("p", "Paragraph"),
- ("c", "Class (tree-sitter)"),
- ("f", "Function (tree-sitter)"),
- ("a", "Argument/parameter (tree-sitter)"),
- ("o", "Comment (tree-sitter)"),
- ("t", "Test (tree-sitter)"),
- ("m", "Closest surrounding pair to cursor"),
- (" ", "... or any character acting as a pair"),
- ];
-
- cx.editor.autoinfo = Some(Info::new(
- title,
- help_text
- .into_iter()
- .map(|(col1, col2)| (col1.to_string(), col2.to_string()))
- .collect(),
- ));
- cx.editor.pseudo_pending = Some(abbrev.to_string());
};
+ let help_text = [
+ ("w", "Word"),
+ ("W", "WORD"),
+ ("p", "Paragraph"),
+ ("c", "Class (tree-sitter)"),
+ ("f", "Function (tree-sitter)"),
+ ("a", "Argument/parameter (tree-sitter)"),
+ ("o", "Comment (tree-sitter)"),
+ ("t", "Test (tree-sitter)"),
+ ("m", "Closest surrounding pair to cursor"),
+ (" ", "... or any character acting as a pair"),
+ ];
+
+ cx.editor.autoinfo = Some(Info::new(title, &help_text));
}
fn surround_add(cx: &mut Context) {
@@ -4440,7 +4495,7 @@ fn surround_add(cx: &mut Context) {
}
let transaction = Transaction::change(doc.text(), changes.into_iter());
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
})
}
@@ -4479,7 +4534,7 @@ fn surround_replace(cx: &mut Context) {
(pos, pos + 1, Some(t))
}),
);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
});
})
}
@@ -4506,7 +4561,7 @@ fn surround_delete(cx: &mut Context) {
let transaction =
Transaction::change(doc.text(), change_pos.into_iter().map(|p| (p, p + 1, None)));
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
})
}
@@ -4681,7 +4736,7 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
if behavior != &ShellBehavior::Ignore {
let transaction = Transaction::change(doc.text(), changes.into_iter());
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
doc.append_changes_to_history(view.id);
}
@@ -4744,7 +4799,7 @@ fn add_newline_impl(cx: &mut Context, open: Open) {
});
let transaction = Transaction::change(text, changes);
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
/// Increment object under cursor by count.
@@ -4837,7 +4892,7 @@ fn increment_impl(cx: &mut Context, amount: i64) {
let transaction = Transaction::change(doc.text(), changes);
let transaction = transaction.with_selection(selection.clone());
- doc.apply(&transaction, view.id);
+ apply_transaction(&transaction, doc, view);
}
}