aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorgi Kirilov <in.the@repo>2020-05-19 07:54:45 +0300
committerGeorgi Kirilov <in.the@repo>2020-05-19 08:01:55 +0300
commit5303063d777f029dcab86ae32fed18c7732d769a (patch)
tree0ae8a4eb7b7f7ef23a88021b8e31fc2fb149f28d
parent625478be10c8860ce0035e0f65feef54f0f5712c (diff)
downloadvis-toggler-5303063d777f029dcab86ae32fed18c7732d769a.tar.gz
inc/dec words and numbers at or after the cursor
-rw-r--r--defaults.lua36
-rw-r--r--init.lua49
2 files changed, 49 insertions, 36 deletions
diff --git a/defaults.lua b/defaults.lua
index a1363aa..5c634b3 100644
--- a/defaults.lua
+++ b/defaults.lua
@@ -3,7 +3,6 @@ return {
{"high", "low"},
{"horizontal", "vertical"},
{"in", "out"},
- {"inner", "outer"},
{"left", "right"},
{"top", "bottom"},
{"up", "down"},
@@ -60,7 +59,6 @@ return {
{"width", "height"},
{"x", "y"},
- {"0", "1"},
{"enabled", "disabled"},
{"enable", "disable"},
{"on", "off"},
@@ -69,30 +67,14 @@ return {
{"header", "footer"},
- -- The tokens below can't be reliably matched by the built-in word textobject.
- --
- -- TODO (maybe): automatically generate a Lua pattern from all the words
- -- in the configuration table, then:
- -- region = {start = selection.range.start - horizon, finish = selection.range.finish + horizon}
- -- match the pattern against file:content(region)
- -- and find the match that contains selection.pos.
+ {"[]", "{}"},
- -- {"[]", "{}"},
- -- {"(", ")"},
- -- {"[", "]"},
- -- {"{", "}"},
- -- {"'", "\"", "`"},
-
- -- {"*=", "/="},
- -- {"*", "/"},
- -- {"&&", "||"},
- -- {"&", "|"},
- -- {"++", "--"},
- -- {"+=", "-="},
- -- {"+", "-"},
- -- {"<<", ">>"},
- -- {"<=", ">="},
- -- {"<", ">"},
- -- {"===", "!=="},
- -- {"==", "!="},
+ {"&&", "||"},
+ {"*=", "/="},
+ {"++", "--"},
+ {"+=", "-="},
+ {"<<", ">>"},
+ {"<=", ">="},
+ {"===", "!=="},
+ {"==", "!="},
}
diff --git a/init.lua b/init.lua
index a08e5da..3f4e146 100644
--- a/init.lua
+++ b/init.lua
@@ -6,13 +6,45 @@
require("vis")
local vis = vis
+require("lpeg")
+local l = lpeg
+local Cc, Cmt, Cp, P, R, V = l.Cc, l.Cmt, l.Cp, l.P, l.R, l.V
+
local M = {}
+
+-- Inverted and unrolled config table.
+-- With this table format, make_shift() can use the same logic for both numeric and word increment/decrement.
local lookup = {}
+
+-- Pattern that matches any one of the words listed in the config table.
+local ordinal_words
+
local count
-local inner_word = 0
local char_next = 17
+local function at_or_after(_, _, pos, start, finish)
+ if start and finish then
+ if pos >= start and pos < finish or pos < start then
+ return true, start, finish
+ end
+ end
+end
+
+local function ordinal(win, pos)
+ local selection
+ for s in win:selections_iterator() do
+ if s.pos == pos then selection = s break end
+ end
+ local line = win.file.lines[selection.line]
+ local dec_num = P"-"^-1 * R"09"^1
+ local patt = dec_num + ordinal_words
+ local start, finish = P{Cmt(Cc(selection.col) * Cp() * patt * Cp(), at_or_after) + 1 * V(1)}:match(line)
+ if not (start and finish) then return end
+ local line_begin = selection.pos - selection.col + 1
+ return line_begin + start - 1, line_begin + finish - 1
+end
+
local function toggle(func, motion)
return function(file, range, pos)
local word = file:content(range)
@@ -70,27 +102,26 @@ local function operator_new(key, handler, object, motion, help, novisual)
end
end
--- Inverts and unrolls all config table entries.
--- With this table format, make_shift() can use the same logic for both numeric and word increment/decrement.
--- The original format is more sensible to humans, though.
local function preprocess(tbl)
- local cfg = {}
+ local cfg, ord = {}, P(-1)
for _, options in ipairs(tbl) do
for i, key in ipairs(options) do
cfg[key] = {i, options}
+ ord = ord + key
end
end
- return cfg
+ return cfg, ord
end
vis.events.subscribe(vis.events.INIT, function()
- operator_new("<C-a>", toggle(increment), inner_word, nil, "Toggle/increment word or selection", true)
- operator_new("<C-x>", toggle(decrement), inner_word, nil, "Toggle/decrement word or selection", true)
+ local ord_next = vis:textobject_register(ordinal)
+ operator_new("<C-a>", toggle(increment), ord_next, nil, "Toggle/increment word or number", true)
+ operator_new("<C-x>", toggle(decrement), ord_next, nil, "Toggle/decrement word or number", true)
operator_new("~", toggle(case, true), nil, char_next, "Toggle case of character or selection")
operator_new("g~", toggle(case), nil, nil, "Toggle-case operator")
operator_new("gu", toggle(string.lower), nil, nil, "Lower-case operator")
operator_new("gU", toggle(string.upper), nil, nil, "Upper-case operator")
- lookup = preprocess(M)
+ lookup, ordinal_words = preprocess(M)
vis:map(vis.modes.NORMAL, "g~~", "g~il")
vis:map(vis.modes.NORMAL, "guu", "guil")
vis:map(vis.modes.NORMAL, "gUU", "gUil")