aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mitchell <70453897+667e-11@users.noreply.github.com>2016-06-15 08:50:11 -0400
committerGravatar mitchell <70453897+667e-11@users.noreply.github.com>2016-06-15 08:50:11 -0400
commit7150a93bfa47217e4f1f04acec868ab8163b242d (patch)
tree109c75ffe778800a333b679a87afc9c244a80f68
parentc39152342e7fe9bbb2cb15906428b18c310a1941 (diff)
Removed handling of tables as key/menu commands; use functions only.
-rw-r--r--core/keys.lua43
-rw-r--r--modules/textadept/menu.lua27
2 files changed, 18 insertions, 52 deletions
diff --git a/core/keys.lua b/core/keys.lua
index ced1ff80..6187b466 100644
--- a/core/keys.lua
+++ b/core/keys.lua
@@ -54,13 +54,10 @@ local M = {}
--
-- ## Commands
--
--- A command bound to a key sequence is either a Lua function or a table
--- containing a Lua function with a set of arguments to pass. They are
--- functionally equivalent; you can use either. Examples are:
+-- A command bound to a key sequence is simply a Lua function. For example:
--
-- keys['cn'] = buffer.new
-- keys['cz'] = buffer.undo
--- keys['a('] = {textadept.editing.enclose, '(', ')'}
-- keys['cu'] = function() io.quick_open(_USERHOME) end
--
-- Textadept handles [`buffer`]() references properly in static contexts.
@@ -98,7 +95,7 @@ local M = {}
-- keys['aa'] = {
-- a = function1,
-- b = function2,
--- c = {function3, arg1, arg2}
+-- c = {...}
-- }
-- @field CLEAR (string)
-- The key that clears the current key chain.
@@ -165,33 +162,14 @@ local function clear_key_sequence()
if #keychain == 1 then keychain[1] = nil else keychain = {} end
end
-local none = {}
-local function key_error(e) events.emit(events.ERROR, e) end
--- Runs a given command.
--- This is also used by *modules/textadept/menu.lua*.
--- @param command A function or table as described above.
--- @param command_type Equivalent to `type(command)`.
--- @return the value the command returns.
-M.run_command = function(command, command_type)
- local f, args = command_type == 'function' and command or command[1], none
- if command_type == 'table' then
- args = command
- -- If the argument is a view or buffer, use the current one instead.
- if type(args[2]) == 'table' then
- local mt, buffer, view = getmetatable(args[2]), buffer, view
- if mt == getmetatable(buffer) and args[2] ~= ui.command_entry then
- args[2] = buffer
- elseif mt == getmetatable(view) then
- args[2] = view
- end
- end
- end
- return select(2, xpcall(f, key_error, table.unpack(args, 2)))
-end
-
-- Return codes for `key_command()`.
local INVALID, PROPAGATE, CHAIN, HALT = -1, 0, 1, 2
+-- Error handler for key commands that simply emits the error. This is needed
+-- so `key_command()` can return `HALT` instead of never returning due to the
+-- error.
+local function key_error(e) events.emit(events.ERROR, e) end
+
-- Runs a key command associated with the current keychain.
-- @param prefix Optional prefix name for mode/lexer-specific commands.
-- @return `INVALID`, `PROPAGATE`, `CHAIN`, or `HALT`.
@@ -201,13 +179,12 @@ local function key_command(prefix)
if type(key) ~= 'table' then return INVALID end
key = key[keychain[i]]
end
- local key_type = type(key)
- if key_type ~= 'function' and key_type ~= 'table' then return INVALID end
- if key_type == 'table' and #key == 0 and next(key) or getmetatable(key) then
+ if type(key) ~= 'function' and type(key) ~= 'table' then return INVALID end
+ if type(key) == 'table' then
ui.statusbar_text = _L['Keychain:']..' '..table.concat(keychain, ' ')
return CHAIN
end
- return M.run_command(key, key_type) == false and PROPAGATE or HALT
+ return select(2, xpcall(key, key_error)) == false and PROPAGATE or HALT
end
-- Handles Textadept keypresses.
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index acbcdd9a..e09c6ca4 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -407,19 +407,6 @@ local function get_gdk_key(key_seq)
return code, modifiers
end
--- Get a string uniquely identifying a key binding.
--- This is used to match menu items with key bindings to show the key shortcut.
--- @param f A value in the `keys` table.
-local function get_id(f)
- local id = ''
- if type(f) == 'function' then
- id = tostring(f)
- elseif type(f) == 'table' then
- for i = 1, #f do id = id..tostring(f[i]) end
- end
- return id
-end
-
-- Creates a menu suitable for `ui.menu()` from the menu table format.
-- Also assigns key commands.
-- @param menu The menu to create a GTK+ menu from.
@@ -437,7 +424,7 @@ local function read_menu_table(menu, contextmenu)
local label, f = menu[i][1], menu[i][2]
local menu_id = not contextmenu and #menu_actions + 1 or
#contextmenu_actions + 1000 + 1
- local key, mods = get_gdk_key(key_shortcuts[get_id(f)])
+ local key, mods = get_gdk_key(key_shortcuts[tostring(f)])
gtkmenu[#gtkmenu + 1] = {label, menu_id, key, mods}
if f then
local actions = not contextmenu and menu_actions or contextmenu_actions
@@ -491,7 +478,7 @@ end
local function set_menubar(menubar)
if not menubar then ui.menubar = {} return end
key_shortcuts, menu_actions = {}, {} -- reset
- for key, f in pairs(keys) do key_shortcuts[get_id(f)] = key end
+ for key, f in pairs(keys) do key_shortcuts[tostring(f)] = key end
local _menubar = {}
for i = 1, #menubar do
_menubar[#_menubar + 1] = ui.menu(read_menu_table(menubar[i]))
@@ -532,9 +519,9 @@ events.connect(events.INITIALIZED, set_contextmenus)
events.connect(events.MENU_CLICKED, function(menu_id)
local actions = menu_id < 1000 and menu_actions or contextmenu_actions
local action = actions[menu_id < 1000 and menu_id or menu_id - 1000]
- assert(type(action) == 'function' or type(action) == 'table',
+ assert(type(action) == 'function',
_L['Unknown command:']..' '..tostring(action))
- keys.run_command(action, type(action))
+ action()
end)
---
@@ -551,7 +538,7 @@ function M.select_command()
elseif menu[i][1] ~= '' then
local label = menu.title and menu.title..': '..menu[i][1] or menu[i][1]
items[#items + 1] = label:gsub('_([^_])', '%1')
- items[#items + 1] = key_shortcuts[get_id(menu[i][2])] or ''
+ items[#items + 1] = key_shortcuts[tostring(menu[i][2])] or ''
commands[#commands + 1] = menu[i][2]
end
end
@@ -562,7 +549,9 @@ function M.select_command()
items = items, width = CURSES and ui.size[1] - 2 or nil
}
if button ~= 1 or not i then return end
- keys.run_command(commands[i], type(commands[i]))
+ assert(type(commands[i]) == 'function',
+ _L['Unknown command:']..' '..tostring(commands[i]))
+ commands[i]()
end
return setmetatable(M, {