mirror of
https://github.com/sheumann/hush.git
synced 2024-12-28 07:30:23 +00:00
lineedit: fix moving backwards across lines with wide chars
function old new delta input_backward 212 208 -4 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
d9a3e89f50
commit
248c324f7c
@ -413,12 +413,22 @@ static void beep(void)
|
|||||||
bb_putchar('\007');
|
bb_putchar('\007');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void put_prompt(void)
|
||||||
|
{
|
||||||
|
unsigned w;
|
||||||
|
|
||||||
|
out1str(cmdedit_prompt);
|
||||||
|
fflush_all();
|
||||||
|
cursor = 0;
|
||||||
|
w = cmdedit_termw; /* read volatile var once */
|
||||||
|
cmdedit_y = cmdedit_prmt_len / w; /* new quasireal y */
|
||||||
|
cmdedit_x = cmdedit_prmt_len % w;
|
||||||
|
}
|
||||||
|
|
||||||
/* Move back one character */
|
/* Move back one character */
|
||||||
/* (optimized for slow terminals) */
|
/* (optimized for slow terminals) */
|
||||||
static void input_backward(unsigned num)
|
static void input_backward(unsigned num)
|
||||||
{
|
{
|
||||||
int count_y;
|
|
||||||
|
|
||||||
if (num > cursor)
|
if (num > cursor)
|
||||||
num = cursor;
|
num = cursor;
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
@ -456,29 +466,44 @@ static void input_backward(unsigned num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Need to go one or more lines up */
|
/* Need to go one or more lines up */
|
||||||
//FIXME: this does not work correctly if prev line has one "unfilled" screen position
|
if (ENABLE_UNICODE_WIDE_WCHARS) {
|
||||||
//caused by wide unicode char not fitting in that one screen position.
|
/* With wide chars, it is hard to "backtrack"
|
||||||
num -= cmdedit_x;
|
* and reliably figure out where to put cursor.
|
||||||
{
|
* Example (<> is a wide char; # is an ordinary char, _ cursor):
|
||||||
unsigned w = cmdedit_termw; /* volatile var */
|
* |prompt: <><> |
|
||||||
|
* |<><><><><><> |
|
||||||
|
* |_ |
|
||||||
|
* and user presses left arrow. num = 1, cmdedit_x = 0,
|
||||||
|
* We need to go up one line, and then - how do we know that
|
||||||
|
* we need to go *10* positions to the right? Because
|
||||||
|
* |prompt: <>#<>|
|
||||||
|
* |<><><>#<><><>|
|
||||||
|
* |_ |
|
||||||
|
* in this situation we need to go *11* positions to the right.
|
||||||
|
*
|
||||||
|
* A simpler thing to do is to redraw everything from the start
|
||||||
|
* up to new cursor position (which is already known):
|
||||||
|
*/
|
||||||
|
unsigned sv_cursor;
|
||||||
|
if (cmdedit_y > 0) /* up to start y */
|
||||||
|
printf("\033[%uA", cmdedit_y);
|
||||||
|
bb_putchar('\r');
|
||||||
|
cmdedit_y = 0;
|
||||||
|
sv_cursor = cursor;
|
||||||
|
put_prompt(); /* sets cursor to 0 */
|
||||||
|
while (cursor < sv_cursor)
|
||||||
|
put_cur_glyph_and_inc_cursor();
|
||||||
|
} else {
|
||||||
|
int count_y;
|
||||||
|
unsigned w;
|
||||||
|
num -= cmdedit_x;
|
||||||
|
w = cmdedit_termw; /* read volatile var once */
|
||||||
count_y = 1 + (num / w);
|
count_y = 1 + (num / w);
|
||||||
cmdedit_y -= count_y;
|
cmdedit_y -= count_y;
|
||||||
cmdedit_x = w * count_y - num;
|
cmdedit_x = w * count_y - num;
|
||||||
|
/* go to 1st column; go up; go to correct column */
|
||||||
|
printf("\r" "\033[%uA" "\033[%uC", count_y, cmdedit_x);
|
||||||
}
|
}
|
||||||
/* go to 1st column; go up; go to correct column */
|
|
||||||
printf("\r" "\033[%uA" "\033[%uC", count_y, cmdedit_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void put_prompt(void)
|
|
||||||
{
|
|
||||||
unsigned w;
|
|
||||||
|
|
||||||
out1str(cmdedit_prompt);
|
|
||||||
fflush_all();
|
|
||||||
cursor = 0;
|
|
||||||
w = cmdedit_termw; /* read volatile var once */
|
|
||||||
cmdedit_y = cmdedit_prmt_len / w; /* new quasireal y */
|
|
||||||
cmdedit_x = cmdedit_prmt_len % w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw prompt, editor line, and clear tail */
|
/* draw prompt, editor line, and clear tail */
|
||||||
|
Loading…
Reference in New Issue
Block a user