From 6cb35d28a878470ef742b813e1e8d412d09e6b52 Mon Sep 17 00:00:00 2001 From: Jason Hansen Date: Mon, 15 Nov 2021 08:32:58 -0700 Subject: 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--- helix-term/src/commands.rs | 38 ++++++++++++++++++++++++++++++++++++++ helix-term/src/keymap.rs | 3 +++ 2 files changed, 41 insertions(+) (limited to 'helix-term/src') 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); + } +} diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index fdf43d87..bf3b594e 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -698,6 +698,9 @@ impl Default for Keymaps { "A-!" => shell_append_output, "$" => shell_keep_pipe, "C-z" => suspend, + + "C-a" => increment, + "C-x" => decrement, }); let mut select = normal.clone(); select.merge_nodes(keymap!({ "Select mode" -- cgit v1.2.3-70-g09d2