aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept/menu.lua
diff options
context:
space:
mode:
Diffstat (limited to 'modules/textadept/menu.lua')
-rw-r--r--modules/textadept/menu.lua90
1 files changed, 65 insertions, 25 deletions
diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua
index 55cf7ee6..dbb34292 100644
--- a/modules/textadept/menu.lua
+++ b/modules/textadept/menu.lua
@@ -6,6 +6,8 @@ local M = {}
--[[ This comment is for LuaDoc.
---
-- Defines the menus used by Textadept.
+-- Menus are simply tables and may be edited in place. Use the '#' operator
+-- (instead of `ipairs()`) for iteration.
-- If applicable, load this module last in your *~/.textadept/init.lua*, after
-- `textadept.keys` since it looks up defined key commands to show them in
-- menus.
@@ -15,7 +17,10 @@ local _L, buffer, view = _L, buffer, view
local editing, utils = textadept.editing, textadept.keys.utils
local SEPARATOR = {''}
+---
-- The default main menubar.
+-- @class table
+-- @name menubar
local menubar = {
{ title = _L['_File'],
{_L['_New'], buffer.new},
@@ -200,7 +205,10 @@ local menubar = {
},
}
+---
-- The default right-click context menu.
+-- @class table
+-- @name context_menu
local context_menu = {
{_L['_Undo'], buffer.undo},
{_L['_Redo'], buffer.redo},
@@ -213,7 +221,10 @@ local context_menu = {
{_L['Select _All'], buffer.select_all}
}
+---
-- The default tabbar context menu.
+-- @class table
+-- @name tab_context_menu
local tab_context_menu = {
{_L['_Close'], io.close_buffer},
SEPARATOR,
@@ -223,6 +234,11 @@ local tab_context_menu = {
{_L['Re_load'], io.reload_file},
}
+-- Table of proxy tables for menus.
+local proxies = {}
+
+local key_shortcuts, menu_actions, contextmenu_actions, items, commands
+
-- Returns the GDK integer keycode and modifier mask for a key sequence.
-- This is used for creating menu accelerators.
-- @param key_seq The string key sequence.
@@ -256,8 +272,6 @@ local function get_id(f)
return id
end
-local key_shortcuts, menu_actions, contextmenu_actions
-
-- 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.
@@ -305,9 +319,27 @@ local function build_command_tables(menu, title, items, commands)
end
end
-local items, commands
+-- Returns a proxy table for menu table *menu* such that when a menu item is
+-- changed or added, *update* is called to update the menu in the UI.
+-- @param menu The menu or table of menus to create a proxy for.
+-- @param update The function to call to update the menu in the UI when a menu
+-- item is changed or added.
+-- @param menubar Used internally to keep track of the top-level menu for
+-- calling *update* with.
+local function proxy_menu(menu, update, menubar)
+ return setmetatable({}, {
+ __index = function(t, k)
+ local v = menu[k]
+ return type(v) == 'table' and proxy_menu(v, update, menubar or menu) or v
+ end,
+ __newindex = function(t, k, v)
+ menu[k] = v
+ update(menubar or menu)
+ end,
+ __len = function(t) return #menu end,
+ })
+end
----
-- Sets `ui.menubar` from menu table *menubar*.
-- Each menu is an ordered list of menu items and has a `title` key for the
-- title text. Menu items are tables containing menu text and either a function
@@ -317,8 +349,7 @@ local items, commands
-- @param menubar The table of menu tables to create the menubar from.
-- @see ui.menubar
-- @see ui.menu
--- @name set_menubar
-function M.set_menubar(menubar)
+local function set_menubar(menubar)
key_shortcuts = {}
for key, f in pairs(keys) do key_shortcuts[get_id(f)] = key end
menu_actions = {}
@@ -329,18 +360,10 @@ function M.set_menubar(menubar)
ui.menubar = _menubar
items, commands = {}, {}
build_command_tables(menubar, nil, items, commands)
+ proxies.menubar = proxy_menu(menubar, set_menubar)
end
-M.set_menubar(menubar)
-
----
--- Sets `ui.context_menu` from menu item list *menu*.
--- Deprecated in favor of `set_contextmenus()`.
--- @param menu The menu table to create the context menu from.
--- @see set_contextmenus
--- @name set_contextmenu
-function M.set_contextmenu(menu) M.set_contextmenus(menu) end
+set_menubar(menubar)
----
-- Sets `ui.context_menu` and `ui.tab_context_menu` from menu item lists
-- *buffer_menu* and *tab_menu*, respectively.
-- Menu items are tables containing menu text and either a function to call or
@@ -354,14 +377,18 @@ function M.set_contextmenu(menu) M.set_contextmenus(menu) end
-- @see ui.context_menu
-- @see ui.tab_context_menu
-- @see ui.menu
--- @name set_contextmenus
-function M.set_contextmenus(buffer_menu, tab_menu)
+local function set_contextmenus(buffer_menu, tab_menu)
contextmenu_actions = {}
- ui.context_menu = ui.menu(read_menu_table(buffer_menu or context_menu, true))
- ui.tab_context_menu = ui.menu(read_menu_table(tab_menu or tab_context_menu,
- true))
+ local menu = buffer_menu or context_menu
+ ui.context_menu = ui.menu(read_menu_table(menu, true))
+ proxies.context_menu = proxy_menu(menu, set_contextmenus)
+ menu = tab_menu or tab_context_menu
+ ui.tab_context_menu = ui.menu(read_menu_table(menu, true))
+ proxies.tab_context_menu = proxy_menu(menu, function()
+ set_contextmenus(nil, menu)
+ end)
end
-if not CURSES then M.set_contextmenus() end
+if not CURSES then set_contextmenus() end
---
-- Prompts the user to select a menu command to run.
@@ -388,8 +415,8 @@ if not CURSES then
-- Set a language-specific context menu or the default one.
local function set_language_contextmenu()
local lang = _G.buffer:get_lexer()
- M.set_contextmenus(_M[lang] and _M[lang].context_menu,
- _M[lang] and _M[lang].tab_context_menu)
+ set_contextmenus(_M[lang] and _M[lang].context_menu,
+ _M[lang] and _M[lang].tab_context_menu)
end
events.connect(events.LEXER_LOADED, set_language_contextmenu)
events.connect(events.BUFFER_AFTER_SWITCH, set_language_contextmenu)
@@ -397,4 +424,17 @@ if not CURSES then
events.connect(events.BUFFER_NEW, set_language_contextmenu)
end
-return M
+return setmetatable(M, {
+ __index = function(t, k) return proxies[k] or M[k] end,
+ __newindex = function(t, k, v)
+ if k == 'menubar' then
+ set_menubar(v)
+ elseif k == 'context_menu' then
+ set_contextmenus(v)
+ elseif k == 'tab_context_menu' then
+ set_contextmenus(nil, v)
+ else
+ M[k] = v
+ end
+ end
+})