You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ri...@apache.org on 2026/04/09 14:49:00 UTC
svn commit: r1932925 - subversion/trunk/subversion/svnbrowse
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;
}