diff options
author | 2014-05-28 01:32:09 -0400 | |
---|---|---|
committer | 2014-05-28 01:32:09 -0400 | |
commit | 016a786eddabc2060dc52a75a8db7b77d737116c (patch) | |
tree | c4c1a157a40f492a14c8529995653ff31f3eda67 | |
parent | 051cbbb22737b7e1937bd12a5f222779de6cd982 (diff) | |
download | textadept-016a786eddabc2060dc52a75a8db7b77d737116c.tar.gz textadept-016a786eddabc2060dc52a75a8db7b77d737116c.zip |
Textadept's menus may be edited in-place via the `textadept.menu` module.
Any changes, even incremental ones, are reflected immediately.
As a result, removed `set_menubar()` and `set_contextmenus()` from API.
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | core/ui.lua | 43 | ||||
-rw-r--r-- | doc/14_Appendix.md | 3 | ||||
-rw-r--r-- | modules/textadept/menu.lua | 90 |
4 files changed, 95 insertions, 45 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 03925900..ce06ae03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -179,8 +179,7 @@ Changes: that do not flash the "black box" on Windows. * Added read-only access to the current key chain via [`keys.keychain`][]. * Renamed "hypertext" lexer and its corresponding module to "html". -* Added configurable tab context menus via - [`textadept.menu.set_contextmenus()`][]. +* Added configurable tab context menus via `textadept.menu.set_contextmenus()`. * New GUI theme for Mac OSX. * [Experimental] Merged separate lexer states into Textadept's Lua state. * Updated to [Lua][] 5.2.3. @@ -194,7 +193,6 @@ Changes: [`ui.maximized`]: api/ui.html#maximized [OSX environment variables]: 02_Installation.html#Environment.Variables [`keys.keychain`]: api/keys.html#keychain -[`textadept.menu.set_contextmenus()`]: api/textadept.menu.html#set_contextmenus [Lua]: http://lua.org [Scintilla]: http://scintilla.org diff --git a/core/ui.lua b/core/ui.lua index 128e16bd..8f40e2fa 100644 --- a/core/ui.lua +++ b/core/ui.lua @@ -7,14 +7,6 @@ local ui = ui -- Utilities for interacting with Textadept's user interface. -- @field title (string, Write-only) -- The title text of Textadept's window. --- @field context_menu --- The buffer's context menu, a [`ui.menu()`](#menu). --- This is a low-level field. You probably want to use the higher-level --- `textadept.menu.set_contextmenus()`. --- @field tab_context_menu --- The context menu for the buffer's tab, a [`ui.menu()`](#menu). --- This is a low-level field. You probably want to use the higher-level --- `textadept.menu.set_contextmenus()`. -- @field clipboard_text (string) -- The text on the clipboard. -- @field statusbar_text (string, Write-only) @@ -397,13 +389,33 @@ events_connect(events.ERROR, ui.print) --[[ The tables below were defined in C. --- --- A table of menus defining a menubar. (Write-only) --- @see textadept.menu.set_menubar +-- A table of menus defining a menubar. +-- This is a low-level field. You probably want to use the higher-level +-- `textadept.menu.menubar`. +-- @see textadept.menu.menubar -- @class table -- @name menubar local menubar --- +-- A menu userdata that defines the buffer's context menu. +-- This is a low-level field. You probably want to use the higher-level +-- `textadept.menu.context_menu`. +-- @see textadept.menu.context_menu +-- @class table +-- @name context_menu +local context_menu + +--- +-- A menu userdata that defines the context menu for the buffer's tab. +-- This is a low-level field. You probably want to use the higher-level +-- `textadept.menu.tab_context_menu`. +-- @see textadept.menu.tab_context_menu +-- @class table +-- @name tab_context_menu +local tab_context_menu + +--- -- A table containing the width and height pixel values of Textadept's window. -- @class table -- @name size @@ -459,9 +471,9 @@ local goto_view --- -- Low-level function for creating a menu from table *menu_table* and returning -- the userdata. --- You probably want to use the higher-level `textadept.menu.set_menubar()` --- or `textadept.menu.set_contextmenus()` functions. Emits a `MENU_CLICKED` --- event when a menu item is selected. +-- You probably want to use the higher-level `textadept.menu.menubar`, +-- `textadept.menu.context_menu`, or `textadept.menu.tab_context_menu` tables. +-- Emits a `MENU_CLICKED` event when a menu item is selected. -- @param menu_table A table defining the menu. It is an ordered list of tables -- with a string menu item, integer menu ID, and optional GDK keycode and -- modifier mask. The latter two are used to display key shortcuts in the @@ -471,8 +483,9 @@ local goto_view -- @usage ui.menu{{'_New', 1}, {'_Open', 2}, {''}, {'_Quit', 4}} -- @usage ui.menu{{'_New', 1, string.byte('n'), 4}} -- 'Ctrl+N' -- @see events.MENU_CLICKED --- @see textadept.menu.set_menubar --- @see textadept.menu.set_contextmenus +-- @see textadept.menu.menubar +-- @see textadept.menu.context_menu +-- @see textadept.menu.tab_context_menu -- @class function -- @name menu local menu diff --git a/doc/14_Appendix.md b/doc/14_Appendix.md index 2abec6b7..7ab00297 100644 --- a/doc/14_Appendix.md +++ b/doc/14_Appendix.md @@ -422,7 +422,7 @@ remove() |Renamed |toggle(false) **_M.textadept.editing** | | prepare\_for\_save() |Removed |N/A **_M.textadept.menu** | | -rebuild\_command\_tables() |Replaced|[set\_menubar()][] +rebuild\_command\_tables() |Replaced|set\_menubar() **_M.textadept.run** | | execute() |Replaced|[run()][] and [compile()][] **_M.textadept.session** | | @@ -431,7 +431,6 @@ prompt\_save() |Replaced|[save()][] [menu()]: api/ui.html#menu [toggle()]: api/textadept.bookmarks.html#toggle -[set\_menubar()]: api/textadept.menu.html#set_menubar [run()]: api/textadept.run.html#run [compile()]: api/textadept.run.html#compile [load()]: api/textadept.session.html#load 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 +}) |