Re: [code] [textadept] Key Modes

From: Mitchell <m.att.foicica.com>
Date: Wed, 10 Jul 2019 14:22:49 -0400 (EDT)

Hi,

On Wed, 10 Jul 2019, Qwerky wrote:

> Hi,
>
> On 2019-07-10 10:13, Qwerky wrote:
>>
>> Hello,
>>
>> On 2019-07-09 18:51, Mitchell wrote:
>>> Hi,
>>>
>>> On Tue, 9 Jul 2019, Qwerky wrote:
>>>
>>>> Hi,
>>>>
>>>> On 2019-07-09 17:11, Mitchell wrote:
>>>>> Hi,
>>>>>
>>>>> On Tue, 9 Jul 2019, Qwerky wrote:
>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> On 2019-07-09 09:43, Mitchell wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Mon, 8 Jul 2019, Qwerky wrote:
>>>>>>>
>>>>>>>> Hello.  Key bindings provide for key modes which, according to the
>>>>>>>> documentation, provide a set of key bindings which are executed when
>>>>>>>> that
>>>>>>>> mode is active, to the exclusion of all other key bindings.
>>>>>>>>
>>>>>>>> Is it possible to have a mode, whose key bindings simply replace the
>>>>>>>> same-named bindings while that mode is active, without blocking all
>>>>>>>> other
>>>>>>>> bindings[1]?
>>>>>>>>
>>>>>>>> An example would be a rectangular-select mode which, when active,
>>>>>>>> would
>>>>>>>> replace bindings such as caret-left-extend with
>>>>>>>> caret-left-rectangular-extend, and so forth; but would not block
>>>>>>>> other
>>>>>>>> bindings, such as caret-left, line-down, etc. This would be extremely
>>>>>>>> useful,
>>>>>>>> in the given example, for making selection easier by not having to
>>>>>>>> hold
>>>>>>>> down
>>>>>>>> the Alt key, and would also free up Alt key combinations for other
>>>>>>>> functions.
>>>>>>>>
>>>>>>>> [1] The mode may also provide new bindings which do not exist outside
>>>>>>>> the
>>>>>>>> mode.
>>>>>>>
>>>>>>> Yes, I'm pretty sure this is possible. In your
>>>>>>> *~/.textadept/init.lua*:
>>>>>>>
>>>>>>>   keys.my_mode = setmetatable({
>>>>>>>     esc = function() keys.MODE = nil end, -- exit mode
>>>>>>>     -- keys to handle specially go here
>>>>>>>   }, {__index = function()
>>>>>>>     return false -- propagate everything else
>>>>>>>   end})
>>>>>>>
>>>>>>> Then set `keys.MODE = 'my_mode'` to initialize it (e.g. via a function
>>>>>>> bound to a key). Escape key, or whatever else you set, will go back to
>>>>>>> "normal" mode.
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Mitchell
>>>>>>
>>>>>> Thanks a lot for the example code, but unfortunately I can't get it to
>>>>>> work.
>>>>>> I copied your code to my init.lua, and then added two keys: 'sright' to
>>>>>> extend rectangular selection to the right, and 'sdown' to extend
>>>>>> rectangular
>>>>>> selection down; and in my keys.lua added 'cl' to set keys.MODE to
>>>>>> my_mode.
>>>>>> When I press Control-L, the status bar becomes blank (presumably
>>>>>> because I
>>>>>> have the buffer status written to statusbar, and have bufstatusbar
>>>>>> cleared);
>>>>>> but when I press Shift-Right or Shift-Down (or any other key), it
>>>>>> simply
>>>>>> performs its normal function, and the status bar info returns. Here's
>>>>>> what
>>>>>> I
>>>>>> now have:
>>>>>>
>>>>>> keys.my_mode = setmetatable({
>>>>>>   esc = function() keys.MODE = nil end, -- exit mode
>>>>>>   -- keys to handle specially go here
>>>>>>   sdown = buffer.line_down_rect_extend,
>>>>>>   sright = buffer.char_right_rect_extend
>>>>>> }, {__index = function()
>>>>>>   return false -- propagate everything else
>>>>>> end})
>>>>>>
>>>>>> And have also tried ['sdown'] and ['sright'] with the same results. 
>>>>>> (Also
>>>>>> tried keys['sdown'], but that gave an error.) Where is the problem?
>>>>>
>>>>> Please post your 'cl' keybinding.
>>>>>
>>>>> Cheers,
>>>>> Mitchell
>>>>
>>>> This is what I have now:
>>>>
>>>> keys.cl = function()
>>>>   keys.MODE = my_mode
>>>>   ui.bufstatusbar_text = 'MY MODE'
>>>> end
>>>>
>>>> Before that, it was just:
>>>>
>>>> keys.cl = function() keys.MODE = my_mode end
>>>
>>> You need 'my_mode' to be a string. When used as an identifier, its value
>>> is `nil`, so `keys.MODE` is being set to `nil`, which means default
>>> behavior.
>>>
>>>   keys.cl = function() keys.MODE = 'my_mode' end
>>>
>>> Cheers,
>>> Mitchell
>>
>> Duh!  After correcting my dumb mistake, it now works as intended.  Thanks!
>>
>> But after a little investigation, I'm not sure if this is the right path. 
>> Although there are rectangular selection functions such as
>> buffer.char_left_rect_extend, etc., I can't find any .lua module which
>> contains references to them, apart from /core/iface.lua, which references
>> leave me baffled. Additionally, although I see keys like 'sleft' bound to a
>> selection function, I can't find where any Alt keys such as 'asleft' are
>> bound to functions.
>>
>> So I suppose that somewhere there is code that says "if alt and shift are
>> both down, change selection mode from stream to rectangular."  If that is
>> the case, then even though my special mode would allow using 'sright' for
>> rectangular selection, it may still not allow 'asright' to be bound to some
>> other function without interference between that other function, and the
>> "alt+shift" code mentioned?
>>
>> qwerky
>>
> It seems that after correcting my mistake, the mode-defined keys are now
> working as I reported, but some other keys no longer function while the mode
> is active; eg. Control-Tab does move to the next tab, Control-Z does not
> undo, and so forth, although most navigation keys still function.  When the
> mode is exited, the other keys resume functioning.  Thoughts?

My bad. For your `__index` metatable function, try:

   __index = function(t, k)
     if keys[k] then return keys[k] end
     return false
   end

That code prefers to return a global keybinding for the key typed. Otherwise, it falls back on Scintilla's default handling (e.g. character insertion, arrow keys, etc.).

Cheers,
Mitchell

-- 
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 Wed 10 Jul 2019 - 14:22:49 EDT

This archive was generated by hypermail 2.2.0 : Thu 11 Jul 2019 - 06:34:55 EDT