lineedit: improve Unicode handling (still buggy though)

function                                             old     new   delta
unicode_strlen                                         -      31     +31
read_line_input                                     3876    3879      +3
lineedit_read_key                                    255     246      -9
parse_and_put_prompt                                 785     755     -30
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/2 up/down: 34/-39)             Total: -5 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2013-08-19 16:44:05 +02:00
parent 8395bd3f52
commit 7a18043a96
2 changed files with 24 additions and 11 deletions

View File

@ -1763,7 +1763,7 @@ static void ask_terminal(void)
static void parse_and_put_prompt(const char *prmt_ptr) static void parse_and_put_prompt(const char *prmt_ptr)
{ {
cmdedit_prompt = prmt_ptr; cmdedit_prompt = prmt_ptr;
cmdedit_prmt_len = strlen(prmt_ptr); cmdedit_prmt_len = unicode_strlen(prmt_ptr);
put_prompt(); put_prompt();
} }
#else #else
@ -1781,7 +1781,7 @@ static void parse_and_put_prompt(const char *prmt_ptr)
char c; char c;
char *pbuf; char *pbuf;
cmdedit_prmt_len = 0; /*cmdedit_prmt_len = 0; - already is */
cbuf[1] = '\0'; /* never changes */ cbuf[1] = '\0'; /* never changes */
@ -1915,7 +1915,8 @@ static void parse_and_put_prompt(const char *prmt_ptr)
} }
case '[': case ']': case '[': case ']':
if (c == flg_not_length) { if (c == flg_not_length) {
flg_not_length = (flg_not_length == '[' ? ']' : '['); /* Toggle '['/']' hex 5b/5d */
flg_not_length ^= 6;
continue; continue;
} }
break; break;
@ -1925,8 +1926,13 @@ static void parse_and_put_prompt(const char *prmt_ptr)
cbuf[0] = c; cbuf[0] = c;
cur_prmt_len = strlen(pbuf); cur_prmt_len = strlen(pbuf);
prmt_len += cur_prmt_len; prmt_len += cur_prmt_len;
if (flg_not_length != ']') if (flg_not_length != ']') {
#if 0 /*ENABLE_UNICODE_SUPPORT - won't work, pbuf is one BYTE string here. FIXME */
cmdedit_prmt_len += unicode_strlen(pbuf);
#else
cmdedit_prmt_len += cur_prmt_len; cmdedit_prmt_len += cur_prmt_len;
#endif
}
prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
free(free_me); free(free_me);
} /* while */ } /* while */
@ -1996,7 +2002,15 @@ static int lineedit_read_key(char *read_key_buffer, int timeout)
S.sent_ESC_br6n = 0; S.sent_ESC_br6n = 0;
if (cursor == 0) { /* otherwise it may be bogus */ if (cursor == 0) { /* otherwise it may be bogus */
int col = ((ic >> 32) & 0x7fff) - 1; int col = ((ic >> 32) & 0x7fff) - 1;
if (col > cmdedit_prmt_len) { /*
* Is col > cmdedit_prmt_len?
* If yes (terminal says cursor is farther to the right
* of where we think it should be),
* the prompt wasn't printed starting at col 1,
* there was additional text before it.
*/
if ((int)(col - cmdedit_prmt_len) > 0) {
/* Fix our understanding of current x position */
cmdedit_x += (col - cmdedit_prmt_len); cmdedit_x += (col - cmdedit_prmt_len);
while (cmdedit_x >= cmdedit_termw) { while (cmdedit_x >= cmdedit_termw) {
cmdedit_x -= cmdedit_termw; cmdedit_x -= cmdedit_termw;
@ -2087,6 +2101,7 @@ static int32_t reverse_i_search(void)
char read_key_buffer[KEYCODE_BUFFER_SIZE]; char read_key_buffer[KEYCODE_BUFFER_SIZE];
const char *matched_history_line; const char *matched_history_line;
const char *saved_prompt; const char *saved_prompt;
unsigned saved_prmt_len;
int32_t ic; int32_t ic;
matched_history_line = NULL; matched_history_line = NULL;
@ -2095,6 +2110,7 @@ static int32_t reverse_i_search(void)
/* Save and replace the prompt */ /* Save and replace the prompt */
saved_prompt = cmdedit_prompt; saved_prompt = cmdedit_prompt;
saved_prmt_len = cmdedit_prmt_len;
goto set_prompt; goto set_prompt;
while (1) { while (1) {
@ -2170,7 +2186,7 @@ static int32_t reverse_i_search(void)
free((char*)cmdedit_prompt); free((char*)cmdedit_prompt);
set_prompt: set_prompt:
cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf); cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf);
cmdedit_prmt_len = strlen(cmdedit_prompt); cmdedit_prmt_len = unicode_strlen(cmdedit_prompt);
goto do_redraw; goto do_redraw;
} }
} }
@ -2192,7 +2208,7 @@ static int32_t reverse_i_search(void)
free((char*)cmdedit_prompt); free((char*)cmdedit_prompt);
cmdedit_prompt = saved_prompt; cmdedit_prompt = saved_prompt;
cmdedit_prmt_len = strlen(cmdedit_prompt); cmdedit_prmt_len = saved_prmt_len;
redraw(cmdedit_y, command_len - cursor); redraw(cmdedit_y, command_len - cursor);
return ic; return ic;

View File

@ -43,8 +43,7 @@ void FAST_FUNC reinit_unicode(const char *LANG)
setlocale(LC_CTYPE, LANG ? LANG : ""); setlocale(LC_CTYPE, LANG ? LANG : "");
/* In unicode, this is a one character string */ /* In unicode, this is a one character string */
// can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused width = unicode_strlen(unicode_0x394);
width = mbstowcs(NULL, unicode_0x394, INT_MAX);
unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF); unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF);
} }
@ -986,7 +985,6 @@ int FAST_FUNC unicode_bidi_is_neutral_wchar(wint_t wc)
/* The rest is mostly same for libc and for "homegrown" support */ /* The rest is mostly same for libc and for "homegrown" support */
#if 0 // UNUSED
size_t FAST_FUNC unicode_strlen(const char *string) size_t FAST_FUNC unicode_strlen(const char *string)
{ {
size_t width = mbstowcs(NULL, string, INT_MAX); size_t width = mbstowcs(NULL, string, INT_MAX);
@ -994,7 +992,6 @@ size_t FAST_FUNC unicode_strlen(const char *string)
return strlen(string); return strlen(string);
return width; return width;
} }
#endif
size_t FAST_FUNC unicode_strwidth(const char *string) size_t FAST_FUNC unicode_strwidth(const char *string)
{ {