mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Fix behaviour of backspace in a 1-column terminal.
This is the first bug found as a direct result of writing that terminal test program - I added some tests for things I expected to work already, and some of them didn't, proving immediately that it was a good idea! If the terminal is one column wide, and you've printed a character (hence, set the wrapnext flag), what should backspace do? Surely it should behave like any other backspace with wrapnext set, i.e. clear the wrapnext flag, returning the cursor's _logical_ position to the location of the most recently printed character. But in fact it was anti-wrapping to the previous line, because I'd got the cases in the wrong order in the if-else chain that forms the backspace handler. So the handler for 'we're in column 0, wrapping time' was coming before 'wrapnext is set, just clear it'. Now wrapnext is checked _first_, before checking anything at all. Any time we can just clear that, we should.
This commit is contained in:
parent
9ba742ad9f
commit
069f7c8b21
@ -3997,7 +3997,10 @@ static void term_out(Terminal *term, bool called_from_term_data)
|
||||
break;
|
||||
}
|
||||
case '\b': /* BS: Back space */
|
||||
if (term->curs.x == 0 && (term->curs.y == 0 || !term->wrap)) {
|
||||
if (term->wrapnext) {
|
||||
term->wrapnext = false;
|
||||
} else if (term->curs.x == 0 &&
|
||||
(term->curs.y == 0 || !term->wrap)) {
|
||||
/* do nothing */
|
||||
} else if (term->curs.x == 0 && term->curs.y > 0) {
|
||||
term->curs.x = term->cols - 1, term->curs.y--;
|
||||
@ -4021,8 +4024,6 @@ static void term_out(Terminal *term, bool called_from_term_data)
|
||||
termline *ldata = scrlineptr(term->curs.y);
|
||||
if (term->curs.x > 0 && (ldata->lattr & LATTR_WRAPPED2))
|
||||
term->curs.x--;
|
||||
} else if (term->wrapnext) {
|
||||
term->wrapnext = false;
|
||||
} else {
|
||||
term->curs.x--;
|
||||
}
|
||||
|
@ -326,6 +326,57 @@ static void test_wrap(Mock *mk)
|
||||
IEQUAL(mk->term->curs.x, 78);
|
||||
IEQUAL(mk->term->curs.y, 0);
|
||||
IEQUAL(mk->term->wrapnext, 0);
|
||||
|
||||
/*
|
||||
* Now test the special cases that arise when the terminal is only
|
||||
* one column wide!
|
||||
*/
|
||||
|
||||
reset(mk);
|
||||
term_size(mk->term, 24, 1, 0);
|
||||
mk->term->curs.x = 0;
|
||||
mk->term->curs.y = 0;
|
||||
mk->term->wrap = true;
|
||||
/* Printing a single-width character takes us into wrapnext immediately */
|
||||
term_datapl(mk->term, PTRLEN_LITERAL("a"));
|
||||
IEQUAL(mk->term->curs.x, 0);
|
||||
IEQUAL(mk->term->curs.y, 0);
|
||||
IEQUAL(mk->term->wrapnext, 1);
|
||||
IEQUAL(get_lineattr(mk->term, 0), 0);
|
||||
IEQUAL(get_termchar(mk->term, 0, 0).chr, CSET_ASCII | 'a');
|
||||
/* Printing a second one wraps, and takes us _back_ to wrapnext */
|
||||
term_datapl(mk->term, PTRLEN_LITERAL("b"));
|
||||
IEQUAL(mk->term->curs.x, 0);
|
||||
IEQUAL(mk->term->curs.y, 1);
|
||||
IEQUAL(mk->term->wrapnext, 1);
|
||||
IEQUAL(get_lineattr(mk->term, 0), LATTR_WRAPPED);
|
||||
IEQUAL(get_termchar(mk->term, 0, 0).chr, CSET_ASCII | 'a');
|
||||
IEQUAL(get_termchar(mk->term, 0, 1).chr, CSET_ASCII | 'b');
|
||||
/* Backspacing once clears the wrapnext flag, putting us on the b */
|
||||
term_datapl(mk->term, PTRLEN_LITERAL("\b"));
|
||||
IEQUAL(mk->term->curs.x, 0);
|
||||
IEQUAL(mk->term->curs.y, 1);
|
||||
IEQUAL(mk->term->wrapnext, 0);
|
||||
/* Backspacing again returns to the previous line, putting us on the a */
|
||||
term_datapl(mk->term, PTRLEN_LITERAL("\b"));
|
||||
IEQUAL(mk->term->curs.x, 0);
|
||||
IEQUAL(mk->term->curs.y, 0);
|
||||
IEQUAL(mk->term->wrapnext, 0);
|
||||
|
||||
/* And now try with a double-width character */
|
||||
reset(mk);
|
||||
term_size(mk->term, 24, 1, 0);
|
||||
mk->term->curs.x = 0;
|
||||
mk->term->curs.y = 0;
|
||||
mk->term->wrap = true;
|
||||
/* DW character won't fit at all, so it transforms into U+FFFD
|
||||
* REPLACEMENT CHARACTER and then behaves like a SW char */
|
||||
term_datapl(mk->term, PTRLEN_LITERAL("\xEA\xB0\x80"));
|
||||
IEQUAL(mk->term->curs.x, 0);
|
||||
IEQUAL(mk->term->curs.y, 0);
|
||||
IEQUAL(mk->term->wrapnext, 1);
|
||||
IEQUAL(get_lineattr(mk->term, 0), 0);
|
||||
IEQUAL(get_termchar(mk->term, 0, 0).chr, 0xFFFD);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
Loading…
Reference in New Issue
Block a user