[code] [textadept] Changes to Key and Menu Internals in hg

From: Mitchell <m.att.foicica.com>
Date: Fri, 15 Apr 2016 21:58:46 -0400 (EDT)

Hi,

I committed a large change just now[1] that reworks Textadept's key and
menu command internals. If you have custom key commands that relied on the
undocumented `keys.utils` table, then this commit will affect you. If you
hide the menubar in your `~/.textadept/init.lua`, this change will also
affect you. If none of the above apply, then I'm pretty sure you've
nothing to be concerned about and can discard this e-mail.

Internally, Textadept is moving towards representing all key and menu
commands as Lua functions and not tables. Currently, the following are
equivalent:

   keys.cu = function() io.snapopen(_USERHOME) end
   keys.cu = {io.snapopen, _USERHOME}

Internally, Textadept will start using the first notation involving
functions. The second notation will still work, but the menus will not
reflect the correct key shortcuts. (Note the key shortcuts displayed in
menus is just for visual display; it has no effect on Textadept itself.)
So to reiterate: if you have defined custom key bindings that use the
table notation, they will still work just fine, they just won't show up as
a shortcut in the menu.

If you want custom key bindings to show up in the menu, you'll have to
bind the same function to the key. For example: by default the "File >
New" menu is assigned to the `buffer.new` Lua function, as is the
`keys.cn` (or OSX equivalent) key shortcut. Thus the "File > New" menu
knows to show Ctrl+N as the key shortcut. That was a trivial example, but
what about an old table notation bindings like:

   keys.cM = {textadept.editing.match_brace, 'select'}

The obvious approach is to use:

   keys.cM = function() textadept.editing.match_brace('select') end

However the function bound to `keys.cM` is ultimately different than the
function bound to "Edit > Select > Select to Matching Brace" (I won't go
into specifics, but trust me.) The only way to ensure you are binding the
same function to `keys.cM` is to retrieve the function from the menu
itself. Another commit[2] I recently made makes this easy:

   local menu = textadept.menu.menubar[_L['_Edit']][_L['_Select']]
   keys.cM = menu[_L['Select to _Matching Brace']][2]

Admittedly it's a bit uglier, but that's the tradeoff for a less-hacky
system. Why do I say less hacky? Well there was an undocumented
`keys.utils` table you may have used to reassign key bindings to utility
functions for deleting words, autocompleting symbols, toggling the
current fold, etc.:

   keys.adel = keys.utils.delete_word
   keys['c '] = keys.utils.autocomplete_symbol
   ...

The menu system ultimately referenced these `keys.utils` functions in
order to use the "same" function for displaying the proper key shortcuts.
Now the role is reversed -- the menu holds the function, and the key
command should reference the menu. Why was it done this way? Well editing
individual menus is easier than ever before and querying menu items for
their functions in order to bind them to a key was the next logical step.

So the ultimate takeaway here is if you are using custom key bindings that
made use of the undocumented `keys.utils` table, you'll have to redefine
those bindings. Take a look at the new `modules/textadept/keys.lua` in my
first referenced commit for how to access the applicable menu item's
function.

Now one last thing: in order to allow more for more customizations to
menus on init (from "~/.textadept/init.lua" and company), and in order for
the key shortcuts to show up properly, the menubar is now only loaded in
the `events.INITIALIZED` event. Therefore, if you are someone who doesn't
like to see or use the menubar and used something like
`textadept.menu.menubar = {}` somewhere in your "~/.textadept/init.lua",
you'll simply need to wrap it like so:

   events.connect(events.INITIALIZED, function()
     textadept.menu.menubar = nil
   end)

Note the setting to `nil`. This allows you to still make use of
`textadept.menu.select_command()` for quick access to nearly all of
Textadept's available commands if you so choose. If you were to use `{}`,
you'll lose easy access to those commands (your key bindings will still
work, of course).

If you're curious what I mean by "allow for more customizations to the
menus on init", check out some of the recent changes to my `ctags`[3],
`spellcheck`[4], and `file_diff`[5] modules. The ctags module inserts
itself at the end of the 'Search' menu, and the spellcheck and file_diff
modules insert themselves into the 'Tools' menu in alphabetic order. Those
modules also show more examples of defining key bindings using menu
accessors.

If you've made it this far, thank you! If not, sorry for the long e-mail
:(

So in summary, or TLDR:

1. If you defined custom key bindings that used `keys.utils`, you'll have
    to update them to either access the proper menu functions (if you want
    the proper shortcuts to show up in the menu) or copy-paste the
    functional equivalent.
2. If you're hiding the menu in your "~/.textadept/init.lua", wrap it in
    an `events.INITIALIZED` event or it will not hide.

Cheers,
Mitchell

[1]: http://foicica.com/hg/textadept/rev/bc0324c611c7
[2]: http://foicica.com/hg/textadept/rev/ed00fd75e55e
[3]: http://foicica.com/hg/ctags/rev/a1a51a95b899
[4]: http://foicica.com/hg/spellcheck/rev/49f705a8ef80
[5]: http://foicica.com/hg/file_diff/rev/c3858a08c50e

-- 
You are subscribed to code.att.foicica.com.
To change subscription settings, send an e-mail to code+help.att.foicica.com.
To unsubscribe, send an e-mail to code+unsubscribe.att.foicica.com.
Received on Fri 15 Apr 2016 - 21:58:46 EDT

This archive was generated by hypermail 2.2.0 : Sat 16 Apr 2016 - 06:36:59 EDT