Re: [code] [Textadept] menu suggestion

From: Gabriel Dubatti <>
Date: Thu, 12 Jan 2017 15:22:26 -0300

El 06/01/2017 a las 10:49, Mitchell escribió:
> Hi Gabriel,
> On Thu, 5 Jan 2017, Gabriel Dubatti wrote:
>> Hi Mitchell,
>> I tried to replace the menu module with my own version in
>> ~/modules/textadept/menu.lua
>> and found that this module is tightly coupled with the keys module,
>> so this module should also be replaced if you want to roll your own
>> menu.
>> I'm referring to code like this:
>> menu.lua:
>> {_L['Select to _Matching Brace'], function()
>> textadept.editing.match_brace('select') end},
>> keys.lua:
>> local m_sel = m_edit[_L['_Select']]
>> keys[GUI and 'cM' or 'mM'] = m_sel[_L['Select to _Matching
>> Brace']][2]
>> Using their own functions, like in:
>> {_L['_Highlight Word'], textadept.editing.highlight_word},
>> keys[not OSX and 'caH' or 'mH'] = textadept.editing.highlight_word
>> Is much cleaner, decoupled and easy to call this commands from
>> scripts (after all, they have a menu and an accelerator, so they are
>> really useful commands).
>> There are near 70 functions in this situation....
>> Just my two cents.
> Yes, if you want to totally replace the menu and have your keybindings
> accurately reflected in the menu accelerators, you'll have to update
> some of your keybindings to reference the same functions that the
> menus do (anonymous functions in particular). Note that the menu
> accelerators are for informative purposes only -- even if there is no
> accelerator shown, a keybinding will still work.
> Cheers,
> Mitchell

Hi Mitchell,

I finally replaced menu.lua and keys.lua locally adding what I call
"actions" (commands that can be run from menues and/or buttons).

["action"]={"menu-text", exec(), ["icon"], [status()]} --status()= nil
or 0=enabled, 1=checked, 2=unchecked, 3=radio-checked,
4=radio-unchecked, +8=disabled

I plan to use "icon" and status() with my toolbar (these fields are not
used by default).


The menu definition is very similar to the current menu.lua but divided
into two halves:

actions.list = {
   ["new"]= {_L['_New'],},
   ["open"]= {_L['_Open'], io.open_file},
   ["about"]= {_L['_About'], function()
         title = 'Textadept', text = _RELEASE, informative_text =
         icon_file = _HOME..'/core/images/ta_64x64.png'

actions.menubar = {
     title = _L['_File'],
     title = _L['_Edit'],
       title = _L['_Select'],
     title = _L['_Help'],

actions.context_menu = { {"undo","redo",SEPARATOR,
"cut","copy","paste","delete_char",SEPARATOR, "selectall"} }

actions.tab_context_menu = { {"close",SEPARATOR,
"save","saveas",SEPARATOR, "reload"} }

Only the action name is used to define menus and accelerators (you don't
need to bind to the same code twice).

Each action has a unique ID equal to the position in the actions table
(that ID is used for creating gtk menus).

The click event code do not need to differentiate between menus and
context menus because both use the same actions ID.

-- Performs the appropriate action when clicking a menu item.
events.connect(events.MENU_CLICKED, function(menu_id)
   local act = actions.action_fromid[menu_id]
   local action = actions.list[act][2]
   assert(type(action) == 'function', _L['Unknown command:']..'


The key module handles the accelerators.

The default accelerators are loaded in a table that can be edited by
other modules before defining the keys[] bindings in the INITIALIZED event.

local default_accelerators= {
   "new", "cn", "mn", "cmn",
   "undo", "cz", "mz", {"cz","mz"}, --^Z suspends in some
   "redo", {"cy","cZ"}, "my", {"cy","cZ"},

--load the accelerators for this OS
local function load_accel_lists()
   actions.accelerators = {}
   local col= not CURSES and (OSX and 2 or 1) or 3
   for i=1, #default_accelerators, 4 do
     local act=default_accelerators[i]
     local key=default_accelerators[i+col]

~~~~~~~~~SOME USE EXAMPLES ~~~~~~~~
--make sure no action already uses this keys
keys.f3 = function() goto_nearest_occurrence(false) end = goto_line_col

--replace some actions code
actions.list["new"][2]= Proj.new_file
actions.list["open"][2]= Proj.open_file

--add new actions
actions.add("trim_trailingspaces", 'Trim trailing spaces',

--add PROJECT menu (before Help)
table.insert( actions.menubar, #actions.menubar,

--add action at the end of the EDIT menu
actions.menubar[2][#actions.menubar[2]+1]= {SEPARATOR,"trim_trailingspaces"}

--replace tab context menu with a new one
actions.tab_context_menu = {
"reload"} }

--add some accelerators
actions.free_accelerator({"f4","sf4","cpgup","cpgdn"}) --make sure no
action already uses this keys


The 2 files are available at github in case someone want to see/use them.

Best wishes,


You are subscribed to
To change subscription settings, send an e-mail to
To unsubscribe, send an e-mail to
Received on Thu 12 Jan 2017 - 13:22:26 EST

This archive was generated by hypermail 2.2.0 : Fri 13 Jan 2017 - 06:41:33 EST