Author: rinrab
Date: Thu Apr 9 14:49:00 2026
New Revision: 1932925
Log:
svnbrowse: More shortcuts for scrolling and moving around the list.
### Current controls ###
- kj, arrows - up/down
- CTRL-P, CTRL-N - also up/down, common in vim list views
- enter - enter, Unix terminals also produce '\n' via CTRL+M.
- backspace, u, '-' - up a directory. I think backspace would be pretty
intuative as the default shortcut. u and '-' are stolen from vim's netrw.
Well technically u is defined as "Change to recently-visited directory" but
it's almost the same as going up and we're not going to implement history
anytime soon.
- CTRL+Y/CTRL+E - scrolls one line up/down
- CTRL+U/CTRL+D - scrolls half-page up/down
- CTRL+B/CTRL+F (forward/backwards), page-up/page-down - scrolls whole page
up/down
- g/HOME - select first element
- G/END - select last element
- z - center selection
- q/ESC - get out of here
TODO: Add repetition by entering a number+action that can be repeated (like
movement by one line). Also CTRL+U/CTRL+D should remember it for usages without
a number. (do we need all of that?)
Note: According to [1], it's a bad practise to use shortcuts like CTRL+arrow or
CTRL+SHIFT+KEY - TUI apps should only use basic combinations or
CTRL+alphabetical symbol.
If there is a useful keybind that I missed, please feel free to extend the
code.
* subversion/svnbrowse/svnbrowse.c
(view_on_event): Factor out scrollsize local variable and implement movement
from above.
* subversion/svnbrowse/model.c
(svn_browse__model_scroll_in_view): Forbid scrolling into negatives.
[1] https://invisible-island.net/ncurses/ncurses.faq.html#modified_keys
Modified:
subversion/trunk/subversion/svnbrowse/model.c
subversion/trunk/subversion/svnbrowse/svnbrowse.c
Modified: subversion/trunk/subversion/svnbrowse/model.c
==============================================================================
--- subversion/trunk/subversion/svnbrowse/model.c Thu Apr 9 13:51:29 2026 (r1932924)
+++ subversion/trunk/subversion/svnbrowse/model.c Thu Apr 9 14:49:00 2026 (r1932925)
@@ -144,6 +144,9 @@ svn_browse__model_scroll_in_view(svn_bro
state->scroller_offset = min(state->scroller_offset,
state->selection);
+ /* forbid scrolling into negatives */
+ state->scroller_offset = max(state->scroller_offset, 0);
+
return SVN_NO_ERROR;
}
Modified: subversion/trunk/subversion/svnbrowse/svnbrowse.c
==============================================================================
--- subversion/trunk/subversion/svnbrowse/svnbrowse.c Thu Apr 9 13:51:29 2026 (r1932924)
+++ subversion/trunk/subversion/svnbrowse/svnbrowse.c Thu Apr 9 14:49:00 2026 (r1932925)
@@ -126,6 +126,9 @@ view_make(svn_browse__model_t *model, ap
static svn_error_t *
view_on_event(svn_browse__view_t *view, int ch, apr_pool_t *scratch_pool)
{
+ /* scrollable height is one row less than the whole view */
+ int scrollsize = getmaxy(stdscr) - 1;
+
/* ch is received from getch() which would read the next character/key with
* the following additional rules:
* 1. as we configured it to use keypad(), arrows and other special keys
@@ -139,10 +142,12 @@ view_on_event(svn_browse__view_t *view,
{
case KEY_UP:
case 'k':
+ case CTRL('p'):
SVN_ERR(svn_browse__model_move_selection(view->model, -1));
break;
case KEY_DOWN:
case 'j':
+ case CTRL('n'):
SVN_ERR(svn_browse__model_move_selection(view->model, 1));
break;
case '\n':
@@ -154,13 +159,45 @@ view_on_event(svn_browse__view_t *view,
case 'u':
SVN_ERR(svn_browse__model_go_up(view->model, scratch_pool));
break;
+ case CTRL('e'):
+ view->model->current->scroller_offset += 1;
+ break;
+ case CTRL('y'):
+ view->model->current->scroller_offset -= 1;
+ break;
+ case CTRL('d'):
+ SVN_ERR(svn_browse__model_move_selection(view->model, scrollsize / 2));
+ break;
+ case CTRL('f'):
+ case KEY_NPAGE:
+ SVN_ERR(svn_browse__model_move_selection(view->model, scrollsize));
+ break;
+ case CTRL('u'):
+ SVN_ERR(svn_browse__model_move_selection(view->model, -scrollsize / 2));
+ break;
+ case CTRL('b'):
+ case KEY_PPAGE:
+ SVN_ERR(svn_browse__model_move_selection(view->model, -scrollsize));
+ break;
+ case 'g':
+ case KEY_HOME:
+ view->model->current->selection = 0;
+ break;
+ case 'G':
+ case KEY_END:
+ view->model->current->selection =
+ view->model->current->list->nelts - 1;
+ break;
+ case 'z':
+ view->model->current->scroller_offset =
+ view->model->current->selection - scrollsize / 2;
+ break;
case 'q':
case KEY_ESC:
return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
}
- /* scrollable height is one row less than the whole view */
- SVN_ERR(svn_browse__model_scroll_in_view(view->model, getmaxy(stdscr) - 1));
+ SVN_ERR(svn_browse__model_scroll_in_view(view->model, scrollsize));
return SVN_NO_ERROR;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.