From 060be30803b10c8ea2893e3ec880a46451d3cfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 1 Oct 2020 20:15:32 +0200 Subject: [PATCH 1/7] =?UTF-8?q?term:=20add=20private=20mode=20flag=20?= =?UTF-8?q?=E2=80=98=E2=80=99reverse-wrap=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- csi.c | 5 +++++ terminal.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/csi.c b/csi.c index 53a90805..5c847089 100644 --- a/csi.c +++ b/csi.c @@ -399,6 +399,10 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) term->hide_cursor = !enable; break; + case 45: + term->reverse_wrap = enable; + break; + case 1000: if (enable) term->mouse_tracking = MOUSE_CLICK; @@ -576,6 +580,7 @@ xtsave(struct terminal *term, unsigned param) } case 25: term->xtsave.show_cursor = !term->hide_cursor; break; + case 45: term->xtsave.reverse_wrap = term->reverse_wrap; break; case 1000: term->xtsave.mouse_click = term->mouse_tracking == MOUSE_CLICK; break; case 1001: break; case 1002: term->xtsave.mouse_drag = term->mouse_tracking == MOUSE_DRAG; break; diff --git a/terminal.h b/terminal.h index 60a4aba4..817ee8ba 100644 --- a/terminal.h +++ b/terminal.h @@ -237,6 +237,7 @@ struct terminal { enum keypad_keys keypad_keys_mode; bool reverse; bool hide_cursor; + bool reverse_wrap; bool auto_margin; bool insert_mode; bool bracketed_paste; @@ -256,6 +257,7 @@ struct terminal { uint32_t application_cursor_keys:1; uint32_t reverse:1; uint32_t show_cursor:1; + uint32_t reverse_wrap:1; uint32_t auto_margin:1; uint32_t cursor_blink:1; uint32_t insert_mode:1; From 03cacaba86c0abb76760216c7327bd92ab1c3c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 1 Oct 2020 20:15:58 +0200 Subject: [PATCH 2/7] term: cursor-left: reverse-wrap when cursor is at the left margin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assuming the private mode ‘reverse-wrap’ has been enabled. --- terminal.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/terminal.c b/terminal.c index 0840a45c..e8a3173b 100644 --- a/terminal.c +++ b/terminal.c @@ -1728,9 +1728,44 @@ term_cursor_home(struct terminal *term) void term_cursor_left(struct terminal *term, int count) { - int move_amount = min(term->grid->cursor.point.col, count); - term->grid->cursor.point.col -= move_amount; - assert(term->grid->cursor.point.col >= 0); + assert(count >= 0); + int new_col = term->grid->cursor.point.col - count; + + /* Reverse wrap */ + if (unlikely(new_col < 0)) { + if (unlikely(term->reverse_wrap)) { + + /* Number of rows to reverse wrap through */ + int row_count = (abs(new_col) - 1) / term->cols + 1; + + /* Row number cursor will end up on */ + int new_row_no = term->grid->cursor.point.row - row_count; + + /* New column number */ + new_col = term->cols - ((abs(new_col) - 1) % term->cols + 1); + assert(new_col >= 0 && new_col < term->cols); + + /* Don't back up past the scroll region */ + /* TODO: should this be allowed? */ + if (new_row_no < term->scroll_region.start) { + new_row_no = term->scroll_region.start; + new_col = 0; + } + + struct row *new_row = grid_row(term->grid, new_row_no); + term->grid->cursor.point.col = new_col; + term->grid->cursor.point.row = new_row_no; + term->grid->cursor.lcf = false; + term->grid->cur_row = new_row; + return; + } + + /* Reverse wrap disabled - don't let cursor move past first column */ + new_col = 0; + } + + assert(new_col >= 0); + term->grid->cursor.point.col = new_col; term->grid->cursor.lcf = false; } From 377f1b7ad3176d12ae274ca9f3b26f7b764493c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 2 Oct 2020 21:40:30 +0200 Subject: [PATCH 3/7] =?UTF-8?q?vt:=20BS:=20*only*=20reset=20lcf=20if=20cur?= =?UTF-8?q?sor=20is=20beyond=20right=20margin:=20don=E2=80=99t=20move=20cu?= =?UTF-8?q?rsor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed to make reverse auto-wrap work correctly. Without it, we’ll end up moving the cursor left one cell extra. --- vt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vt.c b/vt.c index 6b6bbd0b..6cd5ead7 100644 --- a/vt.c +++ b/vt.c @@ -130,7 +130,10 @@ action_execute(struct terminal *term, uint8_t c) case '\b': /* backspace */ - term_cursor_left(term, 1); + if (term->grid->cursor.lcf) + term->grid->cursor.lcf = false; + else + term_cursor_left(term, 1); break; case '\t': { From 1ad766f4fb1fd5e5e2feb8fdefa225b7409d7ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 2 Oct 2020 21:44:03 +0200 Subject: [PATCH 4/7] changelog: reverse auto-wrap --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67d38093..179195b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ ## Unreleased ### Added + +* Implement reverse auto-wrap. This mode can be enabled/disabled with + `CSI ? 45 h` and `CSI `45 l`. It is disabled by default + (https://codeberg.org/dnkl/foot/issues/150). + + ### Changed * Default value of the **scrollback.multiplier** option in `foot.ini` From 97e07c1ea11edf22e8a2f5a860fe6f32f511593b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 3 Oct 2020 10:50:28 +0200 Subject: [PATCH 5/7] =?UTF-8?q?term:=20cursor-left:=20don=E2=80=99t=20do?= =?UTF-8?q?=20reverse-wrapping=20unless=20auto-margins=20are=20enabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches XTerm’s behavior. --- terminal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terminal.c b/terminal.c index e8a3173b..5c94e5aa 100644 --- a/terminal.c +++ b/terminal.c @@ -1733,7 +1733,7 @@ term_cursor_left(struct terminal *term, int count) /* Reverse wrap */ if (unlikely(new_col < 0)) { - if (unlikely(term->reverse_wrap)) { + if (unlikely(term->reverse_wrap && term->auto_margin)) { /* Number of rows to reverse wrap through */ int row_count = (abs(new_col) - 1) / term->cols + 1; From 71c54fb87cc3386210980be4c996f5319672deff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 3 Oct 2020 11:53:03 +0200 Subject: [PATCH 6/7] =?UTF-8?q?csi:=20xtrestore:=20add=20=E2=80=98reverse?= =?UTF-8?q?=20wrap=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- csi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/csi.c b/csi.c index 5c847089..9a8d7a38 100644 --- a/csi.c +++ b/csi.c @@ -611,6 +611,7 @@ xtrestore(struct terminal *term, unsigned param) case 9: /* enable = term->xtsave.mouse_x10; break; */ return; case 12: enable = term->xtsave.cursor_blink; break; case 25: enable = term->xtsave.show_cursor; break; + case 45: enable = term->xtsave.reverse_wrap; break; case 1000: enable = term->xtsave.mouse_click; break; case 1001: return; case 1002: enable = term->xtsave.mouse_drag; break; From 207b24538d2ea3d2a98787487923ac2a6fb1e131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 6 Oct 2020 18:42:26 +0200 Subject: [PATCH 7/7] term: enable reverse wrap-around by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we’re now doing reverse auto-wrapping by default, we add ‘bw’ (‘auto_left_margin’)to terminfo. --- CHANGELOG.md | 5 +++-- foot.info | 1 + terminal.c | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 179195b9..7b247ec9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,9 @@ ## Unreleased ### Added -* Implement reverse auto-wrap. This mode can be enabled/disabled with - `CSI ? 45 h` and `CSI `45 l`. It is disabled by default +* Implement reverse auto-wrap (_auto\_left\_margin_, _bw_, in + terminfo). This mode can be enabled/disabled with `CSI ? 45 h` and + `CSI `45 l`. It is **enabled** by default (https://codeberg.org/dnkl/foot/issues/150). diff --git a/foot.info b/foot.info index 62eb2beb..c7a05653 100644 --- a/foot.info +++ b/foot.info @@ -14,6 +14,7 @@ foot-direct|foot with direct color indexing, foot+base|foot base fragment, am, bce, + bw, ccc, km, mir, diff --git a/terminal.c b/terminal.c index 5c94e5aa..a171b182 100644 --- a/terminal.c +++ b/terminal.c @@ -904,6 +904,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, : FCFT_SUBPIXEL_NONE), .cursor_keys_mode = CURSOR_KEYS_NORMAL, .keypad_keys_mode = KEYPAD_NUMERICAL, + .reverse_wrap = true, .auto_margin = true, .window_title_stack = tll_init(), .scale = 1, @@ -1394,6 +1395,7 @@ term_reset(struct terminal *term, bool hard) term->keypad_keys_mode = KEYPAD_NUMERICAL; term->reverse = false; term->hide_cursor = false; + term->reverse_wrap = true; term->auto_margin = true; term->insert_mode = false; term->bracketed_paste = false;