aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-09-27 19:51:29 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-09-27 19:51:29 +0200
commit521263a2c67d2b5df507858dcd240a9e42790780 (patch)
tree2967b3b921f4e5568825367bbeb367f3f918a19d
parentab264837f7c127ba8ff4666f9c4ed94efd485af0 (diff)
downloadvis-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.h3
-rw-r--r--vis.c8
-rw-r--r--window.c42
-rw-r--r--window.h4
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 */ },
};
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*);