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:
Joachim Nilsson 2010-07-30 02:03:46 +02:00
parent 2a9b087bbc
commit f1edf7ae52

View File

@ -119,6 +119,22 @@ extern int tgetent(char *, const char *);
extern int tgetnum(const char *);
#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.
*/
@ -129,7 +145,7 @@ static void tty_flush(void)
if (ScreenCount) {
if (!el_no_echo)
res = write (1, Screen, ScreenCount);
res = write(1, Screen, ScreenCount);
ScreenCount = 0;
}
}
@ -149,18 +165,18 @@ static void tty_puts(const char *p)
tty_put(*p++);
}
static void tty_show(char c)
static void tty_show(unsigned char c)
{
if (c == DEL) {
tty_put('^');
tty_put('?');
} else if (ISCTL(c)) {
tty_put('^');
tty_put(UNCTL(c));
} else if (rl_meta_chars && ISMETA(c)) {
tty_put('M');
tty_put('-');
tty_put(UNMETA(c));
} else if (ISCTL(c) && !ISMETA(c)) {
tty_put('^');
tty_put(UNCTL(c));
} else {
tty_put(c);
}
@ -172,6 +188,12 @@ static void tty_string(char *p)
tty_show(*p++);
}
static void tty_push(int c)
{
el_pushed = 1;
el_push_back = c;
}
static int tty_get(void)
{
char c;
@ -291,23 +313,24 @@ static void columns(int ac, char **av)
static void reposition(void)
{
int i;
char *p;
int i;
tty_put('\r');
tty_puts(rl_prompt);
for (i = rl_point, p = rl_line_buffer; --i >= 0; p++)
tty_show(*p);
for (i = 0; i < rl_point; i++)
tty_show(rl_line_buffer[i]);
}
static void left(el_status_t Change)
{
tty_back();
if (rl_point) {
if (ISCTL(rl_line_buffer[rl_point - 1])) {
tty_back();
} else if (rl_meta_chars && ISMETA(rl_line_buffer[rl_point - 1])) {
tty_back();
tty_back();
if (ISMETA(rl_line_buffer[rl_point - 1])) {
if (rl_meta_chars) {
tty_back();
tty_back();
}
} else if (ISCTL(rl_line_buffer[rl_point - 1])) {
tty_back();
}
}
@ -318,6 +341,7 @@ static void left(el_status_t Change)
static void right(el_status_t Change)
{
tty_show(rl_line_buffer[rl_point]);
if (Change == CSmove)
rl_point++;
}
@ -356,12 +380,12 @@ static el_status_t do_forward(el_status_t move)
p = &rl_line_buffer[rl_point];
/* 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)
right(CSstay);
/* 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)
right(CSstay);
@ -425,13 +449,15 @@ static void ceol(void)
for (extras = 0, i = rl_point, p = &rl_line_buffer[i]; i <= rl_end; i++, p++) {
tty_put(' ');
if (ISCTL(*p)) {
if (ISMETA(*p)) {
if (rl_meta_chars) {
tty_put(' ');
tty_put(' ');
extras += 2;
}
} if (ISCTL(*p)) {
tty_put(' ');
extras++;
} else if (rl_meta_chars && ISMETA(*p)) {
tty_put(' ');
tty_put(' ');
extras += 2;
}
}
@ -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(rl_prompt);
tty_string(rl_line_buffer);
return CSmove;
}
@ -509,10 +536,12 @@ static el_status_t do_insert_hist(const char *p)
{
if (p == NULL)
return ring_bell();
rl_point = 0;
reposition();
ceol();
rl_end = 0;
return insert_string(p);
}
@ -821,8 +850,7 @@ static el_status_t meta(void)
#ifdef CONFIG_ANSI_ARROWS
/* Also include VT-100 arrows. */
if (c == '[' || c == 'O') {
c = tty_get();
switch (c) {
switch (tty_get()) {
case EOF: return CSeof;
case '2': tty_get(); return CSstay; /* Insert */
case '3': tty_get(); return del_char(); /* Delete */
@ -845,16 +873,16 @@ static el_status_t meta(void)
if (isdigit(c)) {
for (Repeat = c - '0'; (c = tty_get()) != EOF && isdigit(c); )
Repeat = Repeat * 10 + c - '0';
el_pushed = 1;
el_push_back = c;
tty_push(c);
return CSstay;
}
if (isupper(c))
return do_macro(c);
for (kp = MetaMap; kp->Function; kp++)
for (kp = MetaMap; kp->Function; kp++) {
if (kp->Key == c)
return kp->Function();
}
return ring_bell();
}
@ -867,11 +895,8 @@ static el_status_t emacs(int c)
/* Save point before interpreting input character 'c'. */
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)) {
el_pushed = 1;
el_push_back = UNMETA(c);
tty_push(UNMETA(c));
return meta();
}
@ -890,7 +915,7 @@ static el_status_t emacs(int c)
static el_status_t tty_special(int c)
{
if (rl_meta_chars && ISMETA(c))
if (rl_meta_chars && ISMETA(c))
return CSdispatch;
if (c == rl_erase || c == DEL)
@ -1349,10 +1374,10 @@ static el_status_t bk_word(void)
i = 0;
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);
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);
if (rl_point == 0)