vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
commit 50de4d9be29f6bc761bf81619d319f16913597fb parent bbc0cf7f25affd8d05dbb650a755960fd6b7cae1 Author: Marc André Tanner <mat@brain-dump.org> Date: Mon, 3 Oct 2016 13:05:51 +0200 vis: improve cursor positioning after scrolling Make cursor placement after scrolling (half) pages up/down less arbitrary. Close #390, fix #391 Diffstat:
| M | main.c | | | 38 | +++++++++++++++++++++++--------------- |
| M | view.c | | | 37 | +++++++++++++++++++++++++++++++++++++ |
| M | view.h | | | 4 | ++++ |
3 files changed, 64 insertions(+), 15 deletions(-)
diff --git a/main.c b/main.c @@ -1916,35 +1916,43 @@ static const char *insert_verbatim(Vis *vis, const char *keys, const Arg *arg) { return keys; } -static int argi2lines(Vis *vis, const Arg *arg) { +static const char *wscroll(Vis *vis, const char *keys, const Arg *arg) { + View *view = vis_view(vis); int count = vis_count_get(vis); switch (arg->i) { case -PAGE: + view_scroll_page_up(view); + break; case +PAGE: - return view_height_get(vis_view(vis)); + view_scroll_page_down(view); + break; case -PAGE_HALF: + view_scroll_halfpage_up(view); + break; case +PAGE_HALF: - return view_height_get(vis_view(vis))/2; + view_scroll_halfpage_down(view); + break; default: - if (count != VIS_COUNT_UNKNOWN) - return count; - return arg->i < 0 ? -arg->i : arg->i; + if (count == VIS_COUNT_UNKNOWN) + count = arg->i < 0 ? -arg->i : arg->i; + if (arg->i < 0) + view_scroll_up(view, count); + else + view_scroll_down(view, count); + break; } -} - -static const char *wscroll(Vis *vis, const char *keys, const Arg *arg) { - if (arg->i >= 0) - view_scroll_down(vis_view(vis), argi2lines(vis, arg)); - else - view_scroll_up(vis_view(vis), argi2lines(vis, arg)); return keys; } static const char *wslide(Vis *vis, const char *keys, const Arg *arg) { + View *view = vis_view(vis); + int count = vis_count_get(vis); + if (count == VIS_COUNT_UNKNOWN) + count = arg->i < 0 ? -arg->i : arg->i; if (arg->i >= 0) - view_slide_down(vis_view(vis), argi2lines(vis, arg)); + view_slide_down(view, count); else - view_slide_up(vis_view(vis), argi2lines(vis, arg)); + view_slide_up(view, count); return keys; } diff --git a/view.c b/view.c @@ -738,6 +738,43 @@ size_t view_scroll_up(View *view, int lines) { return cursor->pos; } +size_t view_scroll_page_up(View *view) { + Cursor *cursor = view->cursor; + if (view->start == 0) { + view_cursor_to(view, 0); + } else { + view_cursor_to(view, view->start-1); + view_redraw_bottom(view); + view_screenline_begin(cursor); + } + return cursor->pos; +} + +size_t view_scroll_page_down(View *view) { + view_scroll_down(view, view->height); + return view_screenline_begin(view->cursor); +} + +size_t view_scroll_halfpage_up(View *view) { + Cursor *cursor = view->cursor; + if (view->start == 0) { + view_cursor_to(view, 0); + } else { + view_cursor_to(view, view->start-1); + view_redraw_center(view); + view_screenline_begin(cursor); + } + return cursor->pos; +} + +size_t view_scroll_halfpage_down(View *view) { + size_t end = view->end; + size_t pos = view_scroll_down(view, view->height/2); + if (pos < text_size(view->text)) + view_cursor_to(view, end); + return view->cursor->pos; +} + size_t view_scroll_down(View *view, int lines) { Cursor *cursor = view->cursor; if (view_viewport_down(view, lines)) { diff --git a/view.h b/view.h @@ -73,6 +73,10 @@ size_t view_slide_down(View*, int lines); * visible line, try to preserve the column position */ size_t view_scroll_up(View*, int lines); size_t view_scroll_down(View*, int lines); +size_t view_scroll_page_up(View*); +size_t view_scroll_page_down(View*); +size_t view_scroll_halfpage_up(View*); +size_t view_scroll_halfpage_down(View*); /* place the cursor at the start ot the n-th window line, counting from 1 */ size_t view_screenline_goto(View*, int n);