vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit ac35ab5df35defe9d5bee2f0c6a9464ba3aee5ce
parent 9b5df4d082576002408e513f0c870679af299835
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Tue, 28 Feb 2017 10:23:59 +0100

lua: reimplement number increment <C-a> and decrement <C-x>

Based on a patch by Denis Warsow.

Stuff which could probably be improved:

 - in vim the cursor does not need to be on top of the number,
   it suffices to be on the same line.

 - decrementing beyond zero does not work for hexadecimal and
   octal numbers, vim seems to wrap around in this case.

     0x00000000 <C-x> becomes 0xffffffff

Close #506

Diffstat:
Alua/plugins/number-inc-dec.lua | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mlua/vis-std.lua | 1+
2 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/lua/plugins/number-inc-dec.lua b/lua/plugins/number-inc-dec.lua @@ -0,0 +1,54 @@ +-- increment/decrement number in dec/hex/oct format +local lexer = vis.lexers +if not lexer then return end + +local change = function(delta) + + local win = vis.win + local file = win.file + local count = vis.count + if not count then count = 1 end + vis.count = nil -- reset count + + for cursor in win:cursors_iterator() do + local pos = cursor.pos + local word = file:text_object_word(pos); + local s, e = word.start, word.finish; + if s then + local data = file:content(s, e - s) + if data and #data > 0 then + local base, format, padding = 10, 'd', 0 + if lexer.oct_num:match(data) then + base = 8 + format = 'o' + padding = #data + elseif lexer.hex_num:match(data) then + base = 16 + format = 'x' + padding = #data - #"0x" + end + local number = tonumber(data, base == 8 and 8 or nil) + if number then + number = number + delta * count + if base ~= 10 and number < 0 then + -- string.format does not handle negative hex/oct values + -- should we wrap around? + number = 0 + end + number = string.format((base == 16 and "0x" or "") .. "%0"..padding..format, number) + if base == 8 and string.sub(number, 0, 1) ~= "0" then + number = '0' .. number + end + file:delete(s, e - s) + file:insert(s, number) + cursor.pos = s + else + vis:info("Not a number") + end + end + end + end +end + +vis:map(vis.modes.NORMAL, "<C-a>", function() change( 1) end, "Increment number") +vis:map(vis.modes.NORMAL, "<C-x>", function() change(-1) end, "Decrement number") diff --git a/lua/vis-std.lua b/lua/vis-std.lua @@ -128,3 +128,4 @@ end) require('plugins/filetype') require('plugins/textobject-lexer') require('plugins/digraph') +require('plugins/number-inc-dec')