Skip to content

Commit

Permalink
lua: let number increment/decrement handle next number
Browse files Browse the repository at this point in the history
Operate on the next number to the right of the cursor,
for now the matches are not restricted to the current
line.

Based on a patch from Denis Warsow.

Close martanne#509
  • Loading branch information
martanne committed Mar 2, 2017
1 parent 76aa474 commit 5a4ec36
Showing 1 changed file with 47 additions and 37 deletions.
84 changes: 47 additions & 37 deletions lua/plugins/number-inc-dec.lua
Original file line number Diff line number Diff line change
@@ -1,52 +1,62 @@
-- increment/decrement number in dec/hex/oct format
local lexer = vis.lexers
if not lexer then return end
local lpeg = vis.lpeg
if not lexer or not lpeg then return end

local Cp = lpeg.Cp()
local dec_num = lpeg.S('+-')^-1 * lexer.dec_num
local pattern = lpeg.P{ Cp * (lexer.hex_num + lexer.oct_num + dec_num) * Cp + 1 * lpeg.V(1) }

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
vis.count = nil -- reset count, otherwise it affects next motion

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
-- poor man's continue statement, use break to process next cursor
repeat
local pos = cursor.pos
if not pos then break end
local word = file:text_object_word(pos);
if not word then break end
local data = file:content(word.start, 1024)
if not data then break end
local s, e = pattern:match(data)
if not s then break end
data = string.sub(data, s, e-1)
if #data == 0 then break end
-- align start and end for fileindex
s = word.start + s - 1
e = word.start + e - 1
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 not number then
vis:info("Not a number")
break
end
number = number + delta * count
-- string.format does not support negative hex/oct values
if base ~= 10 and number < 0 then 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
end
file:delete(s, e - s)
file:insert(s, number)
cursor.pos = s
until true
end
end

Expand Down

0 comments on commit 5a4ec36

Please sign in to comment.