yurikhan / kitty_grab

Keyboard-driven screen grabber for Kitty
GNU General Public License v3.0
171 stars 11 forks source link

Feature request: multi-line vertical scroll #18

Open omgold opened 2 years ago

omgold commented 2 years ago

As far as I am aware scrolling vertically can only be done one line on each keypress ('up'/'down') or one screen height ('page up'/'page down'). Thus I find it tedious to navigate to a line at the middle of the screen. A big improvement would be to allow binding keys to multi-line cursor movements, either by a fixed number of lines or a fraction of the screen height.

yurikhan commented 2 years ago

Hm, for me, navigating half the screen is a matter of holding down the key for a second. I have never seen any system that lets you move the cursor by multiple lines at a time. (Well, not counting the Emacs and Vi(m) numeric prefixes.)

I will accept a well-designed pull request though.

omgold commented 2 years ago

In emacs I'm used to use the 'move to prev/next empty line' feature (ctrl+arrows). WIth text files this usually works well enough, but as on the shell there are rarely empty lines, I think a fixed distance would be better.

pallaswept commented 10 months ago

I've seen shift+pgup/pgdn being used as a modifier for this in other apps. Since shift selects here, ctrl+pageup/ctrl+pagedown or alt+pgup/pgdn, for a half-page would work, that would be be very cool.

pallaswept commented 10 months ago

Another thought about how to get this effect: In less, I have it set to page up and down minus a few lines, using --window=-10. This way, when I page up/down, I don't skip the entire page, but still have a few lines left over so I have a 'point of reference' for where I came from. Perhaps a feature like this could be added to kitty_grab, so that pageup would go up 1 page+n lines, where n can be a negative number, like how it works in less? I think in reality it already does this where n = -1, because when you pageup, you see the top line become the bottom line.

pallaswept commented 10 months ago

I've seen shift+pgup/pgdn being used as a modifier for this in other apps. Since shift selects here, ctrl+pageup/ctrl+pagedown or alt+pgup/pgdn, for a half-page would work, that would be be very cool.

Thinking about this, as per how kitty_grab works now, if we use ctrl+up (cursor key)/ctrl+down, then it scrolls the page, so using alt as the modifier for this (ie, alt+pgup/alt+pgdn) would be more appropriate, for continuity. You could also have a similar effect where alt+up (cursor key and alt+down could move the cursor in bigger jumps, and ctrl+alt+up/ctrl+alt+down would scroll in bigger jumps. Like perhaps it jumps 5 or 10 or some configurable (in grab.conf) number of lines, instead of just 1.

I hope these thoughts are helpful :)

yurikhan commented 10 months ago

when I page up/down, I don't skip the entire page, but still have a few lines left over so I have a 'point of reference' for where I came from […] I think in reality it already does this where n = -1, because when you pageup, you see the top line become the bottom line.

Yes, PageUp and PageDown motions are carefully programmed to provide continuity:

This is basically the way all editors I am used to behave (not counting Emacs and Vim which let you configure everything and require you to configure everything), and I don’t feel a personal need for keeping more than one line of continuity.

The offer to review and merge a patch still stands, if Someone™ wants an option like that badly enough.

pallaswept commented 10 months ago

The offer to review and merge a patch still stands, if Someone™ wants an option like that badly enough.

My python skills are weaaaak. Buuuuut I dunno, I am kinda interested to see it in action. I might get bored and do stuff. But I don't want to waste time doing something you'll hate, so let's spec it out first:

Are you OK withthis:

alt being used as the modifier for these - as discussed above, ie:

alt+pg[up|down] = cursor [up|down] 1 page minus X for continuity (where pg[up|dn] now is exactly this with X=1) alt+[up|down] = cursor up Y lines alt+ctrl+[up|down] = scroll page up Y lines

Obviously, within the limitations you mention above, like how everything works, where if it hits the end, it stops, it doesn't over-scroll.

Where X and Y are configuration entries.

Also if I'm in there doing all that.... what about ctrl+pg[up|down] being used to scroll, like how it does with ctrl+cursor [up|down] (only, page-wise, not line-wise, obviously)? Obviously this would mix with the above, allowing partial-page up|down scrolling.

If you're OK with this spec (or if you come up with another one that'll work) I might take a shot at it.

@omgold this should suit your original request, just set the X parameter to half a page, right?

yurikhan commented 10 months ago

In your own configuration, you could do anything you want, but in the default bindings, Alt + any motion is reserved for marking rectangular blocks. So Alt+PgUp/Down and Alt+Up/Down are occupied. Alt+Ctrl+Up/Down is free but check if it still makes sense with the restrictions above.

what about ctrl+pg[up|down] being used to scroll

You mean, scroll the view by pages but keep cursor position, potentially even scrolling the cursor out of the viewport?


I’d invite you to first just try hacking the kitten to change the 1 line of overlap to your preferred number. Try and check that it doesn’t break at the edges. See if it works for you without introducing new bindings. If it does, just code up the new numeric option and be done with it. If not, let’s talk further.

pallaswept commented 10 months ago

This post is dumb long. I put a TL'DR at the bottom and I feel like the best way for you to read this post would be to scroll down and read that, and then when you're like "but why tho?" then read the novel that explains my conclusions, if that interests you or isn't immediately obvious.

In your own configuration, you could do anything you want

Yeh but by default it should be consistent, I suggested Alt+ because at a glance it appeared to be free, but that's because I never use the rectangular blocks so I didn't know, and when I experimented real quick didn't press the keys in the right order to trigger it when I tried it.....

, but in the default bindings, Alt + any motion is reserved for marking rectangular blocks. So Alt+PgUp/Down and Alt+Up/Down are occupied.

OK so alt+ is a no go.

Alt+Ctrl+Up/Down is free but check if it still makes sense with the restrictions above.

Yeh but ctrl is used (with cursor up/down) for scrolling the page while keeping the cursor stationary, so that breaks consistency of behaviour. Ctrl+ is used for modifying horizontal jumps (jumps to the next word) so it makes a lot of sense to use ctrl for this vertical jump length modifier too. Ctrl seems a much better way to go.

what about ctrl+pg[up|down] being used to scroll

You mean, scroll the view by pages but keep cursor position,

Yes

potentially even scrolling the cursor out of the viewport?

No I mean the mode where the cursor stays stationary and the text behind it moves. I figure an out-of-viewport cursor is just a good way to get lost. But if selected text rolls off-screen, that's OK, because we saw it and selected it on purpose before we scrolled it off screen.

...

See if it works for you without introducing new bindings. If it does, just code up the new numeric option and be done with it. If not, let’s talk further.

Design by increment is how to end up with spaghetti at the end ;) Let's figure out what we want before we start trying to make it actually exist in an undefined state, writing a bunch of code only to discard it along the way to a mystery. I don't wanna build a rocket to go "where are we going" "I dunno we'll figure it out when we get there" :D

First, we have to figure out an available and consistent keybind for these partial pageup|down events (one does not want to ALWAYS jump in half-pages, that can be super annoyingly slow to move around). The interesting part I find about this is that while alt is used for drawing rectangles, that's alt, alone, and not shift+alt. Whereas any other time we release shift, we break the selection and move the cursor. That's already kinda inconsistent... Kinda.... Then there's the page scrolling with ctrl+cursor up|down, which also doesn't require shift. So shift has this inconsistent behaviour of you need to hold it to grow or shrink your selection, UNLESS you're doing it by scrolling the page or by drawing boxes, but if you're moving the cursor or moving by pages, you have to hold it. If you release shift and pageup|down or cursor up|down, you break the selection. If you release shift and alt|ctrl+up|down, you retain and modify the selection. Then you have the weird thing with rectangular selections if you hold the alt keyand the ctrl+direction key where it expands by-word horizontally but freezes the cursor vertically...

So, shift is either a momentary selection switch, or a latching toggle switch, depending on the movement that follows it; and all this goes for alt, too, but for rectangular selection.

I find this ergonomically comfortable (chording too much is bad for your hands, having to hold down shift and alt and a direction key, and maybe then change to other direction keys, for long periods, is not good design - so I kinda like it how you have it - don't get me wrong!), but at the same time, because shift is now doing sharing the duty of being the "active selection key" with alt, it halves the duty of both keys, and zeroes the duty of both keys combined.... which doesn't leave a lot of room for much else.

I’d invite you to first just try hacking the kitten to change the 1 line of overlap to your preferred number. Try and check that it doesn’t break at the edges.

I would definitely take an incremental approach to implementing this, and make one thing work at a time, that's smart thinking I reckon... But it may be that with the keybinds you've got by default now, you've reduced the availability of modifiers such that the available functionality is limited to just this one feature. But if I try something and it breaks at the edges I'm just gonna fix it. I'm not going to start it and then chicken out half way.

What if you made it so that shift was ALWAYS a latching toggle for selection (ie; I hit shift, and release it, now I'm selecting when I move, however I move - I hit it again, now I'm not selecting when I move) and likewise alt for rectangular selection. I mean think about it, how often do you hold shift+direction, then release shift and press a direction key immediately afterwards? Practically never because it serves no purpose other than to select something and then instantly deselect it. It's essentially something we only do when we selected the wrong thing by accident. Same goes for alt - like, how often do you stat a rectangular selection (holding alt) then immediately destroy it and start a by-character selection (release alt and hit shift instead while moving) (or vice versa) Why not make shift and alt latching, so when I hit alt I'm rectangular selecting from this point and when I hit shift I'm character/line selecting from that point, and if I hit or alt or shift respectively, I cancel that selection mode.

Then you have even LESS chording (which is GREAT because you just tap the key to start the action instead of holding it throughout the entire action, and tap it again when you're done, and mistakes in-between are much more easily handled because you can jiggle your direction keys without having to keep holding the modifier). Now you've just freed up half the duty of each key, meaning that when you're in shift-select mode then alt can do stuff (like say, to use this issue as an example, engaging the stationary-cursor scrolling mode), and when you're in alt-selection mode, shift can do stuff (Probably the same thing) - and you've freed up the combination of the two keys together (ie shift+alt+whatever - shift+alt+[up|down|pgup|pdn|left|right] does NOTHING right now because it can't do anything because it's locked to conflicting selection methods) - and shift+ctrl+direction does the nice word-wise selection sideways, and nothing at all vertically.

Now, I understand that this "half-pageup|down" and "jump N lines up|down" feature isn't one that interests you greatly (or you would have done it instead of asking for a PR ;) and that's cool with me, I am down to pitch in and write the code, and I don't expect you to share use-cases with @omgold and I and others, every user will have different needs and interests....but regardless, you can see that there's a problem here with the keybinds as they are, reducing the availability of any future features that require a modifier, and one day, it's gonna be a feature you want, and you're gonna hit this same wall, and either end up with weird inconsistent keybinds or no way at all.

So what I'm trying to say is, I know you don't care about implementing this feature, and that's cool - but you probably want to care about fixing the thing that's preventing it, so it doesn't prevent something you do care about, later on.....Because by freeing up keybinds to do stuff like this (bigger/smaller vertical jumps) you're also freeing up keybinds to do stuff like <insert future "gee that's a good idea" and avoid being back here doing "but oh crap, I don't have any sane modifier keys left" 😆

Let's work together and see if we can solve this. It's a curly one! But I think we could find a way.

TL;DR

It seem the most sane and consistent keybinds would be:

Doing this, means you still have ctrl+alt+?, shift+ alt+? and sctrl+shift+?, all available for any other future keybinds. So you've gone from "we don't have a consistent way to add even this one feature" to " holy cow look at all these free keybinds" and all it takes is that you don't have to hold down a modifier key for the entire length of an operation, which is actually better for your health (RSI is probably something you've experienced already give you code a lot!) And you get this really consistent UI convention to boot.

I know I said a lot there, sorry for the novella. I'm worried it might come across the wrong way (because text on the internet and you can't see me smiling at you) so to be clear - This is your project I'm not trying to be bossy about it, I just spent a lot of my career in user interfacing (lots of embedded devices in factory automation, where consistent UI conventions are paramount so 'that button always has a predictable effect', and a little web stuff when it was younger, like,' HTML 2 then 3 then 4' younger, lol) and later some government websites that had millions of users and had to be totally idiot proof....so this kind of thing is my jam. I have a lot of experience in the field, decades of work that I'm trying to share as briefly as possible in a github comment - and with little experience with this actual product, so I'm super well informed and simultaneously almost cluelsss....but these are just suggestions and food for thought - I don't mean to seem ranty or argumentative, just verbose and informative. I hope t came across that way.

Like I said, it's a curly one, but I think we could work it out together 😃

yurikhan commented 10 months ago

You’re obviously putting a lot of thought into this. So much that I now want to invite you to make a fork where you can streamline the UI actions and default bindings.

This project’s reason for existence is to plug a particular hole in my workflow; namely, lack of a built-in keyboard-based way to select and copy text from Kitty. I am not in it for the money, and I am not in it for mind share. I do not have to reinvent my personal workflow in order to make things more intuitive or idiot-proof for others. And I’m much too attached to the quasi-modal nature of block selection and holding only a single Alt for a rectangular block and scrolling on Ctrl+↓↑.

pallaswept commented 10 months ago

Yeh man that's cool, I understand you made this thing, for you, to fix a problem and make a perfect solution for you, and it is how you like it for you personally, and it just so happens you've been kind enough to share it with the entire internet for free, which is lovely. I don't expect you to adjust your personal workflow and change this kitten just because it would be technically better, if it's personally worse for you, that defeats its entire reason for existing. I understand, this is Yuri's plugin just for Yuri, and we are just sharing it. So it's better if I want to make it into something else, then I should fork it.

I don't want to feel like I am "stealing" your work here though, so if you'd rather I don't fork it, and just use it as is, then I am totally OK with that. So if you're offering to fork it just because that's the obligatory thing to do, but you'd really rather I don't, please feel free to say so, and don't feel obliged to offer for me to take it away from you. But if you are OK with me basing another kitten on your work, I would find it an interesting project, so you just let me know, if the fork is really OK with you. No pressure mate :)

yurikhan commented 10 months ago

In many senses, it’s not possible to steal a project published under GPL. So don’t be shy.

pallaswept commented 10 months ago

In many senses, it’s not possible to steal a project published under GPL. So don’t be shy.

Laws and licenses don't trouble me, only your feelings on the matter. Since you have said so, I'll go ahead and make a fork, and I'll work on it later when I have some time for this, but if ever you feel treated unfairly - licences be damned, you let me know and we will work things out so that you are happy :)