Fix the del_word function to delete left one word & retain cursor pos
[luakit.git] / lib / bind.lua
blobdd65c0d4be4a2555f3761049eef71f69742f00dc
1 local table = table
2 local setmetatable = setmetatable
3 local print = print
4 local pairs = pairs
5 local ipairs = ipairs
6 local assert = assert
7 local type = type
8 local util = require("util")
9 local unpack = unpack
10 local string = string
12 module("bind")
14 -- Weak table of argects and their buffers
15 local buffers = {}
16 setmetatable(buffers, { __mode = "k" })
18 -- Modifiers to ignore
19 ignore_modifiers = { "Mod2", "Lock" }
21 -- Return cloned, sorted & filtered modifier mask table.
22 function filter_mods(mods, remove_shift)
23 -- Clone & sort new modifiers table
24 local mods = util.table.clone(mods)
25 table.sort(mods)
27 -- Filter out ignored modifiers
28 mods = util.table.difference(mods, ignore_modifiers)
30 if remove_shift then
31 mods = util.table.difference(mods, { "Shift" })
32 end
34 return mods
35 end
37 -- Create new key binding
38 function key(mods, key, func, opts)
39 local mods = filter_mods(mods, #key == 1)
40 return { mods = mods, key = key, func = func, opts = opts}
41 end
43 -- Create new buffer binding
44 function buf(pattern, func, opts)
45 return { pattern = pattern, func = func, opts = opts}
46 end
48 -- Create new command binding
49 function cmd(commands, func, opts)
50 return { commands = commands, func = func, opts = opts}
51 end
53 -- Check if there exists a key binding in the `binds` table which matches the
54 -- pressed key and modifier mask and execute it.
55 function match_key(binds, mods, key, arg)
56 for _, b in ipairs(binds) do
57 if b.key == key and util.table.isclone(b.mods, mods) then
58 b.func(arg, b.opts)
59 return true
60 end
61 end
62 end
64 -- Check if there exists a buffer binding in the `binds` table which matches
65 -- the given buffer and execute it.
66 function match_buf(binds, buffer, arg)
67 for _, b in ipairs(binds) do
68 if b.pattern and string.match(buffer, b.pattern) then
69 b.func(arg, buffer, b.opts)
70 return true
71 end
72 end
73 end
75 -- Check if there exists a buffer binding in the `binds` table which matches
76 -- the given buffer and execute it.
77 function match_cmd(binds, buffer, arg)
78 -- The command is the first word in the buffer string
79 local command = string.match(buffer, "^([^%s]+)")
80 -- And the argument is the entire string thereafter
81 local argument = string.match(buffer, "^[^%s]+%s+(.+)")
83 for _, b in ipairs(binds) do
84 -- Command matching
85 if b.commands and util.table.hasitem(b.commands, command) then
86 b.func(arg, argument, b.opts)
87 return true
88 -- Buffer matching
89 elseif b.pattern and string.match(buffer, b.pattern) then
90 b.func(arg, buffer, b.opts)
91 return true
92 end
93 end
94 end
96 -- Check if a bind exists with the given key & modifier mask then call the
97 -- binds function with `arg` as the first argument.
98 function hit(binds, mods, key, buffer, enable_buffer, arg)
99 -- Filter modifers table
100 local mods = filter_mods(mods, #key == 1)
102 if (not buffer or not enable_buffer) or #mods ~= 0 or #key ~= 1 then
103 if match_key(binds, mods, key, arg) then
104 return true
108 if not enable_buffer or #mods ~= 0 then
109 return false
111 elseif #key == 1 then
112 buffer = (buffer or "") .. key
113 if match_buf(binds, buffer, arg) then
114 return true
118 if buffer then
119 return true, buffer:sub(1, 10)
121 return true
124 -- vim: ft=lua:et:sw=4:ts=8:sts=4:tw=80