diff options
Diffstat (limited to 'toys/pending')
-rw-r--r-- | toys/pending/vi.c | 369 |
1 files changed, 186 insertions, 183 deletions
diff --git a/toys/pending/vi.c b/toys/pending/vi.c index 20368563..6a1c2349 100644 --- a/toys/pending/vi.c +++ b/toys/pending/vi.c @@ -59,9 +59,9 @@ struct linestack_show { static void draw_page(); static void draw_char(char c, int x, int y, int highlight); //utf8 support -static int utf8_dec(char key, char* utf8_scratch,int* sta_p) ; -static int utf8_len(char* str); -static int draw_rune(char* c,int x,int y, int highlight); +static int utf8_dec(char key, char *utf8_scratch, int *sta_p) ; +static int utf8_len(char *str); +static int draw_rune(char *c, int x, int y, int highlight); static void cur_left(); @@ -75,7 +75,7 @@ static void adjust_screen_buffer(); struct str_line { int alloc_len; int str_len; - char* str_data; + char *str_data; }; //lib dllist uses next and prev kinda opposite what im used to so I just @@ -97,7 +97,7 @@ void dlist_insert_nomalloc(struct double_list **list, struct double_list *new) if (*list) { new->next = *list; new->prev = (*list)->prev; - if((*list)->prev) (*list)->prev->next = new; + if ((*list)->prev) (*list)->prev->next = new; (*list)->prev = new; } else *list = new->next = new->prev = new; } @@ -117,39 +117,38 @@ void linelist_unload() } -void write_file(char* filename) +void write_file(char *filename) { struct linelist *lst = text; FILE *fp = 0; if (!filename) filename = (char*)*toys.optargs; - fp = fopen(filename,"w"); + fp = fopen(filename, "w"); if (!fp) return ; - while(lst) { - fprintf(fp,"%s\n",lst->line->str_data); + while (lst) { + fprintf(fp, "%s\n", lst->line->str_data); lst = lst->down; } fclose(fp); } -int linelist_load(char* filename) +int linelist_load(char *filename) { struct linelist *lst = c_r;//cursor position or 0 - FILE* fp = 0; + FILE *fp = 0; if (!filename) filename = (char*)*toys.optargs; fp = fopen(filename, "r"); if (!fp) return 0; - for (;;) { - char* line = xzalloc(80); - ssize_t alc =80; + char *line = xzalloc(80); + ssize_t alc = 80; ssize_t len; - if ((len = getline(&line, (void *)&alc, fp))== -1) { + if ((len = getline(&line, (void *)&alc, fp)) == -1) { if (errno == EINVAL || errno == ENOMEM) { - printf("error %d\n",errno); + printf("error %d\n", errno); } free(line); break; @@ -160,8 +159,8 @@ int linelist_load(char* filename) lst->line->str_len = len; lst->line->str_data = line; - if (lst->line->str_data[len-1]=='\n') { - lst->line->str_data[len-1]=0; + if (lst->line->str_data[len-1] == '\n') { + lst->line->str_data[len-1] = 0; lst->line->str_len--; } if (text == 0) { @@ -179,23 +178,23 @@ int linelist_load(char* filename) //TODO this is overly complicated refactor with lib dllist int ex_dd(int count) { - struct linelist* lst = c_r; - if (c_r==text && text == scr_r) { + struct linelist *lst = c_r; + if (c_r == text && text == scr_r) { if (!text->down && !text->up && text->line) { - text->line->str_len=1; - sprintf(text->line->str_data," "); + text->line->str_len = 1; + sprintf(text->line->str_data, " "); goto success_exit; } if (text->down) { - text =text->down; - text->up=0; - c_r=text; - scr_r=text; + text = text->down; + text->up = 0; + c_r = text; + scr_r = text; free(lst->line->str_data); free(lst->line); free(lst); } - goto recursion_exit; + goto recursion_exit; } //TODO use lib dllist stuff if (lst) @@ -204,15 +203,15 @@ int ex_dd(int count) lst->down->up = lst->up; } if (lst->up) { - lst->up->down = lst->down; + lst->up->down = lst->down; } if (scr_r == c_r) { - scr_r =c_r->down ? c_r->down : c_r->up; + scr_r = c_r->down ? c_r->down : c_r->up; } if (c_r->down) c_r = c_r->down; else { - c_r = c_r->up; + c_r = c_r->up; count = 1; } free(lst->line->str_data); @@ -240,12 +239,13 @@ int ex_deol(int count) { return 1; } + //does not work with utf8 yet int vi_x(int count) { - char* s; - int* l; - int* p; + char *s; + int *l; + int *p; if (!c_r) return 0; s = c_r->line->str_data; @@ -253,12 +253,12 @@ int vi_x(int count) p = &TT.cur_col; if (!(*l)) return 0; if ((*p) == (*l)-1) { - s[*p]=0; + s[*p] = 0; if (*p) (*p)--; (*l)--; } else { - memmove(s+(*p),s+(*p)+1,(*l)-(*p)); - s[*l]=0; + memmove(s+(*p), s+(*p)+1, (*l)-(*p)); + s[*l] = 0; (*l)--; } count--; @@ -272,23 +272,23 @@ 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] <= ' ') { + while (c_r->line->str_data[TT.cur_col] <= ' ') { TT.cur_col++; if (!c_r->line->str_data[TT.cur_col]) { //we could call j and g0 if (!c_r->down) return 0; c_r = c_r->down; - TT.cur_col=0; + TT.cur_col = 0; } } count--; if (count>1) return vi_movw(count); - check_cursor_bounds(); - adjust_screen_buffer(); + check_cursor_bounds(); + adjust_screen_buffer(); return 1; } @@ -299,16 +299,16 @@ int vi_movb(int count) if (!TT.cur_col) { if (!c_r->up) return 0; c_r = c_r->up; - TT.cur_col=(c_r->line->str_len) ? c_r->line->str_len-1 : 0; + TT.cur_col = (c_r->line->str_len) ? c_r->line->str_len-1 : 0; goto exit_function; } if (TT.cur_col) TT.cur_col--; - while(c_r->line->str_data[TT.cur_col] <= ' ') { + 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] > ' ') { + while (c_r->line->str_data[TT.cur_col] > ' ') { if (TT.cur_col)TT.cur_col--; else goto exit_function; } @@ -317,8 +317,8 @@ exit_function: count--; if (count>1) return vi_movb(count); - check_cursor_bounds(); - adjust_screen_buffer(); + check_cursor_bounds(); + adjust_screen_buffer(); return 1; } @@ -330,74 +330,83 @@ int vi_move(int count) 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] > ' ') + while (c_r->line->str_data[TT.cur_col] > ' ') TT.cur_col++; if (TT.cur_col) TT.cur_col--; - check_cursor_bounds(); - adjust_screen_buffer(); + + check_cursor_bounds(); + adjust_screen_buffer(); return 1; } void i_insert() { - char* t = xzalloc(c_r->line->alloc_len); - char* s = c_r->line->str_data; - int sel = c_r->line->str_len-TT.cur_col; - strncpy(t,&s[TT.cur_col],sel); + char *t = xzalloc(c_r->line->alloc_len); + char *s = c_r->line->str_data; + int sel = c_r->line->str_len-TT.cur_col; + 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->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,c_r->line->alloc_len-c_r->line->str_len); - s = c_r->line->str_data; + 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->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, + c_r->line->alloc_len-c_r->line->str_len); + + s = c_r->line->str_data; } - strcpy(&s[TT.cur_col],il->str_data); - strcpy(&s[TT.cur_col+il->str_len],t); + strcpy(&s[TT.cur_col], il->str_data); + strcpy(&s[TT.cur_col+il->str_len], t); TT.cur_col += il->str_len; if (TT.cur_col) TT.cur_col--; - c_r->line->str_len+=il->str_len; + c_r->line->str_len += il->str_len; free(t); } + //new line at split pos; void i_split() { - struct str_line* l = xmalloc(sizeof(struct str_line)); + struct str_line *l = xmalloc(sizeof(struct str_line)); int l_a = c_r->line->alloc_len; int l_len = c_r->line->str_len-TT.cur_col; l->str_data = xzalloc(l_a); - l->alloc_len=l_a; + l->alloc_len = l_a; l->str_len = l_len; - strncpy(l->str_data,&c_r->line->str_data[TT.cur_col],l_len); + strncpy(l->str_data, &c_r->line->str_data[TT.cur_col], l_len); l->str_data[l_len] = 0; - c_r->line->str_len-=l_len; + c_r->line->str_len -= l_len; c_r->line->str_data[c_r->line->str_len] = 0; - c_r = (struct linelist*)dlist_insert((struct double_list**)&c_r,(char*)l); + c_r = (struct linelist*)dlist_insert((struct double_list**)&c_r, (char*)l); c_r->line = l; - TT.cur_col=0; + TT.cur_col = 0; check_cursor_bounds(); adjust_screen_buffer(); } struct vi_cmd_param { - const char* cmd; + const char *cmd; int (*vi_cmd_ptr)(int); }; + struct vi_cmd_param vi_cmds[7] = { - {"dd",&ex_dd}, - {"dw",&ex_dw}, - {"d$",&ex_deol}, - {"w",&vi_movw}, - {"b",&vi_movb}, - {"e",&vi_move}, - {"x",&vi_x}, + {"dd", &ex_dd}, + {"dw", &ex_dw}, + {"d$", &ex_deol}, + {"w", &vi_movw}, + {"b", &vi_movb}, + {"e", &vi_move}, + {"x", &vi_x}, }; -int run_vi_cmd(char* cmd) + +int run_vi_cmd(char *cmd) { int val = 0; - char* cmd_e; + char *cmd_e; errno = 0; + int i = 0; val = strtol(cmd, &cmd_e, 10); if (errno || val == 0) { val = 1; @@ -405,9 +414,8 @@ int run_vi_cmd(char* cmd) else { cmd = cmd_e; } - int i = 0; - for(;i<7;i++) { - if (strstr(cmd,vi_cmds[i].cmd)) { + for (; i<7; i++) { + if (strstr(cmd, vi_cmds[i].cmd)) { return vi_cmds[i].vi_cmd_ptr(val); } } @@ -415,25 +423,25 @@ int run_vi_cmd(char* cmd) } -int search_str(char* s) +int search_str(char *s) { - struct linelist* lst = c_r; - char *c = strstr(&c_r->line->str_data[TT.cur_col],s); + struct linelist *lst = c_r; + char *c = strstr(&c_r->line->str_data[TT.cur_col], s); if (c) { TT.cur_col = c_r->line->str_data-c; - TT.cur_col=c-c_r->line->str_data; + TT.cur_col = c-c_r->line->str_data; } - else for(;!c;) { + else for (; !c;) { lst = lst->down; if (!lst) return 1; - c = strstr(&lst->line->str_data[TT.cur_col],s); + c = strstr(&lst->line->str_data[TT.cur_col], s); } - c_r=lst; - TT.cur_col=c-c_r->line->str_data; + c_r = lst; + TT.cur_col = c-c_r->line->str_data; return 0; } -int run_ex_cmd(char* cmd) +int run_ex_cmd(char *cmd) { if (cmd[0] == '/') { //search pattern @@ -444,15 +452,15 @@ int run_ex_cmd(char* cmd) } else if (cmd[0] == '?') { } else if (cmd[0] == ':') { - if (strstr(&cmd[1],"q!")) { + if (strstr(&cmd[1], "q!")) { //exit_application; return -1; } - else if (strstr(&cmd[1],"wq")) { + else if (strstr(&cmd[1], "wq")) { write_file(0); return -1; } - else if (strstr(&cmd[1],"w")) { + else if (strstr(&cmd[1], "w")) { write_file(0); return 1; } @@ -468,13 +476,13 @@ void vi_main(void) int utf8_dec_p = 0; int key = 0; char vi_buf[16]; - int vi_buf_pos=0; + int vi_buf_pos = 0; il = xzalloc(sizeof(struct str_line)); il->str_data = xzalloc(80); il->alloc_len = 80; keybuf[0] = 0; - memset(vi_buf,0,16); - memset(utf8_code,0,8); + memset(vi_buf, 0, 16); + memset(utf8_code, 0, 8); linelist_load(0); scr_r = text; c_r = text; @@ -484,8 +492,8 @@ void vi_main(void) TT.screen_height = 24; TT.vi_mode = 1; terminal_size(&TT.screen_width, &TT.screen_height); - TT.screen_height -=2; //TODO this is hack fix visual alignment - set_terminal(0,1,0,0); + TT.screen_height -= 2; //TODO this is hack fix visual alignment + set_terminal(0, 1, 0, 0); //writes stdout into different xterm buffer so when we exit //we dont get scroll log full of junk tty_esc("?1049h"); @@ -493,8 +501,8 @@ void vi_main(void) xflush(); draw_page(); while(1) { - key = scan_key(keybuf,-1); - printf("key %d\n",key); + key = scan_key(keybuf, -1); + printf("key %d\n", key); switch (key) { case -1: case 3: @@ -536,10 +544,10 @@ void vi_main(void) vi_buf[vi_buf_pos] = key; vi_buf_pos++; if (run_vi_cmd(vi_buf)) { - memset(vi_buf,0,16); - vi_buf_pos=0; + memset(vi_buf, 0, 16); + vi_buf_pos = 0; } - else if (vi_buf_pos==16) { + else if (vi_buf_pos == 16) { vi_buf_pos = 0; } @@ -550,30 +558,29 @@ void vi_main(void) } else if (TT.vi_mode == 0) { //EX MODE switch (key) { case 27: - TT.vi_mode=1; + TT.vi_mode = 1; il->str_len = 0; - memset(il->str_data,0,il->alloc_len); + memset(il->str_data, 0, il->alloc_len); break; case 0x7F: case 0x08: - if (il->str_len){ + if (il->str_len) { il->str_data[il->str_len] = 0; - if (il->str_len>1) il->str_len--; + if (il->str_len > 1) il->str_len--; } break; case 0x0D: if (run_ex_cmd(il->str_data) == -1) goto cleanup_vi; - TT.vi_mode=1; + TT.vi_mode = 1; il->str_len = 0; - memset(il->str_data,0,il->alloc_len); + memset(il->str_data, 0, il->alloc_len); break; default: //add chars to ex command until ENTER if (key >= 0x20 && key < 0x7F) { //might be utf? - if (il->str_len == il->alloc_len) - { - il->str_data = realloc(il->str_data,il->alloc_len*2); - il->alloc_len *=2; + if (il->str_len == il->alloc_len) { + il->str_data = realloc(il->str_data, il->alloc_len*2); + il->alloc_len *= 2; } il->str_data[il->str_len] = key; il->str_len++; @@ -584,9 +591,9 @@ void vi_main(void) switch (key) { case 27: i_insert(); - TT.vi_mode=1; + TT.vi_mode = 1; il->str_len = 0; - memset(il->str_data,0,il->alloc_len); + memset(il->str_data, 0, il->alloc_len); break; case 0x7F: case 0x08: @@ -604,28 +611,19 @@ void vi_main(void) // i_insert(); il->str_len = 0; - memset(il->str_data,0,il->alloc_len); + memset(il->str_data, 0, il->alloc_len); i_split(); break; default: - if (key >= 0x20 /*&& key < 0x7F) { - if (il->str_len == il->alloc_len) - { - il->str_data = realloc(il->str_data,il->alloc_len*2); - il->alloc_len *=2; + if (key >= 0x20 && utf8_dec(key, utf8_code, &utf8_dec_p)) { + if (il->str_len+utf8_dec_p+1 >= il->alloc_len) { + il->str_data = realloc(il->str_data, il->alloc_len*2); + il->alloc_len *= 2; } - il->str_data[il->str_len] = key; - il->str_len++; - } else if (key > 0x7F */&& utf8_dec(key, utf8_code, &utf8_dec_p)) { - if (il->str_len+utf8_dec_p+1 >= il->alloc_len) - { - il->str_data = realloc(il->str_data,il->alloc_len*2); - il->alloc_len *=2; - } - strcpy(il->str_data+il->str_len,utf8_code); - il->str_len +=utf8_dec_p; - utf8_dec_p=0; - *utf8_code=0; + strcpy(il->str_data+il->str_len, utf8_code); + il->str_len += utf8_dec_p; + utf8_dec_p = 0; + *utf8_code = 0; } break; @@ -636,56 +634,57 @@ void vi_main(void) } cleanup_vi: - tty_reset(); + tty_reset(); tty_esc("?1049l"); } static void draw_page() { unsigned y = 0; - int cy_scr =0; - int cx_scr =0; - struct linelist* scr_buf= scr_r; + int cy_scr = 0; + int cx_scr = 0; + int utf_l = 0; + struct linelist *scr_buf= scr_r; //clear screen tty_esc("2J"); tty_esc("H"); - tty_jump(0,0); - for(; y < TT.screen_height; ) { + tty_jump(0, 0); + for (; y < TT.screen_height; ) { if (scr_buf && scr_buf->line->str_data && scr_buf->line->str_len) { int p = 0; - for(; p < scr_buf->line->str_len;y++) { + for (; p < scr_buf->line->str_len; y++) { unsigned x = 0; - for(;x<TT.screen_width;x++) { + for (; x < TT.screen_width; x++) { if (p < scr_buf->line->str_len) { int hi = 0; if (scr_buf == c_r && p == TT.cur_col) { if (TT.vi_mode == 2) { - tty_jump(x,y); + tty_jump(x, y); tty_esc("1m"); //bold - printf("%s",il->str_data); - x+=il->str_len; + printf("%s", il->str_data); + x += il->str_len; tty_esc("0m"); } cy_scr = y; cx_scr = x; } - int l = draw_rune(&scr_buf->line->str_data[p],x,y,hi); - if (!l) + utf_l = draw_rune(&scr_buf->line->str_data[p], x, y, hi); + if (!utf_l) break; - p+=l; - if (l>2) x++;//traditional chinese is somehow 2 width in tty??? + p += utf_l; + if (utf_l > 2) x++;//traditional chinese is somehow 2 width in tty??? } else { if (scr_buf == c_r && p == TT.cur_col) { if (TT.vi_mode == 2) { - tty_jump(x,y); + tty_jump(x, y); tty_esc("1m"); //bold - printf("%s",il->str_data); - x+=il->str_len; + printf("%s", il->str_data); + x += il->str_len; tty_esc("0m"); } cy_scr = y; @@ -702,22 +701,22 @@ static void draw_page() cy_scr = y; cx_scr = 0; if (TT.vi_mode == 2) { - tty_jump(0,y); + tty_jump(0, y); tty_esc("1m"); //bold - printf("%s",il->str_data); - cx_scr +=il->str_len; + printf("%s", il->str_data); + cx_scr += il->str_len; tty_esc("0m"); - } else draw_char(' ',0,y,1); + } else draw_char(' ', 0, y, 1); } - y++; + y++; } printf("\n"); if (scr_buf->down) scr_buf=scr_buf->down; else break; } - for(;y < TT.screen_height;y++) { - printf("\n"); + for (; y < TT.screen_height; y++) { + printf("\n"); } tty_jump(0, TT.screen_height); @@ -739,50 +738,52 @@ static void draw_page() //DEBUG tty_esc("47m"); tty_esc("30m"); - int i = utf8_len(&c_r->line->str_data[TT.cur_col]); - if (i) { - char t[5] = {0,0,0,0,0}; - strncpy(t,&c_r->line->str_data[TT.cur_col],i); - printf("utf: %d %s",i,t); + utf_l = utf8_len(&c_r->line->str_data[TT.cur_col]); + if (utf_l) { + char t[5] = {0, 0, 0, 0, 0}; + strncpy(t, &c_r->line->str_data[TT.cur_col], utf_l); + printf("utf: %d %s", utf_l, t); } - printf("| %d, %d\n",cx_scr,cy_scr); //screen coord + 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); + printf("| %d, %d\n", TT.cur_row, TT.cur_col); tty_esc("37m"); tty_esc("40m"); if (!TT.vi_mode) { tty_esc("1m"); - tty_jump(0,TT.screen_height+1); - printf("%s",il->str_data); - } else tty_jump(cx_scr,cy_scr); + tty_jump(0, TT.screen_height+1); + printf("%s", il->str_data); + } else tty_jump(cx_scr, cy_scr); xflush(); } + static void draw_char(char c, int x, int y, int highlight) { - tty_jump(x,y); + tty_jump(x, y); if (highlight) { tty_esc("30m"); //foreground black tty_esc("47m"); //background white } - printf("%c",c); + printf("%c", c); } + //utf rune draw //printf and useless copy could be replaced by direct write() to stdout -static int draw_rune(char* c,int x,int y, int highlight) +static int draw_rune(char *c, int x, int y, int highlight) { int l = utf8_len(c); - char t[5] = {0,0,0,0,0}; + char t[5] = {0, 0, 0, 0, 0}; if (!l) return 0; - tty_jump(x,y); + tty_jump(x, y); tty_esc("0m"); if (highlight) { tty_esc("30m"); //foreground black tty_esc("47m"); //background white } - strncpy(t,c,5); - printf("%s",t); + strncpy(t, c, 5); + printf("%s", t); tty_esc("0m"); return l; } @@ -800,11 +801,11 @@ static void check_cursor_bounds() static void adjust_screen_buffer() { //search cursor and screen TODO move this perhaps - struct linelist* t = text; + struct linelist *t = text; int c = -1; int s = -1; int i = 0; - for(;;) { + for (;;) { i++; if (t == c_r) c = i; @@ -819,7 +820,7 @@ static void adjust_screen_buffer() } else if ( c > s ) { //should count multiline long strings! - int distance = c - s +1; + int distance = c - s + 1; //TODO instead iterate scr_r up and check strlen%screen_width //for each iteration if (distance >= (int)TT.screen_height) { @@ -841,7 +842,7 @@ static void adjust_screen_buffer() //2 110xxxxx 10xxxxxx //3 1110xxxx 10xxxxxx 10xxxxxx //4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx -static int utf8_len(char* str) +static int utf8_len(char *str) { int len = 0; int i = 0; @@ -853,16 +854,16 @@ static int utf8_len(char* str) else if ((*c & 0xF8) == 0xF0 ) len = 4; else return 0; c++; - for(i = len-1;i>0;i--) { - if ((*c++ & 0xc0)!=0x80) return 0; + for (i = len-1; i > 0; i--) { + if ((*c++ & 0xc0) != 0x80) return 0; } return len; } -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; + char *c = utf8_scratch; c[*sta_p] = key; if (!(*sta_p)) *c = key; if (*c < 0x7F) { *sta_p = 1; return 1; } @@ -874,7 +875,7 @@ static int utf8_dec(char key, char* utf8_scratch,int* sta_p) (*sta_p)++; if (*sta_p == 1) return 0; - if ((c[*sta_p-1] & 0xc0)!=0x80) {*sta_p = 0; return 0; } + if ((c[*sta_p-1] & 0xc0) != 0x80) {*sta_p = 0; return 0; } if (*sta_p == len) { c[(*sta_p)] = 0; return 1; } @@ -900,6 +901,7 @@ static void cur_up() { if (c_r->up != 0) c_r = c_r->up; + if (!utf8_len(&c_r->line->str_data[TT.cur_col])) cur_left(); check_cursor_bounds(); adjust_screen_buffer(); @@ -909,6 +911,7 @@ static void cur_down() { if (c_r->down != 0) c_r = c_r->down; + if (!utf8_len(&c_r->line->str_data[TT.cur_col])) cur_left(); check_cursor_bounds(); adjust_screen_buffer(); |