Support incrementing/decrementing the number below the cursor

Vim supports incrementing & decrementing the number below the cursor (or
after it) via Ctrl-a and Ctrl-x, respectively. Given fish's Vi mode
support, it makes sense to provide similar functionality when working on
the command line, to provide a more natural environment for Vim users.
With this change we add the necessary functionality.

Closes: #8320
Closes #11570
This commit is contained in:
Daniel Müller
2022-01-08 17:02:56 -08:00
committed by Johannes Altmanninger
parent b5bb50d742
commit 5b39efc96d
10 changed files with 220 additions and 0 deletions

View File

@@ -64,6 +64,7 @@ New or improved bindings
this is only enabled by default if the terminal advertises support for the ``indn`` capability via XTGETTCAP.
- Bindings using shift with non-ASCII letters (such as :kbd:`ctrl-shift-ä`) are now supported.
If there is any modifier other than shift, this is the recommended notation (as opposed to :kbd:`ctrl-Ä`).
- Vi mode has learned :kbd:`ctrl-a` (increment) and :kbd:`ctrl-x` (decrement) (:issue:`11570`).
Completions
^^^^^^^^^^^

View File

@@ -74706,6 +74706,9 @@ msgstr ""
msgid "increase verbosity level by one"
msgstr ""
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr ""

View File

@@ -74702,6 +74702,9 @@ msgstr ""
msgid "increase verbosity level by one"
msgstr ""
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr ""

View File

@@ -74803,6 +74803,9 @@ msgstr ""
msgid "increase verbosity level by one"
msgstr "Incrémenter le niveau de verbosité"
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr ""

View File

@@ -74698,6 +74698,9 @@ msgstr ""
msgid "increase verbosity level by one"
msgstr ""
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr ""

View File

@@ -74725,6 +74725,9 @@ msgstr ""
msgid "increase verbosity level by one"
msgstr ""
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr ""

View File

@@ -74701,6 +74701,9 @@ msgstr ""
msgid "increase verbosity level by one"
msgstr ""
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr ""

View File

@@ -74701,6 +74701,9 @@ msgstr "增加动词"
msgid "increase verbosity level by one"
msgstr "将动词水平增加一个"
msgid "increment or decrement the number below the cursor"
msgstr ""
msgid "incremental mode"
msgstr "递增模式"

View File

@@ -1,3 +1,80 @@
alias fish_vi_dec 'fish_vi_inc_dec dec'
alias fish_vi_inc 'fish_vi_inc_dec inc'
# TODO: Currently we do not support hexadecimal and octal values.
function fish_vi_inc_dec --description 'increment or decrement the number below the cursor'
# The cursor is zero based, but all string functions assume 1 to be
# the lowest index. Adjust accordingly.
set --local cursor (math -- (commandline --cursor) + 1)
set --local line (commandline --current-buffer | string collect)
set --local candidate (string sub --start $cursor -- $line | string collect)
if set --local just_found (string match --regex '^-?[0-9]+' -- $candidate)
# Search from the current cursor position backwards for as long as we
# can identify a valid number.
set --function found $just_found
set --function found_at $cursor
set --local end (math -- $cursor + (string length -- $found) - 1)
set i (math -- $cursor - 1)
while [ $i -ge 1 ]
set candidate (string sub --start $i --end $end -- $line)
if set just_found (string match --regex '^-?[0-9]+$' -- $candidate)
set found $just_found
set found_at $i
# We found a candidate, but continue to make sure that we captured
# the complete number and not just part of it.
else
# We have already found a number earlier. Work with that.
break
end
set i (math -- $i - 1)
end
else
# We didn't find a match below the cursor. Mirror Vim behavior by
# checking ahead as well.
for i in (seq (math -- $cursor + 1) (math -- (string length -- $line) - 1))
set candidate (string sub --start $i -- $line | string collect)
if set just_found (string match --regex '^-?[0-9]+' -- $candidate)
set found $just_found
set found_at $i
break
end
end
if [ -z "$found" ]
return
end
end
if [ $argv = inc ]
set number (math -- $found + 1)
else if [ $argv = dec ]
set number (math -- $found - 1)
end
set --local number_abs (string trim --left --chars=- -- $number)
set --local signed $status
set --local found_abs (string trim --left --chars=- -- $found)
set number (string pad --char 0 --width (string length -- $found_abs) -- $number_abs)
if test $signed -eq 0
set number "-$number"
end
# `string sub` may bitch about `--end` being zero if `found_at` is 1.
# So ignore errors here...
set --local before (string sub --end (math -- $found_at - 1) -- $line 2> /dev/null | string collect)
set --local after (string sub --start (math -- $found_at + (string length -- $found)) -- $line | string collect)
commandline --replace -- "$before$number$after"
# Need to subtract two here because 1) cursor is zero based 2)
# `found_at` is the index of the first character of the match, but we
# want the one before that.
commandline --cursor -- (math -- $found_at + (string length -- $number) - 2)
commandline --function -- repaint
end
function fish_vi_key_bindings --description 'vi-like key bindings for fish'
if contains -- -h $argv
or contains -- --help $argv
@@ -271,6 +348,12 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
bind -s --preset -M replace backspace backward-char
bind -s --preset -M replace shift-backspace backward-char
#
# Increment or decrement number under the cursor with ctrl+x ctrl+a
#
bind -s --preset -M default ctrl-a fish_vi_inc
bind -s --preset -M default ctrl-x fish_vi_dec
#
# visual mode
#

115
tests/checks/vi.fish Normal file
View File

@@ -0,0 +1,115 @@
# RUN: %fish --interactive %s
fish_vi_key_bindings
commandline '1'; commandline --cursor 0; fish_vi_dec
commandline --current-buffer
# CHECK: 0
commandline '0'; commandline --cursor 0; fish_vi_dec
commandline --current-buffer
# CHECK: -1
commandline -- '-1'; commandline --cursor 0; fish_vi_dec
commandline --current-buffer
# CHECK: -2
commandline -- '-1'; commandline --cursor 0; fish_vi_inc
commandline --current-buffer
# CHECK: 0
commandline '0'; commandline --cursor 0; fish_vi_inc
commandline --current-buffer
# CHECK: 1
commandline '123'; commandline --cursor 0; fish_vi_inc
commandline --current-buffer
# CHECK: 124
commandline '123'; commandline --cursor 0; fish_vi_dec
commandline --current-buffer
# CHECK: 122
commandline '123'; commandline --cursor 1; fish_vi_inc
commandline --current-buffer
# CHECK: 124
commandline '123'; commandline --cursor 1; fish_vi_dec
commandline --current-buffer
# CHECK: 122
commandline '123'; commandline --cursor 2; fish_vi_inc
commandline --current-buffer
# CHECK: 124
commandline '123'; commandline --cursor 2; fish_vi_dec
commandline --current-buffer
# CHECK: 122
commandline 'abc123'; commandline --cursor 1; fish_vi_inc
commandline --current-buffer
# CHECK: abc124
commandline 'abc123'; commandline --cursor 1; fish_vi_dec
commandline --current-buffer
# CHECK: abc122
commandline 'abc123def'; commandline --cursor 1; fish_vi_inc
commandline --current-buffer
# CHECK: abc124def
commandline 'abc123def'; commandline --cursor 1; fish_vi_dec
commandline --current-buffer
# CHECK: abc122def
commandline 'abc123def'; commandline --cursor 5; fish_vi_inc
commandline --current-buffer
# CHECK: abc124def
commandline 'abc123def'; commandline --cursor 5; fish_vi_dec
commandline --current-buffer
# CHECK: abc122def
commandline 'abc123def'; commandline --cursor 6; fish_vi_inc
commandline --current-buffer
# CHECK: abc123def
commandline 'abc123def'; commandline --cursor 6; fish_vi_dec
commandline --current-buffer
# CHECK: abc123def
commandline 'abc99def'; commandline --cursor 1; fish_vi_inc
commandline --current-buffer
# CHECK: abc100def
commandline 'abc99def'; commandline --cursor 1; fish_vi_dec
commandline --current-buffer
# CHECK: abc98def
commandline 'abc-99def'; commandline --cursor 1; fish_vi_inc
commandline --current-buffer
# CHECK: abc-98def
commandline 'abc-99def'; commandline --cursor 1; fish_vi_dec
commandline --current-buffer
# CHECK: abc-100def
commandline '2022-04-09'; commandline --cursor 7; fish_vi_inc
commandline --current-buffer
# CHECK: 2022-04-08
commandline 'to 2022-04-09'; commandline --cursor 4; fish_vi_inc
commandline --current-buffer
# CHECK: to 2023-04-09
commandline 'to 2022-04-09'; commandline --cursor 4; fish_vi_dec
commandline --current-buffer
# CHECK: to 2021-04-09
commandline 'to 2022-04-09'; commandline --cursor 11; fish_vi_dec
commandline --current-buffer
# CHECK: to 2022-04-10
commandline 'to 2022-04-09'; commandline --cursor 11; fish_vi_inc
commandline --current-buffer
# CHECK: to 2022-04-08