dnkl/foot
41
2.0k
Fork
You've already forked foot
244

vimode - keyboard selection mode #2017

Open
kociap wants to merge 40 commits from kociap/foot-vi:master into master
pull from: kociap/foot-vi:master
merge into: dnkl:master
dnkl:master
dnkl:osc-5522
dnkl:sixel-heap-buffer-overflow
dnkl:releases/1.27
dnkl:releases/1.26
dnkl:releases/1.25
dnkl:releases/1.24
dnkl:multi-cursor
dnkl:releases/1.23
dnkl:pixman-16f-2
dnkl:releases/1.22
dnkl:releases/1.21
dnkl:releases/1.20
dnkl:releases/1.19
dnkl:releases/1.18
dnkl:releases/1.17
dnkl:releases/1.16
dnkl:releases/1.15
dnkl:releases/1.14
dnkl:releases/1.13
dnkl:releases/1.12
dnkl:releases/1.11
dnkl:releases/1.10
dnkl:releases/1.9
dnkl:releases/1.8
dnkl:releases/1.7
dnkl:releases/1.6
dnkl:releases/1.5
dnkl:releases/1.4
dnkl:releases/1.3
dnkl:releases/1.2
dnkl:releases/1.1
dnkl:releases/1.0
First-time contributor
Copy link

What does this MR do?

This MR introduces what I call the vimode. vimode provides keyboard-centric
means of navigating the scrollback, selecting and copying text, searching and
jumping between search matches. By default, vimode provides actions and
keybinds similar to those of vi(m).

vimode is meant to be a complete replacement of the current search mode. Its
primary advantage over the search mode is the ability to arbitrarily manipulate
the selection region (extending, shrinking, resizing) using keyboard only.

vimode may be entered via the default search mode keybind (C+S+r) and exited
via Esc or C+c. vimode includes a submode for performing search (C+/ to search
forward or C+S+/ to search backward, or C+S+/ outside vimode to enter the
search mode directly, Enter to confirm, Esc to exit). Most of the search code
has been adapted to fit vimode. vimode maintains the most recent confirmed
search allowing to navigate between search matches (n to move forward, S+n to
move backward).

Why the name 'vimode'?

For a moment I thought about 'bar mode' to complement 'foo terminal', but that
name would most likely be misleading, thus the next best name I could come up
with had been 'vimode' because its controls resemble those of vi(m). I also
considered keyboard_selection (too long) and kbsel (not bad, vimode won).

Further work

  • Updated man page, changelog, readme.

Possible further extensions

  • operator pending mode - the current implementation has no operator pending,
    thus all keybinds execute immediately. As such, certain actions are not
    possible, e.g. jump forward to character ('f' + character) or yank inner word
    ('yiw').
  • scrolloff - maintains a fixed distance from the cursor to the edges of the
    viewport, e.g. scrolloff=5 would maintain 5 lines of distance between the
    top/bottom of the viewport and the cursor.
  • jump list - keep a number of past jump locations for quick navigation (C+i,
    C+o in vim).
  • support regex in search.
  • WORD motions.

Further notes

  • I worked on this feature as I learned how foot works, thus the commit history
    ended up being quite chaotic. I suppose squashing this would be best.
  • SELECTION_QUOTE_WISE has been removed as it seemed to me it existed solely to
    be a toggle of the initial state, serving no purpose beyond that (as
    indicated by the asserts in all other occurences of this enumeration). There
    is now a function 'selection_start_matching_delimiters' which fulfills the
    purpose of this selection mode.
    Why is this change included? I started reworking selection and this was in
    the changeset. Decided to backtrack on the selection rework due to its scale,
    but this bit seemed like a reasonable inclusion.

Relevant issues

#136 #419 #1168 #1338 #1414 #1912

### What does this MR do? This MR introduces what I call the vimode. vimode provides keyboard-centric means of navigating the scrollback, selecting and copying text, searching and jumping between search matches. By default, vimode provides actions and keybinds similar to those of vi(m). vimode is meant to be a complete replacement of the current search mode. Its primary advantage over the search mode is the ability to arbitrarily manipulate the selection region (extending, shrinking, resizing) using keyboard only. vimode may be entered via the default search mode keybind (C+S+r) and exited via Esc or C+c. vimode includes a submode for performing search (C+/ to search forward or C+S+/ to search backward, or C+S+/ outside vimode to enter the search mode directly, Enter to confirm, Esc to exit). Most of the search code has been adapted to fit vimode. vimode maintains the most recent confirmed search allowing to navigate between search matches (n to move forward, S+n to move backward). ### Why the name 'vimode'? For a moment I thought about 'bar mode' to complement 'foo terminal', but that name would most likely be misleading, thus the next best name I could come up with had been 'vimode' because its controls resemble those of vi(m). I also considered keyboard_selection (too long) and kbsel (not bad, vimode won). ### Further work - Updated man page, changelog, readme. ### Possible further extensions - operator pending mode - the current implementation has no operator pending, thus all keybinds execute immediately. As such, certain actions are not possible, e.g. jump forward to character ('f' + character) or yank inner word ('yiw'). - scrolloff - maintains a fixed distance from the cursor to the edges of the viewport, e.g. scrolloff=5 would maintain 5 lines of distance between the top/bottom of the viewport and the cursor. - jump list - keep a number of past jump locations for quick navigation (C+i, C+o in vim). - support regex in search. - WORD motions. ### Further notes - I worked on this feature as I learned how foot works, thus the commit history ended up being quite chaotic. I suppose squashing this would be best. - SELECTION_QUOTE_WISE has been removed as it seemed to me it existed solely to be a toggle of the initial state, serving no purpose beyond that (as indicated by the asserts in all other occurences of this enumeration). There is now a function 'selection_start_matching_delimiters' which fulfills the purpose of this selection mode. Why is this change included? I started reworking selection and this was in the changeset. Decided to backtrack on the selection rework due to its scale, but this bit seemed like a reasonable inclusion. ### Relevant issues #136 #419 #1168 #1338 #1414 #1912
kociap force-pushed master from 1904a81bda
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
to 524aaa523a
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
2025年06月03日 14:04:40 +02:00
Compare
kociap force-pushed master from 9d66f94e39
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
to ea6c9b1cea
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
2025年06月14日 02:05:32 +02:00
Compare
kociap force-pushed master from c31cbdcc4a
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
to f2f61d2b38
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
2025年06月17日 01:55:22 +02:00
Compare
Author
First-time contributor
Copy link

I am moving this out of WIP as I believe this is now mostly complete and I would like to receive feedback.

There are a few minor pending issues, namely:

  • mouse click in vimode starts selection (expected behaviour is just repositioning the cursor). I frankly do not know how to address this.
  • (削除) changing selection mode after scrolling changes the selection start. (削除ここまで)

A few things I am unsure how to handle:

  • selection is cancelled when the first line of the range is scrolled out. I suppose the expected behaviour here would be to not cancel selection?
  • default binding for PREV_WORD_END ('ge' in vim, cannot provide equivalent yet).
  • cursor is being drawn when search is active. should it? it is not quite clear which match is the primary one. what if instead the primary match was drawn in a different color and the cursor hidden?

And a few improvements to be made:

  • the search box should be rendered below (instead of on top) the scrollback buffer to not obscure the text.
  • the text within the search box should be wrapped when overlong.

I am aware that the formatting is all over the place. I will be addressing that later on.

I am moving this out of WIP as I believe this is now mostly complete and I would like to receive feedback. There are a few minor pending issues, namely: - mouse click in vimode starts selection (expected behaviour is just repositioning the cursor). I frankly do not know how to address this. - ~~changing selection mode after scrolling changes the selection start.~~ A few things I am unsure how to handle: - selection is cancelled when the first line of the range is scrolled out. I suppose the expected behaviour here would be to not cancel selection? - default binding for PREV_WORD_END ('ge' in vim, cannot provide equivalent yet). - cursor is being drawn when search is active. should it? it is not quite clear which match is the primary one. what if instead the primary match was drawn in a different color and the cursor hidden? And a few improvements to be made: - the search box should be rendered below (instead of on top) the scrollback buffer to not obscure the text. - the text within the search box should be wrapped when overlong. I am aware that the formatting is all over the place. I will be addressing that later on.
kociap changed title from (削除) WIP: vimode - keyboard selection mode (削除ここまで) to vimode - keyboard selection mode 2025年06月17日 02:15:26 +02:00
First-time contributor
Copy link

Thanks for your work on this - this would be absolutely wonderful to get in.

Thanks for your work on this - this would be absolutely wonderful to get in.
kociap force-pushed master from 7fde449363
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
to 4646703e16
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
2025年09月17日 16:05:24 +02:00
Compare
kociap force-pushed master from 4646703e16
Some checks are pending
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job completed
to bac341bde3
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
2025年10月22日 10:08:59 +02:00
Compare
kociap force-pushed master from a9d8b6ff07
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
to 757ffa8d3b
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
2025年12月02日 11:05:23 +01:00
Compare
kociap force-pushed master from 757ffa8d3b
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
to 2b17abff3d
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
2025年12月02日 12:11:41 +01:00
Compare
First-time contributor
Copy link

Hey, I tried out your branch and it seems to work well. The only issue I found was not being able to copy selected text when in vimode. Otherwise I really like this!

Hey, I tried out your branch and it seems to work well. The only issue I found was not being able to copy selected text when in vimode. Otherwise I really like this!
Author
First-time contributor
Copy link

Glad you like my work @ffoss! Unless you mean something else, in vimode the default keybind to copy the selection is y.

I am aware of several issues, mainly user experience ones, which I plan to address once I finish my master's thesis in approximately a month.

Glad you like my work @ffoss! Unless you mean something else, in vimode the default keybind to copy the selection is `y`. I am aware of several issues, mainly user experience ones, which I plan to address once I finish my master's thesis in approximately a month.
Some checks reported errors
ci/woodpecker/pr/woodpecker Pipeline is pending approval
builds.sr.ht/freebsd-x64 Job failed
This pull request has changes conflicting with the target branch.
  • input.c
  • render.c
  • tests/test-config.c
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u master:kociap-master
git switch kociap-master

Merge

Merge the changes and update on Forgejo.
git switch master
git merge --no-ff kociap-master
git switch kociap-master
git rebase master
git switch master
git merge --ff-only kociap-master
git switch kociap-master
git rebase master
git switch master
git merge --no-ff kociap-master
git switch master
git merge --squash kociap-master
git switch master
git merge --ff-only kociap-master
git switch master
git merge kociap-master
git push origin master
Sign in to join this conversation.
No reviewers
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dnkl/foot!2017
Reference in a new issue
dnkl/foot
No description provided.
Delete branch "kociap/foot-vi:master"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?