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 | } |