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;