diff options
Diffstat (limited to 'helix-term/src/commands.rs')
-rw-r--r-- | helix-term/src/commands.rs | 148 |
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 '{}'", '/', ®ex); - 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(®ex); 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)); |