aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/commands.rs
diff options
context:
space:
mode:
authorJason Hansen2021-11-15 15:32:58 +0000
committerGitHub2021-11-15 15:32:58 +0000
commit6cb35d28a878470ef742b813e1e8d412d09e6b52 (patch)
tree40b3ee4e697f3b41f22b0bdff1b87569eed8c644 /helix-term/src/commands.rs
parent46d9ae2b62f5b8494c527e0f8475509ce5fad095 (diff)
Add command to inc/dec number under cursor (#1027)
* Add command to inc/dec number under cursor With the cursor over a number in normal mode, Ctrl + A will increment the number and Ctrl + X will decrement the number. It works with binary, octal, decimal, and hexidecimal numbers. Here are some examples. 0b01110100 0o1734 -24234 0x1F245 If the number isn't over a number it will try to find a number after the cursor on the same line. * Move several functions to helix-core * Change to work based on word under selection * It no longer finds the next number if the cursor isn't already over a number. * It only matches numbers that are part of words with other characters like "foo123bar". * It now works with multiple selections. * Add some unit tests * Fix for clippy * Simplify some things * Keep previous selection after incrementing * Use short word instead of long word This change requires us to manually handle minus sign. * Don't pad decimal numbers if no leading zeros * Handle numbers with `_` separators * Refactor and add tests * Move most of the code into core * Add tests for the incremented output * Use correct range * Formatting * Rename increment functions * Make docs more specific * This is easier to read * This is clearer * Type can be inferred
Diffstat (limited to 'helix-term/src/commands.rs')
-rw-r--r--helix-term/src/commands.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 74bc52fd..7ef8f56c 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -6,6 +6,7 @@ use helix_core::{
line_ending::{get_line_ending_of_str, line_end_char_index, str_is_line_ending},
match_brackets,
movement::{self, Direction},
+ numbers::NumberIncrementor,
object, pos_at_coords,
regex::{self, Regex, RegexBuilder},
register::Register,
@@ -354,6 +355,8 @@ impl Command {
shell_keep_pipe, "Filter selections with shell predicate",
suspend, "Suspend",
rename_symbol, "Rename symbol",
+ increment, "Increment",
+ decrement, "Decrement",
);
}
@@ -5459,3 +5462,38 @@ fn rename_symbol(cx: &mut Context) {
);
cx.push_layer(Box::new(prompt));
}
+
+/// Increment object under cursor by count.
+fn increment(cx: &mut Context) {
+ increment_impl(cx, cx.count() as i64);
+}
+
+/// Decrement object under cursor by count.
+fn decrement(cx: &mut Context) {
+ increment_impl(cx, -(cx.count() as i64));
+}
+
+/// Decrement object under cursor by `amount`.
+fn increment_impl(cx: &mut Context, amount: i64) {
+ let (view, doc) = current!(cx.editor);
+ let selection = doc.selection(view.id);
+ let text = doc.text();
+
+ let changes = selection.ranges().iter().filter_map(|range| {
+ let incrementor = NumberIncrementor::from_range(text.slice(..), *range)?;
+ let new_text = incrementor.incremented_text(amount);
+ Some((
+ incrementor.range.from(),
+ incrementor.range.to(),
+ Some(new_text),
+ ))
+ });
+
+ if changes.clone().count() > 0 {
+ let transaction = Transaction::change(doc.text(), changes);
+ let transaction = transaction.with_selection(selection.clone());
+
+ doc.apply(&transaction, view.id);
+ doc.append_changes_to_history(view.id);
+ }
+}