aboutsummaryrefslogtreecommitdiff
path: root/libbb/lineedit.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-05-17 16:44:54 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-05-17 16:44:54 +0200
commit020f40693a08b836abdea74f3823a0bce0378ec5 (patch)
tree4ae11c9b2156cccc1af8904c11c195b25b2886b0 /libbb/lineedit.c
parent071ede1e5de784820f39c2546000c08d74b12f6d (diff)
downloadbusybox-w32-020f40693a08b836abdea74f3823a0bce0378ec5.tar.gz
busybox-w32-020f40693a08b836abdea74f3823a0bce0378ec5.tar.bz2
busybox-w32-020f40693a08b836abdea74f3823a0bce0378ec5.zip
line editing: add an option to emit ESC [ 6 n and use results
This makes line editing able to recognize case when cursor was not at the beginning of the line. It may also be adapted later to find out display size (serial line users would love it). Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/lineedit.c')
-rw-r--r--libbb/lineedit.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index ccf3e0dc8..e1404fb68 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -86,8 +86,8 @@ struct lineedit_statics {
86 volatile unsigned cmdedit_termw; /* = 80; */ /* actual terminal width */ 86 volatile unsigned cmdedit_termw; /* = 80; */ /* actual terminal width */
87 sighandler_t previous_SIGWINCH_handler; 87 sighandler_t previous_SIGWINCH_handler;
88 88
89 unsigned cmdedit_x; /* real x terminal position */ 89 unsigned cmdedit_x; /* real x (col) terminal position */
90 unsigned cmdedit_y; /* pseudoreal y terminal position */ 90 unsigned cmdedit_y; /* pseudoreal y (row) terminal position */
91 unsigned cmdedit_prmt_len; /* length of prompt (without colors etc) */ 91 unsigned cmdedit_prmt_len; /* length of prompt (without colors etc) */
92 92
93 unsigned cursor; 93 unsigned cursor;
@@ -299,6 +299,16 @@ static void input_backward(unsigned num)
299 299
300static void put_prompt(void) 300static void put_prompt(void)
301{ 301{
302#if ENABLE_FEATURE_EDITING_ASK_TERMINAL
303 /* Ask terminal where is cursor now.
304 * lineedit_read_key handles response and corrects
305 * our idea of current cursor position.
306 * Testcase: run "echo -n long_line_long_line_long_line",
307 * then type in a long, wrapping command and try to
308 * delete it using backspace key.
309 */
310 out1str("\033" "[6n");
311#endif
302 out1str(cmdedit_prompt); 312 out1str(cmdedit_prompt);
303 cursor = 0; 313 cursor = 0;
304 { 314 {
@@ -1430,18 +1440,33 @@ static void win_changed(int nsig)
1430 signal(SIGWINCH, win_changed); /* rearm ourself */ 1440 signal(SIGWINCH, win_changed); /* rearm ourself */
1431} 1441}
1432 1442
1433static int lineedit_read_key(smalluint *read_key_bufsize, char *read_key_buffer) 1443static int lineedit_read_key(char *read_key_buffer)
1434{ 1444{
1435 int ic; 1445 int64_t ic;
1436 struct pollfd pfd; 1446 struct pollfd pfd;
1447
1437 pfd.fd = STDIN_FILENO; 1448 pfd.fd = STDIN_FILENO;
1438 pfd.events = POLLIN; 1449 pfd.events = POLLIN;
1439 do { 1450 do {
1451 poll_again:
1440 /* Wait for input. Can't just call read_key, it will return 1452 /* Wait for input. Can't just call read_key, it will return
1441 * at once if stdin is in non-blocking mode. */ 1453 * at once if stdin is in non-blocking mode. */
1442 safe_poll(&pfd, 1, -1); 1454 safe_poll(&pfd, 1, -1);
1443 /* note: read_key sets errno to 0 on success: */ 1455 /* note: read_key sets errno to 0 on success: */
1444 ic = read_key(STDIN_FILENO, read_key_bufsize, read_key_buffer); 1456 ic = read_key(STDIN_FILENO, read_key_buffer);
1457 if (ENABLE_FEATURE_EDITING_ASK_TERMINAL
1458 && (int32_t)ic == KEYCODE_CURSOR_POS
1459 ) {
1460 int col = ((ic >> 32) & 0x7fff) - 1;
1461 if (col > 0) {
1462 cmdedit_x += col;
1463 while (cmdedit_x >= cmdedit_termw) {
1464 cmdedit_x -= cmdedit_termw;
1465 cmdedit_y++;
1466 }
1467 }
1468 goto poll_again;
1469 }
1445 } while (errno == EAGAIN); 1470 } while (errno == EAGAIN);
1446 return ic; 1471 return ic;
1447} 1472}
@@ -1482,7 +1507,6 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1482#endif 1507#endif
1483 struct termios initial_settings; 1508 struct termios initial_settings;
1484 struct termios new_settings; 1509 struct termios new_settings;
1485 smalluint read_key_bufsize;
1486 char read_key_buffer[KEYCODE_BUFFER_SIZE]; 1510 char read_key_buffer[KEYCODE_BUFFER_SIZE];
1487 1511
1488 INIT_S(); 1512 INIT_S();
@@ -1561,7 +1585,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1561 1585
1562 while (1) { 1586 while (1) {
1563 fflush(NULL); 1587 fflush(NULL);
1564 ic = lineedit_read_key(&read_key_bufsize, read_key_buffer); 1588 ic = lineedit_read_key(read_key_buffer);
1565 1589
1566#if ENABLE_FEATURE_EDITING_VI 1590#if ENABLE_FEATURE_EDITING_VI
1567 newdelflag = 1; 1591 newdelflag = 1;
@@ -1738,7 +1762,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1738 sc = cursor; 1762 sc = cursor;
1739 prev_ic = ic; 1763 prev_ic = ic;
1740 1764
1741 ic = lineedit_read_key(&read_key_bufsize, read_key_buffer); 1765 ic = lineedit_read_key(read_key_buffer);
1742 if (errno) /* error */ 1766 if (errno) /* error */
1743 goto prepare_to_die; 1767 goto prepare_to_die;
1744 1768
@@ -1801,7 +1825,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1801 put(); 1825 put();
1802 break; 1826 break;
1803 case 'r'|VI_CMDMODE_BIT: 1827 case 'r'|VI_CMDMODE_BIT:
1804 ic = lineedit_read_key(&read_key_bufsize, read_key_buffer); 1828 ic = lineedit_read_key(read_key_buffer);
1805 if (errno) /* error */ 1829 if (errno) /* error */
1806 goto prepare_to_die; 1830 goto prepare_to_die;
1807 if (ic < ' ' || ic > 255) { 1831 if (ic < ' ' || ic > 255) {