aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Mäkipää <jmakip87@gmail.com>2019-03-29 18:44:23 +0200
committerRob Landley <rob@landley.net>2019-03-29 18:59:10 -0500
commit1387c0a6ea9a9fb35ccbd3dff1c141de7bbe0996 (patch)
tree0624175d53cd0af294a6cafb0ee39882011dc99b
parent1201a665bfa6295ef9c0fd2b1a6476e0f0f5d0ac (diff)
downloadtoybox-1387c0a6ea9a9fb35ccbd3dff1c141de7bbe0996.tar.gz
vi: bug fixes
Style cleanups: Removing whitespaces at end of lines, hopefully reduces git am warnings Bug fixes: fix segfault if file did not exist, now creates one empty line fix insert mode text not showing on start of line fix append on empty line fix cursor move right on empty line
-rw-r--r--toys/pending/vi.c203
1 files changed, 107 insertions, 96 deletions
diff --git a/toys/pending/vi.c b/toys/pending/vi.c
index ab15bfe0..c5c87507 100644
--- a/toys/pending/vi.c
+++ b/toys/pending/vi.c
@@ -31,20 +31,20 @@ GLOBALS(
*
* TODO:
* BUGS: screen pos adjust does not cover "widelines"
- *
+ *
*
* REFACTOR: use dllist functions where possible.
* draw_page dont draw full page at time if nothing changed...
* ex callbacks
- *
+ *
* FEATURE: ex: / ? % //atleast easy cases
- * vi: x dw d$ d0
+ * vi: x dw d$ d0
* vi: yw yy (y0 y$)
* vi+ex: gg G //line movements
- * ex: r
+ * ex: r
* ex: !external programs
* ex: w filename //only writes to same file now
- * big file support?
+ * big file support?
*/
@@ -75,7 +75,7 @@ static void adjust_screen_buffer();
struct str_line {
int alloc_len;
- int str_len;
+ int str_len;
char *str_data;
};
@@ -90,7 +90,7 @@ struct linelist {
struct str_line *il;
struct linelist *text; //file loaded into buffer
struct linelist *scr_r;//current screen coord 0 row
-struct linelist *c_r;//cursor position row
+struct linelist *c_r;//cursor position row
int modified;
void dlist_insert_nomalloc(struct double_list **list, struct double_list *new)
@@ -113,9 +113,9 @@ struct double_list *dlist_insert(struct double_list **list, char *data)
return new;
}
-void linelist_unload()
+void linelist_unload()
{
-
+
}
void write_file(char *filename)
@@ -133,7 +133,7 @@ void write_file(char *filename)
fclose(fp);
}
-int linelist_load(char *filename)
+int linelist_load(char *filename)
{
struct linelist *lst = c_r;//cursor position or 0
FILE *fp = 0;
@@ -141,7 +141,18 @@ int linelist_load(char *filename)
filename = (char*)*toys.optargs;
fp = fopen(filename, "r");
- if (!fp) return 0;
+ if (!fp) {
+ char *line = xzalloc(80);
+ ssize_t alc = 80;
+ lst = (struct linelist*)dlist_add((struct double_list**)&lst,
+ xzalloc(sizeof(struct str_line)));
+ lst->line->alloc_len = alc;
+ lst->line->str_len = 0;
+ lst->line->str_data = line;
+ text = lst;
+ dlist_terminate(text->up);
+ return 1;
+ }
for (;;) {
char *line = xzalloc(80);
@@ -177,7 +188,7 @@ int linelist_load(char *filename)
}
//TODO this is overly complicated refactor with lib dllist
-int ex_dd(int count)
+int ex_dd(int count)
{
struct linelist *lst = c_r;
if (c_r == text && text == scr_r) {
@@ -185,7 +196,7 @@ int ex_dd(int count)
text->line->str_len = 1;
sprintf(text->line->str_data, " ");
goto success_exit;
- }
+ }
if (text->down) {
text = text->down;
text->up = 0;
@@ -236,7 +247,7 @@ int ex_dw(int count)
return 1;
}
-int ex_deol(int count)
+int ex_deol(int count)
{
return 1;
}
@@ -253,27 +264,27 @@ int vi_x(int count)
l = &c_r->line->str_len;
p = &TT.cur_col;
if (!(*l)) return 0;
- if ((*p) == (*l)-1) {
+ if ((*p) == (*l)-1) {
s[*p] = 0;
- if (*p) (*p)--;
+ if (*p) (*p)--;
+ (*l)--;
+ } else {
+ memmove(s+(*p), s+(*p)+1, (*l)-(*p));
+ s[*l] = 0;
(*l)--;
- } else {
- memmove(s+(*p), s+(*p)+1, (*l)-(*p));
- s[*l] = 0;
- (*l)--;
}
count--;
- return (count) ? vi_x(count) : 1;
+ return (count) ? vi_x(count) : 1;
}
//move commands does not behave correct way yet.
//only jump to next space for now.
-int vi_movw(int count)
+int vi_movw(int count)
{
if (!c_r)
return 0;
//could we call moveend first
- while (c_r->line->str_data[TT.cur_col] > ' ')
+ while (c_r->line->str_data[TT.cur_col] > ' ')
TT.cur_col++;
while (c_r->line->str_data[TT.cur_col] <= ' ') {
TT.cur_col++;
@@ -283,7 +294,7 @@ int vi_movw(int count)
c_r = c_r->down;
TT.cur_col = 0;
}
- }
+ }
count--;
if (count>1)
return vi_movw(count);
@@ -293,7 +304,7 @@ int vi_movw(int count)
return 1;
}
-int vi_movb(int count)
+int vi_movb(int count)
{
if (!c_r)
return 0;
@@ -308,7 +319,7 @@ int vi_movb(int count)
while (c_r->line->str_data[TT.cur_col] <= ' ') {
if (TT.cur_col) TT.cur_col--;
else goto exit_function;
- }
+ }
while (c_r->line->str_data[TT.cur_col] > ' ') {
if (TT.cur_col)TT.cur_col--;
else goto exit_function;
@@ -323,15 +334,15 @@ exit_function:
return 1;
}
-int vi_move(int count)
+int vi_move(int count)
{
if (!c_r)
return 0;
if (TT.cur_col < c_r->line->str_len)
TT.cur_col++;
if (c_r->line->str_data[TT.cur_col] <= ' ' || count > 1)
- vi_movw(count); //find next word;
- while (c_r->line->str_data[TT.cur_col] > ' ')
+ vi_movw(count); //find next word;
+ while (c_r->line->str_data[TT.cur_col] > ' ')
TT.cur_col++;
if (TT.cur_col) TT.cur_col--;
@@ -348,11 +359,11 @@ void i_insert()
strncpy(t, &s[TT.cur_col], sel);
t[sel+1] = 0;
if (c_r->line->alloc_len < c_r->line->str_len+il->str_len+5) {
- c_r->line->str_data = xrealloc(c_r->line->str_data,
+ c_r->line->str_data = xrealloc(c_r->line->str_data,
c_r->line->alloc_len*2+il->alloc_len*2);
c_r->line->alloc_len = c_r->line->alloc_len*2+2*il->alloc_len;
- memset(&c_r->line->str_data[c_r->line->str_len], 0,
+ memset(&c_r->line->str_data[c_r->line->str_len], 0,
c_r->line->alloc_len-c_r->line->str_len);
s = c_r->line->str_data;
@@ -402,7 +413,7 @@ struct vi_cmd_param vi_cmds[7] =
{"x", &vi_x},
};
-int run_vi_cmd(char *cmd)
+int run_vi_cmd(char *cmd)
{
int val = 0;
char *cmd_e;
@@ -441,11 +452,11 @@ int search_str(char *s)
TT.cur_col = c-c_r->line->str_data;
return 0;
}
-
+
int run_ex_cmd(char *cmd)
{
if (cmd[0] == '/') {
- //search pattern
+ //search pattern
if (!search_str(&cmd[1]) ) {
check_cursor_bounds();
adjust_screen_buffer();
@@ -532,7 +543,8 @@ void vi_main(void)
il->str_len++;
break;
case 'a':
- TT.cur_col++;
+ if (c_r && c_r->line->str_len)
+ TT.cur_col++;
case 'i':
TT.vi_mode = 2;
break;
@@ -552,7 +564,7 @@ void vi_main(void)
vi_buf_pos = 0;
}
- }
+ }
break;
}
@@ -649,6 +661,7 @@ static void draw_page()
char* line = 0;
int bytes = 0;
int drawn = 0;
+ int x = 0;
struct linelist *scr_buf= scr_r;
//clear screen
tty_esc("2J");
@@ -665,12 +678,14 @@ static void draw_page()
y++;
tty_jump(0, y);
} else if (scr_buf && scr_buf->line->str_data && scr_buf->line->str_len) {
- if (scr_buf == c_r)
+ if (scr_buf == c_r)
break;
line = scr_buf->line->str_data;
bytes = scr_buf->line->str_len;
scr_buf = scr_buf->down;
} else {
+ if (scr_buf == c_r)
+ break;
y++;
tty_jump(0, y);
//printf(" \n");
@@ -680,64 +695,59 @@ static void draw_page()
}
//draw cursor row until cursor
//this is to calculate cursor position on screen and possible insert
- if (TT.cur_col) {
- int x = 0;
- line = scr_buf->line->str_data;
- bytes = TT.cur_col;
+ line = scr_buf->line->str_data;
+ bytes = TT.cur_col;
+ for (; y < TT.screen_height; ) {
+ if (bytes) {
+ x = draw_str_until(&drawn, line, TT.screen_width, bytes);
+ bytes = drawn ? (bytes-drawn) : 0;
+ line = bytes ? (line+drawn) : 0;
+ }
+ if (!bytes) break;
+ y++;
+ tty_jump(0, y);
+ }
+ if (TT.vi_mode == 2 && il->str_len) {
+ line = il->str_data;
+ bytes = il->str_len;
+ cx_scr = x;
+ cy_scr = y;
+ x = draw_str_until(&drawn, line, TT.screen_width-x, bytes);
+ bytes = drawn ? (bytes-drawn) : 0;
+ line = bytes ? (line+drawn) : 0;
+ cx_scr += x;
for (; y < TT.screen_height; ) {
if (bytes) {
x = draw_str_until(&drawn, line, TT.screen_width, bytes);
bytes = drawn ? (bytes-drawn) : 0;
line = bytes ? (line+drawn) : 0;
+ cx_scr = x;
}
if (!bytes) break;
y++;
- tty_jump(0, y);
- }
- if (TT.vi_mode == 2 && il->str_len) {
- line = il->str_data;
- bytes = il->str_len;
- cx_scr = x;
- cy_scr = y;
- x = draw_str_until(&drawn, line, TT.screen_width-x, bytes);
- bytes = drawn ? (bytes-drawn) : 0;
- line = bytes ? (line+drawn) : 0;
- cx_scr += x;
- for (; y < TT.screen_height; ) {
- if (bytes) {
- x = draw_str_until(&drawn, line, TT.screen_width, bytes);
- bytes = drawn ? (bytes-drawn) : 0;
- line = bytes ? (line+drawn) : 0;
- cx_scr = x;
- }
- if (!bytes) break;
- y++;
- cy_scr = y;
- tty_jump(0, y);
- }
- } else {
cy_scr = y;
- cx_scr = x;
+ tty_jump(0, y);
}
- line = scr_buf->line->str_data+TT.cur_col;
- bytes = scr_buf->line->str_len-TT.cur_col;
- scr_buf = scr_buf->down;
- x = draw_str_until(&drawn,line, TT.screen_width-x, bytes);
- bytes = drawn ? (bytes-drawn) : 0;
- line = bytes ? (line+drawn) : 0;
- y++;
- tty_jump(0, y);
} else {
cy_scr = y;
- cx_scr = 0;
+ cx_scr = x;
}
+ line = scr_buf->line->str_data+TT.cur_col;
+ bytes = scr_buf->line->str_len-TT.cur_col;
+ scr_buf = scr_buf->down;
+ x = draw_str_until(&drawn,line, TT.screen_width-x, bytes);
+ bytes = drawn ? (bytes-drawn) : 0;
+ line = bytes ? (line+drawn) : 0;
+ y++;
+ tty_jump(0, y);
+
//draw until end
for (; y < TT.screen_height; ) {
if (line && bytes) {
draw_str_until(&drawn, line, TT.screen_width, bytes);
bytes = drawn ? (bytes-drawn) : 0;
line = bytes ? (line+drawn) : 0;
- y++;
+ y++;
tty_jump(0, y);
} else if (scr_buf && scr_buf->line->str_data && scr_buf->line->str_len) {
line = scr_buf->line->str_data;
@@ -754,22 +764,22 @@ static void draw_page()
tty_jump(0, TT.screen_height);
switch (TT.vi_mode) {
case 0:
- tty_esc("30;44m");
+ tty_esc("30;44m");
printf("COMMAND|");
break;
case 1:
- tty_esc("30;42m");
+ tty_esc("30;42m");
printf("NORMAL|");
break;
case 2:
- tty_esc("30;41m");
+ tty_esc("30;41m");
printf("INSERT|");
break;
}
//DEBUG
- tty_esc("47m");
- tty_esc("30m");
+ tty_esc("47m");
+ tty_esc("30m");
utf_l = utf8_len(&c_r->line->str_data[TT.cur_col]);
if (utf_l) {
char t[5] = {0, 0, 0, 0, 0};
@@ -777,10 +787,10 @@ static void draw_page()
printf("utf: %d %s", utf_l, t);
}
printf("| %d, %d\n", cx_scr, cy_scr); //screen coord
-
+
tty_jump(TT.screen_width-12, TT.screen_height);
printf("| %d, %d\n", TT.cur_row, TT.cur_col);
- tty_esc("37m");
+ tty_esc("37m");
tty_esc("40m");
if (!TT.vi_mode) {
tty_esc("1m");
@@ -788,17 +798,17 @@ static void draw_page()
printf("%s", il->str_data);
tty_esc("0m");
} else tty_jump(cx_scr, cy_scr);
-
+
xflush();
}
-static void draw_char(char c, int x, int y, int highlight)
+static void draw_char(char c, int x, int y, int highlight)
{
tty_jump(x, y);
if (highlight) {
tty_esc("30m"); //foreground black
- tty_esc("47m"); //background white
+ tty_esc("47m"); //background white
}
printf("%c", c);
}
@@ -814,7 +824,7 @@ static int draw_rune(char *c, int x, int y, int highlight)
tty_esc("0m");
if (highlight) {
tty_esc("30m"); //foreground black
- tty_esc("47m"); //background white
+ tty_esc("47m"); //background white
}
strncpy(t, c, 5);
printf("%s", t);
@@ -832,7 +842,7 @@ static void check_cursor_bounds()
}
}
-static void adjust_screen_buffer()
+static void adjust_screen_buffer()
{
//search cursor and screen TODO move this perhaps
struct linelist *t = text;
@@ -855,7 +865,7 @@ static void adjust_screen_buffer()
else if ( c > s ) {
//should count multiline long strings!
int distance = c - s + 1;
- //TODO instead iterate scr_r up and check strlen%screen_width
+ //TODO instead iterate scr_r up and check strlen%screen_width
//for each iteration
if (distance >= (int)TT.screen_height) {
int adj = distance - TT.screen_height;
@@ -880,9 +890,9 @@ static int utf8_len(char *str)
{
int len = 0;
int i = 0;
- uint8_t *c = (uint8_t*)str;
- if (!c || !(*c)) return 0;
- if (*c < 0x7F) return 1;
+ uint8_t *c = (uint8_t*)str;
+ if (!c || !(*c)) return 0;
+ if (*c < 0x7F) return 1;
if ((*c & 0xE0) == 0xc0) len = 2;
else if ((*c & 0xF0) == 0xE0 ) len = 3;
else if ((*c & 0xF8) == 0xF0 ) len = 4;
@@ -931,7 +941,7 @@ static int utf8_width(char *str, int bytes)
return 0;
}
-static int utf8_dec(char key, char *utf8_scratch, int *sta_p)
+static int utf8_dec(char key, char *utf8_scratch, int *sta_p)
{
int len = 0;
char *c = utf8_scratch;
@@ -942,14 +952,14 @@ static int utf8_dec(char key, char *utf8_scratch, int *sta_p)
else if ((*c & 0xF0) == 0xE0 ) len = 3;
else if ((*c & 0xF8) == 0xF0 ) len = 4;
else {*sta_p = 0; return 0; }
-
+
(*sta_p)++;
if (*sta_p == 1) return 0;
if ((c[*sta_p-1] & 0xc0) != 0x80) {*sta_p = 0; return 0; }
if (*sta_p == len) { c[(*sta_p)] = 0; return 1; }
-
+
return 0;
}
@@ -963,7 +973,7 @@ static int draw_str_until(int *drawn, char *str, int width, int bytes)
for (;width && bytes;) {
rune_bytes = utf8_lnw(&rune_width, end, 4);
if (!rune_bytes) break;
- if (width - rune_width < 0) goto write_bytes;
+ if (width - rune_width < 0) goto write_bytes;
width -= rune_width;
bytes -= rune_bytes;
end += rune_bytes;
@@ -991,6 +1001,7 @@ static void cur_left()
static void cur_right()
{
+ if (c_r->line->str_len <= 1) return;
if (TT.cur_col == c_r->line->str_len-1) return;
TT.cur_col++;
if (!utf8_len(&c_r->line->str_data[TT.cur_col])) cur_right();