aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
authorJarno Mäkipää <jmakip87@gmail.com>2019-04-03 21:44:59 +0300
committerRob Landley <rob@landley.net>2019-04-03 19:49:36 -0500
commit5ec4aa7ee58cdf209db31e8dda53224026d1167f (patch)
tree36acb82cfabf0578923e6f61c4572aba4028754e /toys
parent7b11e55921aa4e5d3265e96756436ee97641ccf5 (diff)
downloadtoybox-5ec4aa7ee58cdf209db31e8dda53224026d1167f.tar.gz
VI rewrote char delete and hjkl movements
Reimplemented basic cursor movements and char delete. In order to work more correctly with utf-8 data. x,h,j,k,l seems to work now with test data such as tests/files/utf8/test2.txt hjkl now accept count parameter so 1000j will scroll file 1000 lines relative move to bottom word movements w,e,b... still need to be still reimplemented in order to step correctly on utf-8 data
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/vi.c154
1 files changed, 100 insertions, 54 deletions
diff --git a/toys/pending/vi.c b/toys/pending/vi.c
index c5c87507..31516b55 100644
--- a/toys/pending/vi.c
+++ b/toys/pending/vi.c
@@ -63,12 +63,13 @@ static int utf8_dec(char key, char *utf8_scratch, int *sta_p) ;
static int utf8_len(char *str);
static int utf8_width(char *str, int bytes);
static int draw_rune(char *c, int x, int y, int highlight);
+static char* utf8_last(char* str, int size);
-static void cur_left();
-static void cur_right();
-static void cur_up();
-static void cur_down();
+static int cur_left(int count);
+static int cur_right(int count);
+static int cur_up(int count);
+static int cur_down(int count);
static void check_cursor_bounds();
static void adjust_screen_buffer();
@@ -252,29 +253,57 @@ int ex_deol(int count)
return 1;
}
-//does not work with utf8 yet
int vi_x(int count)
{
char *s;
+ char *last;
int *l;
- int *p;
+ int length = 0;
+ int width = 0;
+ int remaining = 0;
+ char *end;
+ char *start;
if (!c_r)
return 0;
s = c_r->line->str_data;
l = &c_r->line->str_len;
- p = &TT.cur_col;
- if (!(*l)) return 0;
- if ((*p) == (*l)-1) {
- s[*p] = 0;
- if (*p) (*p)--;
- (*l)--;
+
+ last = utf8_last(s,*l);
+ if (last == s+TT.cur_col) {
+ memset(last, 0, (*l)-TT.cur_col);
+ *l = TT.cur_col;
+ if (!TT.cur_col) return 1;
+ last = utf8_last(s, TT.cur_col);
+ TT.cur_col = last-s;
+ return 1;
+ }
+
+ start = s+TT.cur_col;
+ end = start;
+ remaining = (*l)-TT.cur_col;
+ for (;remaining;) {
+ int next = utf8_lnw(&width, end, remaining);
+ if (next && width) {
+ if (!count) break;
+ count--;
+ } if (!next) break;
+ length += next;
+ end += next;
+ remaining -= next;
+ }
+ if (remaining) {
+ memmove(start, end, remaining);
+ memset(end+remaining,0,end-start);
} else {
- memmove(s+(*p), s+(*p)+1, (*l)-(*p));
- s[*l] = 0;
- (*l)--;
+ memset(start,0,(*l)-TT.cur_col);
}
- count--;
- return (count) ? vi_x(count) : 1;
+ *l -= end-start;
+ if (!TT.cur_col) return 1;
+ if (TT.cur_col == (*l)) {
+ last = utf8_last(s, TT.cur_col);
+ TT.cur_col = last-s;
+ }
+ return 1;
}
//move commands does not behave correct way yet.
@@ -402,7 +431,7 @@ struct vi_cmd_param {
int (*vi_cmd_ptr)(int);
};
-struct vi_cmd_param vi_cmds[7] =
+struct vi_cmd_param vi_cmds[11] =
{
{"dd", &ex_dd},
{"dw", &ex_dw},
@@ -411,6 +440,10 @@ struct vi_cmd_param vi_cmds[7] =
{"b", &vi_movb},
{"e", &vi_move},
{"x", &vi_x},
+ {"h", &cur_left},
+ {"j", &cur_down},
+ {"k", &cur_up},
+ {"l", &cur_right},
};
int run_vi_cmd(char *cmd)
@@ -426,7 +459,7 @@ int run_vi_cmd(char *cmd)
else {
cmd = cmd_e;
}
- for (; i<7; i++) {
+ for (; i < 11; i++) {
if (strstr(cmd, vi_cmds[i].cmd)) {
return vi_cmds[i].vi_cmd_ptr(val);
}
@@ -440,7 +473,7 @@ int search_str(char *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_r->line->str_data-c; //TODO ??
TT.cur_col = c-c_r->line->str_data;
}
else for (; !c;) {
@@ -523,18 +556,6 @@ void vi_main(void)
}
if (TT.vi_mode == 1) { //NORMAL
switch (key) {
- case 'h':
- cur_left();
- break;
- case 'j':
- cur_down();
- break;
- case 'k':
- cur_up();
- break;
- case 'l':
- cur_right();
- break;
case '/':
case '?':
case ':':
@@ -554,7 +575,7 @@ void vi_main(void)
break;
default:
if (key > 0x20 && key < 0x7B) {
- vi_buf[vi_buf_pos] = key;
+ vi_buf[vi_buf_pos] = key;//TODO handle input better
vi_buf_pos++;
if (run_vi_cmd(vi_buf)) {
memset(vi_buf, 0, 16);
@@ -562,6 +583,7 @@ void vi_main(void)
}
else if (vi_buf_pos == 16) {
vi_buf_pos = 0;
+ memset(vi_buf, 0, 16);
}
}
@@ -834,12 +856,10 @@ static int draw_rune(char *c, int x, int y, int highlight)
static void check_cursor_bounds()
{
- if (c_r->line->str_len-1 < TT.cur_col) {
- if (c_r->line->str_len == 0)
- TT.cur_col = 0;
- else
- TT.cur_col = c_r->line->str_len-1;
- }
+ if (c_r->line->str_len == 0) TT.cur_col = 0;
+ else if (c_r->line->str_len-1 < TT.cur_col) TT.cur_col = c_r->line->str_len-1;
+ if(utf8_width(&c_r->line->str_data[TT.cur_col], c_r->line->str_len-TT.cur_col) <= 0)
+ cur_left(1);
}
static void adjust_screen_buffer()
@@ -963,6 +983,20 @@ static int utf8_dec(char key, char *utf8_scratch, int *sta_p)
return 0;
}
+static char* utf8_last(char* str, int size)
+{
+ char* end = str+size;
+ int pos = size;
+ int len = 0;
+ int width = 0;
+ while (pos >= 0) {
+ len = utf8_lnw(&width, end, size-pos);
+ if (len && width) return end;
+ end--; pos--;
+ }
+ return 0;
+}
+
static int draw_str_until(int *drawn, char *str, int width, int bytes)
{
int rune_width = 0;
@@ -991,38 +1025,50 @@ write_bytes:
return max_width-width;
}
-static void cur_left()
+static int cur_left(int count)
{
- if (!TT.cur_col) return;
- TT.cur_col--;
+ for (;count--;) {
+ if (!TT.cur_col) return 1;
- if (!utf8_len(&c_r->line->str_data[TT.cur_col])) cur_left();
+ TT.cur_col--;
+ check_cursor_bounds();//has bit ugly recursion hidden here
+ }
+ return 1;
}
-static void cur_right()
+static int cur_right(int count)
{
- 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();
+ for (;count--;) {
+ if (c_r->line->str_len <= 1) return 1;
+ if (TT.cur_col >= c_r->line->str_len-1) {
+ TT.cur_col = utf8_last(c_r->line->str_data, c_r->line->str_len)
+ - c_r->line->str_data;
+ return 1;
+ }
+ TT.cur_col++;
+ if (utf8_width(&c_r->line->str_data[TT.cur_col],
+ c_r->line->str_len-TT.cur_col) <= 0)
+ cur_right(1);
+ }
+ return 1;
}
-static void cur_up()
+static int cur_up(int count)
{
- if (c_r->up != 0)
+ for (;count-- && c_r->up;)
c_r = c_r->up;
- if (!utf8_len(&c_r->line->str_data[TT.cur_col])) cur_left();
check_cursor_bounds();
adjust_screen_buffer();
+ return 1;
}
-static void cur_down()
+static int cur_down(int count)
{
- if (c_r->down != 0)
+ for (;count-- && c_r->down;)
c_r = c_r->down;
- if (!utf8_len(&c_r->line->str_data[TT.cur_col])) cur_left();
check_cursor_bounds();
adjust_screen_buffer();
+ return 1;
}