Merge branch 'echoprotocol-simple_multiline'

This commit is contained in:
Joachim Nilsson 2019-11-28 07:01:48 +01:00
commit 0b295197f6

View File

@ -113,6 +113,9 @@ static int Searching = 0;
static const char *(*search_move)(void); static const char *(*search_move)(void);
static const char *old_prompt = NULL; static const char *old_prompt = NULL;
static rl_vcpfunc_t *line_handler = NULL; static rl_vcpfunc_t *line_handler = NULL;
static char *line_up = "\x1b[A";
static char *line_down = "\x1b[B";
int prompt_len = 0;
int el_no_echo = 0; /* e.g., under Emacs */ int el_no_echo = 0; /* e.g., under Emacs */
int el_no_hist = 0; int el_no_hist = 0;
@ -134,7 +137,6 @@ extern char *tgetstr(const char *, char **);
extern int tgetent(char *, const char *); extern int tgetent(char *, const char *);
extern int tgetnum(const char *); extern int tgetnum(const char *);
#endif #endif
/* /*
** Misc. local helper functions. ** Misc. local helper functions.
@ -206,8 +208,13 @@ static void tty_show(unsigned char c)
static void tty_string(char *p) static void tty_string(char *p)
{ {
while (*p) int i = rl_point + prompt_len + 1;
while (*p) {
tty_show(*p++); tty_show(*p++);
if ((i++) % tty_cols == 0)
tty_put('\n');
}
} }
static void tty_push(int c) static void tty_push(int c)
@ -255,7 +262,6 @@ static void tty_info(void)
{ {
rl_reset_terminal(NULL); rl_reset_terminal(NULL);
} }
/* /*
** Glue routines to rl_ttyset() ** Glue routines to rl_ttyset()
@ -291,8 +297,10 @@ void el_print_columns(int ac, char **av)
if ((j = strlen((char *)av[i])) > longest) if ((j = strlen((char *)av[i])) > longest)
longest = j; longest = j;
} }
colwidth = longest + 3; colwidth = longest + 3;
if (colwidth > tty_cols) colwidth = tty_cols; if (colwidth > tty_cols)
colwidth = tty_cols;
cols = tty_cols / colwidth; cols = tty_cols / colwidth;
tty_puts(NEWLINE); tty_puts(NEWLINE);
@ -311,20 +319,92 @@ void el_print_columns(int ac, char **av)
} }
} }
static void reposition(void) static void reposition(int key)
{ {
int i; int len_with_prompt = prompt_len + rl_end;
int n = len_with_prompt / tty_cols; /* determine the number of lines */
int i = 0;
tty_put('\r'); tty_put('\r');
if (n > 0) {
int line;
/* determine num of current line */
if (key == CTL('A') || key == CTL('E') || key == rl_kill)
line = (prompt_len + old_point) / tty_cols;
else
line = len_with_prompt / tty_cols;
/* move to end of line(s) */
if (key == CTL('E')) {
int k;
for (k = line; k < n; k++)
tty_puts(line_down);
/* determine reminder of last line and redraw only it */
i = rl_point - (len_with_prompt % tty_cols);
} else {
int k;
/* CTRL-A, CTRL-U, insert (end, middle), remove (end, middle) */
for (k = line; k > 0; k--)
tty_puts(line_up); /* redraw characters until changed data */
tty_puts(rl_prompt); tty_puts(rl_prompt);
for (i = 0; i < rl_point; i++) }
} else if (n == 0) {
tty_puts(rl_prompt);
}
for (; i < rl_point; i++) {
tty_show(rl_line_buffer[i]); tty_show(rl_line_buffer[i]);
/* move to the next line */
if ((i + prompt_len + 1) % tty_cols == 0)
tty_put('\n');
}
}
void itoa(int val, char* buf)
{
int digits = 0;
int temp = val;
while (temp != 0) {
temp = temp / 10;
++digits;
}
*(buf+digits) = 'C';
int i = 5; digits--;
for(; val && i ; --i, val /= 10) {
*(buf+digits) = "0123456789"[val % 10];
digits--;
}
}
static void move_cursor_forward(int columns)
{
const char* line_forward = "\x1b[";
char buf[12] = {0};
strcpy(buf, line_forward);
itoa(columns, buf + 2);
tty_puts(buf);
} }
static void left(el_status_t Change) static void left(el_status_t Change)
{ {
if (rl_point) { if (rl_point) {
if ((rl_point + prompt_len) % tty_cols == 0) {
tty_puts(line_up);
move_cursor_forward(tty_cols);
} else {
tty_back(); tty_back();
}
if (ISMETA(rl_line_buffer[rl_point - 1])) { if (ISMETA(rl_line_buffer[rl_point - 1])) {
if (rl_meta_chars) { if (rl_meta_chars) {
tty_back(); tty_back();
@ -341,6 +421,9 @@ static void left(el_status_t Change)
static void right(el_status_t Change) static void right(el_status_t Change)
{ {
if ((rl_point + prompt_len + 1) % tty_cols == 0)
tty_put('\n');
else
tty_show(rl_line_buffer[rl_point]); tty_show(rl_line_buffer[rl_point]);
if (Change == CSmove) if (Change == CSmove)
@ -461,10 +544,14 @@ static void ceol(void)
while (rl_point < 0) { while (rl_point < 0) {
tty_put(' '); tty_put(' ');
rl_point++; rl_point++;
extras++;
} }
for (i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) { for (i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) {
if ((i + prompt_len + 1) % tty_cols == 0){
tty_put(' ');
tty_put('\n');
}
else
tty_put(' '); tty_put(' ');
if (ISMETA(*p)) { if (ISMETA(*p)) {
if (rl_meta_chars) { if (rl_meta_chars) {
@ -478,15 +565,32 @@ static void ceol(void)
} }
} }
for (i += extras; i > rl_point; i--) for (i += extras; i > rl_point; i--) {
if ((i + prompt_len) % tty_cols == 0) {
tty_puts(line_up);
move_cursor_forward(tty_cols);
} else {
tty_back(); tty_back();
}
}
} }
static void clear_line(void) static void clear_line(void)
{ {
int n = (rl_point + prompt_len) / tty_cols;
rl_point = -(int)strlen(rl_prompt); rl_point = -(int)strlen(rl_prompt);
if (n > 0) {
for(int k = 0; k < n; k++)
tty_puts(line_up);
tty_put('\r'); tty_put('\r');
}
else {
tty_put('\r');
}
ceol(); ceol();
rl_point = 0; rl_point = 0;
rl_end = 0; rl_end = 0;
rl_line_buffer[0] = '\0'; rl_line_buffer[0] = '\0';
@ -538,14 +642,15 @@ int rl_insert_text(const char *text)
static el_status_t redisplay(int cls) static el_status_t redisplay(int cls)
{ {
if (cls && rl_point == 0 && rl_end == 0) if (cls)
tty_puts(CLEAR); tty_puts(CLEAR);
else else
tty_puts("\r\e[K"); tty_puts("\r\e[K");
tty_puts(rl_prompt); tty_puts(rl_prompt);
rl_point = 0;
tty_string(rl_line_buffer); tty_string(rl_line_buffer);
rl_point = rl_end;
return CSmove; return CSmove;
} }
@ -565,7 +670,6 @@ static el_status_t toggle_meta_mode(void)
rl_meta_chars = ! rl_meta_chars; rl_meta_chars = ! rl_meta_chars;
return redisplay(0); return redisplay(0);
} }
const char *el_next_hist(void) const char *el_next_hist(void)
{ {
@ -585,7 +689,7 @@ static el_status_t do_insert_hist(const char *p)
clear_line(); clear_line();
rl_point = 0; rl_point = 0;
reposition(); reposition(-1);
rl_end = 0; rl_end = 0;
return insert_string(p); return insert_string(p);
@ -792,6 +896,7 @@ static el_status_t delete_string(int count)
for (p = &rl_line_buffer[rl_point], i = rl_end - (rl_point + count) + 1; --i >= 0; p++) for (p = &rl_line_buffer[rl_point], i = rl_end - (rl_point + count) + 1; --i >= 0; p++)
p[0] = p[count]; p[0] = p[count];
ceol(); ceol();
rl_end -= count; rl_end -= count;
tty_string(&rl_line_buffer[rl_point]); tty_string(&rl_line_buffer[rl_point]);
@ -832,7 +937,7 @@ static el_status_t kill_line(void)
if (Repeat < rl_point) { if (Repeat < rl_point) {
i = rl_point; i = rl_point;
rl_point = Repeat; rl_point = Repeat;
reposition(); reposition(-1);
delete_string(i - rl_point); delete_string(i - rl_point);
} else if (Repeat > rl_point) { } else if (Repeat > rl_point) {
right(CSmove); right(CSmove);
@ -1059,8 +1164,9 @@ static el_status_t tty_special(int c)
if (c == rl_kill) { if (c == rl_kill) {
if (rl_point != 0) { if (rl_point != 0) {
old_point = rl_point;
rl_point = 0; rl_point = 0;
reposition(); reposition(c);
} }
Repeat = NO_ARG; Repeat = NO_ARG;
@ -1095,7 +1201,7 @@ static char *editinput(int complete)
return (char *)""; return (char *)"";
case CSmove: case CSmove:
reposition(); reposition(c);
break; break;
case CSdispatch: case CSdispatch:
@ -1110,7 +1216,7 @@ static char *editinput(int complete)
return (char *)""; return (char *)"";
case CSmove: case CSmove:
reposition(); reposition(c);
break; break;
case CSdispatch: case CSdispatch:
@ -1334,6 +1440,8 @@ static int el_prep(const char *prompt)
return -1; return -1;
rl_prompt = prompt ? prompt : NILSTR; rl_prompt = prompt ? prompt : NILSTR;
prompt_len = strlen(rl_prompt);
if (el_no_echo) { if (el_no_echo) {
int old = el_no_echo; int old = el_no_echo;
@ -1529,7 +1637,6 @@ int write_history(const char *filename)
return errno; return errno;
} }
/* /*
** Move back to the beginning of the current word and return an ** Move back to the beginning of the current word and return an