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

What is the reason for not providing key release events to Lua API like it is done in SciTE? #457

Closed oOosys closed 11 months ago

oOosys commented 11 months ago

SciTE provides in its Lua API both, the key presses and the key releases. Textadept code subscribes to the key release events, but does not forward them any further except deciding about their further processing. What is the reason for such a design decision? Having key releases in the Lua API would make customization of Textadept much more flexible without any performance disadvantages. Which lines in which files need to be changed to patch Textadept to provide key releases to the Lua API?

oOosys commented 11 months ago

My current progress on this topic seems to show that there is most probably no good reason for not covering key releases in the Lua API. Following changes to textadept_gtk.c make the key releases available:

SciObject *new_scintilla(void (*notified)(SciObject *, int, SCNotification *, void *)) {
    SciObject *view = scintilla_new();
    if (notified) g_signal_connect(view, SCINTILLA_NOTIFY, G_CALLBACK(notified), NULL);
    g_signal_connect(view, "key-press-event", G_CALLBACK(keypress), NULL);
    g_signal_connect(view, "key-release-event", G_CALLBACK(keypress), NULL); // << oOosys
    g_signal_connect(view, "button-press-event", G_CALLBACK(mouse_clicked), NULL);
    return view;
}

and

static int keypress(GtkWidget *_, GdkEventKey *event, void *__) {
    int modifiers = (event->state & GDK_SHIFT_MASK ? SCMOD_SHIFT : 0) |
        (event->state & GDK_CONTROL_MASK ? SCMOD_CTRL : 0) |
        (event->state & GDK_MOD1_MASK ? SCMOD_ALT : 0) |
        (event->state & GDK_META_MASK ? SCMOD_META : 0);
    int state   =   2;                                  // << added by   oOosys
    state       =   2;                                  // << added by   oOosys
    if (event->type == GDK_KEY_PRESS)       { state=1; };   // << added by   oOosys
    if (event->type == GDK_KEY_RELEASE) { state=0; };   // << added by   oOosys

    //return emit("key", LUA_TNUMBER, event->keyval, LUA_TNUMBER, modifiers, -1);
    return emit("key",  LUA_TNUMBER,event->keyval,  LUA_TNUMBER,modifiers,  LUA_TNUMBER,state,  -1); // << oOosys
}

This above is only the proof of concept and not a solution because of the side-effects it comes with. The cursor keys are still not available in the Lua API and the side-effect is that the cursor moves by two characters on each single cursor keypress because of the captured release event considered to be a keypress.

The keyboard event processing appears still a bit weird to me, so any help explaining what does what and why would sure speed up my progress of implementing key release reporting to the Lua API in Textadept. At least this above shows that it can be done with very little change to the code, but it still needs to make the entire concept of keyboard input processing more straightforward than it currently is for to me not yet known reasons. By the way: I am not interested in making it platform independent - I am just only after a solution for the GTK Linux Mint 21.2 Xfce only. From my perspective of supporting really very flexible customization without polluting the code with branching depending on platform, GUI toolkit or if it should work in a Terminal. This branching takes almost more code lines than the actual code needed for one specific version only. It would maybe make sense to have separate Textadept versions for the platforms and used GUI libraries to avoid unnecessary over-complicating the code while trying to make it work on each platform and each used GUI library with only one starting point CMake file which in addition also goes online because most of the required code is not provided in the Textadept download itself.

orbitalquark commented 11 months ago

To answer the original question, I never saw a need for emitting events on key release. Emitting events on keypress was enough. The only reason I can see the need for listening for key release is if you want to detect release of a modifier like Ctrl if you are implementing something like switching tabs based on z-order and updating the list after Ctrl release.

If events were to be emitted on press and release, typing text would be up to 2x slower. Perhaps it wouldn't be noticeable, but I'm not sure it's worth it.

Regarding your proof-of-concept, that looks like the right area of the code. You might have an if statement to call emit() with "key" or "key_release" depending on event->type. That should fix the double-movement and similar issues.

You are correct that implementation of this would have to be done for each platform: Gtk, Qt, and the terminal version, each in its own place. Your intuition about the terminal version is correct: I don't think this feature would work there.

oOosys commented 11 months ago

@orbitalquark Do I understand it right, that you are not really very deep into how Textadept handles keyboard and mouse input because you don't see the need of diving that deep into it? At least so my impression from not getting details of the core idea behind the process and lack of response on the evident bug of double call of "key" in case of pressing control keys?

To my knowledge the system forwards multiple events on keyboard input for the same key action (press/release) which need to be distinguished by other means than only the key code and the control key status. In Textadept listening to key-press events results because of that in case of control keys in two events for only one key press which are both forwarded to Lua as key presses what is not correct, because the second event is not about a key-press, but suggests to Lua a second separate one which had not actually took place.

But ... considering your above explained general view of what is necessary and what not I conclude that I need to go my own way on this without the hope that you are willing to provide better keyboard input Lua interface in future releases as you are neither interested in providing correct forwarding of only one event on key presses for control keys, nor in forwarding key releases to the Lua API, right?

Without the information about key releases you can't distinguish some of the different possible control key combinations.

For example you want to trigger a function on subsequent or simultaneous presses of left Shift, right Shift and a Control key. There are several different ways which can be clearly distinguished from each other but only if the key release events are available to Lua scripting:

(*) you press the Control while holding both Shift keys pressed
(*) you press the Control with the left Shift key pressed only 
(*) you press the Control with the right Shift key pressed only
(*) you hold the left Shift key pressed, then tap the right Shift key (tap, means you press and release it) and then press the right Control
(*) you tap (press and release) the left Shift key, then press the right shift key holding it, then press the Control key
(*) and so on (have you got the main idea from the above already?)

If key release events are not available, you just can't distinguish between these different keyboard input patterns, so you can't use them to trigger different custom functions from Lua.

Why is this important from my point of view?

Combinations of control key actions are not yet utilized by known to me systems and software, so they are freely available for own customization purposes without colliding with any already taken keyboard input patterns providing a variety of patterns with shorter key sequences compared to for example Emacs which defines fixed introductory Ctrl+? patterns followed by a key sequence, what leads to unnecessary strain on fingers because of need for preliminary holding two keys at the same time for any custom action.

By the way: speed of handling keyboard input events does not matter at all as you won't never ever be able to type at a speed which would make the hardware/software system handling this typing with a delay (like for example it was the case for type-wheel driven electronic type writers in the far past).

In other words you if you really want to deliver on the promise of customizing Textadept to the most possible extent using Lua scripting you need to fix the issue with double control key events and provide key releases to Lua API. You consider it not worth the effort. OK ... if you are neither interested in providing the above described functionality in future releases of Textadept nor in fixing the issue with double key-press events forwarded to Lua API for control keys when only one key press actually took place I am ready to close this issue now, because it isn't one from your perspective.

orbitalquark commented 11 months ago

@orbitalquark Do I understand it right, that you are not really very deep into how Textadept handles keyboard and mouse input because you don't see the need of diving that deep into it?

Correct. Textadept has been in development for more than 15 years and this is I think the second time this issue has been brought up. The first time was in passing, and this time it is more in depth. I'm not saying it's not a legitimate concern, though.

At least so my impression from not getting details of the core idea behind the process and lack of response on the evident bug of double call of "key" in case of pressing control keys?

That looks to be a bug in the GTK version (not the Qt version). Thanks for insisting on this. I was lumping it in with the double-arrow-key issue you previously mentioned.

To my knowledge the system forwards multiple events on keyboard input for the same key action (press/release) which need to be distinguished by other means than only the key code and the control key status. In Textadept listening to key-press events results because of that in case of control keys in two events for only one key press which are both forwarded to Lua as key presses what is not correct, because the second event is not about a key-press, but suggests to Lua a second separate one which had not actually took place.

But ... considering your above explained general view of what is necessary and what not I conclude that I need to go my own way on this without the hope that you are willing to provide better keyboard input Lua interface in future releases as you are neither interested in providing correct forwarding of only one event on key presses for control keys, nor in forwarding key releases to the Lua API, right?

Since you appear to only want to do the bare minimum and not work on a cross-platform way to accomplish this, I would say yes you should go out of your way to do what you want. A cross-platform patch could help accelerate this. I can put it on my TODO list, but it's not a high priority for me.

Without the information about key releases you can't distinguish some of the different possible control key combinations.

I am aware, as I made note of a particular use case involving buffer switching an z-order. I agree that there are additional cases like the ones you brought up.

In other words you if you really want to deliver on the promise of customizing Textadept to the most possible extent using Lua scripting you need to fix the issue with double control key events and provide key releases to Lua API. You consider it not worth the effort. OK ... if you are neither interested in providing the above described functionality in future releases of Textadept nor in fixing the issue with double key-press events forwarded to Lua API for control keys when only one key press actually took place I am ready to close this issue now, because it isn't one from your perspective.

Thanks for sharing your opinion on this. Sorry my false advertising led you to believe Textadept was something that it was not.

oOosys commented 11 months ago

Your advertising is OK, no reason for "sorry". Sure, I am wondering why some obvious issues had not been raised in the last 15 years, but on the other side I have been through most if not already through all of the free editors available out there. I have put more than one month full time into an attempt to master Emacs which was most promising approach on limitless customization before I focused on Textadept. Textadept is from my perspective much easier to master than Emacs and delivers on the promise of very flexible customization mostly because of a relatively small code base and usage of Lua for most of its functionality beyond this one provided by Scintilla. Lua as scripting language is a very smart choice as the concept behind Lua appears to me as superior compared for example to Python.

I am not interested in cross-platform because first I don't have access to any other platform and second it would add from my perspective unnecessary complexity making it much harder to have it fully under own control. Each GUI-Toolkit has probably its own quirks related to handling of keyboard/mouse input, too, so if you are after cross-platform and cross GUI-Kits, the bare minimum of handling key-presses and the state of control keys is what should work on any platform with any GUI-Toolkit. GTK is maybe delivering the full system key information on control keys, but not on the other keys ... a bit weird behavior ... but I am avoiding usage of Qt whenever possible because it comes with a more complex and harder to use API. I will probably more or less rewrite the GTK-version of Textadept adapting it to my specific requirements neither caring about cross-platform nor about other GUI-libs or the Console version. Textadept seems to be the best starting point I was yet able to find - just a genius text editor worth to become the absolute number one text editor for everyone. Congratulations! I am really wondering how it comes that it is not yet recognized as the best text editor concept ever ... maybe because of too less "batteries included"?

If I succeed in mastering the C and Lua code in near future then you are welcome to check out my oOo repository ( https://github.com/oOosys/oOo ) not only to see the guidelines behind the goals I am after but also for code related to text editing using the concept behind Textadept as starting point and maybe find something there you can reuse to patch this or other Textadept issue related to the GTK-version on Linux.

oOosys commented 11 months ago

@orbitalquark : in the context of the above conversation I would like to mention that the less people use Textadept Lua scripting API to create customized behavior then surely less issues are coming up. In other words considering an issue as not important because it had not often came up in the last 15 years can be evidence of a very limited use of Textadept scripting API for sophisticated customization purposes. The small number of opened issues seems to confirm this kind of interpretation. The number of opened issues for the probably much more popular Emacs goes into multiple hundreds ... In other words the lack of full coverage of keyboard input events is maybe the reason why Textadept is not as widely used as it could be if they were implemented?

rgieseke commented 11 months ago

I think there are two points to consider, first, Textadept's community is obviously much smaller than Emacs' and it's been on GitHub only for a short while, so it's probably not a fair comparison.

Second, much of the appeal of Textadept (at least to me and why I initially started using and contributing to it) is that it works quite the same on all platforms. Thus, features which are hard to implement in a cross-platform manner aren't high priority. Also for a long time, Textadept was pretty strict in its code line count. This has helped to keep an editor where it's possible to learn about its internals and also modify if desired.

oOosys commented 11 months ago

I have been into Emacs ... full time way over one month and consider Textadept and Lua superior to Emacs and eLisp. From this perspective I am wondering how it comes that the Textadept community is obviously much smaller than Emacs'? Textadept appears heavy influenced by typical Emacs concepts like providing user input via functions bound to keys exposed by the scripting API and to some extend the coding style mimics the idea of having data and functions integrated in same symbol name. Emacs developer seem to be lost in the large code base so only some of them really understand the code. Especially the graphics part seems to be a black box only few of them are brave enough to actually cope with it. From my perspective Emacs is a bunch of mess and dust collected into it over a very looooong time and because of its size it's nearly impossible to master it and clean it up. In order to shine again Emacs need to be rewritten ... and Textadept appears to be a much better starting point than Emacs itself.

@rgieseke : OK ... your motivation and the purpose behind usage of Textadept are very different from mine. I was looking after an application taking user text input for the purpose of being the entry point to the entire system and able to be a START menu, overall tool for any kind of required functionality and a text editor at the same time integrated into something I call the oOo system which focuses on the ability of creating by the user himself customized way of communicating his intent to the system ( https://github.com/oOosys/oOo ) using an editing tool and Lua scripting (which appears to me superior to Python) as core components.

paaguti commented 11 months ago

I have been into Emacs ... full time way over one month and consider Textadept and Lua superior to Emacs and eLisp.

I'm into both, Emacs since the 1990's, and I can't be so affirmative. Each have their own specific application field and are in many aspects non-comparable. I use TextAdept for quick edits and Emacs when I need to get my hands really dirty. But that's because of ??tradition, custom, patterns??.

From my perspective Emacs is a bunch of mess and dust collected into it over a very looooong time

And a lot of nice things too... The myriad of OSes covered by Emacs has allowed (at least) me to have a standard interface in some not so comfortable operating systems.

In order to shine again Emacs need to be rewritten

Then start a neo-emacs project yourself ;-)

My .2 cents, /PA

On Sat, 16 Sept 2023 at 17:54, oOosys @.***> wrote:

I have been into Emacs ... full time way over one month and consider Textadept and Lua superior to Emacs and eLisp. From this perspective I am wondering how it comes that the Textadept community is obviously much smaller than Emacs'? Textadept appears heavy influenced by typical Emacs concepts like providing user input via functions bound to keys exposed by the scripting API and to some extend the coding style mimics the idea of having data and functions integrated in same symbol name. Emacs developer seem to be lost in the large code base so only some of them really understand the code. Especially the graphics part seems to be a black box only few of them are brave enough to actually cope with it. From my perspective Emacs is a bunch of mess and dust collected into it over a very looooong time and because of its size it's nearly impossible to master it and clean it up. In order to shine again Emacs need to be rewritten ... and Textadept appears to be a much better starting point than Emacs itself.

@rgieseke https://github.com/rgieseke : OK ... your motivation and the purpose behind usage of Textadept are very different from mine. I was looking after an application taking user text input for the purpose of being the entry point to the entire system and able to be a START menu, overall tool for any kind of required functionality and a text editor at the same time integrated into something I call the oOo system which focuses on the ability of creating by the user himself customized way of communicating his intent to the system ( https://github.com/oOosys/oOo ) using an editing tool and Lua scripting (which appears to me superior to Python) as core components.

— Reply to this email directly, view it on GitHub https://github.com/orbitalquark/textadept/issues/457#issuecomment-1722258520, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZKU4BK2NDBFEVS4DVFQO3X2XDSZANCNFSM6AAAAAA4THVCCI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Fragen sind nicht da, um beantwortet zu werden, Fragen sind da um gestellt zu werden Georg Kreisler

Headaches with a Juju log: unit-basic-16: 09:17:36 WARNING juju.worker.uniter.operation we should run a leader-deposed hook here, but we can't yet

oOosys commented 11 months ago

@paaguti : exactly this ( start a neo-emacs project yourself ) idea has lead me to Textadept. Trying to rewrite Emacs starting with its own code-base and documentation was what resulted in the insight that this is the wrong way approaching it because of the mess. Mess in the code base, mess in the terminology. Just a box full of features often each for itself without being well harmonized with all the others. Textadept would be a much better start. I suggest you visit my oOo repository from time to time next to see if there are any updates with code of features for the eoOo (the neo-emacs version of Textadept) text editor (currently it's too early stage for making it public).

As a starter a feature I currently use most you can implement in your /home/yourUserName/.textadept/init.lua :

--                                  CLIPBOARD
--[[   ui.clipboard_text (read/write)   sets/gets system-wide available content of clipboard:   ]]
--  ui.clipboard_text = 'textToCopyToClipboard     textFromClipboard = ui.clipboard_text
--[[ MAKE ANY SELECTION in   eoOo   automatically system-wide available for pasting:    ]]
copySelectedTextToClipboard_callsCounter = 0
copySelectedTextToClipboard = function (UPDATE_UI_eventBitmask)
    copySelectedTextToClipboard_callsCounter = copySelectedTextToClipboard_callsCounter + 1
    if debugMode then print("  >CLIPBOARD> copySelectedTextToClipboard() triggered by 'UPDATE_UI', call number:", copySelectedTextToClipboard_callsCounter) end
    if (UPDATE_UI_eventBitmask & buffer.UPDATE_SELECTION) == 0 then 
        if debugMode then print("   >>  >>  >>  event with another reason than selection change or caret movement") end
        return nil -- propagate the event
    else 
        local selection = buffer:get_sel_text()
        if selection and #selection > 0 then
            ui.clipboard_text = selection
            if debugMode then print("   >>  >>  >>  copied selected text to CLIPBOARD") end 
            return nil -- propagate the event
        else
            if debugMode then print("   >>  >>  >>  event of caret movement (empty selection)") end end
        return nil end end -- propagate the event
events.connect(events.UPDATE_UI, copySelectedTextToClipboard)

With the above code what you have selected in Textadept is immediately available for pasting. The "downsides" of this feature are that a just selected text will be on paste (Ctrl+V) replaced with itself, not with the text put into clipboard before ... and the previous clipboard content gets automatically lost on any new selection. But if you often need to copy/paste within the edited text then this code will allow you to forget about the need of using Ctrl+C.

I am currently working on "followMode" for Textadept where you have multiple views showing the same buffer with synchronized scrolling so that you have more lines of the text visible than the lines of the display height.

Which Emacs feature do you miss most in Textadept???

orbitalquark commented 11 months ago

@orbitalquark : in the context of the above conversation I would like to mention that the less people use Textadept Lua scripting API to create customized behavior then surely less issues are coming up. In other words considering an issue as not important because it had not often came up in the last 15 years can be evidence of a very limited use of Textadept scripting API for sophisticated customization purposes. The small number of opened issues seems to confirm this kind of interpretation. The number of opened issues for the probably much more popular Emacs goes into multiple hundreds ... In other words the lack of full coverage of keyboard input events is maybe the reason why Textadept is not as widely used as it could be if they were implemented?

Maybe. I personally doubt it though, for reasons below.

I have been into Emacs ... full time way over one month and consider Textadept and Lua superior to Emacs and eLisp. From this perspective I am wondering how it comes that the Textadept community is obviously much smaller than Emacs'?

Simply because I wrote Textadept for myself and decided to share it with others. I don't advertise anywhere, and all of our community's growth has been completely organic. Also, as was mentioned previously, Textadept was recently added to GitHub (maybe 2 years ago?). Everything (including a mailing list) was previously on a self-hosted VPS.

orbitalquark commented 11 months ago

The double-pressing of control (and other unhandled keys) should be fixed via https://github.com/orbitalquark/textadept/commit/96b735ca1da6527779d6fa6f854f83d9a6fd1951