aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-05-11 14:49:13 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-05-11 14:49:13 +0200
commit94043e8ad2d30cc2199b35d18c853314ade174a3 (patch)
tree4647f99bce2f4c8075e8a4a2cd07c90c21e2b4e9 /libbb
parentda1382410bbc0dccad0d3936774a9232509f7deb (diff)
downloadbusybox-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.c73
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}
222static unsigned save_string(char *dst, unsigned maxsize) 226static 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... */
262static void BB_PUTCHAR(wchar_t c) 266static 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 300static void put_cur_glyph_and_inc_cursor(void)
297static void cmdedit_set_out_char(void)
298#define cmdedit_set_out_char(next_char) cmdedit_set_out_char()
299#else
300static 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) */
349static void input_end(void) 358static 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 */
356static void goto_new_line(void) 365static 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)
505static void input_forward(void) 515static 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 }