diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-11 14:49:13 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-11 14:49:13 +0200 |
| commit | 94043e8ad2d30cc2199b35d18c853314ade174a3 (patch) | |
| tree | 4647f99bce2f4c8075e8a4a2cd07c90c21e2b4e9 /libbb | |
| parent | da1382410bbc0dccad0d3936774a9232509f7deb (diff) | |
| download | busybox-w32-94043e8ad2d30cc2199b35d18c853314ade174a3.tar.gz busybox-w32-94043e8ad2d30cc2199b35d18c853314ade174a3.tar.bz2 busybox-w32-94043e8ad2d30cc2199b35d18c853314ade174a3.zip | |
lineedit: change how cmdedit_set_out_char works
Rename two badly names functions, use "clear to end of screen"
to eliminate annoying problems with clearing wide/combining chars,
and such. Run tested.
function old new delta
put_cur_glyph_and_inc_cursor - 124 +124
put_till_end_and_adv_cursor - 24 +24
input_delete 125 130 +5
Ceos 5 4 -1
Ceol 5 4 -1
input_end 24 - -24
cmdedit_set_out_char 122 - -122
------------------------------------------------------------------------------
(add/remove: 2/2 grow/shrink: 1/2 up/down: 153/-148) Total: 5 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/lineedit.c | 73 |
1 files changed, 41 insertions, 32 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 622f9ddfc..7fffe7ba2 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
| @@ -66,6 +66,10 @@ | |||
| 66 | #endif | 66 | #endif |
| 67 | 67 | ||
| 68 | 68 | ||
| 69 | #define SEQ_CLEAR_TILL_END_OF_SCREEN "\033[J" | ||
| 70 | //#define SEQ_CLEAR_TILL_END_OF_LINE "\033[K" | ||
| 71 | |||
| 72 | |||
| 69 | #undef CHAR_T | 73 | #undef CHAR_T |
| 70 | #if ENABLE_UNICODE_SUPPORT | 74 | #if ENABLE_UNICODE_SUPPORT |
| 71 | # define BB_NUL ((wchar_t)0) | 75 | # define BB_NUL ((wchar_t)0) |
| @@ -221,13 +225,13 @@ static size_t load_string(const char *src, int maxsize) | |||
| 221 | } | 225 | } |
| 222 | static unsigned save_string(char *dst, unsigned maxsize) | 226 | static unsigned save_string(char *dst, unsigned maxsize) |
| 223 | { | 227 | { |
| 224 | #if !ENABLE_UNICODE_PRESERVE_BROKEN | 228 | # if !ENABLE_UNICODE_PRESERVE_BROKEN |
| 225 | ssize_t len = wcstombs(dst, command_ps, maxsize - 1); | 229 | ssize_t len = wcstombs(dst, command_ps, maxsize - 1); |
| 226 | if (len < 0) | 230 | if (len < 0) |
| 227 | len = 0; | 231 | len = 0; |
| 228 | dst[len] = '\0'; | 232 | dst[len] = '\0'; |
| 229 | return len; | 233 | return len; |
| 230 | #else | 234 | # else |
| 231 | unsigned dstpos = 0; | 235 | unsigned dstpos = 0; |
| 232 | unsigned srcpos = 0; | 236 | unsigned srcpos = 0; |
| 233 | 237 | ||
| @@ -256,7 +260,7 @@ static unsigned save_string(char *dst, unsigned maxsize) | |||
| 256 | } | 260 | } |
| 257 | dst[dstpos] = '\0'; | 261 | dst[dstpos] = '\0'; |
| 258 | return dstpos; | 262 | return dstpos; |
| 259 | #endif | 263 | # endif |
| 260 | } | 264 | } |
| 261 | /* I thought just fputwc(c, stdout) would work. But no... */ | 265 | /* I thought just fputwc(c, stdout) would work. But no... */ |
| 262 | static void BB_PUTCHAR(wchar_t c) | 266 | static void BB_PUTCHAR(wchar_t c) |
| @@ -293,19 +297,19 @@ static void save_string(char *dst, unsigned maxsize) | |||
| 293 | * Advance cursor on screen. If we reached right margin, scroll text up | 297 | * Advance cursor on screen. If we reached right margin, scroll text up |
| 294 | * and remove terminal margin effect by printing 'next_char' */ | 298 | * and remove terminal margin effect by printing 'next_char' */ |
| 295 | #define HACK_FOR_WRONG_WIDTH 1 | 299 | #define HACK_FOR_WRONG_WIDTH 1 |
| 296 | #if HACK_FOR_WRONG_WIDTH | 300 | static void put_cur_glyph_and_inc_cursor(void) |
| 297 | static void cmdedit_set_out_char(void) | ||
| 298 | #define cmdedit_set_out_char(next_char) cmdedit_set_out_char() | ||
| 299 | #else | ||
| 300 | static void cmdedit_set_out_char(int next_char) | ||
| 301 | #endif | ||
| 302 | { | 301 | { |
| 303 | CHAR_T c = command_ps[cursor]; | 302 | CHAR_T c = command_ps[cursor]; |
| 304 | 303 | ||
| 305 | if (c == BB_NUL) { | 304 | if (c == BB_NUL) { |
| 306 | /* erase character after end of input string */ | 305 | /* erase character after end of input string */ |
| 307 | c = ' '; | 306 | c = ' '; |
| 307 | } else { | ||
| 308 | /* advance cursor only if we aren't at the end yet */ | ||
| 309 | cursor++; | ||
| 310 | cmdedit_x++; | ||
| 308 | } | 311 | } |
| 312 | |||
| 309 | #if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT | 313 | #if ENABLE_FEATURE_NONPRINTABLE_INVERSE_PUT |
| 310 | /* Display non-printable characters in reverse */ | 314 | /* Display non-printable characters in reverse */ |
| 311 | if (!BB_isprint(c)) { | 315 | if (!BB_isprint(c)) { |
| @@ -321,7 +325,7 @@ static void cmdedit_set_out_char(int next_char) | |||
| 321 | { | 325 | { |
| 322 | BB_PUTCHAR(c); | 326 | BB_PUTCHAR(c); |
| 323 | } | 327 | } |
| 324 | if (++cmdedit_x >= cmdedit_termw) { | 328 | if (cmdedit_x >= cmdedit_termw) { |
| 325 | /* terminal is scrolled down */ | 329 | /* terminal is scrolled down */ |
| 326 | cmdedit_y++; | 330 | cmdedit_y++; |
| 327 | cmdedit_x = 0; | 331 | cmdedit_x = 0; |
| @@ -335,27 +339,32 @@ static void cmdedit_set_out_char(int next_char) | |||
| 335 | * this will break things: there will be one extra empty line */ | 339 | * this will break things: there will be one extra empty line */ |
| 336 | puts("\r"); /* + implicit '\n' */ | 340 | puts("\r"); /* + implicit '\n' */ |
| 337 | #else | 341 | #else |
| 338 | /* Works ok only if cmdedit_termw is correct */ | 342 | /* VT-10x terminals don't wrap cursor to next line when last char |
| 339 | /* destroy "(auto)margin" */ | 343 | * on the line is printed - cursor stays "over" this char. |
| 340 | bb_putchar(next_char); | 344 | * Need to print _next_ char too (first one to appear on next line) |
| 345 | * to make cursor move down to next line. | ||
| 346 | */ | ||
| 347 | /* Works ok only if cmdedit_termw is correct. */ | ||
| 348 | c = command_ps[cursor]; | ||
| 349 | if (c == BB_NUL) | ||
| 350 | c = ' '; | ||
| 351 | BB_PUTCHAR(c); | ||
| 341 | bb_putchar('\b'); | 352 | bb_putchar('\b'); |
| 342 | #endif | 353 | #endif |
| 343 | } | 354 | } |
| 344 | // Huh? What if command_ps[cursor] == BB_NUL (we are at the end already?) | ||
| 345 | cursor++; | ||
| 346 | } | 355 | } |
| 347 | 356 | ||
| 348 | /* Move to end of line (by printing all chars till the end) */ | 357 | /* Move to end of line (by printing all chars till the end) */ |
| 349 | static void input_end(void) | 358 | static void put_till_end_and_adv_cursor(void) |
| 350 | { | 359 | { |
| 351 | while (cursor < command_len) | 360 | while (cursor < command_len) |
| 352 | cmdedit_set_out_char(' '); | 361 | put_cur_glyph_and_inc_cursor(); |
| 353 | } | 362 | } |
| 354 | 363 | ||
| 355 | /* Go to the next line */ | 364 | /* Go to the next line */ |
| 356 | static void goto_new_line(void) | 365 | static void goto_new_line(void) |
| 357 | { | 366 | { |
| 358 | input_end(); | 367 | put_till_end_and_adv_cursor(); |
| 359 | if (cmdedit_x) | 368 | if (cmdedit_x) |
| 360 | bb_putchar('\n'); | 369 | bb_putchar('\n'); |
| 361 | } | 370 | } |
| @@ -433,8 +442,8 @@ static void redraw(int y, int back_cursor) | |||
| 433 | printf("\033[%uA", y); | 442 | printf("\033[%uA", y); |
| 434 | bb_putchar('\r'); | 443 | bb_putchar('\r'); |
| 435 | put_prompt(); | 444 | put_prompt(); |
| 436 | input_end(); /* rewrite */ | 445 | put_till_end_and_adv_cursor(); |
| 437 | printf("\033[J"); /* erase after cursor */ | 446 | printf(SEQ_CLEAR_TILL_END_OF_SCREEN); |
| 438 | input_backward(back_cursor); | 447 | input_backward(back_cursor); |
| 439 | } | 448 | } |
| 440 | 449 | ||
| @@ -468,8 +477,9 @@ static void input_delete(int save) | |||
| 468 | * simplified into (command_len - j) */ | 477 | * simplified into (command_len - j) */ |
| 469 | (command_len - j) * sizeof(command_ps[0])); | 478 | (command_len - j) * sizeof(command_ps[0])); |
| 470 | command_len--; | 479 | command_len--; |
| 471 | input_end(); /* rewrite new line */ | 480 | put_till_end_and_adv_cursor(); |
| 472 | cmdedit_set_out_char(' '); /* erase char */ | 481 | /* Last char is still visible, erase it (and more) */ |
| 482 | printf(SEQ_CLEAR_TILL_END_OF_SCREEN); | ||
| 473 | input_backward(cursor - j); /* back to old pos cursor */ | 483 | input_backward(cursor - j); /* back to old pos cursor */ |
| 474 | } | 484 | } |
| 475 | 485 | ||
| @@ -487,7 +497,7 @@ static void put(void) | |||
| 487 | (command_len - cursor + 1) * sizeof(command_ps[0])); | 497 | (command_len - cursor + 1) * sizeof(command_ps[0])); |
| 488 | memcpy(command_ps + cursor, delbuf, j * sizeof(command_ps[0])); | 498 | memcpy(command_ps + cursor, delbuf, j * sizeof(command_ps[0])); |
| 489 | command_len += j; | 499 | command_len += j; |
| 490 | input_end(); /* rewrite new line */ | 500 | put_till_end_and_adv_cursor(); |
| 491 | input_backward(cursor - ocursor - j + 1); /* at end of new text */ | 501 | input_backward(cursor - ocursor - j + 1); /* at end of new text */ |
| 492 | } | 502 | } |
| 493 | #endif | 503 | #endif |
| @@ -505,7 +515,7 @@ static void input_backspace(void) | |||
| 505 | static void input_forward(void) | 515 | static void input_forward(void) |
| 506 | { | 516 | { |
| 507 | if (cursor < command_len) | 517 | if (cursor < command_len) |
| 508 | cmdedit_set_out_char(command_ps[cursor + 1]); | 518 | put_cur_glyph_and_inc_cursor(); |
| 509 | } | 519 | } |
| 510 | 520 | ||
| 511 | #if ENABLE_FEATURE_TAB_COMPLETION | 521 | #if ENABLE_FEATURE_TAB_COMPLETION |
| @@ -1955,7 +1965,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
| 1955 | case CTRL('E'): | 1965 | case CTRL('E'): |
| 1956 | vi_case('$'|VI_CMDMODE_BIT:) | 1966 | vi_case('$'|VI_CMDMODE_BIT:) |
| 1957 | /* Control-e -- End of line */ | 1967 | /* Control-e -- End of line */ |
| 1958 | input_end(); | 1968 | put_till_end_and_adv_cursor(); |
| 1959 | break; | 1969 | break; |
| 1960 | case CTRL('F'): | 1970 | case CTRL('F'): |
| 1961 | vi_case('l'|VI_CMDMODE_BIT:) | 1971 | vi_case('l'|VI_CMDMODE_BIT:) |
| @@ -1984,12 +1994,12 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
| 1984 | /* Control-k -- clear to end of line */ | 1994 | /* Control-k -- clear to end of line */ |
| 1985 | command_ps[cursor] = BB_NUL; | 1995 | command_ps[cursor] = BB_NUL; |
| 1986 | command_len = cursor; | 1996 | command_len = cursor; |
| 1987 | printf("\033[J"); | 1997 | printf(SEQ_CLEAR_TILL_END_OF_SCREEN); |
| 1988 | break; | 1998 | break; |
| 1989 | case CTRL('L'): | 1999 | case CTRL('L'): |
| 1990 | vi_case(CTRL('L')|VI_CMDMODE_BIT:) | 2000 | vi_case(CTRL('L')|VI_CMDMODE_BIT:) |
| 1991 | /* Control-l -- clear screen */ | 2001 | /* Control-l -- clear screen */ |
| 1992 | printf("\033[H"); | 2002 | printf("\033[H"); /* cursor to top,left */ |
| 1993 | redraw(0, command_len - cursor); | 2003 | redraw(0, command_len - cursor); |
| 1994 | break; | 2004 | break; |
| 1995 | #if MAX_HISTORY > 0 | 2005 | #if MAX_HISTORY > 0 |
| @@ -2040,7 +2050,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
| 2040 | vi_cmdmode = 0; | 2050 | vi_cmdmode = 0; |
| 2041 | break; | 2051 | break; |
| 2042 | case 'A'|VI_CMDMODE_BIT: | 2052 | case 'A'|VI_CMDMODE_BIT: |
| 2043 | input_end(); | 2053 | put_till_end_and_adv_cursor(); |
| 2044 | vi_cmdmode = 0; | 2054 | vi_cmdmode = 0; |
| 2045 | break; | 2055 | break; |
| 2046 | case 'x'|VI_CMDMODE_BIT: | 2056 | case 'x'|VI_CMDMODE_BIT: |
| @@ -2200,7 +2210,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
| 2200 | input_backward(cursor); | 2210 | input_backward(cursor); |
| 2201 | break; | 2211 | break; |
| 2202 | case KEYCODE_END: | 2212 | case KEYCODE_END: |
| 2203 | input_end(); | 2213 | put_till_end_and_adv_cursor(); |
| 2204 | break; | 2214 | break; |
| 2205 | 2215 | ||
| 2206 | default: | 2216 | default: |
| @@ -2260,7 +2270,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
| 2260 | /* We are at the end, append */ | 2270 | /* We are at the end, append */ |
| 2261 | command_ps[cursor] = ic; | 2271 | command_ps[cursor] = ic; |
| 2262 | command_ps[cursor + 1] = BB_NUL; | 2272 | command_ps[cursor + 1] = BB_NUL; |
| 2263 | cmdedit_set_out_char(' '); | 2273 | put_cur_glyph_and_inc_cursor(); |
| 2264 | if (unicode_bidi_isrtl(ic)) | 2274 | if (unicode_bidi_isrtl(ic)) |
| 2265 | input_backward(1); | 2275 | input_backward(1); |
| 2266 | } else { | 2276 | } else { |
| @@ -2273,8 +2283,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
| 2273 | /* is right-to-left char, or neutral one (e.g. comma) was just added to rtl text? */ | 2283 | /* is right-to-left char, or neutral one (e.g. comma) was just added to rtl text? */ |
| 2274 | if (!isrtl_str()) | 2284 | if (!isrtl_str()) |
| 2275 | sc++; /* no */ | 2285 | sc++; /* no */ |
| 2276 | /* rewrite from cursor */ | 2286 | put_till_end_and_adv_cursor(); |
| 2277 | input_end(); | ||
| 2278 | /* to prev x pos + 1 */ | 2287 | /* to prev x pos + 1 */ |
| 2279 | input_backward(cursor - sc); | 2288 | input_backward(cursor - sc); |
| 2280 | } | 2289 | } |
