Released version 3-2014010502
[notion.git] / contrib / keybindings / vim_bindings.lua
blob1780ae4b14d37fdfa7eab2adaef219732f4d4d2b
1 -- Authors: Unknown
2 -- License: Unknown
3 -- Last Changed: Unknown
4 --
5 -- vim-bindings.lua
6 --
7 -- This only affects queries.
8 --
9 -- Features:
10 -- Vi-keys for normal and insert modes.
11 -- Vim-style highlighting.
12 -- Numbered prefixes work for most maneuvers.
13 --
14 -- Limitations:
15 -- All WEdln objects share the same mode and undo history.
16 -- No r replace
17 -- No . repeat last action
18 -- No character search.
19 -- 3cw will work; c3w won't.
20 -- Not all unused symbols are silenced in normal mode
21 -- (so don't type them)
22 -- Use Shift+Insert to paste from other apps, p to paste yanked text.
24 vim={clip="",old="",oldpoint=0}
25 function vim.normal_mode()
26 defbindings("WEdln", {
27 kpress("a", "{WEdln.forward(_), vim.insert_mode(), vim.savehist(_)}"),
28 kpress("Shift+a", "{WEdln.eol(_), vim.insert_mode(), vim.savehist(_)}"),
29 kpress("b", "vim.multiply(WEdln.bskip_word, _)"),
30 kpress("Shift+b", "vim.multiply(WEdln.bskip_word, _)"),
31 submap("c", {
32 kpress("b", "vim.yank(_, 'b', true, true)"),
33 kpress("c", "vim.yank(_, 'd', true, true)"),
34 kpress("h", "vim.yank(_, 'h', true, true)"),
35 kpress("l", "vim.yank(_, 'l', true, true)"),
36 kpress("w", "vim.yank(_, 'w', true, true)"),
37 kpress("0", "vim.yank(_, '0', true, true)"),
38 kpress("Shift+6", "vim.yank(_, '0', true, true)"),
39 kpress("Shift+4", "vim.yank(_, 'D', true, true)"),
40 }),
41 kpress("Shift+c", "vim.yank(_, 'D', true, true)"),
42 submap("d", {
43 kpress("b", "vim.yank(_, 'b', true)"),
44 kpress("d", "vim.yank(_, 'd', true)"),
45 kpress("h", "vim.yank(_, 'h', true)"),
46 kpress("l", "vim.yank(_, 'l', true)"),
47 kpress("w", "vim.yank(_, 'w', true)"),
48 kpress("0", "vim.yank(_, '0', true)"),
49 kpress("Shift+6", "vim.yank(_, '0', true)"),
50 kpress("Shift+4", "vim.yank(_, 'D', true)"),
51 }),
52 kpress("Shift+d", "vim.yank(_, 'D', true)"),
53 kpress("e", "{_:forward(), vim.multiply(WEdln.skip_word,_), _:back()}"),
54 kpress("Shift+e", "{_:forward(), vim.multiply(WEdln.skip_word,_), _:back()}"),
55 kpress("f", "vim.cleardigit()"),
56 kpress("g", "vim.cleardigit()"),
57 kpress("h", "vim.multiply(WEdln.back,_)"),
58 kpress("i", "{vim.insert_mode(), vim.savehist(_)}"),
59 kpress("Shift+i", "{WEdln.bol(_), vim.insert_mode(), vim.savehist(_)}"),
60 kpress("j", "vim.multiply(WEdln.history_next, _)"),
61 kpress("k", "vim.multiply(WEdln.history_prev, _)"),
62 kpress("Control+n", "vim.multiply(WEdln.history_next, _)"),
63 kpress("Control+p", "vim.multiply(WEdln.history_prev, _)"),
64 kpress("l", "vim.multiply(WEdln.forward, _)"),
65 kpress("m", "vim.cleardigit()"),
66 kpress("n", "vim.cleardigit()"),
67 kpress("o", "vim.cleardigit()"),
68 kpress("p", "{WEdln.forward(_), vim.multiply(vim.paste,_,true),"
69 .."WEdln.back(_)}"),
70 kpress("Shift+p", "vim.multiply(vim.paste,_,true)"),
71 kpress("q", "vim.cleardigit()"),
72 kpress("r", "vim.cleardigit()"),
73 kpress("s", "vim.yank(_, 'l', true, true)"),
74 kpress("Shift+s", "vim.yank(_, 'd', true, true)"),
75 kpress("t", "vim.cleardigit()"),
76 kpress("u", "vim.undo(_)"),
77 kpress("v", "vim.highlight(_)"),
78 kpress("w", "vim.multiply(WEdln.skip_word, _)"),
79 kpress("Shift+w", "vim.multiply(WEdln.skip_word, _)"),
80 kpress("x", "vim.x(_)"),
81 kpress("Shift+x", "vim.yank(_, 'h', true)"),
82 kpress("y", "vim.yank(_)"),
83 kpress("Shift+y", "vim.yank(_, 'd')"),
84 kpress("z", "vim.cleardigit()"),
85 kpress("0", "vim.zero(_)"),
86 kpress("1", "vim.dodigit(1)"),
87 kpress("2", "vim.dodigit(2)"),
88 kpress("3", "vim.dodigit(3)"),
89 kpress("4", "vim.dodigit(4)"),
90 kpress("5", "vim.dodigit(5)"),
91 kpress("6", "vim.dodigit(6)"),
92 kpress("7", "vim.dodigit(7)"),
93 kpress("8", "vim.dodigit(8)"),
94 kpress("9", "vim.dodigit(9)"),
95 kpress("Shift+6", "{vim.cleardigit(), WEdln.bol(_)}"),
96 kpress("Shift+4", "{vim.cleardigit(), WEdln.eol(_)}"),
97 kpress("BackSpace", "vim.multiply(WEdln.back, _)"),
98 kpress("space", "vim.multiply(WEdln.forward, _)"),
99 kpress("Shift+grave", "vim.multiply(vim.switchcase,_,true)"),
100 kpress("Control+A", "vim.multiply(vim.increment, _)"),
101 kpress("Control+X", "vim.multiply(vim.decrement, _)"),
103 kpress("Shift+f", "vim.cleardigit()"),
104 kpress("Shift+g", "vim.cleardigit()"), kpress("Shift+h", "vim.cleardigit()"),
105 kpress("Shift+j", "vim.cleardigit()"), kpress("Shift+k", "vim.cleardigit()"),
106 kpress("Shift+l", "vim.cleardigit()"), kpress("Shift+m", "vim.cleardigit()"),
107 kpress("Shift+n", "vim.cleardigit()"), kpress("Shift+o", "vim.cleardigit()"),
108 kpress("Shift+q", "vim.cleardigit()"), kpress("Shift+r", "vim.cleardigit()"),
109 kpress("Shift+t", "vim.cleardigit()"), kpress("Shift+u", "vim.cleardigit()"),
110 kpress("Shift+v", "vim.cleardigit()"),
111 kpress("Shift+z", "vim.cleardigit()"), kpress("Shift+0", "vim.cleardigit()"),
112 kpress("Shift+1", "vim.cleardigit()"), kpress("Shift+2", "vim.cleardigit()"),
113 kpress("Shift+3", "vim.cleardigit()"), kpress("Shift+5", "vim.cleardigit()"),
114 kpress("Shift+7", "vim.cleardigit()"), kpress("Shift+8", "vim.cleardigit()"),
115 kpress("Shift+9", "vim.cleardigit()"),
119 function vim.insert_mode()
120 for _,edln in pairs(ioncore.region_list("WEdln")) do
121 edln:clear_mark()
123 defbindings("WEdln", {
124 kpress("Control+w", "WEdln.bkill_word(_)"),
125 kpress("Control+n", "WEdln.next_completion(_, true)"),
126 kpress("Control+p", "WEdln.prev_completion(_, true)"),
127 kpress("Escape", "vim.normal_mode()"),
128 kpress("Control+bracketleft", "vim.normal_mode()"),
130 kpress("BackSpace", "WEdln.backspace(_)"),
131 kpress("Mod1+BackSpace", "WEdln.bkill_word(_)"),
132 kpress("a", nil), kpress("b", nil), kpress("c", nil),
133 kpress("d", nil), kpress("e", nil), kpress("f", nil),
134 kpress("g", nil), kpress("h", nil), kpress("i", nil),
135 kpress("j", nil), kpress("k", nil), kpress("l", nil),
136 kpress("m", nil), kpress("n", nil), kpress("o", nil),
137 kpress("p", nil), kpress("q", nil), kpress("r", nil),
138 kpress("s", nil), kpress("t", nil), kpress("u", nil),
139 kpress("v", nil), kpress("w", nil), kpress("x", nil),
140 kpress("y", nil), kpress("z", nil), kpress("0", nil),
141 kpress("1", nil), kpress("2", nil), kpress("3", nil),
142 kpress("4", nil), kpress("5", nil), kpress("6", nil),
143 kpress("7", nil), kpress("8", nil), kpress("9", nil),
144 kpress("Shift+a", nil), kpress("Shift+b", nil), kpress("Shift+c", nil),
145 kpress("Shift+d", nil), kpress("Shift+e", nil), kpress("Shift+f", nil),
146 kpress("Shift+g", nil), kpress("Shift+h", nil), kpress("Shift+i", nil),
147 kpress("Shift+j", nil), kpress("Shift+k", nil), kpress("Shift+l", nil),
148 kpress("Shift+m", nil), kpress("Shift+n", nil), kpress("Shift+o", nil),
149 kpress("Shift+p", nil), kpress("Shift+q", nil), kpress("Shift+r", nil),
150 kpress("Shift+s", nil), kpress("Shift+t", nil), kpress("Shift+u", nil),
151 kpress("Shift+v", nil), kpress("Shift+w", nil), kpress("Shift+x", nil),
152 kpress("Shift+y", nil), kpress("Shift+z", nil), kpress("Shift+0", nil),
153 kpress("Shift+1", nil), kpress("Shift+2", nil), kpress("Shift+3", nil),
154 kpress("Shift+4", nil), kpress("Shift+5", nil), kpress("Shift+6", nil),
155 kpress("Shift+7", nil), kpress("Shift+8", nil), kpress("Shift+9", nil),
156 kpress("space", nil),
157 kpress("Shift+grave", nil),
158 kpress("Control+A", nil),
159 kpress("Control+X", nil),
163 defbindings("WInput", {
164 kpress("Control+C", "{vim.cleardigit(), WInput.cancel(_)}"),
165 kpress("Control+F", "WInput.scrollup(_)"),
166 kpress("Control+B", "WInput.scrolldown(_)"),
167 kpress("Page_Up", "WInput.scrollup(_)"),
168 kpress("Page_Down", "WInput.scrolldown(_)"),
170 defbindings("WEdln", {
171 kpress("Shift+Insert", "WEdln.paste(_)"),
172 kpress("Return", "{vim.cleardigit(), WEdln.finish(_)}"),
175 function vim.yank(edln, how, kill, insert)
176 vim.old=edln:contents()
177 vim.oldpoint=edln:point()
178 local first,last
179 local n=1
180 if vim.digit1 then n=vim.digit1 end
181 if vim.digit10 then n=n+10*vim.digit10 end
183 if edln:mark() < 0 then
184 edln:set_mark()
185 for i=1,n do
186 if how=="b" then
187 edln:bskip_word()
188 elseif how=="D" then
189 edln:eol()
190 elseif how=="d" then
191 edln:bol()
192 edln:set_mark()
193 edln:eol()
194 elseif how=="h" then
195 edln:back()
196 elseif how=="l" then
197 edln:forward()
198 elseif how=="w" then
199 edln:skip_word()
200 elseif how=="0" then
201 edln:bol()
205 first=edln:mark()+1
206 last=edln:point()
207 if first>last then
208 first=last+1
209 last=edln:mark()
211 vim.clip=string.sub(edln:contents(), first, last)
212 if kill then
213 edln:cut()
214 else
215 edln:copy()
217 edln:clear_mark() -- just in case?
218 vim.cleardigit()
219 if insert then
220 vim.insert_mode()
224 function vim.undo(edln)
225 local str=edln:contents()
226 edln:kill_line()
227 edln:insstr(vim.old)
228 vim.old=str
229 edln:bol()
230 for i=1,vim.oldpoint do
231 edln:forward()
235 function vim.savehist(edln)
236 vim.old=edln:contents()
237 vim.oldpoint=edln:point()
240 function vim.zero(edln)
241 if vim.digit1 then
242 vim.dodigit(0)
243 else
244 edln:bol()
245 vim.cleardigit()
249 function vim.x(edln)
250 -- x is only a backspace when there is nothing ahead.
251 if string.len(edln:contents()) == edln:point() then
252 vim.yank(edln, 'h', true)
253 else
254 vim.yank(edln, 'l', true)
258 function vim.highlight(edln)
259 if edln:mark() > -1 then
260 edln:clear_mark()
261 else
262 edln:set_mark()
264 vim.cleardigit()
267 function vim.paste(edln)
268 -- if something is highlighted, replace it.
269 local clip2=vim.clip
270 if edln:mark() > -1 then
271 first=edln:mark()+1
272 last=edln:point()
273 if first>last then
274 first=last+1
275 last=edln:mark()
277 vim.clip=string.sub(edln:contents(), first, last)
278 edln:cut()
280 edln:insstr(clip2)
281 vim.cleardigit()
284 function vim.multiply(f, edln, addtohistory)
285 if edln and addtohistory then
286 vim.old=edln:contents()
287 vim.oldpoint=edln:point()
289 local n=1
290 if vim.digit1 then n=vim.digit1 end
291 if vim.digit10 then n=n+10*vim.digit10 end
292 for i=1,n do
293 f(edln)
295 vim.cleardigit()
298 function vim.dodigit(digit)
299 vim.digit10=vim.digit1
300 vim.digit1=digit
303 function vim.cleardigit()
304 -- This function needs to go almost everywhere. Doing the wrong thing
305 -- 10 times because a number was pressed ages ago, would be bad.
306 vim.digit1=nil
307 vim.digit10=nil
310 function vim.switchcase(edln)
311 local c=string.sub(edln:contents(), edln:point()+1, edln:point()+1)
312 if string.find(c, "%u") then
313 edln:delete()
314 edln:insstr(string.lower(c))
315 elseif string.find(c, "%l") then
316 edln:delete()
317 edln:insstr(string.upper(c))
318 else
319 edln:forward()
323 function vim.decrement(edln)
324 local c=string.sub(edln:contents(), edln:point()+1, edln:point()+1)
325 if string.find(c, "%d") then
326 edln:delete()
327 c=c-1
328 if c==-1 then c=9 end
329 edln:insstr(tostring(c))
330 edln:back()
334 function vim.increment(edln)
335 local c=string.sub(edln:contents(), edln:point()+1, edln:point()+1)
336 if string.find(c, "%d") then
337 edln:delete()
338 c=c+1
339 if c==10 then c=0 end
340 edln:insstr(tostring(c))
341 edln:back()
345 vim.normal_mode()
346 vim.insert_mode()