diff --git a/terminal/terminal.c b/terminal/terminal.c index 90150044..08df6e59 100644 --- a/terminal/terminal.c +++ b/terminal/terminal.c @@ -1796,8 +1796,13 @@ void term_reconfig(Terminal *term, Conf *conf) conf_free(term->conf); term->conf = conf_copy(conf); - if (reset_wrap) + if (reset_wrap) { term->alt_wrap = term->wrap = conf_get_bool(term->conf, CONF_wrap_mode); + if (!term->wrap) + term->wrapnext = false; + if (!term->alt_wrap) + term->alt_wnext = false; + } if (reset_decom) term->alt_om = term->dec_om = conf_get_bool(term->conf, CONF_dec_om); if (reset_bce) { @@ -3093,6 +3098,8 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state) break; case 7: /* DECAWM: auto wrap */ term->wrap = state; + if (!term->wrap) + term->wrapnext = false; break; case 8: /* DECARM: auto key repeat */ term->repeat_off = !state; @@ -3425,15 +3432,23 @@ static void term_display_graphic_char(Terminal *term, unsigned long c) term->curs.x++; if (term->curs.x >= linecols) { term->curs.x = linecols - 1; - term->wrapnext = true; - if (term->wrap && term->vt52_mode) { - cline->lattr |= LATTR_WRAPPED; - if (term->curs.y == term->marg_b) - scroll(term, term->marg_t, term->marg_b, 1, true); - else if (term->curs.y < term->rows - 1) - term->curs.y++; - term->curs.x = 0; - term->wrapnext = false; + + if (term->wrap) { + if (!term->vt52_mode) { + /* Set the wrapnext flag, so that the next character + * wraps, but this one doesn't. */ + term->wrapnext = true; + } else { + /* VT52 mode expects simpler handling, and we just + * wrap straight away. */ + cline->lattr |= LATTR_WRAPPED; + if (term->curs.y == term->marg_b) + scroll(term, term->marg_t, term->marg_b, 1, true); + else if (term->curs.y < term->rows - 1) + term->curs.y++; + term->curs.x = 0; + term->wrapnext = false; + } } } seen_disp_event(term); @@ -5655,6 +5670,7 @@ static void term_out(Terminal *term, bool called_from_term_data) case 'w': /* Autowrap off */ /* compatibility(ATARI) */ term->wrap = false; + term->wrapnext = false; break; case 'R': diff --git a/test/test_terminal.c b/test/test_terminal.c index 9fdca6cc..5ebc1204 100644 --- a/test/test_terminal.c +++ b/test/test_terminal.c @@ -384,7 +384,8 @@ static void test_wrap(Mock *mk) static void test_nonwrap(Mock *mk) { - /* Test behaviour when printing characters hit end of line without wrap */ + /* Test behaviour when printing characters hit end of line without wrap. + * The wrapnext flag is never set in this mode. */ mk->ucsdata->line_codepage = CP_UTF8; /* Print 'abc' without enough space for the c */ @@ -398,27 +399,22 @@ static void test_nonwrap(Mock *mk) IEQUAL(mk->term->curs.y, 0); IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, CSET_ASCII | 'a'); - /* The 'b' prints, leaving the cursor where it is with wrapnext set */ + /* The 'b' prints, leaving the cursor where it is */ term_datapl(mk->term, PTRLEN_LITERAL("b")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_lineattr(mk->term, 0), 0); IEQUAL(get_termchar(mk->term, 79, 0).chr, CSET_ASCII | 'b'); - /* The 'c' overwrites the b, leaving wrapnext still set */ + /* The 'c' overwrites the b */ term_datapl(mk->term, PTRLEN_LITERAL("c")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_lineattr(mk->term, 0), 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, CSET_ASCII | 'a'); IEQUAL(get_termchar(mk->term, 79, 0).chr, CSET_ASCII | 'c'); - /* So backspacing clears wrapnext, leaving us on the c */ - term_datapl(mk->term, PTRLEN_LITERAL("\b")); - IEQUAL(mk->term->curs.x, 79); - IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 0); - /* And backspacing again returns the cursor to the a */ + /* Since wrapnext was never set, backspacing returns us to the a */ term_datapl(mk->term, PTRLEN_LITERAL("\b")); IEQUAL(mk->term->curs.x, 78); IEQUAL(mk->term->curs.y, 0); @@ -428,18 +424,18 @@ static void test_nonwrap(Mock *mk) mk->term->curs.x = 78; mk->term->curs.y = 0; mk->term->wrap = false; - /* The DW character goes directly to the wrapnext state */ + /* The DW character occupies the rightmost two columns */ term_datapl(mk->term, PTRLEN_LITERAL("\xEA\xB0\x80")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, 0xAC00); IEQUAL(get_termchar(mk->term, 79, 0).chr, UCSWIDE); /* The 'c' must overprint the RHS of the DW char, clearing the LHS */ term_datapl(mk->term, PTRLEN_LITERAL("c")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_lineattr(mk->term, 0), 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, CSET_ASCII | ' '); IEQUAL(get_termchar(mk->term, 79, 0).chr, CSET_ASCII | 'c'); @@ -459,7 +455,7 @@ static void test_nonwrap(Mock *mk) term_datapl(mk->term, PTRLEN_LITERAL("\xEA\xB0\x80")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_lineattr(mk->term, 0), 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, CSET_ASCII | 'a'); IEQUAL(get_termchar(mk->term, 79, 0).chr, 0xFFFD); @@ -469,18 +465,18 @@ static void test_nonwrap(Mock *mk) mk->term->curs.x = 78; mk->term->curs.y = 0; mk->term->wrap = false; - /* First DW character goes directly to the wrapnext state */ + /* First DW character occupies the rightmost columns */ term_datapl(mk->term, PTRLEN_LITERAL("\xEA\xB0\x80")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, 0xAC00); IEQUAL(get_termchar(mk->term, 79, 0).chr, UCSWIDE); /* Second DW char becomes U+FFFD, overwriting RHS of the first one */ term_datapl(mk->term, PTRLEN_LITERAL("\xEA\xB0\x81")); IEQUAL(mk->term->curs.x, 79); IEQUAL(mk->term->curs.y, 0); - IEQUAL(mk->term->wrapnext, 1); + IEQUAL(mk->term->wrapnext, 0); IEQUAL(get_lineattr(mk->term, 0), 0); IEQUAL(get_termchar(mk->term, 78, 0).chr, CSET_ASCII | ' '); IEQUAL(get_termchar(mk->term, 79, 0).chr, 0xFFFD);