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.rs148
1 files changed, 80 insertions, 68 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 58c17296..d9ea580d 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1847,11 +1847,11 @@ fn search_impl(
fn search_completions(cx: &mut Context, reg: Option<char>) -> Vec<String> {
let mut items = reg
- .and_then(|reg| cx.editor.registers.get(reg))
- .map_or(Vec::new(), |reg| reg.read().iter().take(200).collect());
+ .and_then(|reg| cx.editor.registers.read(reg, cx.editor))
+ .map_or(Vec::new(), |reg| reg.take(200).collect());
items.sort_unstable();
items.dedup();
- items.into_iter().cloned().collect()
+ items.into_iter().map(|value| value.to_string()).collect()
}
fn search(cx: &mut Context) {
@@ -1910,9 +1910,8 @@ 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 (_, doc) = current!(cx.editor);
- let registers = &cx.editor.registers;
- if let Some(query) = registers.read('/').and_then(|query| query.last()) {
+ if let Some(query) = cx.editor.registers.last('/', cx.editor) {
+ let doc = doc!(cx.editor);
let contents = doc.text().slice(..).to_string();
let search_config = &config.search;
let case_insensitive = if search_config.smart_case {
@@ -1921,7 +1920,7 @@ fn search_next_or_prev_impl(cx: &mut Context, movement: Movement, direction: Dir
false
};
let wrap_around = search_config.wrap_around;
- if let Ok(regex) = RegexBuilder::new(query)
+ if let Ok(regex) = RegexBuilder::new(&query)
.case_insensitive(case_insensitive)
.multi_line(true)
.build()
@@ -1974,12 +1973,14 @@ fn search_selection(cx: &mut Context) {
.join("|");
let msg = format!("register '{}' set to '{}'", '/', &regex);
- cx.editor.registers.push('/', regex);
- cx.editor.set_status(msg);
+ match cx.editor.registers.push('/', regex) {
+ Ok(_) => cx.editor.set_status(msg),
+ Err(err) => cx.editor.set_error(err.to_string()),
+ }
}
fn make_search_word_bounded(cx: &mut Context) {
- let regex = match cx.editor.registers.last('/') {
+ let regex = match cx.editor.registers.last('/', cx.editor) {
Some(regex) => regex,
None => return,
};
@@ -1997,14 +1998,16 @@ fn make_search_word_bounded(cx: &mut Context) {
if !start_anchored {
new_regex.push_str("\\b");
}
- new_regex.push_str(regex);
+ new_regex.push_str(&regex);
if !end_anchored {
new_regex.push_str("\\b");
}
let msg = format!("register '{}' set to '{}'", '/', &new_regex);
- cx.editor.registers.push('/', new_regex);
- cx.editor.set_status(msg);
+ match cx.editor.registers.push('/', new_regex) {
+ Ok(_) => cx.editor.set_status(msg),
+ Err(err) => cx.editor.set_error(err.to_string()),
+ }
}
fn global_search(cx: &mut Context) {
@@ -2367,7 +2370,10 @@ fn delete_selection_impl(cx: &mut Context, op: Operation) {
let text = doc.text().slice(..);
let values: Vec<String> = selection.fragments(text).map(Cow::into_owned).collect();
let reg_name = cx.register.unwrap_or('"');
- cx.editor.registers.write(reg_name, values);
+ if let Err(err) = cx.editor.registers.write(reg_name, values) {
+ cx.editor.set_error(err.to_string());
+ return;
+ }
};
// then delete
@@ -3758,18 +3764,16 @@ fn yank(cx: &mut Context) {
.fragments(text)
.map(Cow::into_owned)
.collect();
+ let selections = values.len();
+ let register = cx.register.unwrap_or('"');
- let msg = format!(
- "yanked {} selection(s) to register {}",
- values.len(),
- cx.register.unwrap_or('"')
- );
-
- cx.editor
- .registers
- .write(cx.register.unwrap_or('"'), values);
+ match cx.editor.registers.write(register, values) {
+ Ok(_) => cx.editor.set_status(format!(
+ "yanked {selections} selection(s) to register {register}",
+ )),
+ Err(err) => cx.editor.set_error(err.to_string()),
+ }
- cx.editor.set_status(msg);
exit_select_mode(cx);
}
@@ -3778,6 +3782,7 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
let text = doc.text().slice(..);
let selection = doc.selection(view.id);
+ let selections = selection.len();
let joined = selection
.fragments(text)
.fold(String::new(), |mut acc, fragment| {
@@ -3788,14 +3793,12 @@ fn yank_joined_impl(editor: &mut Editor, separator: &str, register: char) {
acc
});
- let msg = format!(
- "joined and yanked {} selection(s) to register {}",
- selection.len(),
- register,
- );
-
- editor.registers.write(register, vec![joined]);
- editor.set_status(msg);
+ match editor.registers.write(register, vec![joined]) {
+ Ok(_) => editor.set_status(format!(
+ "joined and yanked {selections} selection(s) to register {register}",
+ )),
+ Err(err) => editor.set_error(err.to_string()),
+ }
}
fn yank_joined(cx: &mut Context) {
@@ -4040,34 +4043,34 @@ fn paste_primary_clipboard_before(cx: &mut Context) {
fn replace_with_yanked(cx: &mut Context) {
let count = cx.count();
let reg_name = cx.register.unwrap_or('"');
- let (view, doc) = current!(cx.editor);
- let registers = &mut cx.editor.registers;
-
- if let Some(values) = registers.read(reg_name) {
- if !values.is_empty() {
- let repeat = std::iter::repeat(
- values
- .last()
- .map(|value| Tendril::from(&value.repeat(count)))
- .unwrap(),
- );
- let mut values = values
- .iter()
- .map(|value| Tendril::from(&value.repeat(count)))
- .chain(repeat);
- let selection = doc.selection(view.id);
- let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
- if !range.is_empty() {
- (range.from(), range.to(), Some(values.next().unwrap()))
- } else {
- (range.from(), range.to(), None)
- }
- });
- doc.apply(&transaction, view.id);
- exit_select_mode(cx);
+ let Some(values) = cx.editor.registers
+ .read(reg_name, cx.editor)
+ .filter(|values| values.len() > 0) else { return };
+ let values: Vec<_> = values.map(|value| value.to_string()).collect();
+
+ let (view, doc) = current!(cx.editor);
+ let repeat = std::iter::repeat(
+ values
+ .last()
+ .map(|value| Tendril::from(&value.repeat(count)))
+ .unwrap(),
+ );
+ let mut values = values
+ .iter()
+ .map(|value| Tendril::from(&value.repeat(count)))
+ .chain(repeat);
+ let selection = doc.selection(view.id);
+ let transaction = Transaction::change_by_selection(doc.text(), selection, |range| {
+ if !range.is_empty() {
+ (range.from(), range.to(), Some(values.next().unwrap()))
+ } else {
+ (range.from(), range.to(), None)
}
- }
+ });
+
+ doc.apply(&transaction, view.id);
+ exit_select_mode(cx);
}
fn replace_selections_with_clipboard_impl(
@@ -4109,12 +4112,12 @@ fn replace_selections_with_primary_clipboard(cx: &mut Context) {
fn paste(cx: &mut Context, pos: Paste) {
let count = cx.count();
let reg_name = cx.register.unwrap_or('"');
- let (view, doc) = current!(cx.editor);
- let registers = &mut cx.editor.registers;
- if let Some(values) = registers.read(reg_name) {
- paste_impl(values, doc, view, pos, count, cx.editor.mode);
- }
+ let Some(values) = cx.editor.registers.read(reg_name, cx.editor) else { return };
+ let values: Vec<_> = values.map(|value| value.to_string()).collect();
+
+ let (view, doc) = current!(cx.editor);
+ paste_impl(&values, doc, view, pos, count, cx.editor.mode);
}
fn paste_after(cx: &mut Context) {
@@ -5593,9 +5596,12 @@ fn record_macro(cx: &mut Context) {
}
})
.collect::<String>();
- cx.editor.registers.write(reg, vec![s]);
- cx.editor
- .set_status(format!("Recorded to register [{}]", reg));
+ match cx.editor.registers.write(reg, vec![s]) {
+ Ok(_) => cx
+ .editor
+ .set_status(format!("Recorded to register [{}]", reg)),
+ Err(err) => cx.editor.set_error(err.to_string()),
+ }
} else {
let reg = cx.register.take().unwrap_or('@');
cx.editor.macro_recording = Some((reg, Vec::new()));
@@ -5615,8 +5621,14 @@ fn replay_macro(cx: &mut Context) {
return;
}
- let keys: Vec<KeyEvent> = if let Some([keys_str]) = cx.editor.registers.read(reg) {
- match helix_view::input::parse_macro(keys_str) {
+ let keys: Vec<KeyEvent> = if let Some(keys) = cx
+ .editor
+ .registers
+ .read(reg, cx.editor)
+ .filter(|values| values.len() == 1)
+ .map(|mut values| values.next().unwrap())
+ {
+ match helix_view::input::parse_macro(&keys) {
Ok(keys) => keys,
Err(err) => {
cx.editor.set_error(format!("Invalid macro: {}", err));