diff options
| -rw-r--r-- | config.def.h | 20 | ||||
| -rw-r--r-- | vis.c | 44 | ||||
| -rw-r--r-- | window.c | 46 | ||||
| -rw-r--r-- | window.h | 2 |
4 files changed, 72 insertions, 40 deletions
diff --git a/config.def.h b/config.def.h index d21b603..b502135 100644 --- a/config.def.h +++ b/config.def.h @@ -93,8 +93,8 @@ static KeyBinding basic_movement[] = { { { KEY(SRIGHT) }, movement, { .i = MOVE_WORD_START_NEXT } }, { { KEY(UP) }, movement, { .i = MOVE_LINE_UP } }, { { KEY(DOWN) }, movement, { .i = MOVE_LINE_DOWN } }, - { { KEY(PPAGE) }, cursor, { .m = window_page_up } }, - { { KEY(NPAGE) }, cursor, { .m = window_page_down } }, + { { KEY(PPAGE) }, wscroll, { .i = -PAGE } }, + { { KEY(NPAGE) }, wscroll, { .i = +PAGE } }, { { KEY(HOME) }, movement, { .i = MOVE_LINE_START } }, { { KEY(END) }, movement, { .i = MOVE_LINE_FINISH } }, { /* empty last element, array terminator */ }, @@ -347,8 +347,12 @@ static KeyBinding vis_mode_normal[] = { { { CONTROL('w'), NONE('s') }, winsplit, { .b = false } }, { { CONTROL('w'), NONE('j') }, call, { .f = editor_window_next } }, { { CONTROL('w'), NONE('k') }, call, { .f = editor_window_prev } }, - { { CONTROL('F') }, cursor, { .m = window_page_up } }, - { { CONTROL('B') }, cursor, { .m = window_page_down } }, + { { CONTROL('F') }, wscroll, { .i = -PAGE } }, + { { CONTROL('B') }, wscroll, { .i = +PAGE } }, + { { CONTROL('U') }, wscroll, { .i = -PAGE_HALF } }, + { { CONTROL('D') }, wscroll, { .i = +PAGE_HALF } }, + { { CONTROL('E') }, wslide, { .i = -1 } }, + { { CONTROL('Y') }, wslide, { .i = +1 } }, { { NONE('A') }, insertmode, { .i = MOVE_LINE_END } }, { { NONE('C') }, change, { .i = MOVE_LINE_END } }, { { NONE('D') }, delete, { .i = MOVE_LINE_END } }, @@ -675,10 +679,10 @@ static KeyBinding nano_keys[] = { { { CONTROL('F') }, movement, { .i = MOVE_CHAR_NEXT } }, { { CONTROL('P') }, movement, { .i = MOVE_LINE_UP } }, { { CONTROL('N') }, movement, { .i = MOVE_LINE_DOWN } }, - { { CONTROL('Y') }, cursor, { .m = window_page_up } }, - { { KEY(F(7)) }, cursor, { .m = window_page_up } }, - { { CONTROL('V') }, cursor, { .m = window_page_down } }, - { { KEY(F(8)) }, cursor, { .m = window_page_down } }, + { { CONTROL('Y') }, wscroll, { .i = -PAGE } }, + { { KEY(F(7)) }, wscroll, { .i = -PAGE } }, + { { CONTROL('V') }, wscroll, { .i = +PAGE } }, + { { KEY(F(8)) }, wscroll, { .i = +PAGE } }, #if 0 // CONTROL(' ') == 0 which signals the end of array { { CONTROL(' ') }, movement, { .i = MOVE_WORD_START_NEXT } }, @@ -21,6 +21,7 @@ #include <signal.h> #include <errno.h> #include <fcntl.h> +#include <limits.h> #include <sys/select.h> #include <sys/types.h> #include <sys/stat.h> @@ -41,7 +42,7 @@ int ESCDELAY; typedef union { bool b; - size_t i; + int i; const char *s; size_t (*m)(Win*); /* cursor movement based on window content */ void (*f)(Editor*); /* generic editor commands */ @@ -163,6 +164,9 @@ static Operator ops[] = { [OP_PUT] = { op_put, true }, }; +#define PAGE INT_MAX +#define PAGE_HALF (INT_MAX-1) + /* these can be passed as int argument to movement(&(const Arg){ .i = MOVE_* }) */ enum { MOVE_LINE_UP, @@ -384,9 +388,12 @@ static void prompt_up(const Arg *arg); static void prompt_down(const Arg *arg); /* blocks to read 3 consecutive digits and inserts the corresponding byte value */ static void insert_verbatim(const Arg *arg); -/* cursor movement based on the current window content as indicated by arg->m - * which should point to a function from window.h */ -static void cursor(const Arg *arg); +/* scroll window content according to arg->i which can be either PAGE, PAGE_HALF, + * or an arbitrary number of lines. a multiplier overrides what is given in arg->i. + * negative values scroll back, positive forward. */ +static void wscroll(const Arg *arg); +/* similar to scroll, but do only move window content not cursor position */ +static void wslide(const Arg *arg); /* call editor function as indicated by arg->f */ static void call(const Arg *arg); /* quit editor, discard all changes */ @@ -734,8 +741,33 @@ static void winsplit(const Arg *arg) { editor_window_split(vis, NULL); } -static void cursor(const Arg *arg) { - arg->m(vis->win->win); +static int argi2lines(const Arg *arg) { + switch (arg->i) { + case -PAGE: + case +PAGE: + return vis->win->height-1; + case -PAGE_HALF: + case +PAGE_HALF: + return vis->win->height/2; + default: + if (action.count > 0) + return action.count; + return arg->i < 0 ? -arg->i : arg->i; + } +} + +static void wscroll(const Arg *arg) { + if (arg->i >= 0) + window_scroll_down(vis->win->win, argi2lines(arg)); + else + window_scroll_up(vis->win->win, argi2lines(arg)); +} + +static void wslide(const Arg *arg) { + if (arg->i >= 0) + window_slide_down(vis->win->win, argi2lines(arg)); + else + window_slide_up(vis->win->win, argi2lines(arg)); } static void call(const Arg *arg) { @@ -619,52 +619,50 @@ static bool window_viewport_up(Win *win, int n) { size_t window_slide_up(Win *win, int lines) { Cursor *cursor = &win->cursor; - if (window_viewport_up(win, lines)) { - if (cursor->line == win->lastline) - window_cursor_set(win, win->lastline, cursor->col); + if (window_viewport_down(win, lines)) { + if (cursor->line == win->topline) + window_cursor_set(win, win->topline, cursor->col); else window_cursor_to(win, cursor->pos); } else { - window_cursor_to(win, 0); + window_line_down(win); } return cursor->pos; } size_t window_slide_down(Win *win, int lines) { Cursor *cursor = &win->cursor; - if (window_viewport_down(win, lines)) { - if (cursor->line == win->topline) - window_cursor_set(win, win->topline, cursor->col); + if (window_viewport_up(win, lines)) { + if (cursor->line == win->lastline) + window_cursor_set(win, win->lastline, cursor->col); else window_cursor_to(win, cursor->pos); } else { - window_cursor_to(win, text_size(win->text)); + window_line_up(win); } return cursor->pos; } size_t window_scroll_up(Win *win, int lines) { - if (window_viewport_up(win, lines)) - window_cursor_set(win, win->topline, win->cursor.col); - else + Cursor *cursor = &win->cursor; + if (window_viewport_up(win, lines)) { + Line *line = cursor->line < win->lastline ? cursor->line : win->lastline; + window_cursor_set(win, line, win->cursor.col); + } else { window_cursor_to(win, 0); - return win->cursor.pos; + } + return cursor->pos; } size_t window_scroll_down(Win *win, int lines) { - if (window_viewport_down(win, lines)) - window_cursor_set(win, win->lastline, win->cursor.col); - else + Cursor *cursor = &win->cursor; + if (window_viewport_down(win, lines)) { + Line *line = cursor->line > win->topline ? cursor->line : win->topline; + window_cursor_set(win, line, cursor->col); + } else { window_cursor_to(win, text_size(win->text)); - return win->cursor.pos; -} - -size_t window_page_up(Win *win) { - return window_scroll_up(win, win->height); -} - -size_t window_page_down(Win *win) { - return window_scroll_down(win, win->height); + } + return cursor->pos; } size_t window_line_up(Win *win) { @@ -27,8 +27,6 @@ void window_update(Win*); /* cursor movements which also update selection if one is active. * they return new cursor postion */ -size_t window_page_down(Win*); -size_t window_page_up(Win*); size_t window_char_next(Win*); size_t window_char_prev(Win*); size_t window_line_down(Win*); |
