orbitalquark / textadept

Textadept is a fast, minimalist, and remarkably extensible cross-platform text editor for programmers.
https://orbitalquark.github.io/textadept
MIT License
636 stars 38 forks source link

SciTE vs. Textadept 12 keyboard event handling #447

Closed ClaudioGi closed 12 months ago

ClaudioGi commented 1 year ago

I would like to switch from using SciTE to Textadept, but have trouble to understand how the keyboard event handling works in Textadept. It seems that there is no support for general detection of any key presses and releases exposed to init.lua, so that any standalone key press and key release also of single control keys and cursor keys can be detected and handled, not only keyboard events for key combinations which add something to the buffer. I am using the GTK version on Linux Mint Cinnamon and would like to transfer my SciTE Lua startup script which comes with full handling of any key press and key release no matter which key and no matter if used as shortcut or not. Is this possible in Textadept? For example to run a function only when both of the Control keys are pressed?

orbitalquark commented 1 year ago

You can probably get away with connecting to events.KEYPRESS (https://orbitalquark.github.io/textadept/api.html#events.KEYPRESS) with an index of 1. This should be good enough for 99% of use cases.

If you'd like complete control over keypresses, you'd connect, with an index of 1, to the undocumented events.KEY, which Textadept uses to emit event.KEYPRESS: https://github.com/orbitalquark/textadept/blob/ffa167958081a7720d4d34122fb6d7894f9e969a/core/keys.lua#L128-L144

Technically these events are only emitted when a buffer/view has focus, but with the exception of an active Find & Replace session, this is always the case when pressing a key.

Textadept does not emit key release event.

ClaudioGi commented 1 year ago

Thanks for the very quick response :) . In SciTE I am using also a double/triple keypress of Ctrl key and need the release event in order to refrain from coping with timing and side-effects which are unavoidable in case of not being able to track key releases. I suppose that it should be relatively easy to modify the Textadept code to be aware of key releases like SciTE is. It probably needs only one or two lines somewhere to register for key release events with GTK ... is it that simple I suppose it to be? I am ready to cope with C-code if necessary ... Or are any good reasons why key releases are not exposed I am not aware of? By the way: what do you mean with "you'd connect with an index of 1"? And why do is see two calls of the handler function for each single keypress in case of control keys or control+anotherKey presses?

ClaudioGi commented 1 year ago
local scc = _SCINTILLA.constants
local sccShift, sccCtrl, sccAlt, sccMeta = scc.MOD_SHIFT, scc.MOD_CTRL, scc.MOD_ALT, scc.MOD_META
local LCtrl=65507 local RCtrl=65508 local otherKeyBefore=1
events.connect(events.KEY, 
    function(keycode, mods) local shift, ctrl, alt, meta = mods&sccShift>0, mods&sccCtrl>0, mods&sccAlt>0,mods&sccMeta>0
           print(keycode, otherKeyBefore,"|",shift,ctrl,alt,meta)
        if otherKeyBefore and ctrl and (keycode==LCtrl or keycode==RCtrl) then 
                otherKeyBefore=nil  print("Double CTRL detected!") 
                                -- nil because  0  is  true  in Lua
        else    otherKeyBefore=1 end end)

does the job, but ... Cursor keys are not detected ... AND ... because of the double call of the callback function in case of a single keypress of Ctrl it is necessary to suppress the second detection of double CTRL on the second function call.

ClaudioGi commented 12 months ago

After some further considerations it seems that for my use-case lifting the restriction: "Textadept does not emit key release events." at cost of responsiveness of the interface is not worth the effort ... What is annoying and should probably be fixed is the double call of the event handler in case of pressing control keys, but to address exactly this issue opening another issue is sure a better way to go, so I am closing this issue here. The not documented events.KEY was the missing piece I needed to achieve the desired functionality.