mirror of
https://github.com/troglobit/editline.git
synced 2025-05-07 21:31:13 +08:00
Replace previous commit for quoted chars with a much improved one.
1. Simplify code in reposition() 2. Add tty_push() for commonly used operation, reduce code duplication. 3. Fix left() so that it treats 8-bit chars as one when not in meta-mode. 4. Replace isalnum() with homegrown implementation that understands 8-bit and control chars. 5. Fix ceol() before introducing ANSI "kill-to-end-of-line" escape code. This actually seems to work, previously I erronesouly used an UTF-8 terminal for testing. Which of course broke the test on an ISO-8859-1 [only] terminal.
This commit is contained in:
parent
2a9b087bbc
commit
f1edf7ae52
@ -119,6 +119,22 @@ extern int tgetent(char *, const char *);
|
|||||||
extern int tgetnum(const char *);
|
extern int tgetnum(const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Misc. local helper functions.
|
||||||
|
*/
|
||||||
|
static int is_alpha_num(unsigned char c)
|
||||||
|
{
|
||||||
|
if (isalnum(c))
|
||||||
|
return 1;
|
||||||
|
if (ISMETA(c))
|
||||||
|
return 1;
|
||||||
|
if (ISCTL(c))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** TTY input/output functions.
|
** TTY input/output functions.
|
||||||
*/
|
*/
|
||||||
@ -149,18 +165,18 @@ static void tty_puts(const char *p)
|
|||||||
tty_put(*p++);
|
tty_put(*p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tty_show(char c)
|
static void tty_show(unsigned char c)
|
||||||
{
|
{
|
||||||
if (c == DEL) {
|
if (c == DEL) {
|
||||||
tty_put('^');
|
tty_put('^');
|
||||||
tty_put('?');
|
tty_put('?');
|
||||||
|
} else if (ISCTL(c)) {
|
||||||
|
tty_put('^');
|
||||||
|
tty_put(UNCTL(c));
|
||||||
} else if (rl_meta_chars && ISMETA(c)) {
|
} else if (rl_meta_chars && ISMETA(c)) {
|
||||||
tty_put('M');
|
tty_put('M');
|
||||||
tty_put('-');
|
tty_put('-');
|
||||||
tty_put(UNMETA(c));
|
tty_put(UNMETA(c));
|
||||||
} else if (ISCTL(c) && !ISMETA(c)) {
|
|
||||||
tty_put('^');
|
|
||||||
tty_put(UNCTL(c));
|
|
||||||
} else {
|
} else {
|
||||||
tty_put(c);
|
tty_put(c);
|
||||||
}
|
}
|
||||||
@ -172,6 +188,12 @@ static void tty_string(char *p)
|
|||||||
tty_show(*p++);
|
tty_show(*p++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tty_push(int c)
|
||||||
|
{
|
||||||
|
el_pushed = 1;
|
||||||
|
el_push_back = c;
|
||||||
|
}
|
||||||
|
|
||||||
static int tty_get(void)
|
static int tty_get(void)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
@ -292,24 +314,25 @@ static void columns(int ac, char **av)
|
|||||||
static void reposition(void)
|
static void reposition(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
|
||||||
|
|
||||||
tty_put('\r');
|
tty_put('\r');
|
||||||
tty_puts(rl_prompt);
|
tty_puts(rl_prompt);
|
||||||
for (i = rl_point, p = rl_line_buffer; --i >= 0; p++)
|
for (i = 0; i < rl_point; i++)
|
||||||
tty_show(*p);
|
tty_show(rl_line_buffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void left(el_status_t Change)
|
static void left(el_status_t Change)
|
||||||
{
|
{
|
||||||
tty_back();
|
|
||||||
if (rl_point) {
|
if (rl_point) {
|
||||||
if (ISCTL(rl_line_buffer[rl_point - 1])) {
|
|
||||||
tty_back();
|
tty_back();
|
||||||
} else if (rl_meta_chars && ISMETA(rl_line_buffer[rl_point - 1])) {
|
if (ISMETA(rl_line_buffer[rl_point - 1])) {
|
||||||
|
if (rl_meta_chars) {
|
||||||
tty_back();
|
tty_back();
|
||||||
tty_back();
|
tty_back();
|
||||||
}
|
}
|
||||||
|
} else if (ISCTL(rl_line_buffer[rl_point - 1])) {
|
||||||
|
tty_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (Change == CSmove)
|
if (Change == CSmove)
|
||||||
rl_point--;
|
rl_point--;
|
||||||
@ -318,6 +341,7 @@ static void left(el_status_t Change)
|
|||||||
static void right(el_status_t Change)
|
static void right(el_status_t Change)
|
||||||
{
|
{
|
||||||
tty_show(rl_line_buffer[rl_point]);
|
tty_show(rl_line_buffer[rl_point]);
|
||||||
|
|
||||||
if (Change == CSmove)
|
if (Change == CSmove)
|
||||||
rl_point++;
|
rl_point++;
|
||||||
}
|
}
|
||||||
@ -356,12 +380,12 @@ static el_status_t do_forward(el_status_t move)
|
|||||||
p = &rl_line_buffer[rl_point];
|
p = &rl_line_buffer[rl_point];
|
||||||
|
|
||||||
/* Skip to end of word, if inside a word. */
|
/* Skip to end of word, if inside a word. */
|
||||||
for (; rl_point < rl_end && isalnum(p[0]); rl_point++, p++)
|
for (; rl_point < rl_end && is_alpha_num(p[0]); rl_point++, p++)
|
||||||
if (move == CSmove)
|
if (move == CSmove)
|
||||||
right(CSstay);
|
right(CSstay);
|
||||||
|
|
||||||
/* Skip to next word, or skip leading white space if outside a word. */
|
/* Skip to next word, or skip leading white space if outside a word. */
|
||||||
for ( ; rl_point < rl_end && (p[0] == ' ' || !isalnum(p[0])); rl_point++, p++)
|
for ( ; rl_point < rl_end && (p[0] == ' ' || !is_alpha_num(p[0])); rl_point++, p++)
|
||||||
if (move == CSmove)
|
if (move == CSmove)
|
||||||
right(CSstay);
|
right(CSstay);
|
||||||
|
|
||||||
@ -425,14 +449,16 @@ static void ceol(void)
|
|||||||
|
|
||||||
for (extras = 0, i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) {
|
for (extras = 0, i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) {
|
||||||
tty_put(' ');
|
tty_put(' ');
|
||||||
if (ISCTL(*p)) {
|
if (ISMETA(*p)) {
|
||||||
tty_put(' ');
|
if (rl_meta_chars) {
|
||||||
extras++;
|
|
||||||
} else if (rl_meta_chars && ISMETA(*p)) {
|
|
||||||
tty_put(' ');
|
tty_put(' ');
|
||||||
tty_put(' ');
|
tty_put(' ');
|
||||||
extras += 2;
|
extras += 2;
|
||||||
}
|
}
|
||||||
|
} if (ISCTL(*p)) {
|
||||||
|
tty_put(' ');
|
||||||
|
extras++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i += extras; i > rl_point; i--)
|
for (i += extras; i > rl_point; i--)
|
||||||
@ -485,6 +511,7 @@ static el_status_t redisplay(void)
|
|||||||
tty_puts(NEWLINE); /* XXX: Use "\r\e[K" to get really neat effect on ANSI capable terminals. */
|
tty_puts(NEWLINE); /* XXX: Use "\r\e[K" to get really neat effect on ANSI capable terminals. */
|
||||||
tty_puts(rl_prompt);
|
tty_puts(rl_prompt);
|
||||||
tty_string(rl_line_buffer);
|
tty_string(rl_line_buffer);
|
||||||
|
|
||||||
return CSmove;
|
return CSmove;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,10 +536,12 @@ static el_status_t do_insert_hist(const char *p)
|
|||||||
{
|
{
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return ring_bell();
|
return ring_bell();
|
||||||
|
|
||||||
rl_point = 0;
|
rl_point = 0;
|
||||||
reposition();
|
reposition();
|
||||||
ceol();
|
ceol();
|
||||||
rl_end = 0;
|
rl_end = 0;
|
||||||
|
|
||||||
return insert_string(p);
|
return insert_string(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -821,8 +850,7 @@ static el_status_t meta(void)
|
|||||||
#ifdef CONFIG_ANSI_ARROWS
|
#ifdef CONFIG_ANSI_ARROWS
|
||||||
/* Also include VT-100 arrows. */
|
/* Also include VT-100 arrows. */
|
||||||
if (c == '[' || c == 'O') {
|
if (c == '[' || c == 'O') {
|
||||||
c = tty_get();
|
switch (tty_get()) {
|
||||||
switch (c) {
|
|
||||||
case EOF: return CSeof;
|
case EOF: return CSeof;
|
||||||
case '2': tty_get(); return CSstay; /* Insert */
|
case '2': tty_get(); return CSstay; /* Insert */
|
||||||
case '3': tty_get(); return del_char(); /* Delete */
|
case '3': tty_get(); return del_char(); /* Delete */
|
||||||
@ -845,16 +873,16 @@ static el_status_t meta(void)
|
|||||||
if (isdigit(c)) {
|
if (isdigit(c)) {
|
||||||
for (Repeat = c - '0'; (c = tty_get()) != EOF && isdigit(c); )
|
for (Repeat = c - '0'; (c = tty_get()) != EOF && isdigit(c); )
|
||||||
Repeat = Repeat * 10 + c - '0';
|
Repeat = Repeat * 10 + c - '0';
|
||||||
el_pushed = 1;
|
tty_push(c);
|
||||||
el_push_back = c;
|
|
||||||
return CSstay;
|
return CSstay;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isupper(c))
|
if (isupper(c))
|
||||||
return do_macro(c);
|
return do_macro(c);
|
||||||
for (kp = MetaMap; kp->Function; kp++)
|
for (kp = MetaMap; kp->Function; kp++) {
|
||||||
if (kp->Key == c)
|
if (kp->Key == c)
|
||||||
return kp->Function();
|
return kp->Function();
|
||||||
|
}
|
||||||
|
|
||||||
return ring_bell();
|
return ring_bell();
|
||||||
}
|
}
|
||||||
@ -867,11 +895,8 @@ static el_status_t emacs(int c)
|
|||||||
/* Save point before interpreting input character 'c'. */
|
/* Save point before interpreting input character 'c'. */
|
||||||
old_point = rl_point;
|
old_point = rl_point;
|
||||||
|
|
||||||
/* This test makes it impossible to enter eight-bit characters when
|
|
||||||
* meta-char mode is enabled. */
|
|
||||||
if (rl_meta_chars && ISMETA(c)) {
|
if (rl_meta_chars && ISMETA(c)) {
|
||||||
el_pushed = 1;
|
tty_push(UNMETA(c));
|
||||||
el_push_back = UNMETA(c);
|
|
||||||
return meta();
|
return meta();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1349,10 +1374,10 @@ static el_status_t bk_word(void)
|
|||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
do {
|
do {
|
||||||
for (p = &rl_line_buffer[rl_point]; p > rl_line_buffer && !isalnum(p[-1]); p--)
|
for (p = &rl_line_buffer[rl_point]; p > rl_line_buffer && !is_alpha_num(p[-1]); p--)
|
||||||
left(CSmove);
|
left(CSmove);
|
||||||
|
|
||||||
for (; p > rl_line_buffer && p[-1] != ' ' && isalnum(p[-1]); p--)
|
for (; p > rl_line_buffer && !isblank(p[-1]) && is_alpha_num(p[-1]); p--)
|
||||||
left(CSmove);
|
left(CSmove);
|
||||||
|
|
||||||
if (rl_point == 0)
|
if (rl_point == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user