From 521263a2c67d2b5df507858dcd240a9e42790780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Sat, 27 Sep 2014 19:51:29 +0200 Subject: Implement 'zt', 'zz', 'zb' In particular 'zb' might not work if there are wrapped lines involved. --- config.def.h | 3 +++ vis.c | 8 +++++++- window.c | 42 ++++++++++++++++++++++++++++++++++++++++++ window.h | 4 ++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index ebc9057..484b152 100644 --- a/config.def.h +++ b/config.def.h @@ -402,6 +402,9 @@ static KeyBinding vis_mode_normal[] = { { { NONE(':') }, prompt, { .s = ":" } }, { { NONE('Z'), NONE('Z') }, cmd, { .s = "wq" } }, { { NONE('Z'), NONE('Q') }, cmd, { .s = "q!" } }, + { { NONE('z'), NONE('t') }, window, { .w = window_redraw_top } }, + { { NONE('z'), NONE('z') }, window, { .w = window_redraw_center } }, + { { NONE('z'), NONE('b') }, window, { .w = window_redraw_bottom } }, { /* empty last element, array terminator */ }, }; diff --git a/vis.c b/vis.c index f2da978..9127c9e 100644 --- a/vis.c +++ b/vis.c @@ -48,7 +48,7 @@ typedef union { bool b; int i; const char *s; - size_t (*m)(Win*); /* cursor movement based on window content */ + void (*w)(Win*); /* generic window commands */ void (*f)(Editor*); /* generic editor commands */ } Arg; @@ -449,6 +449,8 @@ static void wscroll(const Arg *arg); static void wslide(const Arg *arg); /* call editor function as indicated by arg->f */ static void call(const Arg *arg); +/* call window function as indicated by arg->w */ +static void window(const Arg *arg); /* quit editor, discard all changes */ static void quit(const Arg *arg); @@ -981,6 +983,10 @@ static void call(const Arg *arg) { arg->f(vis); } +static void window(const Arg *arg) { + arg->w(vis->win->win); +} + static void insert(const Arg *arg) { editor_insert_key(vis, arg->s, arg->s ? strlen(arg->s) : 0); } diff --git a/window.c b/window.c index cb22f56..43bae70 100644 --- a/window.c +++ b/window.c @@ -639,6 +639,48 @@ static bool window_viewport_up(Win *win, int n) { return true; } +void window_redraw_top(Win *win) { + Line *line = win->cursor.line; + for (Line *cur = win->topline; cur && cur != line; cur = cur->next) + win->start += cur->len; + window_draw(win); + window_cursor_to(win, win->cursor.pos); +} + +void window_redraw_center(Win *win) { + int center = win->height / 2; + size_t pos = win->cursor.pos; + for (int i = 0; i < 2; i++) { + int linenr = 0; + Line *line = win->cursor.line; + for (Line *cur = win->topline; cur && cur != line; cur = cur->next) + linenr++; + if (linenr < center) { + window_slide_down(win, center - linenr); + continue; + } + for (Line *cur = win->topline; cur && cur != line && linenr > center; cur = cur->next) { + win->start += cur->len; + linenr--; + } + break; + } + window_draw(win); + window_cursor_to(win, pos); +} + +void window_redraw_bottom(Win *win) { + Line *line = win->cursor.line; + if (line == win->lastline) + return; + int linenr = 0; + size_t pos = win->cursor.pos; + for (Line *cur = win->topline; cur && cur != line; cur = cur->next) + linenr++; + window_slide_down(win, win->height - linenr - 1); + window_cursor_to(win, pos); +} + size_t window_slide_up(Win *win, int lines) { Cursor *cursor = &win->cursor; if (window_viewport_down(win, lines)) { diff --git a/window.h b/window.h index 6c4b72f..4d00b48 100644 --- a/window.h +++ b/window.h @@ -58,6 +58,10 @@ void window_scroll_to(Win*, size_t pos); * position is visible. if the position is in the middle of a line, try to * adjust the viewport in such a way that the whole line is displayed */ void window_cursor_to(Win*, size_t pos); +/* redraw current cursor line at top/center/bottom of window */ +void window_redraw_top(Win*); +void window_redraw_center(Win*); +void window_redraw_bottom(Win*); /* start selected area at current cursor position. further cursor movements will * affect the selected region. */ void window_selection_start(Win*); -- cgit v1.2.3