-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mouse support #666
Comments
I have a POC for mouse support via Lua. It's only working without curses, currently; I believe getting curses to work would require more substantial patching of vis itself. Here's a Lua extension that will output mouse events via require "vis"
vis.events.subscribe(vis.events.QUIT, function ()
io.write("\x1b[?1002l")
io.flush()
end)
vis.events.subscribe(vis.events.INIT, function ()
io.write("\x1b[?1002h")
io.flush()
end)
vis:map(vis.modes.NORMAL, "<Mouse", function (keys)
rest = keys:match(".*>")
if rest == nil then
return -1
end
vis:info("<Mouse"..rest)
return #rest
end, "Mouse detection") If vis is patched like this, it will also output the coordinates of the event: diff --git a/vis.c b/vis.c
index 431c779..845b280 100644
--- a/vis.c
+++ b/vis.c
@@ -1280,7 +1280,7 @@ static const char *getkey(Vis *vis) {
}
TermKey *termkey = vis->ui->termkey_get(vis->ui);
- termkey_strfkey(termkey, vis->key, sizeof(vis->key), &key, TERMKEY_FORMAT_VIM);
+ termkey_strfkey(termkey, vis->key, sizeof(vis->key), &key, TERMKEY_FORMAT_VIM | TERMKEY_FORMAT_MOUSE_POS);
return vis->key;
} |
Hmmm... Turns out that actually works fine with curses. Also, to make curses do the initialisation instead of manually outputting escape codes, it's a one-line patch: diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c
index 744cbb4..4d6ec51 100644
--- a/ui-terminal-curses.c
+++ b/ui-terminal-curses.c
@@ -271,6 +271,7 @@ static bool ui_curses_init(UiTerm *tui, char *term) {
keypad(stdscr, TRUE);
meta(stdscr, TRUE);
curs_set(0);
+ mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
return true;
} |
I'll leave my script and |
When this snippet is placed in the mouse mapping, it will enable scrolling: if rest:match("^Press%(4%)") then
vis:feedkeys("<C-y>")
elseif rest:match("^Press%(5%)") then
vis:feedkeys("<C-e>")
end |
As we have briefly discussed on IRC you were on the right track. Translating window coordinates to buffer positions can be done with the information available in Furthermore libtermkey doesn't properly parse mouse events from symbolic keys meaning the input handling wouldn't work as expected. In general I agree that the mouse can be a quite powerful input device. However, I'm not sure whether a (Unix) terminal is the most suitable environment for it. In any case this will require more thought and probably some architectural changes. |
I believe I saw some mention in the README about a possible client-server architecture with Neovim-style standalone frontends. Perhaps it would be better to wait for that to become reality and then write a graphical frontend for vis? |
@martanne Any idea why this isn't working in INSERT mode? (I just get the names of all the mouse events inserted into my file) for name, mode in pairs(vis.modes) do
vis:map(mode, "<Mouse", mousemap, "Mouse detection")
end |
People avoids |
@erf, @now-im I agree with both of you. Mouse support is not necessary as a core part of vis, but it would be nice to expose appropriate APIs to Lua functions in order to support it through plugins. Personally, I would much rather use a terminal-based text editor with mouse support than a GUI editor, but alternate frontends may well be a better option for this. |
Mouse is good if you want to quickly jump to an on-screen location in a repetitively structured/typed document without sitting there counting symbols. 99.99% of my modal text editor work is done with the keyboard, but once in a while one must admit that the mouse is the fastest way to get from point a to point b esp. without cognitive overhead. This is an important point, imho: you're in the middle of task n (not in between tasks). To need to "calculate" where you want to land is a distraction from the task at hand, and there is a cognitive price to be paid accordingly. Personally, when I use vis I completely forget about the lack of mouse support except once an hour or so I find myself clicking and wondering why nothing happened. So I'm not speaking as someone that can't live without the mouse - the problem is that I'm in a terminal window in a GUI and not at a text-mode tty, the mouse is there and I will reach for it subconsciously on occasion. When I do, it would be nice for it to work :) |
@mqudsi i see your point and i'm not really opposed to mouse support, but have you tried enabling line numbers |
Is there any chance of revisiting this? Especially as (to me) it seems like libtermkey has implemented mouse event parsing. |
It seem like libtickit also have mouse support, and is more up to date. Replacing libtermkey has been discussed before, but maybe it would make sense to replace it only for input. Perhaps it also could replace ncurses, but not quite sure about the status of it's rendering capabilites, but you can read about it here. Perhaps better would be to abstract both rendering and input in some sort of server architecture, as mentioned here and here. |
Only five days away from four years of inactivity, I am pleased as punch to announce that I've finally implemented a working mouse patch that covers every usecase mentioned in this issue! The full code is available now, in dther/vis, under the tag After compilation, to activate it, simply add The default behaviour should be very intuitive, but in summary:
All of this can be changed in vis-mouse.lua, which is subject to change heavily in future versions, but gives a decent overview of how I want mouse support to work going forward! Next steps to consider before I'd be willing to write a PR:
Please leave thoughts and suggestions for how this can be further developed! I'm happy to continue working on this feature alone, but if anyone would like to assist, I'm open to collaborate. |
Thanks! I tried it for a few minutes; two comments:
Even with broken copy and paste, this is going to be really useful to me for quickly moving the cursor. |
Oops, just realized it's completely broken in xterm without tmux. With tmux in xterm, at least the ghost cursor and left click and left drag work. But in bare xterm, the ghost cursor is stuck somewhere, left clicking enters visual mode (sometimes near the mouse, sometimes not), and left dragging either moves the cursor or selects some text, but it doesn't match where I dragged. |
@falsifian I'd only used suckless st (and tmux) to test, so I did some quick tests with xterm, urxvt and kitty. What I found was confusing, to say the least.
To be honest, these problems look like improper implementation within xterm and urxvt, given that we seem to be getting different results, and kitty has no issues. The patch relies on |
I just did a bit of debugging, and suspect this is a bug in I ran the following simple program:
I built libtermkey with With tmux within xterm, I see:
With bare xterm, I see:
Observations:
Maybe I will report this to |
@falsifian I'VE FIGURED OUT THE PROBLEM! The quick fix is to simply set |
Hi @dther, I tried to verify some of what you said but things aren't quite adding up. I have a different explanation for what is happening.
Is that fact documented somewhere?
Are you talking about the two sequences A simple experiment seems to contradict what you're saying. In xterm, I run:
And then I move the mouse, and see output in the terminal like (Maybe I misunderstood what you were getting at. I didn't look into what ncurses does.)
On my system, setting I'm pretty sure the following is what is going on. In this part of driver-ti.c in libtermkey 0.22
if I set The I maintain that this is probably a *EDIT to add: In my |
@falsifian After further investigation, you're right, xterm detects mouse movement and SGR sequences just fine. I was wrong about how it handles control codes. My bad- my theory was based on a misreading of I can also confirm that All that being said, from delving even deeper into the details of terminfo, I don't believe libtermkey is responsible. Vis only uses libtermkey to translate key input which is retrieved from ncurses, and that it is ncurses that is preventing the inputs from being received by the input queue.
Not in a way that I found easy to understand. I'm learning way more about
Cross-referencing with the uncompiled xterm terminfo entry available here, I think our ncurses might be exhibiting slightly different, but both still "correct", behaviour. this is my current working understanding:
In short: The root cause is terminfo, not due to bugginess, but due to cruft. All of this is weird implementation greebles caused by ncurses, libtermkey and xterm trying to remain compatible with very old mouse-driven terminal software and "new" (almost 10 years old now...) experimental mouse support modes. Because of this, my naive implementation of mouse initialisation (just manually flip the bits that control mouse events) clashes with all this compatibility negotiation. The "correct" fix is to have either ncurses or libtermkey handle the negotiation of mouse input initialisation, which isn't particularly difficult, but I foresee needing some non-trivial C logic so as to avoid annoying the other fine folks who use vis, but don't care for mouse support. Activating mouse support tends to disable terminal emulator features that many consider essential, like direct copy and paste. I'll take all this into account in my next mouse patch, which I'm also hoping will be clean enough to be released as a PR. (I'm too full of pride/ashamed of the mess in mouse-patch-v0 to suggest merging it into master.) Thanks for your help in testing things out! It's made me reassess a lot of accidental assumptions I'd made while bug testing this. PS: Could you try setting |
I like how Mouse Support is issue #666 |
Would be very nice if vis had mouse integration so you could scroll, click to move the cursor, etc.
Currently (for me at least) scrolling moves the cursor up and down the page, which sort of works, but isn't ideal. Clicking doesn't work at all.
I recently switched from vim, and this is one of the major things I'm missing. I'm currently trying to implement it as a plugin, but I'm not sure how well that'll work.
The text was updated successfully, but these errors were encountered: