diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-08-09 20:01:42 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-08-09 20:01:42 -0700 |
commit | e709c65e67f873541b958ba43e425b08f3e073e3 (patch) | |
tree | 37d7203b4f2874e41e178938f1f00917dae949c8 | |
parent | 6fef33fd0872ffcb5141a926d1dae5b0eded3071 (diff) | |
download | mu-e709c65e67f873541b958ba43e425b08f3e073e3.tar.gz |
1964 - don't mess up paste
It took me a long time to fix termbox because the escape codes it was seeing seemed all wrong. Had to stop calling tb_shutdown/printf and put in the extra 3 lines to log to a file. Then everything cleared up. Weird.
-rw-r--r-- | edit.mu | 61 | ||||
-rw-r--r-- | termbox/input.inl | 35 | ||||
-rw-r--r-- | termbox/output.inl | 28 | ||||
-rw-r--r-- | termbox/termbox.c | 2 | ||||
-rw-r--r-- | termbox/termbox.h | 2 |
5 files changed, 115 insertions, 13 deletions
diff --git a/edit.mu b/edit.mu index 369d0089..a61940e7 100644 --- a/edit.mu +++ b/edit.mu @@ -83,6 +83,7 @@ recipe new-editor [ *y <- copy *init # initial render to screen, just for some old tests _, screen <- render screen, result + +editor-initialization reply result ] @@ -1017,7 +1018,16 @@ scenario editor-wraps-cursor-after-inserting-characters-2 [ ] ] -# if newline, move cursor to start of next line +# if newline, move cursor to start of next line, and maybe align indent with previous line + +container editor-data [ + indent:boolean +] + +after +editor-initialization [ + indent:address:boolean <- get-address *result, indent:offset + *indent <- copy 1/true +] scenario editor-moves-cursor-down-after-inserting-newline [ assume-screen 10/width, 5/height @@ -1052,6 +1062,8 @@ after +insert-character-special-case [ *cursor-row <- subtract *cursor-row, 1 # bring back into screen range } # indent if necessary + indent?:boolean <- get *editor, indent:offset + reply-unless indent? d:address:duplex-list <- get *editor, data:offset end-of-previous-line:address:duplex-list <- prev-duplex *before-cursor indent:number <- line-indent end-of-previous-line, d @@ -1173,6 +1185,52 @@ ef] ] ] +scenario editor-skips-indent-around-paste [ + assume-screen 10/width, 10/height + 1:address:array:character <- new [ab + cd +ef] + 2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0/left, 10/right + # position cursor after 'cd' and hit 'newline' surrounded by paste markers + assume-console [ + left-click 2, 8 + press 65507 # start paste + type [ +] + press 65506 # end paste + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 3:number <- get *2:address:editor-data, cursor-row:offset + 4:number <- get *2:address:editor-data, cursor-column:offset + ] + # cursor should be below start of previous line + memory-should-contain [ + 3 <- 3 # cursor row + 4 <- 0 # cursor column (not indented) + ] +] + +after +handle-special-key [ + { + paste-start?:boolean <- equal *k, 65507/paste-start + break-unless paste-start? + indent:address:boolean <- get-address *editor, indent:offset + *indent <- copy 0/false + reply + } +] + +after +handle-special-key [ + { + paste-end?:boolean <- equal *k, 65506/paste-end + break-unless paste-end? + indent:address:boolean <- get-address *editor, indent:offset + *indent <- copy 1/true + reply + } +] + ## special shortcuts for manipulating the editor # Some keys on the keyboard generate unicode characters, others generate # terminfo key codes. We need to modify different places in the two cases. @@ -3765,6 +3823,7 @@ recipe new-programming-environment [ current-sandbox:address:address:editor-data <- get-address *result, current-sandbox:offset *current-sandbox <- new-editor initial-sandbox-contents, screen, new-left, width/right screen <- render-all screen, result + +programming-environment-initialization reply result ] diff --git a/termbox/input.inl b/termbox/input.inl index 618e0b28..4cbba0a5 100644 --- a/termbox/input.inl +++ b/termbox/input.inl @@ -12,9 +12,20 @@ static bool starts_with(const char *s1, int len, const char *s2) return *s2 == 0; } +#define FOO(...) { \ + FILE* f = fopen("log", "a+"); \ + fprintf(f, __VA_ARGS__); \ + fclose(f); \ +} + // convert escape sequence to event, and return consumed bytes on success (failure == 0) static int parse_escape_seq(struct tb_event *event, const char *buf, int len) { +//? int x = 0; +//? FOO("-- %d\n", len); +//? for (x = 0; x < len; ++x) { +//? FOO("%d\n", (unsigned char)buf[x]); +//? } if (len >= 6 && starts_with(buf, len, "\033[M")) { switch (buf[3] & 3) { @@ -58,6 +69,18 @@ static int parse_escape_seq(struct tb_event *event, const char *buf, int len) return strlen(keys[i]); } } + + if (starts_with(buf, len, "\033[200~")) { + event->ch = 0; + event->key = TB_KEY_START_PASTE; + return strlen("\033[200~"); + } + if (starts_with(buf, len, "\033[201~")) { + event->ch = 0; + event->key = TB_KEY_END_PASTE; + return strlen("\033[201~"); + } + return 0; } @@ -68,8 +91,15 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf) if (len == 0) return false; +//? int x = 0; +//? FOO("== %d\n", len); +//? for (x = 0; x < len; ++x) { +//? FOO("%x\n", (unsigned char)buf[x]); +//? } if (buf[0] == '\033') { +//? FOO("AAA\n"); int n = parse_escape_seq(event, buf, len); +//? FOO("AAA: %u %u %u %u\n", n, (unsigned int)event->type, (unsigned int)event->key, event->ch); if (n != 0) { bool success = true; if (n < 0) { @@ -79,6 +109,7 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf) bytebuffer_truncate(inbuf, n); return success; } else { +//? FOO("escape sequence\n"); // it's not escape sequence; assume it's esc event->ch = 0; event->key = TB_KEY_ESC; @@ -94,6 +125,7 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf) if ((unsigned char)buf[0] <= TB_KEY_SPACE || (unsigned char)buf[0] == TB_KEY_BACKSPACE2) { +//? FOO("BBB\n"); // fill event, pop buffer, return success */ event->ch = 0; event->key = (uint16_t)buf[0]; @@ -105,8 +137,10 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf) // check if there is all bytes if (len >= tb_utf8_char_length(buf[0])) { +//? FOO("CCC\n"); /* everything ok, fill event, pop buffer, return success */ tb_utf8_char_to_unicode(&event->ch, buf); +//? FOO("CCC: %d\n", event->ch); event->key = 0; bytebuffer_truncate(inbuf, tb_utf8_char_length(buf[0])); return true; @@ -114,5 +148,6 @@ static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf) // event isn't recognized, perhaps there is not enough bytes in utf8 // sequence +//? FOO("ZZZ\n"); return false; } diff --git a/termbox/output.inl b/termbox/output.inl index 427f221c..277817fa 100644 --- a/termbox/output.inl +++ b/termbox/output.inl @@ -13,6 +13,8 @@ enum { T_EXIT_KEYPAD, T_ENTER_MOUSE, T_EXIT_MOUSE, + T_ENTER_BRACKETED_PASTE, + T_EXIT_BRACKETED_PASTE, T_FUNCS_NUM, }; @@ -23,7 +25,7 @@ static const char *rxvt_256color_keys[] = { "\033[11~", "\033[12~", "\033[13~", "\033[14~", "\033[15~", "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\033[2~", "\033[3~", "\033[7~", "\033[8~", "\033[5~", "\033[6~", "\033[A", "\033[B", "\033[D", "\033[C", 0 }; static const char *rxvt_256color_funcs[] = { - "\0337\033[?47h", "\033[2J\033[?47l\0338", "\033[?25h", "\033[?25l", "\033[H\033[2J", "\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033=", "\033>", "\033[?1000h", "\033[?1000l", + "\0337\033[?47h", "\033[2J\033[?47l\0338", "\033[?25h", "\033[?25l", "\033[H\033[2J", "\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033=", "\033>", "\033[?1000h", "\033[?1000l", "\033[?2004h", "\033[?2004l", }; // Eterm @@ -31,7 +33,7 @@ static const char *eterm_keys[] = { "\033[11~", "\033[12~", "\033[13~", "\033[14~", "\033[15~", "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\033[2~", "\033[3~", "\033[7~", "\033[8~", "\033[5~", "\033[6~", "\033[A", "\033[B", "\033[D", "\033[C", 0 }; static const char *eterm_funcs[] = { - "\0337\033[?47h", "\033[2J\033[?47l\0338", "\033[?25h", "\033[?25l", "\033[H\033[2J", "\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "", "", "", "", + "\0337\033[?47h", "\033[2J\033[?47l\0338", "\033[?25h", "\033[?25l", "\033[H\033[2J", "\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "", "", "", "", "", "", }; // screen @@ -39,7 +41,7 @@ static const char *screen_keys[] = { "\033OP", "\033OQ", "\033OR", "\033OS", "\033[15~", "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\033[2~", "\033[3~", "\033[1~", "\033[4~", "\033[5~", "\033[6~", "\033OA", "\033OB", "\033OD", "\033OC", 0 }; static const char *screen_funcs[] = { - "\033[?1049h", "\033[?1049l", "\033[34h\033[?25h", "\033[?25l", "\033[H\033[J", "\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033[?1h\033=", "\033[?1l\033>", "\033[?1000h", "\033[?1000l", + "\033[?1049h", "\033[?1049l", "\033[34h\033[?25h", "\033[?25l", "\033[H\033[J", "\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033[?1h\033=", "\033[?1l\033>", "\033[?1000h", "\033[?1000l", "\033[?2004h", "\033[?2004l", }; // rxvt-unicode @@ -47,7 +49,7 @@ static const char *rxvt_unicode_keys[] = { "\033[11~", "\033[12~", "\033[13~", "\033[14~", "\033[15~", "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\033[2~", "\033[3~", "\033[7~", "\033[8~", "\033[5~", "\033[6~", "\033[A", "\033[B", "\033[D", "\033[C", 0 }; static const char *rxvt_unicode_funcs[] = { - "\033[?1049h", "\033[r\033[?1049l", "\033[?25h", "\033[?25l", "\033[H\033[2J", "\033[m\033(B", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033=", "\033>", "\033[?1000h", "\033[?1000l", + "\033[?1049h", "\033[r\033[?1049l", "\033[?25h", "\033[?25l", "\033[H\033[2J", "\033[m\033(B", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033=", "\033>", "\033[?1000h", "\033[?1000l", "\033[?2004h", "\033[?2004l", }; // linux @@ -55,7 +57,7 @@ static const char *linux_keys[] = { "\033[[A", "\033[[B", "\033[[C", "\033[[D", "\033[[E", "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\033[2~", "\033[3~", "\033[1~", "\033[4~", "\033[5~", "\033[6~", "\033[A", "\033[B", "\033[D", "\033[C", 0 }; static const char *linux_funcs[] = { - "", "", "\033[?25h\033[?0c", "\033[?25l\033[?1c", "\033[H\033[J", "\033[0;10m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "", "", "", "", + "", "", "\033[?25h\033[?0c", "\033[?25l\033[?1c", "\033[H\033[J", "\033[0;10m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "", "", "", "", "", "", }; // xterm @@ -63,7 +65,7 @@ static const char *xterm_keys[] = { "\033OP", "\033OQ", "\033OR", "\033OS", "\033[15~", "\033[17~", "\033[18~", "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\033[2~", "\033[3~", "\033OH", "\033OF", "\033[5~", "\033[6~", "\033OA", "\033OB", "\033OD", "\033OC", 0 }; static const char *xterm_funcs[] = { - "\033[?1049h", "\033[?1049l", "\033[?12l\033[?25h", "\033[?25l", "\033[H\033[2J", "\033(B\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033[?1h\033=", "\033[?1l\033>", "\033[?1000h", "\033[?1000l", + "\033[?1049h", "\033[?1049l", "\033[?12l\033[?25h", "\033[?25l", "\033[H\033[2J", "\033(B\033[m", "\033[4m", "\033[1m", "\033[5m", "\033[7m", "\033[?1h\033=", "\033[?1l\033>", "\033[?1000h", "\033[?1000l", "\033[?2004h", "\033[?2004l", }; static struct term { @@ -273,15 +275,17 @@ static int init_term(void) { keys[TB_KEYS_NUM] = 0; funcs = malloc(sizeof(const char*) * T_FUNCS_NUM); - // the last two entries are reserved for mouse. because the table offset is + // the last four entries are reserved for mouse, bracketed paste. because the table offset is // not there, the two entries have to fill in manually - for (i = 0; i < T_FUNCS_NUM-2; i++) { + for (i = 0; i < T_FUNCS_NUM-4; i++) { funcs[i] = terminfo_copy_string(data, str_offset + 2 * ti_funcs[i], table_offset); } - funcs[T_FUNCS_NUM-2] = "\033[?1000h"; - funcs[T_FUNCS_NUM-1] = "\033[?1000l"; + funcs[T_FUNCS_NUM-4] = "\033[?1000h"; + funcs[T_FUNCS_NUM-3] = "\033[?1000l"; + funcs[T_FUNCS_NUM-2] = "\033[?2004h"; + funcs[T_FUNCS_NUM-1] = "\033[?2004l"; init_from_terminfo = true; free(data); @@ -294,10 +298,10 @@ static void shutdown_term(void) { for (i = 0; i < TB_KEYS_NUM; i++) { free((void*)keys[i]); } - // the last two entries are reserved for mouse. because the table offset + // the last four entries are reserved for mouse, bracketed paste. because the table offset // is not there, the two entries have to fill in manually and do not // need to be freed. - for (i = 0; i < T_FUNCS_NUM-2; i++) { + for (i = 0; i < T_FUNCS_NUM-4; i++) { free((void*)funcs[i]); } free(keys); diff --git a/termbox/termbox.c b/termbox/termbox.c index 0092abd1..d8cc4514 100644 --- a/termbox/termbox.c +++ b/termbox/termbox.c @@ -116,6 +116,7 @@ int tb_init(void) bytebuffer_puts(&output_buffer, funcs[T_ENTER_KEYPAD]); bytebuffer_puts(&output_buffer, funcs[T_HIDE_CURSOR]); bytebuffer_puts(&output_buffer, funcs[T_ENTER_MOUSE]); + bytebuffer_puts(&output_buffer, funcs[T_ENTER_BRACKETED_PASTE]); send_clear(); update_term_size(); @@ -137,6 +138,7 @@ void tb_shutdown(void) bytebuffer_puts(&output_buffer, funcs[T_EXIT_CA]); bytebuffer_puts(&output_buffer, funcs[T_EXIT_KEYPAD]); bytebuffer_puts(&output_buffer, funcs[T_EXIT_MOUSE]); + bytebuffer_puts(&output_buffer, funcs[T_EXIT_BRACKETED_PASTE]); bytebuffer_flush(&output_buffer, inout); tcsetattr(inout, TCSAFLUSH, &orig_tios); diff --git a/termbox/termbox.h b/termbox/termbox.h index c257434c..c629b01c 100644 --- a/termbox/termbox.h +++ b/termbox/termbox.h @@ -127,6 +127,8 @@ struct tb_event { #define TB_KEY_MOUSE_RELEASE (0xFFFF-25) #define TB_KEY_MOUSE_WHEEL_UP (0xFFFF-26) #define TB_KEY_MOUSE_WHEEL_DOWN (0xFFFF-27) +#define TB_KEY_START_PASTE (0xFFFF-28) +#define TB_KEY_END_PASTE (0xFFFF-29) /* These are all ASCII code points below SPACE character and a BACKSPACE key. */ #define TB_KEY_CTRL_TILDE 0x00 #define TB_KEY_CTRL_2 0x00 /* clash with 'CTRL_TILDE' */ |