tvi: horizontal scrolling for long lines - neatvi - [fork] simple vi-type editor with UTF-8 support (HTM) git clone git://src.adamsgaard.dk/neatvi (DIR) Log (DIR) Files (DIR) Refs (DIR) README --- (DIR) commit 2cf2cba137d3316342f56e7e035c74e214b1cbb2 (DIR) parent e7975f55419e9eea1dc579bcf0aa7e53b0db479b (HTM) Author: Ali Gholami Rudi <ali@rudi.ir> Date: Tue, 1 Sep 2015 11:47:22 +0430 vi: horizontal scrolling for long lines Diffstat: M ex.c | 1 + M led.c | 52 ++++++++++++++++--------------- M vi.c | 10 +++++++++- M vi.h | 1 + 4 files changed, 38 insertions(+), 26 deletions(-) --- (DIR) diff --git a/ex.c b/ex.c t@@ -8,6 +8,7 @@ #include "vi.h" int xrow, xoff, xtop; /* current row, column, and top row */ +int xleft; /* the first visible column */ int xquit; /* exit if set */ int xvis; /* visual mode */ int xai = 1; /* autoindent option */ (DIR) diff --git a/led.c b/led.c t@@ -25,15 +25,15 @@ static char *kmap_map(char *kmap, int c) return keymap[c] ? keymap[c] : cs; } -/* map cursor horizontal position to terminal column number */ -int led_pos(char *s, int pos) +static int led_posctx(int dir, int pos) { - return dir_context(s) >= 0 ? pos : xcols - pos - 1; + return dir >= 0 ? pos - xleft : xcols - (pos - xleft) - 1; } -static int led_posctx(int dir, int pos) +/* map cursor horizontal position to terminal column number */ +int led_pos(char *s, int pos) { - return dir >= 0 ? pos : xcols - pos - 1; + return led_posctx(dir_context(s), pos); } static int led_offdir(char **chrs, int *pos, int i) t@@ -63,9 +63,9 @@ static void led_markrev(int n, char **chrs, int *pos, int *att) } } -static char *led_render(char *s0) +static char *led_render(char *s0, int cbeg, int cend) { - int n, maxcol = 0; + int n; int *pos; /* pos[i]: the screen position of the i-th character */ int *off; /* off[i]: the character at screen position i */ int *att; /* att[i]: the attributes of i-th character */ t@@ -76,25 +76,23 @@ static char *led_render(char *s0) int ctx = dir_context(s0); chrs = uc_chop(s0, &n); pos = ren_position(s0); - off = malloc(xcols * sizeof(off[0])); - memset(off, 0xff, xcols * sizeof(off[0])); + off = malloc((cend - cbeg) * sizeof(off[0])); + memset(off, 0xff, (cend - cbeg) * sizeof(off[0])); for (i = 0; i < n; i++) { - int curpos = pos[i]; - int curwid = ren_cwid(chrs[i], curpos); - if (curpos >= 0 && curpos + curwid < xcols) { - for (j = 0; j < curwid; j++) { - off[led_posctx(ctx, curpos + j)] = i; - if (led_posctx(ctx, curpos + j) > maxcol) - maxcol = led_posctx(ctx, curpos + j); - } - } + int curwid = ren_cwid(chrs[i], pos[i]); + int curbeg = led_posctx(ctx, pos[i]); + int curend = led_posctx(ctx, pos[i] + curwid - 1); + if (curbeg >= 0 && curbeg < (cend - cbeg) && + curend >= 0 && curend < (cend - cbeg)) + for (j = 0; j < curwid; j++) + off[led_posctx(ctx, pos[i] + j)] = i; } att = syn_highlight(ex_filetype(), s0); led_markrev(n, chrs, pos, att); out = sbuf_make(); - i = 0; - while (i <= maxcol) { - int o = off[i]; + i = cbeg; + while (i < cend) { + int o = off[i - cbeg]; int att_new = o >= 0 ? att[o] : 0; sbuf_str(out, term_att(att_new, att_old)); att_old = att_new; t@@ -104,9 +102,9 @@ static char *led_render(char *s0) else if (uc_isprint(chrs[o])) sbuf_mem(out, chrs[o], uc_len(chrs[o])); else - for (j = i; j <= maxcol && off[j] == o; j++) + for (j = i; j < cend && off[j - cbeg] == o; j++) sbuf_chr(out, ' '); - while (i <= maxcol && off[i] == o) + while (i < cend && off[i - cbeg] == o) i++; } else { sbuf_chr(out, ' '); t@@ -123,7 +121,7 @@ static char *led_render(char *s0) void led_print(char *s, int row) { - char *r = led_render(s); + char *r = led_render(s, xleft, xleft + xcols); term_pos(row, 0); term_kill(); term_str(r); t@@ -171,8 +169,12 @@ static void led_printparts(char *ai, char *pref, char *main, char *post, char *k } term_record(); sbuf_str(ln, post); - led_print(sbuf_buf(ln), -1); pos = ren_cursor(sbuf_buf(ln), ren_pos(sbuf_buf(ln), MAX(0, off - 1))); + if (pos >= xleft + xcols) + xleft = pos - xcols / 2; + if (pos < xleft) + xleft = pos < xcols ? 0 : pos - xcols / 2; + led_print(sbuf_buf(ln), -1); term_pos(-1, led_pos(sbuf_buf(ln), pos + idir)); sbuf_free(ln); term_commit(); (DIR) diff --git a/vi.c b/vi.c t@@ -33,8 +33,11 @@ static void vi_wait(void) static void vi_drawmsg(void) { + int oleft = xleft; + xleft = 0; led_print(vi_msg, xrows); vi_msg[0] = '\0'; + xleft = oleft; } /* redraw the screen */ t@@ -1010,6 +1013,7 @@ static void vi(void) int nrow = xrow; int noff = ren_noeol(lbuf_get(xb, xrow), xoff); int otop = xtop; + int oleft = xleft; int mv, n; term_cmd(&n); vi_arg2 = 0; t@@ -1265,8 +1269,12 @@ static void vi(void) xoff = ren_noeol(lbuf_get(xb, xrow), xoff); if (redraw) xcol = vi_off2col(xb, xrow, xoff); + if (xcol >= xleft + xcols) + xleft = xcol - xcols / 2; + if (xcol < xleft) + xleft = xcol < xcols ? 0 : xcol - xcols / 2; vi_wait(); - if (redraw || xtop != otop) + if (redraw || xtop != otop || xleft != oleft) vi_draw(xcol); if (vi_msg[0]) vi_drawmsg(); (DIR) diff --git a/vi.h b/vi.h t@@ -182,6 +182,7 @@ int conf_highlight_revdir(int *att); extern int xrow; extern int xoff; extern int xtop; +extern int xleft; extern int xvis; extern int xled; extern int xquit;