summaryrefslogtreecommitdiff
path: root/.config/luakit/modes.lua
diff options
context:
space:
mode:
Diffstat (limited to '.config/luakit/modes.lua')
-rw-r--r--.config/luakit/modes.lua163
1 files changed, 163 insertions, 0 deletions
diff --git a/.config/luakit/modes.lua b/.config/luakit/modes.lua
new file mode 100644
index 0000000..bd15c67
--- /dev/null
+++ b/.config/luakit/modes.lua
@@ -0,0 +1,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},
+})