ref: d34b159e55b36629eb8c980dc1d4570dc81ead72
parent: b9f1b0038904401222a9b99d308e13ac6094462a
author: cancel <cancel@cancel.fm>
date: Fri Jan 3 14:46:07 EST 2020
Clean up bracketed paste control flow
--- a/tui_main.c
+++ b/tui_main.c
@@ -2145,6 +2145,43 @@
return false;
}
+typedef enum {
+ Bracketed_paste_sequence_none = 0,
+ Bracketed_paste_sequence_begin,
+ Bracketed_paste_sequence_end,
+} Bracketed_paste_sequence;
+
+Bracketed_paste_sequence bracketed_paste_sequence_getch_ungetch(WINDOW* win) {
+ int esc1 = wgetch(win);
+ if (esc1 == '[') {
+ int esc2 = wgetch(win);
+ if (esc2 == '2') {
+ int esc3 = wgetch(win);
+ if (esc3 == '0') {
+ int esc4 = wgetch(win);
+ // Start or end of bracketed paste
+ if (esc4 == '0' || esc4 == '1') {
+ int esc5 = wgetch(win);
+ if (esc5 == '~') {
+ switch (esc4) {
+ case '0':
+ return Bracketed_paste_sequence_begin;
+ case '1':
+ return Bracketed_paste_sequence_end;
+ }
+ }
+ ungetch(esc5);
+ }
+ ungetch(esc4);
+ }
+ ungetch(esc3);
+ }
+ ungetch(esc2);
+ }
+ ungetch(esc1);
+ return Bracketed_paste_sequence_none;
+}
+
int main(int argc, char** argv) {
static struct option tui_options[] = {
{"margins", required_argument, 0, Argopt_margins},
@@ -2647,12 +2684,12 @@
goto next_getch;
}
#endif
- case CTRL_PLUS('q'):
- goto quit;
}
Qblock* qb = qnav_top_block();
if (qb) {
+ if (key == CTRL_PLUS('q'))
+ goto quit;
switch (qb->tag) {
case Qblock_type_qmsg: {
Qmsg* qm = qmsg_of(qb);
@@ -2811,7 +2848,64 @@
goto next_getch;
}
+ // If this key input is intended to reach the grid, check to see if we're
+ // in bracketed paste and use alternate 'filtered input for characters'
+ // mode. We'll ignore most control sequences here.
+ if (is_in_bracketed_paste) {
+ if (key == 27 /* escape */) {
+ if (bracketed_paste_sequence_getch_ungetch(stdscr) ==
+ Bracketed_paste_sequence_end) {
+ is_in_bracketed_paste = false;
+ ged_state.ged_cursor.y = bracketed_paste_starting_y;
+ ged_state.ged_cursor.x = bracketed_paste_starting_x;
+ ged_cursor_confine(&ged_state.ged_cursor, ged_state.field.height,
+ ged_state.field.width);
+ ged_state.needs_remarking = true;
+ ged_state.is_draw_dirty = true;
+ }
+ goto next_getch;
+ }
+ if (key == KEY_ENTER)
+ key = '\r';
+ if (key >= CHAR_MIN && key <= CHAR_MAX) {
+ if ((char)key == '\r' || (char)key == '\n') {
+ if (bracketed_paste_went_off_bottom_edge)
+ goto next_getch;
+ bracketed_paste_went_off_right_edge = false;
+ ged_state.ged_cursor.x = bracketed_paste_starting_x;
+ ++ged_state.ged_cursor.y; // TODO overflow check
+ if (ged_state.ged_cursor.y >= ged_state.field.height)
+ bracketed_paste_went_off_bottom_edge = true;
+ ged_cursor_confine(&ged_state.ged_cursor, ged_state.field.height,
+ ged_state.field.width);
+ goto next_getch;
+ }
+ if (bracketed_paste_went_off_right_edge ||
+ bracketed_paste_went_off_bottom_edge)
+ goto next_getch;
+ if (key != ' ') {
+ char cleaned = (char)key;
+ if (!is_valid_glyph((Glyph)key))
+ cleaned = '.';
+ gbuffer_poke(ged_state.field.buffer, ged_state.field.height,
+ ged_state.field.width, ged_state.ged_cursor.y,
+ ged_state.ged_cursor.x, cleaned);
+ }
+ ++ged_state.ged_cursor.x; // TODO overflow check
+ if (ged_state.ged_cursor.x >= ged_state.field.width)
+ bracketed_paste_went_off_right_edge = true;
+ ged_cursor_confine(&ged_state.ged_cursor, ged_state.field.height,
+ ged_state.field.width);
+ }
+ goto next_getch;
+ }
+
+ // Regular inputs when we're not in a menu and not in bracketed paste.
switch (key) {
+ // Checking again for 'quit' here, because it's only listened for if we're
+ // in the menus or *not* in bracketed paste mode.
+ case CTRL_PLUS('q'):
+ goto quit;
case KEY_UP:
case CTRL_PLUS('k'):
ged_dir_input(&ged_state, Ged_dir_up, 1);
@@ -2868,8 +2962,6 @@
break;
case '\r':
case KEY_ENTER:
- if (is_in_bracketed_paste)
- goto newline_in_bracketed_paste;
// Currently unused. Formerly was the toggle for insert/append mode.
break;
case CTRL_PLUS('i'):
@@ -2904,8 +2996,6 @@
ged_input_cmd(&ged_state, Ged_input_cmd_toggle_selresize_mode);
break;
case ' ':
- if (is_in_bracketed_paste)
- goto key_input_in_bracketed_paste;
if (ged_state.input_mode == Ged_input_mode_append) {
ged_input_character(&ged_state, '.');
} else {
@@ -2915,54 +3005,18 @@
case 27: { // Escape
// Check for escape sequences we're interested in that ncurses didn't
// handle.
- int esc1 = wgetch(stdscr);
- if (esc1 == '[') {
- int esc2 = wgetch(stdscr);
- if (esc2 == '2') {
- int esc3 = wgetch(stdscr);
- if (esc3 == '0') {
- int esc4 = wgetch(stdscr);
- // Start or end of bracketed paste
- if (esc4 == '0' || esc4 == '1') {
- int esc5 = wgetch(stdscr);
- if (esc5 == '~') {
- switch (esc4) {
- case '0': // Enter bracketed paste
- if (!is_in_bracketed_paste) {
- is_in_bracketed_paste = true;
- bracketed_paste_went_off_right_edge = false;
- bracketed_paste_went_off_bottom_edge = false;
- undo_history_push(&ged_state.undo_hist, &ged_state.field,
- ged_state.tick_num);
- bracketed_paste_starting_y = ged_state.ged_cursor.y;
- bracketed_paste_starting_x = ged_state.ged_cursor.x;
- }
- goto finished_escape_sequence;
- case '1': // End bracketed paste
- if (is_in_bracketed_paste) {
- is_in_bracketed_paste = false;
- ged_state.ged_cursor.y = bracketed_paste_starting_y;
- ged_state.ged_cursor.x = bracketed_paste_starting_x;
- ged_cursor_confine(&ged_state.ged_cursor,
- ged_state.field.height,
- ged_state.field.width);
- ged_state.needs_remarking = true;
- ged_state.is_draw_dirty = true;
- }
- goto finished_escape_sequence;
- }
- }
- ungetch(esc5);
- }
- ungetch(esc4);
- }
- ungetch(esc3);
- }
- ungetch(esc2);
+ if (bracketed_paste_sequence_getch_ungetch(stdscr) ==
+ Bracketed_paste_sequence_begin) {
+ is_in_bracketed_paste = true;
+ bracketed_paste_went_off_right_edge = false;
+ bracketed_paste_went_off_bottom_edge = false;
+ undo_history_push(&ged_state.undo_hist, &ged_state.field,
+ ged_state.tick_num);
+ bracketed_paste_starting_y = ged_state.ged_cursor.y;
+ bracketed_paste_starting_x = ged_state.ged_cursor.x;
+ break;
}
- ungetch(esc1);
ged_input_cmd(&ged_state, Ged_input_cmd_escape);
- finished_escape_sequence:;
} break;
// Selection size modification. These may not work in all terminals. (Only
@@ -3039,41 +3093,6 @@
break;
default:
- if (is_in_bracketed_paste) {
- key_input_in_bracketed_paste:
- if (key >= CHAR_MIN && key <= CHAR_MAX) {
- if ((char)key == '\n') {
- newline_in_bracketed_paste:
- if (bracketed_paste_went_off_bottom_edge)
- break;
- bracketed_paste_went_off_right_edge = false;
- ged_state.ged_cursor.x = bracketed_paste_starting_x;
- ++ged_state.ged_cursor.y; // TODO overflow check
- if (ged_state.ged_cursor.y >= ged_state.field.height)
- bracketed_paste_went_off_bottom_edge = true;
- ged_cursor_confine(&ged_state.ged_cursor, ged_state.field.height,
- ged_state.field.width);
- break;
- }
- if (bracketed_paste_went_off_right_edge ||
- bracketed_paste_went_off_bottom_edge)
- break;
- if (key != ' ') {
- char cleaned = (char)key;
- if (!is_valid_glyph((Glyph)key))
- cleaned = '.';
- gbuffer_poke(ged_state.field.buffer, ged_state.field.height,
- ged_state.field.width, ged_state.ged_cursor.y,
- ged_state.ged_cursor.x, cleaned);
- }
- ++ged_state.ged_cursor.x; // TODO overflow check
- if (ged_state.ged_cursor.x >= ged_state.field.width)
- bracketed_paste_went_off_right_edge = true;
- ged_cursor_confine(&ged_state.ged_cursor, ged_state.field.height,
- ged_state.field.width);
- }
- break;
- }
if (key >= CHAR_MIN && key <= CHAR_MAX && is_valid_glyph((Glyph)key)) {
ged_input_character(&ged_state, (char)key);
}