1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
-------------------------------
-- luakit mode configuration --
-------------------------------
-- Table of modes and their callback hooks
local modes = {}
local lousy = require "lousy"
local join = lousy.util.table.join
local order = 0
-- Add new mode table (optionally merges with original mode)
function new_mode(name, desc, mode, replace)
assert(string.match(name, "^[%w-_]+$"), "invalid mode name: " .. name)
-- Detect optional description
if type(desc) == "table" then
desc, mode, replace = nil, desc, mode
end
local traceback = debug.traceback("Creation traceback:", 2)
order = order + 1
modes[name] = join({ order = order, traceback = traceback },
(not replace and modes[name]) or {}, mode or {},
{ name = name, desc = desc })
end
-- Get mode table
function get_mode(name) return modes[name] end
function get_modes() return lousy.util.table.clone(modes) end
-- Attach window & input bar signals for mode hooks
window.init_funcs.modes_setup = function (w)
-- Calls the `enter` and `leave` mode hooks.
w:add_signal("mode-changed", function (_, name, ...)
local leave = (w.mode or {}).leave
-- Get new modes functions/hooks/data
local mode = assert(modes[name], "invalid mode: " .. name)
-- Call last modes leave hook.
if leave then leave(w) end
-- Create w.mode object
w.mode = mode
-- Update window binds
w:update_binds(name)
-- Call new modes enter hook.
if mode.enter then mode.enter(w, ...) end
w:emit_signal("mode-entered", mode)
end)
local input = w.ibar.input
-- Calls the changed hook on input widget changed.
input:add_signal("changed", function ()
local changed = w.mode.changed
if changed then changed(w, input.text) end
end)
input:add_signal("property::position", function ()
local move_cursor = w.mode.move_cursor
if move_cursor then move_cursor(w, input.position) end
end)
-- Calls the `activate` hook on input widget activate.
input:add_signal("activate", function ()
local mode = w.mode
if mode and mode.activate then
local text, hist = input.text, mode.history
if mode.activate(w, text) == false then return end
-- Check if last history item is identical
if hist and hist.items and hist.items[hist.len or -1] ~= text then
table.insert(hist.items, text)
end
end
end)
end
-- Add mode related window methods
window.methods.set_mode = lousy.mode.set
local mget = lousy.mode.get
window.methods.is_mode = function (w, name) return name == mget(w) end
-- Setup normal mode
new_mode("normal", [[When luakit first starts you will find yourself in this
mode.]], {
enter = function (w)
w:set_prompt()
w:set_input()
end,
})
new_mode("all", [[Special meta-mode in which the bindings for this mode are
present in all modes.]])
-- Setup insert mode
new_mode("insert", [[When clicking on form fields luakit will enter the insert
mode which allows you to enter text in form fields without accidentally
triggering normal mode bindings.]], {
enter = function (w)
w:set_prompt("-- INSERT --")
w:set_input()
w.view:focus()
end,
-- Send key events to webview
passthrough = true,
})
new_mode("passthrough", [[Luakit will pass every key event to the WebView
until the user presses Escape.]], {
enter = function (w)
w:set_prompt("-- PASS THROUGH --")
w:set_input()
end,
-- Send key events to webview
passthrough = true,
-- Don't exit mode when clicking outside of form fields
reset_on_focus = false,
-- Don't exit mode on navigation
reset_on_navigation = false,
})
-- Setup command mode
new_mode("command", [[Enter commands.]], {
enter = function (w)
w:set_prompt()
w:set_input(":")
end,
changed = function (w, text)
-- Auto-exit command mode if user backspaces ":" in the input bar.
if not string.match(text, "^:") then w:set_mode() end
end,
activate = function (w, text)
w:set_mode()
local cmd = string.sub(text, 2)
if not string.find(cmd, "%S") then return end
local success, match = xpcall(
function () return w:match_cmd(cmd) end,
function (err) w:error(debug.traceback(err, 3)) end)
if success and not match then
w:error(string.format("Not a browser command: %q", cmd))
end
end,
history = {maxlen = 50},
})
new_mode("lua", [[Execute arbitrary Lua commands within the luakit
environment.]], {
enter = function (w)
w:set_prompt(">")
w:set_input("")
end,
activate = function (w, text)
w:set_input("")
local ret = assert(loadstring("return function(w) return "..text.." end"))()(w)
if ret then print(ret) end
end,
history = {maxlen = 50},
})
|