diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-27 19:51:29 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-27 19:51:29 +0200 |
| commit | 521263a2c67d2b5df507858dcd240a9e42790780 (patch) | |
| tree | 2967b3b921f4e5568825367bbeb367f3f918a19d | |
| parent | ab264837f7c127ba8ff4666f9c4ed94efd485af0 (diff) | |
| download | vis-521263a2c67d2b5df507858dcd240a9e42790780.tar.gz vis-521263a2c67d2b5df507858dcd240a9e42790780.tar.xz | |
Implement 'zt', 'zz', 'zb'
In particular 'zb' might not work if there are wrapped lines involved.
| -rw-r--r-- | config.def.h | 3 | ||||
| -rw-r--r-- | vis.c | 8 | ||||
| -rw-r--r-- | window.c | 42 | ||||
| -rw-r--r-- | window.h | 4 |
4 files changed, 56 insertions, 1 deletions
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 */ }, }; @@ -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); } @@ -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)) { @@ -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*); |
