aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-10-03 13:05:51 +0200
committerMarc André Tanner <mat@brain-dump.org>2016-10-03 13:05:51 +0200
commit5aa0a68d3d5af745b97ddec576f0bbfbe18ed2ab (patch)
tree46e601387828285d253f6b08da7339ecf404de06
parent2f337a347bf1ec9cfeeb11232ad0fa72d4a9990f (diff)
downloadvis-5aa0a68d3d5af745b97ddec576f0bbfbe18ed2ab.tar.gz
vis-5aa0a68d3d5af745b97ddec576f0bbfbe18ed2ab.tar.xz
vis: improve cursor positioning after scrolling
Make cursor placement after scrolling (half) pages up/down less arbitrary. Close #390, fix #391
-rw-r--r--main.c38
-rw-r--r--view.c37
-rw-r--r--view.h4
3 files changed, 64 insertions, 15 deletions
diff --git a/main.c b/main.c
index 83b6910..8e76429 100644
--- 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
index 8f37dcc..1d620de 100644
--- 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
index 8cd2ce3..07fedf4 100644
--- 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);