diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2017-03-01 22:00:05 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2017-03-02 12:05:40 +0100 |
| commit | 5a4ec36070aed439d509870b793a008fee24a48f (patch) | |
| tree | 2f2fece9fbd50c0e92831c2a2b73db7e94ef7222 /lua | |
| parent | 76aa4748dea85bd39970723539289ebb238a0931 (diff) | |
| download | vis-5a4ec36070aed439d509870b793a008fee24a48f.tar.gz vis-5a4ec36070aed439d509870b793a008fee24a48f.tar.xz | |
lua: let number increment/decrement handle next number
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 #509
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/plugins/number-inc-dec.lua | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/lua/plugins/number-inc-dec.lua b/lua/plugins/number-inc-dec.lua index a165b5a..e2f5f2e 100644 --- a/lua/plugins/number-inc-dec.lua +++ b/lua/plugins/number-inc-dec.lua @@ -1,6 +1,11 @@ -- 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) @@ -8,45 +13,50 @@ local change = function(delta) 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 |
