To: vim_dev@googlegroups.com Subject: Patch 8.1.1885 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1885 Problem: Comments in libvterm are inconsistent. Solution: Use // comments. Als update the table of combining characters. Files: src/libvterm/bin/unterm.c, src/libvterm/bin/vterm-ctrl.c, src/libvterm/bin/vterm-dump.c, src/libvterm/include/vterm.h, src/libvterm/include/vterm_keycodes.h, src/libvterm/src/encoding.c, src/libvterm/src/keyboard.c, src/libvterm/src/mouse.c, src/libvterm/src/parser.c, src/libvterm/src/pen.c, src/libvterm/src/rect.h, src/libvterm/src/state.c, src/libvterm/src/unicode.c, src/libvterm/src/utf8.h, src/libvterm/src/vterm.c, src/libvterm/src/vterm_internal.h, src/libvterm/src/termscreen.c *** ../vim-8.1.1884/src/libvterm/bin/unterm.c 2018-04-24 17:46:22.000000000 +0200 --- src/libvterm/bin/unterm.c 2019-08-18 20:33:43.910266791 +0200 *************** *** 208,221 **** } static VTermScreenCallbacks cb_screen = { ! NULL, /* damage */ ! NULL, /* moverect */ ! NULL, /* movecursor */ ! NULL, /* settermprop */ ! NULL, /* bell */ ! &screen_resize, /* resize */ ! &screen_sb_pushline, /* sb_pushline */ ! NULL, /* popline */ }; int main(int argc, char *argv[]) --- 208,221 ---- } static VTermScreenCallbacks cb_screen = { ! NULL, // damage ! NULL, // moverect ! NULL, // movecursor ! NULL, // settermprop ! NULL, // bell ! &screen_resize, // resize ! &screen_sb_pushline, // sb_pushline ! NULL, // popline }; int main(int argc, char *argv[]) *** ../vim-8.1.1884/src/libvterm/bin/vterm-ctrl.c 2018-04-24 17:50:02.000000000 +0200 --- src/libvterm/bin/vterm-ctrl.c 2019-08-18 20:34:04.090193837 +0200 *************** *** 1,4 **** ! #define _XOPEN_SOURCE 500 /* strdup */ #include #include --- 1,4 ---- ! #define _XOPEN_SOURCE 500 // strdup #include #include *************** *** 86,92 **** { unsigned char c; ! /* await CSI - 8bit or 2byte 7bit form */ int in_esc = FALSE; while((c = getchar())) { if(c == c1) --- 86,92 ---- { unsigned char c; ! // await CSI - 8bit or 2byte 7bit form int in_esc = FALSE; while((c = getchar())) { if(c == c1) *************** *** 107,114 **** await_c1(0x9B); // CSI ! /* TODO: This really should be a more robust CSI parser ! */ for(; i < sizeof(csi)-1; i++) { int c = csi[i] = getchar(); if(c >= 0x40 && c <= 0x7e) --- 107,113 ---- await_c1(0x9B); // CSI ! // TODO: This really should be a more robust CSI parser for(; i < sizeof(csi)-1; i++) { int c = csi[i] = getchar(); if(c >= 0x40 && c <= 0x7e) *************** *** 175,186 **** free(s); s = read_csi(); ! /* expect "?" mode ";" value "$y" */ ! /* If the sscanf format string ends in a literal, we can't tell from ! * its return value if it matches. Hence we'll %c the cmd and check it ! * explicitly ! */ if(sscanf(s, "?%d;%d$%c", &reply_mode, &reply_value, &reply_cmd) < 3) continue; if(reply_cmd != 'y') --- 174,184 ---- free(s); s = read_csi(); ! // expect "?" mode ";" value "$y" ! // If the sscanf format string ends in a literal, we can't tell from ! // its return value if it matches. Hence we'll %c the cmd and check it ! // explicitly if(sscanf(s, "?%d;%d$%c", &reply_mode, &reply_value, &reply_cmd) < 3) continue; if(reply_cmd != 'y') *** ../vim-8.1.1884/src/libvterm/bin/vterm-dump.c 2018-04-24 17:51:44.000000000 +0200 --- src/libvterm/bin/vterm-dump.c 2019-08-18 20:34:55.594004679 +0200 *************** *** 21,27 **** unsigned char *b = (unsigned char *)bytes; int i; ! for(i = 0; i < len; /* none */) { if(b[i] < 0x20) // C0 break; else if(b[i] < 0x80) // ASCII --- 21,27 ---- unsigned char *b = (unsigned char *)bytes; int i; ! for(i = 0; i < len; ) { if(b[i] < 0x20) // C0 break; else if(b[i] < 0x80) // ASCII *************** *** 51,57 **** return i; } ! /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ static const char *name_c0[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "LS0", "LS1", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", --- 51,57 ---- return i; } ! // 0 1 2 3 4 5 6 7 8 9 A B C D E F static const char *name_c0[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", "BS", "HT", "LF", "VT", "FF", "CR", "LS0", "LS1", "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", *************** *** 91,104 **** return len; } ! /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ static const char *name_csi_plain[] = { "ICH", "CUU", "CUD", "CUF", "CUB", "CNL", "CPL", "CHA", "CUP", "CHT", "ED", "EL", "IL", "DL", "EF", "EA", "DCH", "SSE", "CPR", "SU", "SD", "NP", "PP", "CTC", "ECH", "CVT", "CBT", "SRS", "PTX", "SDS", "SIMD",NULL, "HPA", "HPR", "REP", "DA", "VPA", "VPR", "HVP", "TBC", "SM", "MC", "HPB", "VPB", "RM", "SGR", "DSR", "DAQ", }; ! /*0 4 8 B */ static const int newline_csi_plain[] = { 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, --- 91,104 ---- return len; } ! // 0 1 2 3 4 5 6 7 8 9 A B C D E F static const char *name_csi_plain[] = { "ICH", "CUU", "CUD", "CUF", "CUB", "CNL", "CPL", "CHA", "CUP", "CHT", "ED", "EL", "IL", "DL", "EF", "EA", "DCH", "SSE", "CPR", "SU", "SD", "NP", "PP", "CTC", "ECH", "CVT", "CBT", "SRS", "PTX", "SDS", "SIMD",NULL, "HPA", "HPR", "REP", "DA", "VPA", "VPR", "HVP", "TBC", "SM", "MC", "HPB", "VPB", "RM", "SGR", "DSR", "DAQ", }; ! //0 4 8 B static const int newline_csi_plain[] = { 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, *************** *** 111,117 **** if(!leader && !intermed && command < 0x70) name = name_csi_plain[command - 0x40]; else if(leader && streq(leader, "?") && !intermed) { ! /* DEC */ switch(command) { case 'h': name = "DECSM"; break; case 'l': name = "DECRM"; break; --- 111,117 ---- if(!leader && !intermed && command < 0x70) name = name_csi_plain[command - 0x40]; else if(leader && streq(leader, "?") && !intermed) { ! // DEC switch(command) { case 'h': name = "DECSM"; break; case 'l': name = "DECRM"; break; *************** *** 172,184 **** } static VTermParserCallbacks parser_cbs = { ! &parser_text, /* text */ ! &parser_control, /* control */ ! &parser_escape, /* escape */ ! &parser_csi, /* csi */ ! &parser_osc, /* osc */ ! &parser_dcs, /* dcs */ ! NULL /* resize */ }; int main(int argc, char *argv[]) --- 172,184 ---- } static VTermParserCallbacks parser_cbs = { ! &parser_text, // text ! &parser_control, // control ! &parser_escape, // escape ! &parser_csi, // csi ! &parser_osc, // osc ! &parser_dcs, // dcs ! NULL // resize }; int main(int argc, char *argv[]) *************** *** 214,220 **** special_end = "}\x1b[m"; } ! /* Size matters not for the parser */ vt = vterm_new(25, 80); vterm_set_utf8(vt, 1); vterm_parser_set_callbacks(vt, &parser_cbs, NULL); --- 214,220 ---- special_end = "}\x1b[m"; } ! // Size matters not for the parser vt = vterm_new(25, 80); vterm_set_utf8(vt, 1); vterm_parser_set_callbacks(vt, &parser_cbs, NULL); *** ../vim-8.1.1884/src/libvterm/include/vterm.h 2018-04-24 17:55:28.000000000 +0200 --- src/libvterm/include/vterm.h 2019-08-18 20:39:15.732994566 +0200 *************** *** 15,21 **** #define TRUE 1 #define FALSE 0 ! /* from stdint.h */ typedef unsigned char uint8_t; typedef unsigned int uint32_t; --- 15,21 ---- #define TRUE 1 #define FALSE 0 ! // from stdint.h typedef unsigned char uint8_t; typedef unsigned int uint32_t; *************** *** 23,29 **** typedef struct VTermState VTermState; typedef struct VTermScreen VTermScreen; ! /* Specifies a screen point. */ typedef struct { int row; int col; --- 23,29 ---- typedef struct VTermState VTermState; typedef struct VTermScreen VTermScreen; ! // Specifies a screen point. typedef struct { int row; int col; *************** *** 48,54 **** } #endif ! /* Specifies a rectangular screen area. */ typedef struct { int start_row; int end_row; --- 48,54 ---- } #endif ! // Specifies a rectangular screen area. typedef struct { int start_row; int end_row; *************** *** 56,62 **** int end_col; } VTermRect; ! /* Return true if the rect "r" contains the point "p". */ int vterm_rect_contains(VTermRect r, VTermPos p); #if defined(DEFINE_INLINES) || USE_INLINE --- 56,62 ---- int end_col; } VTermRect; ! // Return true if the rect "r" contains the point "p". int vterm_rect_contains(VTermRect r, VTermPos p); #if defined(DEFINE_INLINES) || USE_INLINE *************** *** 67,74 **** } #endif ! /* Move "rect" "row_delta" down and "col_delta" right. ! * Does not check boundaries. */ void vterm_rect_move(VTermRect *rect, int row_delta, int col_delta); #if defined(DEFINE_INLINES) || USE_INLINE --- 67,74 ---- } #endif ! // Move "rect" "row_delta" down and "col_delta" right. ! // Does not check boundaries. void vterm_rect_move(VTermRect *rect, int row_delta, int col_delta); #if defined(DEFINE_INLINES) || USE_INLINE *************** *** 79,90 **** } #endif ! /* The ansi_index is used for the lower 16 colors, which can be set to any ! * color. */ ! #define VTERM_ANSI_INDEX_DEFAULT 0 /* color cleared */ #define VTERM_ANSI_INDEX_MIN 1 #define VTERM_ANSI_INDEX_MAX 16 ! #define VTERM_ANSI_INDEX_NONE 255 /* non-ANSI color, use red/green/blue */ typedef struct { uint8_t red, green, blue; --- 79,90 ---- } #endif ! // The ansi_index is used for the lower 16 colors, which can be set to any ! // color. ! #define VTERM_ANSI_INDEX_DEFAULT 0 // color cleared #define VTERM_ANSI_INDEX_MIN 1 #define VTERM_ANSI_INDEX_MAX 16 ! #define VTERM_ANSI_INDEX_NONE 255 // non-ANSI color, use red/green/blue typedef struct { uint8_t red, green, blue; *************** *** 92,98 **** } VTermColor; typedef enum { ! /* VTERM_VALUETYPE_NONE = 0 */ VTERM_VALUETYPE_BOOL = 1, VTERM_VALUETYPE_INT, VTERM_VALUETYPE_STRING, --- 92,98 ---- } VTermColor; typedef enum { ! // VTERM_VALUETYPE_NONE = 0 VTERM_VALUETYPE_BOOL = 1, VTERM_VALUETYPE_INT, VTERM_VALUETYPE_STRING, *************** *** 109,115 **** } VTermValue; typedef enum { ! /* VTERM_ATTR_NONE = 0 */ VTERM_ATTR_BOLD = 1, // bool: 1, 22 VTERM_ATTR_UNDERLINE, // number: 4, 21, 24 VTERM_ATTR_ITALIC, // bool: 3, 23 --- 109,115 ---- } VTermValue; typedef enum { ! // VTERM_ATTR_NONE = 0 VTERM_ATTR_BOLD = 1, // bool: 1, 22 VTERM_ATTR_UNDERLINE, // number: 4, 21, 24 VTERM_ATTR_ITALIC, // bool: 3, 23 *************** *** 124,130 **** } VTermAttr; typedef enum { ! /* VTERM_PROP_NONE = 0 */ VTERM_PROP_CURSORVISIBLE = 1, // bool VTERM_PROP_CURSORBLINK, // bool VTERM_PROP_ALTSCREEN, // bool --- 124,130 ---- } VTermAttr; typedef enum { ! // VTERM_PROP_NONE = 0 VTERM_PROP_CURSORVISIBLE = 1, // bool VTERM_PROP_CURSORBLINK, // bool VTERM_PROP_ALTSCREEN, // bool *************** *** 158,190 **** typedef struct { const uint32_t *chars; int width; ! unsigned int protected_cell:1; /* DECSCA-protected against DECSEL/DECSED */ ! unsigned int dwl:1; /* DECDWL or DECDHL double-width line */ ! unsigned int dhl:2; /* DECDHL double-height line (1=top 2=bottom) */ } VTermGlyphInfo; typedef struct { ! unsigned int doublewidth:1; /* DECDWL or DECDHL line */ ! unsigned int doubleheight:2; /* DECDHL line (1=top 2=bottom) */ } VTermLineInfo; typedef struct { ! /* libvterm relies on the allocated memory to be zeroed out before it is ! * returned by the allocator. */ void *(*malloc)(size_t size, void *allocdata); void (*free)(void *ptr, void *allocdata); } VTermAllocatorFunctions; ! /* Allocate and initialize a new terminal with default allocators. */ VTerm *vterm_new(int rows, int cols); ! /* Allocate and initialize a new terminal with specified allocators. */ VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata); ! /* Free and cleanup a terminal and all its data. */ void vterm_free(VTerm* vt); ! /* Get the current size of the terminal and store in "rowsp" and "colsp". */ void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp); void vterm_set_size(VTerm *vt, int rows, int cols); --- 158,190 ---- typedef struct { const uint32_t *chars; int width; ! unsigned int protected_cell:1; // DECSCA-protected against DECSEL/DECSED ! unsigned int dwl:1; // DECDWL or DECDHL double-width line ! unsigned int dhl:2; // DECDHL double-height line (1=top 2=bottom) } VTermGlyphInfo; typedef struct { ! unsigned int doublewidth:1; // DECDWL or DECDHL line ! unsigned int doubleheight:2; // DECDHL line (1=top 2=bottom) } VTermLineInfo; typedef struct { ! // libvterm relies on the allocated memory to be zeroed out before it is ! // returned by the allocator. void *(*malloc)(size_t size, void *allocdata); void (*free)(void *ptr, void *allocdata); } VTermAllocatorFunctions; ! // Allocate and initialize a new terminal with default allocators. VTerm *vterm_new(int rows, int cols); ! // Allocate and initialize a new terminal with specified allocators. VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata); ! // Free and cleanup a terminal and all its data. void vterm_free(VTerm* vt); ! // Get the current size of the terminal and store in "rowsp" and "colsp". void vterm_get_size(const VTerm *vt, int *rowsp, int *colsp); void vterm_set_size(VTerm *vt, int rows, int cols); *************** *** 207,214 **** void vterm_keyboard_end_paste(VTerm *vt); void vterm_mouse_move(VTerm *vt, int row, int col, VTermModifier mod); ! /* "button" is 1 for left, 2 for middle, 3 for right. ! * Button 4 is scroll wheel down, button 5 is scroll wheel up. */ void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod); // ------------ --- 207,214 ---- void vterm_keyboard_end_paste(VTerm *vt); void vterm_mouse_move(VTerm *vt, int row, int col, VTermModifier mod); ! // "button" is 1 for left, 2 for middle, 3 for right. ! // Button 4 is scroll wheel down, button 5 is scroll wheel up. void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod); // ------------ *************** *** 229,235 **** #define CSI_ARG_HAS_MORE(a) ((a) & CSI_ARG_FLAG_MORE) #define CSI_ARG(a) ((a) & CSI_ARG_MASK) ! /* Can't use -1 to indicate a missing argument; use this instead */ #define CSI_ARG_MISSING ((1<<30)-1) #define CSI_ARG_IS_MISSING(a) (CSI_ARG(a) == CSI_ARG_MISSING) --- 229,235 ---- #define CSI_ARG_HAS_MORE(a) ((a) & CSI_ARG_FLAG_MORE) #define CSI_ARG(a) ((a) & CSI_ARG_MASK) ! // Can't use -1 to indicate a missing argument; use this instead #define CSI_ARG_MISSING ((1<<30)-1) #define CSI_ARG_IS_MISSING(a) (CSI_ARG(a) == CSI_ARG_MISSING) *************** *** 261,268 **** int (*erase)(VTermRect rect, int selective, void *user); int (*initpen)(void *user); int (*setpenattr)(VTermAttr attr, VTermValue *val, void *user); ! /* Callback for setting various properties. Must return 1 if the property ! * was accepted, 0 otherwise. */ int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); int (*resize)(int rows, int cols, VTermPos *delta, void *user); --- 261,268 ---- int (*erase)(VTermRect rect, int selective, void *user); int (*initpen)(void *user); int (*setpenattr)(VTermAttr attr, VTermValue *val, void *user); ! // Callback for setting various properties. Must return 1 if the property ! // was accepted, 0 otherwise. int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); int (*resize)(int rows, int cols, VTermPos *delta, void *user); *************** *** 279,285 **** #define MOUSE_WANT_CLICK 0x01 #define MOUSE_WANT_DRAG 0x02 #define MOUSE_WANT_MOVE 0x04 ! /* useful to add protocol? */ } VTermMouseState; VTermState *vterm_obtain_state(VTerm *vt); --- 279,285 ---- #define MOUSE_WANT_CLICK 0x01 #define MOUSE_WANT_DRAG 0x02 #define MOUSE_WANT_MOVE 0x04 ! // useful to add protocol? } VTermMouseState; VTermState *vterm_obtain_state(VTerm *vt); *************** *** 291,297 **** void vterm_state_set_unrecognised_fallbacks(VTermState *state, const VTermParserCallbacks *fallbacks, void *user); void *vterm_state_get_unrecognised_fbdata(VTermState *state); ! /* Initialize the state. */ void vterm_state_reset(VTermState *state, int hard); void vterm_state_get_cursorpos(const VTermState *state, VTermPos *cursorpos); --- 291,297 ---- void vterm_state_set_unrecognised_fallbacks(VTermState *state, const VTermParserCallbacks *fallbacks, void *user); void *vterm_state_get_unrecognised_fbdata(VTermState *state); ! // Initialize the state. void vterm_state_reset(VTermState *state, int hard); void vterm_state_get_cursorpos(const VTermState *state, VTermPos *cursorpos); *************** *** 318,326 **** unsigned int blink : 1; unsigned int reverse : 1; unsigned int strike : 1; ! unsigned int font : 4; /* 0 to 9 */ ! unsigned int dwl : 1; /* On a DECDWL or DECDHL line */ ! unsigned int dhl : 2; /* On a DECDHL line (1=top 2=bottom) */ } VTermScreenCellAttrs; typedef struct { --- 318,326 ---- unsigned int blink : 1; unsigned int reverse : 1; unsigned int strike : 1; ! unsigned int font : 4; // 0 to 9 ! unsigned int dwl : 1; // On a DECDWL or DECDHL line ! unsigned int dhl : 2; // On a DECDHL line (1=top 2=bottom) } VTermScreenCellAttrs; typedef struct { *************** *** 331,337 **** VTermColor fg, bg; } VTermScreenCell; ! /* All fields are optional, NULL when not used. */ typedef struct { int (*damage)(VTermRect rect, void *user); int (*moverect)(VTermRect dest, VTermRect src, void *user); --- 331,337 ---- VTermColor fg, bg; } VTermScreenCell; ! // All fields are optional, NULL when not used. typedef struct { int (*damage)(VTermRect rect, void *user); int (*moverect)(VTermRect dest, VTermRect src, void *user); *************** *** 339,352 **** int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); int (*resize)(int rows, int cols, void *user); ! /* A line was pushed off the top of the window. ! * "cells[cols]" contains the cells of that line. ! * Return value is unused. */ int (*sb_pushline)(int cols, const VTermScreenCell *cells, void *user); int (*sb_popline)(int cols, VTermScreenCell *cells, void *user); } VTermScreenCallbacks; ! /* Return the screen of the vterm. */ VTermScreen *vterm_obtain_screen(VTerm *vt); /* --- 339,352 ---- int (*settermprop)(VTermProp prop, VTermValue *val, void *user); int (*bell)(void *user); int (*resize)(int rows, int cols, void *user); ! // A line was pushed off the top of the window. ! // "cells[cols]" contains the cells of that line. ! // Return value is unused. int (*sb_pushline)(int cols, const VTermScreenCell *cells, void *user); int (*sb_popline)(int cols, VTermScreenCell *cells, void *user); } VTermScreenCallbacks; ! // Return the screen of the vterm. VTermScreen *vterm_obtain_screen(VTerm *vt); /* *************** *** 356,380 **** void vterm_screen_set_callbacks(VTermScreen *screen, const VTermScreenCallbacks *callbacks, void *user); void *vterm_screen_get_cbdata(VTermScreen *screen); ! // Only invokes control, csi, osc, dcs void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermParserCallbacks *fallbacks, void *user); void *vterm_screen_get_unrecognised_fbdata(VTermScreen *screen); ! /* Enable support for using the alternate screen if "altscreen" is non-zero. ! * Before that switching to the alternate screen won't work. ! * Calling with "altscreen" zero has no effect. */ void vterm_screen_enable_altscreen(VTermScreen *screen, int altscreen); typedef enum { ! VTERM_DAMAGE_CELL, /* every cell */ ! VTERM_DAMAGE_ROW, /* entire rows */ ! VTERM_DAMAGE_SCREEN, /* entire screen */ ! VTERM_DAMAGE_SCROLL, /* entire screen + scrollrect */ VTERM_N_DAMAGES } VTermDamageSize; ! /* Invoke the relevant callbacks to update the screen. */ void vterm_screen_flush_damage(VTermScreen *screen); void vterm_screen_set_damage_merge(VTermScreen *screen, VTermDamageSize size); --- 356,380 ---- void vterm_screen_set_callbacks(VTermScreen *screen, const VTermScreenCallbacks *callbacks, void *user); void *vterm_screen_get_cbdata(VTermScreen *screen); ! /* Only invokes control, csi, osc, dcs */ void vterm_screen_set_unrecognised_fallbacks(VTermScreen *screen, const VTermParserCallbacks *fallbacks, void *user); void *vterm_screen_get_unrecognised_fbdata(VTermScreen *screen); ! // Enable support for using the alternate screen if "altscreen" is non-zero. ! // Before that switching to the alternate screen won't work. ! // Calling with "altscreen" zero has no effect. void vterm_screen_enable_altscreen(VTermScreen *screen, int altscreen); typedef enum { ! VTERM_DAMAGE_CELL, // every cell ! VTERM_DAMAGE_ROW, // entire rows ! VTERM_DAMAGE_SCREEN, // entire screen ! VTERM_DAMAGE_SCROLL, // entire screen + scrollrect VTERM_N_DAMAGES } VTermDamageSize; ! // Invoke the relevant callbacks to update the screen. void vterm_screen_flush_damage(VTermScreen *screen); void vterm_screen_set_damage_merge(VTermScreen *screen, VTermDamageSize size); *************** *** 385,391 **** */ void vterm_screen_reset(VTermScreen *screen, int hard); ! /* Neither of these functions NUL-terminate the buffer */ size_t vterm_screen_get_chars(const VTermScreen *screen, uint32_t *chars, size_t len, const VTermRect rect); size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, const VTermRect rect); --- 385,391 ---- */ void vterm_screen_reset(VTermScreen *screen, int hard); ! // Neither of these functions NUL-terminate the buffer size_t vterm_screen_get_chars(const VTermScreen *screen, uint32_t *chars, size_t len, const VTermRect rect); size_t vterm_screen_get_text(const VTermScreen *screen, char *str, size_t len, const VTermRect rect); *** ../vim-8.1.1884/src/libvterm/include/vterm_keycodes.h 2018-04-24 17:56:28.000000000 +0200 --- src/libvterm/include/vterm_keycodes.h 2019-08-18 20:16:39.287915036 +0200 *************** *** 7,16 **** VTERM_MOD_ALT = 0x02, VTERM_MOD_CTRL = 0x04, ! VTERM_ALL_MODS_MASK = 0x07 } VTermModifier; ! /* The order here must match keycodes[] in src/keyboard.c! */ typedef enum { VTERM_KEY_NONE, --- 7,16 ---- VTERM_MOD_ALT = 0x02, VTERM_MOD_CTRL = 0x04, ! VTERM_ALL_MODS_MASK = 0x07 } VTermModifier; ! // The order here must match keycodes[] in src/keyboard.c! typedef enum { VTERM_KEY_NONE, *************** *** 31,41 **** VTERM_KEY_PAGEUP, VTERM_KEY_PAGEDOWN, ! /* F1 is VTERM_KEY_FUNCTION(1), F2 VTERM_KEY_FUNCTION(2), etc. */ VTERM_KEY_FUNCTION_0 = 256, VTERM_KEY_FUNCTION_MAX = VTERM_KEY_FUNCTION_0 + 255, ! /* keypad keys */ VTERM_KEY_KP_0, VTERM_KEY_KP_1, VTERM_KEY_KP_2, --- 31,41 ---- VTERM_KEY_PAGEUP, VTERM_KEY_PAGEDOWN, ! // F1 is VTERM_KEY_FUNCTION(1), F2 VTERM_KEY_FUNCTION(2), etc. VTERM_KEY_FUNCTION_0 = 256, VTERM_KEY_FUNCTION_MAX = VTERM_KEY_FUNCTION_0 + 255, ! // keypad keys VTERM_KEY_KP_0, VTERM_KEY_KP_1, VTERM_KEY_KP_2, *** ../vim-8.1.1884/src/libvterm/src/encoding.c 2018-04-24 17:58:04.000000000 +0200 --- src/libvterm/src/encoding.c 2019-08-18 20:16:59.199956129 +0200 *************** *** 157,164 **** } static VTermEncoding encoding_utf8 = { ! &init_utf8, /* init */ ! &decode_utf8 /* decode */ }; static void decode_usascii(VTermEncoding *enc UNUSED, void *data UNUSED, --- 157,164 ---- } static VTermEncoding encoding_utf8 = { ! &init_utf8, // init ! &decode_utf8 // decode }; static void decode_usascii(VTermEncoding *enc UNUSED, void *data UNUSED, *************** *** 178,185 **** } static VTermEncoding encoding_usascii = { ! NULL, /* init */ ! &decode_usascii /* decode */ }; struct StaticTableEncoding { --- 178,185 ---- } static VTermEncoding encoding_usascii = { ! NULL, // init ! &decode_usascii // decode }; struct StaticTableEncoding { *************** *** 223,229 **** { 0, 0, NULL }, }; ! /* This ought to be INTERNAL but isn't because it's used by unit testing */ VTermEncoding *vterm_lookup_encoding(VTermEncodingType type, char designation) { int i; --- 223,229 ---- { 0, 0, NULL }, }; ! // This ought to be INTERNAL but isn't because it's used by unit testing VTermEncoding *vterm_lookup_encoding(VTermEncodingType type, char designation) { int i; *** ../vim-8.1.1884/src/libvterm/src/keyboard.c 2018-04-24 18:01:25.000000000 +0200 --- src/libvterm/src/keyboard.c 2019-08-18 20:17:21.875996877 +0200 *************** *** 8,16 **** { int needs_CSIu; ! /* The shift modifier is never important for Unicode characters ! * apart from Space ! */ if(c != ' ') mod &= ~VTERM_MOD_SHIFT; --- 8,15 ---- { int needs_CSIu; ! // The shift modifier is never important for Unicode characters ! // apart from Space if(c != ' ') mod &= ~VTERM_MOD_SHIFT; *************** *** 23,46 **** } switch(c) { ! /* Special Ctrl- letters that can't be represented elsewise */ case 'i': case 'j': case 'm': case '[': needs_CSIu = 1; break; ! /* Ctrl-\ ] ^ _ don't need CSUu */ case '\\': case ']': case '^': case '_': needs_CSIu = 0; break; ! /* Shift-space needs CSIu */ case ' ': needs_CSIu = !!(mod & VTERM_MOD_SHIFT); break; ! /* All other characters needs CSIu except for letters a-z */ default: needs_CSIu = (c < 'a' || c > 'z'); } ! /* ALT we can just prefix with ESC; anything else requires CSI u */ if(needs_CSIu && (mod & ~VTERM_MOD_ALT)) { vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", c, mod+1); return; --- 22,45 ---- } switch(c) { ! // Special Ctrl- letters that can't be represented elsewise case 'i': case 'j': case 'm': case '[': needs_CSIu = 1; break; ! // Ctrl-\ ] ^ _ don't need CSUu case '\\': case ']': case '^': case '_': needs_CSIu = 0; break; ! // Shift-space needs CSIu case ' ': needs_CSIu = !!(mod & VTERM_MOD_SHIFT); break; ! // All other characters needs CSIu except for letters a-z default: needs_CSIu = (c < 'a' || c > 'z'); } ! // ALT we can just prefix with ESC; anything else requires CSI u if(needs_CSIu && (mod & ~VTERM_MOD_ALT)) { vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", c, mod+1); return; *************** *** 68,74 **** int csinum; } keycodes_s; ! /* Order here must be exactly the same as VTermKey enum! */ static keycodes_s keycodes[] = { { KEYCODE_NONE, 0, 0 }, // NONE --- 67,73 ---- int csinum; } keycodes_s; ! // Order here must be exactly the same as VTermKey enum! static keycodes_s keycodes[] = { { KEYCODE_NONE, 0, 0 }, // NONE *************** *** 155,161 **** break; case KEYCODE_TAB: ! /* Shift-Tab is CSI Z but plain Tab is 0x09 */ if(mod == VTERM_MOD_SHIFT) vterm_push_output_sprintf_ctrl(vt, C1_CSI, "Z"); else if(mod & VTERM_MOD_SHIFT) --- 154,160 ---- break; case KEYCODE_TAB: ! // Shift-Tab is CSI Z but plain Tab is 0x09 if(mod == VTERM_MOD_SHIFT) vterm_push_output_sprintf_ctrl(vt, C1_CSI, "Z"); else if(mod & VTERM_MOD_SHIFT) *************** *** 165,171 **** break; case KEYCODE_ENTER: ! /* Enter is CRLF in newline mode, but just LF in linefeed */ if(vt->state->mode.newline) vterm_push_output_sprintf(vt, "\r\n"); else --- 164,170 ---- break; case KEYCODE_ENTER: ! // Enter is CRLF in newline mode, but just LF in linefeed if(vt->state->mode.newline) vterm_push_output_sprintf(vt, "\r\n"); else *** ../vim-8.1.1884/src/libvterm/src/mouse.c 2018-03-11 17:55:59.000000000 +0100 --- src/libvterm/src/mouse.c 2019-08-18 20:17:31.268011922 +0200 *************** *** 83,89 **** state->mouse_buttons &= ~(1 << (button-1)); } ! /* Most of the time we don't get button releases from 4/5 */ if(state->mouse_buttons == old_buttons && button < 4) return; if (!(state->mouse_flags & MOUSE_WANT_CLICK)) --- 83,89 ---- state->mouse_buttons &= ~(1 << (button-1)); } ! // Most of the time we don't get button releases from 4/5 if(state->mouse_buttons == old_buttons && button < 4) return; if (!(state->mouse_flags & MOUSE_WANT_CLICK)) *** ../vim-8.1.1884/src/libvterm/src/parser.c 2018-04-24 18:03:23.000000000 +0200 --- src/libvterm/src/parser.c 2019-08-18 20:17:49.092037648 +0200 *************** *** 125,131 **** size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len) { size_t pos = 0; ! const char *string_start = NULL; /* init to avoid gcc warning */ switch(vt->parser.state) { case NORMAL: --- 125,131 ---- size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len) { size_t pos = 0; ! const char *string_start = NULL; // init to avoid gcc warning switch(vt->parser.state) { case NORMAL: *************** *** 226,248 **** break; case CSI_LEADER: ! /* Extract leader bytes 0x3c to 0x3f */ if(c >= 0x3c && c <= 0x3f) { if(vt->parser.csi_leaderlen < CSI_LEADER_MAX-1) vt->parser.csi_leader[vt->parser.csi_leaderlen++] = c; break; } ! /* else fallthrough */ vt->parser.csi_leader[vt->parser.csi_leaderlen] = 0; vt->parser.csi_argi = 0; vt->parser.csi_args[0] = CSI_ARG_MISSING; vt->parser.state = CSI_ARGS; ! /* fallthrough */ case CSI_ARGS: ! /* Numerical value of argument */ if(c >= '0' && c <= '9') { if(vt->parser.csi_args[vt->parser.csi_argi] == CSI_ARG_MISSING) vt->parser.csi_args[vt->parser.csi_argi] = 0; --- 226,248 ---- break; case CSI_LEADER: ! // Extract leader bytes 0x3c to 0x3f if(c >= 0x3c && c <= 0x3f) { if(vt->parser.csi_leaderlen < CSI_LEADER_MAX-1) vt->parser.csi_leader[vt->parser.csi_leaderlen++] = c; break; } ! // else fallthrough vt->parser.csi_leader[vt->parser.csi_leaderlen] = 0; vt->parser.csi_argi = 0; vt->parser.csi_args[0] = CSI_ARG_MISSING; vt->parser.state = CSI_ARGS; ! // fallthrough case CSI_ARGS: ! // Numerical value of argument if(c >= '0' && c <= '9') { if(vt->parser.csi_args[vt->parser.csi_argi] == CSI_ARG_MISSING) vt->parser.csi_args[vt->parser.csi_argi] = 0; *************** *** 260,270 **** break; } ! /* else fallthrough */ vt->parser.csi_argi++; vt->parser.intermedlen = 0; vt->parser.state = CSI_INTERMED; ! /* fallthrough */ case CSI_INTERMED: if(is_intermed(c)) { if(vt->parser.intermedlen < INTERMED_MAX-1) --- 260,270 ---- break; } ! // else fallthrough vt->parser.csi_argi++; vt->parser.intermedlen = 0; vt->parser.state = CSI_INTERMED; ! // fallthrough case CSI_INTERMED: if(is_intermed(c)) { if(vt->parser.intermedlen < INTERMED_MAX-1) *************** *** 272,284 **** break; } else if(c == 0x1b) { ! /* ESC in CSI cancels */ } else if(c >= 0x40 && c <= 0x7e) { vt->parser.intermed[vt->parser.intermedlen] = 0; do_csi(vt, c); } ! /* else was invalid CSI */ ENTER_NORMAL_STATE(); break; --- 272,284 ---- break; } else if(c == 0x1b) { ! // ESC in CSI cancels } else if(c >= 0x40 && c <= 0x7e) { vt->parser.intermed[vt->parser.intermedlen] = 0; do_csi(vt, c); } ! // else was invalid CSI ENTER_NORMAL_STATE(); break; *************** *** 289,296 **** ENTER_NORMAL_STATE(); } else if (pos + 1 == len) { ! /* end of input but OSC string isn't finished yet, copy it to ! * vt->parser.strbuffer to continue it later */ more_string(vt, string_start, bytes + pos + 1 - string_start); } break; --- 289,296 ---- ENTER_NORMAL_STATE(); } else if (pos + 1 == len) { ! // end of input but OSC string isn't finished yet, copy it to ! // vt->parser.strbuffer to continue it later more_string(vt, string_start, bytes + pos + 1 - string_start); } break; *************** *** 321,327 **** if(!eaten) { DEBUG_LOG("libvterm: Text callback did not consume any input\n"); ! /* force it to make progress */ eaten = 1; } --- 321,327 ---- if(!eaten) { DEBUG_LOG("libvterm: Text callback did not consume any input\n"); ! // force it to make progress eaten = 1; } *** ../vim-8.1.1884/src/libvterm/src/pen.c 2019-03-30 18:46:57.356077354 +0100 --- src/libvterm/src/pen.c 2019-08-18 20:18:35.224087648 +0200 *************** *** 3,9 **** #include static const VTermColor ansi_colors[] = { ! /* R G B index */ { 0, 0, 0, 1 }, // black { 224, 0, 0, 2 }, // red { 0, 224, 0, 3 }, // green --- 3,9 ---- #include static const VTermColor ansi_colors[] = { ! // R G B index { 0, 0, 0, 1 }, // black { 224, 0, 0, 2 }, // red { 0, 224, 0, 3 }, // green *************** *** 28,34 **** 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF, }; ! /* Use 0x81 instead of 0x80 to be able to distinguish from ansi black */ static int ramp24[] = { 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76, 0x81, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE, --- 28,34 ---- 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF, }; ! // Use 0x81 instead of 0x80 to be able to distinguish from ansi black static int ramp24[] = { 0x08, 0x12, 0x1C, 0x26, 0x30, 0x3A, 0x44, 0x4E, 0x58, 0x62, 0x6C, 0x76, 0x81, 0x8A, 0x94, 0x9E, 0xA8, 0xB2, 0xBC, 0xC6, 0xD0, 0xDA, 0xE4, 0xEE, *** ../vim-8.1.1884/src/libvterm/src/rect.h 2017-06-30 20:59:02.000000000 +0200 --- src/libvterm/src/rect.h 2019-08-18 20:14:29.568412784 +0200 *************** *** 5,11 **** #define STRFrect "(%d,%d-%d,%d)" #define ARGSrect(r) (r).start_row, (r).start_col, (r).end_row, (r).end_col ! /* Expand dst to contain src as well */ static void rect_expand(VTermRect *dst, VTermRect *src) { if(dst->start_row > src->start_row) dst->start_row = src->start_row; --- 5,11 ---- #define STRFrect "(%d,%d-%d,%d)" #define ARGSrect(r) (r).start_row, (r).start_col, (r).end_row, (r).end_col ! // Expand dst to contain src as well static void rect_expand(VTermRect *dst, VTermRect *src) { if(dst->start_row > src->start_row) dst->start_row = src->start_row; *************** *** 14,32 **** if(dst->end_col < src->end_col) dst->end_col = src->end_col; } ! /* Clip the dst to ensure it does not step outside of bounds */ static void rect_clip(VTermRect *dst, VTermRect *bounds) { if(dst->start_row < bounds->start_row) dst->start_row = bounds->start_row; if(dst->start_col < bounds->start_col) dst->start_col = bounds->start_col; if(dst->end_row > bounds->end_row) dst->end_row = bounds->end_row; if(dst->end_col > bounds->end_col) dst->end_col = bounds->end_col; ! /* Ensure it doesn't end up negatively-sized */ if(dst->end_row < dst->start_row) dst->end_row = dst->start_row; if(dst->end_col < dst->start_col) dst->end_col = dst->start_col; } ! /* True if the two rectangles are equal */ static int rect_equal(VTermRect *a, VTermRect *b) { return (a->start_row == b->start_row) && --- 14,32 ---- if(dst->end_col < src->end_col) dst->end_col = src->end_col; } ! // Clip the dst to ensure it does not step outside of bounds static void rect_clip(VTermRect *dst, VTermRect *bounds) { if(dst->start_row < bounds->start_row) dst->start_row = bounds->start_row; if(dst->start_col < bounds->start_col) dst->start_col = bounds->start_col; if(dst->end_row > bounds->end_row) dst->end_row = bounds->end_row; if(dst->end_col > bounds->end_col) dst->end_col = bounds->end_col; ! // Ensure it doesn't end up negatively-sized if(dst->end_row < dst->start_row) dst->end_row = dst->start_row; if(dst->end_col < dst->start_col) dst->end_col = dst->start_col; } ! // True if the two rectangles are equal static int rect_equal(VTermRect *a, VTermRect *b) { return (a->start_row == b->start_row) && *************** *** 35,41 **** (a->end_col == b->end_col); } ! /* True if small is contained entirely within big */ static int rect_contains(VTermRect *big, VTermRect *small) { if(small->start_row < big->start_row) return 0; --- 35,41 ---- (a->end_col == b->end_col); } ! // True if small is contained entirely within big static int rect_contains(VTermRect *big, VTermRect *small) { if(small->start_row < big->start_row) return 0; *************** *** 45,51 **** return 1; } ! /* True if the rectangles overlap at all */ static int rect_intersects(VTermRect *a, VTermRect *b) { if(a->start_row > b->end_row || b->start_row > a->end_row) --- 45,51 ---- return 1; } ! // True if the rectangles overlap at all static int rect_intersects(VTermRect *a, VTermRect *b) { if(a->start_row > b->end_row || b->start_row > a->end_row) *** ../vim-8.1.1884/src/libvterm/src/state.c 2019-04-27 22:44:57.226305660 +0200 --- src/libvterm/src/state.c 2019-08-18 20:28:45.771242550 +0200 *************** *** 11,17 **** static int on_resize(int rows, int cols, void *user); ! /* Some convenient wrappers to make callback functions easier */ static void putglyph(VTermState *state, const uint32_t chars[], int width, VTermPos pos) { --- 11,17 ---- static int on_resize(int rows, int cols, void *user); ! // Some convenient wrappers to make callback functions easier static void putglyph(VTermState *state, const uint32_t chars[], int width, VTermPos pos) { *************** *** 266,274 **** codepoints, &npoints, state->gsingle_set ? 1 : (int)len, bytes, &eaten, len); ! /* There's a chance an encoding (e.g. UTF-8) hasn't found enough bytes yet ! * for even a single codepoint ! */ if(!npoints) { vterm_allocator_free(state->vt, codepoints); --- 266,273 ---- codepoints, &npoints, state->gsingle_set ? 1 : (int)len, bytes, &eaten, len); ! // There's a chance an encoding (e.g. UTF-8) hasn't found enough bytes yet ! // for even a single codepoint if(!npoints) { vterm_allocator_free(state->vt, codepoints); *************** *** 278,287 **** if(state->gsingle_set && npoints) state->gsingle_set = 0; ! /* This is a combining char. that needs to be merged with the previous ! * glyph output */ if(vterm_unicode_is_combining(codepoints[i])) { ! /* See if the cursor has moved since */ if(state->pos.row == state->combine_pos.row && state->pos.col == state->combine_pos.col + state->combine_width) { #ifdef DEBUG_GLYPH_COMBINE int printpos; --- 277,286 ---- if(state->gsingle_set && npoints) state->gsingle_set = 0; ! // This is a combining char. that needs to be merged with the previous ! // glyph output if(vterm_unicode_is_combining(codepoints[i])) { ! // See if the cursor has moved since if(state->pos.row == state->combine_pos.row && state->pos.col == state->combine_pos.col + state->combine_width) { #ifdef DEBUG_GLYPH_COMBINE int printpos; *************** *** 291,302 **** printf("} + {"); #endif ! /* Find where we need to append these combining chars */ int saved_i = 0; while(state->combine_chars[saved_i]) saved_i++; ! /* Add extra ones */ while(i < npoints && vterm_unicode_is_combining(codepoints[i])) { if(saved_i >= (int)state->combine_chars_size) grow_combine_buffer(state); --- 290,301 ---- printf("} + {"); #endif ! // Find where we need to append these combining chars int saved_i = 0; while(state->combine_chars[saved_i]) saved_i++; ! // Add extra ones while(i < npoints && vterm_unicode_is_combining(codepoints[i])) { if(saved_i >= (int)state->combine_chars_size) grow_combine_buffer(state); *************** *** 312,318 **** printf("}\n"); #endif ! /* Now render it */ putglyph(state, state->combine_chars, state->combine_width, state->combine_pos); } else { --- 311,317 ---- printf("}\n"); #endif ! // Now render it putglyph(state, state->combine_chars, state->combine_width, state->combine_pos); } else { *************** *** 366,375 **** } if(state->mode.insert) { ! /* TODO: This will be a little inefficient for large bodies of text, as ! * it'll have to 'ICH' effectively before every glyph. We should scan ! * ahead and ICH as many times as required ! */ VTermRect rect; rect.start_row = state->pos.row; rect.end_row = state->pos.row + 1; --- 365,373 ---- } if(state->mode.insert) { ! // TODO: This will be a little inefficient for large bodies of text, as ! // it'll have to 'ICH' effectively before every glyph. We should scan ! // ahead and ICH as many times as required VTermRect rect; rect.start_row = state->pos.row; rect.end_row = state->pos.row + 1; *************** *** 381,388 **** putglyph(state, chars, width, state->pos); if(i == npoints - 1) { ! /* End of the buffer. Save the chars in case we have to combine with ! * more on the next call */ int save_i; for(save_i = 0; chars[save_i]; save_i++) { if(save_i >= (int)state->combine_chars_size) --- 379,386 ---- putglyph(state, chars, width, state->pos); if(i == npoints - 1) { ! // End of the buffer. Save the chars in case we have to combine with ! // more on the next call int save_i; for(save_i = 0; chars[save_i]; save_i++) { if(save_i >= (int)state->combine_chars_size) *************** *** 577,585 **** { VTermState *state = user; ! /* Easier to decode this from the first byte, even though the final ! * byte terminates it ! */ switch(bytes[0]) { case ' ': if(len != 2) --- 575,582 ---- { VTermState *state = user; ! // Easier to decode this from the first byte, even though the final ! // byte terminates it switch(bytes[0]) { case ' ': if(len != 2) *************** *** 911,917 **** VTermPos oldpos = state->pos; int handled = 1; ! /* Some temporaries for later code */ int count, val; int row, col; VTermRect rect; --- 908,914 ---- VTermPos oldpos = state->pos; int handled = 1; ! // Some temporaries for later code int count, val; int row, col; VTermRect rect; *************** *** 1258,1264 **** case 2: case 4: break; ! /* TODO: 1, 2 and 4 aren't meaningful yet without line tab stops */ default: return 0; } --- 1255,1261 ---- case 2: case 4: break; ! // TODO: 1, 2 and 4 aren't meaningful yet without line tab stops default: return 0; } *************** *** 1418,1424 **** case 0x74: switch(CSI_ARG(args[0])) { ! case 8: /* CSI 8 ; rows ; cols t set size */ if (argcount == 3) on_resize(CSI_ARG(args[1]), CSI_ARG(args[2]), state); break; --- 1415,1421 ---- case 0x74: switch(CSI_ARG(args[0])) { ! case 8: // CSI 8 ; rows ; cols t set size if (argcount == 3) on_resize(CSI_ARG(args[1]), CSI_ARG(args[2]), state); break; *************** *** 1531,1537 **** return 1; } else if(strneq(command, "10;", 3)) { ! /* request foreground color: ]10;?<0x07> */ int red = state->default_fg.red; int blue = state->default_fg.blue; int green = state->default_fg.green; --- 1528,1534 ---- return 1; } else if(strneq(command, "10;", 3)) { ! // request foreground color: ]10;?<0x07> int red = state->default_fg.red; int blue = state->default_fg.blue; int green = state->default_fg.green; *************** *** 1539,1545 **** return 1; } else if(strneq(command, "11;", 3)) { ! /* request background color: ]11;?<0x07> */ int red = state->default_bg.red; int blue = state->default_bg.blue; int green = state->default_bg.green; --- 1536,1542 ---- return 1; } else if(strneq(command, "11;", 3)) { ! // request background color: ]11;?<0x07> int red = state->default_bg.red; int blue = state->default_bg.blue; int green = state->default_bg.green; *************** *** 1591,1597 **** switch(state->mode.cursor_shape) { case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break; case VTERM_PROP_CURSORSHAPE_UNDERLINE: reply = 4; break; ! default: /* VTERM_PROP_CURSORSHAPE_BAR_LEFT */ reply = 6; break; } if(state->mode.cursor_blink) reply--; --- 1588,1594 ---- switch(state->mode.cursor_shape) { case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break; case VTERM_PROP_CURSORSHAPE_UNDERLINE: reply = 4; break; ! default: /* VTERM_PROP_CURSORSHAPE_BAR_LEFT */ reply = 6; break; } if(state->mode.cursor_blink) reply--; *************** *** 1634,1640 **** if (newtabstops == NULL) return 0; ! /* TODO: This can all be done much more efficiently bytewise */ for(col = 0; col < state->cols && col < cols; col++) { unsigned char mask = 1 << (col & 7); if(state->tabstops[col >> 3] & mask) --- 1631,1637 ---- if (newtabstops == NULL) return 0; ! // TODO: This can all be done much more efficiently bytewise for(col = 0; col < state->cols && col < cols; col++) { unsigned char mask = 1 << (col & 7); if(state->tabstops[col >> 3] & mask) *************** *** 1704,1716 **** } static const VTermParserCallbacks parser_callbacks = { ! on_text, /* text */ ! on_control, /* control */ ! on_escape, /* escape */ ! on_csi, /* csi */ ! on_osc, /* osc */ ! on_dcs, /* dcs */ ! on_resize /* resize */ }; /* --- 1701,1713 ---- } static const VTermParserCallbacks parser_callbacks = { ! on_text, // text ! on_control, // control ! on_escape, // escape ! on_csi, // csi ! on_osc, // osc ! on_dcs, // dcs ! on_resize // resize }; /* *************** *** 1875,1882 **** int vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue *val) { ! /* Only store the new value of the property if usercode said it was happy. ! * This is especially important for altscreen switching */ if(state->callbacks && state->callbacks->settermprop) if(!(*state->callbacks->settermprop)(prop, val, state->cbdata)) return 0; --- 1872,1879 ---- int vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue *val) { ! // Only store the new value of the property if usercode said it was happy. ! // This is especially important for altscreen switching if(state->callbacks && state->callbacks->settermprop) if(!(*state->callbacks->settermprop)(prop, val, state->cbdata)) return 0; *** ../vim-8.1.1884/src/libvterm/src/unicode.c 2018-04-24 18:21:55.000000000 +0200 --- src/libvterm/src/unicode.c 2019-08-18 20:27:26.867459579 +0200 *************** *** 1,10 **** #include "vterm_internal.h" ! // ### The following from http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c ! // With modifications: ! // made functions static ! // moved 'combining' table to file scope, so other functions can see it ! // ################################################################### /* * This is an implementation of wcwidth() and wcswidth() (defined in --- 1,11 ---- #include "vterm_internal.h" ! /* ### The following from http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c ! * With modifications: ! * made functions static ! * moved 'combining' table to file scope, so other functions can see it ! * ################################################################### ! */ /* * This is an implementation of wcwidth() and wcswidth() (defined in *************** *** 73,132 **** int last; }; ! /* sorted list of non-overlapping intervals of non-spacing characters */ ! /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */ static const struct interval combining[] = { ! { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 }, ! { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, ! { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 }, ! { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 }, ! { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED }, ! { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A }, ! { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 }, ! { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, ! { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, ! { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, ! { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C }, ! { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, ! { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, ! { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, ! { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C }, ! { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D }, ! { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 }, ! { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 }, ! { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC }, ! { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD }, ! { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, ! { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, ! { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, ! { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, ! { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, ! { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, ! { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, ! { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, ! { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, ! { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F }, ! { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 }, ! { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, ! { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, ! { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, ! { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, ! { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, ! { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, ! { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF }, ! { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 }, ! { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F }, ! { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B }, ! { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, ! { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, ! { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, ! { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 }, ! { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, ! { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, ! { 0xE0100, 0xE01EF } }; ! /* auxiliary function for binary search in interval table */ static int bisearch(uint32_t ucs, const struct interval *table, int max) { int min = 0; int mid; --- 74,366 ---- int last; }; ! // sorted list of non-overlapping intervals of non-spacing characters ! // generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" ! // Replaced by the combining table from Vim. static const struct interval combining[] = { ! {0X0300, 0X036F}, ! {0X0483, 0X0489}, ! {0X0591, 0X05BD}, ! {0X05BF, 0X05BF}, ! {0X05C1, 0X05C2}, ! {0X05C4, 0X05C5}, ! {0X05C7, 0X05C7}, ! {0X0610, 0X061A}, ! {0X064B, 0X065F}, ! {0X0670, 0X0670}, ! {0X06D6, 0X06DC}, ! {0X06DF, 0X06E4}, ! {0X06E7, 0X06E8}, ! {0X06EA, 0X06ED}, ! {0X0711, 0X0711}, ! {0X0730, 0X074A}, ! {0X07A6, 0X07B0}, ! {0X07EB, 0X07F3}, ! {0X07FD, 0X07FD}, ! {0X0816, 0X0819}, ! {0X081B, 0X0823}, ! {0X0825, 0X0827}, ! {0X0829, 0X082D}, ! {0X0859, 0X085B}, ! {0X08D3, 0X08E1}, ! {0X08E3, 0X0903}, ! {0X093A, 0X093C}, ! {0X093E, 0X094F}, ! {0X0951, 0X0957}, ! {0X0962, 0X0963}, ! {0X0981, 0X0983}, ! {0X09BC, 0X09BC}, ! {0X09BE, 0X09C4}, ! {0X09C7, 0X09C8}, ! {0X09CB, 0X09CD}, ! {0X09D7, 0X09D7}, ! {0X09E2, 0X09E3}, ! {0X09FE, 0X09FE}, ! {0X0A01, 0X0A03}, ! {0X0A3C, 0X0A3C}, ! {0X0A3E, 0X0A42}, ! {0X0A47, 0X0A48}, ! {0X0A4B, 0X0A4D}, ! {0X0A51, 0X0A51}, ! {0X0A70, 0X0A71}, ! {0X0A75, 0X0A75}, ! {0X0A81, 0X0A83}, ! {0X0ABC, 0X0ABC}, ! {0X0ABE, 0X0AC5}, ! {0X0AC7, 0X0AC9}, ! {0X0ACB, 0X0ACD}, ! {0X0AE2, 0X0AE3}, ! {0X0AFA, 0X0AFF}, ! {0X0B01, 0X0B03}, ! {0X0B3C, 0X0B3C}, ! {0X0B3E, 0X0B44}, ! {0X0B47, 0X0B48}, ! {0X0B4B, 0X0B4D}, ! {0X0B56, 0X0B57}, ! {0X0B62, 0X0B63}, ! {0X0B82, 0X0B82}, ! {0X0BBE, 0X0BC2}, ! {0X0BC6, 0X0BC8}, ! {0X0BCA, 0X0BCD}, ! {0X0BD7, 0X0BD7}, ! {0X0C00, 0X0C04}, ! {0X0C3E, 0X0C44}, ! {0X0C46, 0X0C48}, ! {0X0C4A, 0X0C4D}, ! {0X0C55, 0X0C56}, ! {0X0C62, 0X0C63}, ! {0X0C81, 0X0C83}, ! {0X0CBC, 0X0CBC}, ! {0X0CBE, 0X0CC4}, ! {0X0CC6, 0X0CC8}, ! {0X0CCA, 0X0CCD}, ! {0X0CD5, 0X0CD6}, ! {0X0CE2, 0X0CE3}, ! {0X0D00, 0X0D03}, ! {0X0D3B, 0X0D3C}, ! {0X0D3E, 0X0D44}, ! {0X0D46, 0X0D48}, ! {0X0D4A, 0X0D4D}, ! {0X0D57, 0X0D57}, ! {0X0D62, 0X0D63}, ! {0X0D82, 0X0D83}, ! {0X0DCA, 0X0DCA}, ! {0X0DCF, 0X0DD4}, ! {0X0DD6, 0X0DD6}, ! {0X0DD8, 0X0DDF}, ! {0X0DF2, 0X0DF3}, ! {0X0E31, 0X0E31}, ! {0X0E34, 0X0E3A}, ! {0X0E47, 0X0E4E}, ! {0X0EB1, 0X0EB1}, ! {0X0EB4, 0X0EBC}, ! {0X0EC8, 0X0ECD}, ! {0X0F18, 0X0F19}, ! {0X0F35, 0X0F35}, ! {0X0F37, 0X0F37}, ! {0X0F39, 0X0F39}, ! {0X0F3E, 0X0F3F}, ! {0X0F71, 0X0F84}, ! {0X0F86, 0X0F87}, ! {0X0F8D, 0X0F97}, ! {0X0F99, 0X0FBC}, ! {0X0FC6, 0X0FC6}, ! {0X102B, 0X103E}, ! {0X1056, 0X1059}, ! {0X105E, 0X1060}, ! {0X1062, 0X1064}, ! {0X1067, 0X106D}, ! {0X1071, 0X1074}, ! {0X1082, 0X108D}, ! {0X108F, 0X108F}, ! {0X109A, 0X109D}, ! {0X135D, 0X135F}, ! {0X1712, 0X1714}, ! {0X1732, 0X1734}, ! {0X1752, 0X1753}, ! {0X1772, 0X1773}, ! {0X17B4, 0X17D3}, ! {0X17DD, 0X17DD}, ! {0X180B, 0X180D}, ! {0X1885, 0X1886}, ! {0X18A9, 0X18A9}, ! {0X1920, 0X192B}, ! {0X1930, 0X193B}, ! {0X1A17, 0X1A1B}, ! {0X1A55, 0X1A5E}, ! {0X1A60, 0X1A7C}, ! {0X1A7F, 0X1A7F}, ! {0X1AB0, 0X1ABE}, ! {0X1B00, 0X1B04}, ! {0X1B34, 0X1B44}, ! {0X1B6B, 0X1B73}, ! {0X1B80, 0X1B82}, ! {0X1BA1, 0X1BAD}, ! {0X1BE6, 0X1BF3}, ! {0X1C24, 0X1C37}, ! {0X1CD0, 0X1CD2}, ! {0X1CD4, 0X1CE8}, ! {0X1CED, 0X1CED}, ! {0X1CF4, 0X1CF4}, ! {0X1CF7, 0X1CF9}, ! {0X1DC0, 0X1DF9}, ! {0X1DFB, 0X1DFF}, ! {0X20D0, 0X20F0}, ! {0X2CEF, 0X2CF1}, ! {0X2D7F, 0X2D7F}, ! {0X2DE0, 0X2DFF}, ! {0X302A, 0X302F}, ! {0X3099, 0X309A}, ! {0XA66F, 0XA672}, ! {0XA674, 0XA67D}, ! {0XA69E, 0XA69F}, ! {0XA6F0, 0XA6F1}, ! {0XA802, 0XA802}, ! {0XA806, 0XA806}, ! {0XA80B, 0XA80B}, ! {0XA823, 0XA827}, ! {0XA880, 0XA881}, ! {0XA8B4, 0XA8C5}, ! {0XA8E0, 0XA8F1}, ! {0XA8FF, 0XA8FF}, ! {0XA926, 0XA92D}, ! {0XA947, 0XA953}, ! {0XA980, 0XA983}, ! {0XA9B3, 0XA9C0}, ! {0XA9E5, 0XA9E5}, ! {0XAA29, 0XAA36}, ! {0XAA43, 0XAA43}, ! {0XAA4C, 0XAA4D}, ! {0XAA7B, 0XAA7D}, ! {0XAAB0, 0XAAB0}, ! {0XAAB2, 0XAAB4}, ! {0XAAB7, 0XAAB8}, ! {0XAABE, 0XAABF}, ! {0XAAC1, 0XAAC1}, ! {0XAAEB, 0XAAEF}, ! {0XAAF5, 0XAAF6}, ! {0XABE3, 0XABEA}, ! {0XABEC, 0XABED}, ! {0XFB1E, 0XFB1E}, ! {0XFE00, 0XFE0F}, ! {0XFE20, 0XFE2F}, ! {0X101FD, 0X101FD}, ! {0X102E0, 0X102E0}, ! {0X10376, 0X1037A}, ! {0X10A01, 0X10A03}, ! {0X10A05, 0X10A06}, ! {0X10A0C, 0X10A0F}, ! {0X10A38, 0X10A3A}, ! {0X10A3F, 0X10A3F}, ! {0X10AE5, 0X10AE6}, ! {0X10D24, 0X10D27}, ! {0X10F46, 0X10F50}, ! {0X11000, 0X11002}, ! {0X11038, 0X11046}, ! {0X1107F, 0X11082}, ! {0X110B0, 0X110BA}, ! {0X11100, 0X11102}, ! {0X11127, 0X11134}, ! {0X11145, 0X11146}, ! {0X11173, 0X11173}, ! {0X11180, 0X11182}, ! {0X111B3, 0X111C0}, ! {0X111C9, 0X111CC}, ! {0X1122C, 0X11237}, ! {0X1123E, 0X1123E}, ! {0X112DF, 0X112EA}, ! {0X11300, 0X11303}, ! {0X1133B, 0X1133C}, ! {0X1133E, 0X11344}, ! {0X11347, 0X11348}, ! {0X1134B, 0X1134D}, ! {0X11357, 0X11357}, ! {0X11362, 0X11363}, ! {0X11366, 0X1136C}, ! {0X11370, 0X11374}, ! {0X11435, 0X11446}, ! {0X1145E, 0X1145E}, ! {0X114B0, 0X114C3}, ! {0X115AF, 0X115B5}, ! {0X115B8, 0X115C0}, ! {0X115DC, 0X115DD}, ! {0X11630, 0X11640}, ! {0X116AB, 0X116B7}, ! {0X1171D, 0X1172B}, ! {0X1182C, 0X1183A}, ! {0X119D1, 0X119D7}, ! {0X119DA, 0X119E0}, ! {0X119E4, 0X119E4}, ! {0X11A01, 0X11A0A}, ! {0X11A33, 0X11A39}, ! {0X11A3B, 0X11A3E}, ! {0X11A47, 0X11A47}, ! {0X11A51, 0X11A5B}, ! {0X11A8A, 0X11A99}, ! {0X11C2F, 0X11C36}, ! {0X11C38, 0X11C3F}, ! {0X11C92, 0X11CA7}, ! {0X11CA9, 0X11CB6}, ! {0X11D31, 0X11D36}, ! {0X11D3A, 0X11D3A}, ! {0X11D3C, 0X11D3D}, ! {0X11D3F, 0X11D45}, ! {0X11D47, 0X11D47}, ! {0X11D8A, 0X11D8E}, ! {0X11D90, 0X11D91}, ! {0X11D93, 0X11D97}, ! {0X11EF3, 0X11EF6}, ! {0X16AF0, 0X16AF4}, ! {0X16B30, 0X16B36}, ! {0X16F4F, 0X16F4F}, ! {0X16F51, 0X16F87}, ! {0X16F8F, 0X16F92}, ! {0X1BC9D, 0X1BC9E}, ! {0X1D165, 0X1D169}, ! {0X1D16D, 0X1D172}, ! {0X1D17B, 0X1D182}, ! {0X1D185, 0X1D18B}, ! {0X1D1AA, 0X1D1AD}, ! {0X1D242, 0X1D244}, ! {0X1DA00, 0X1DA36}, ! {0X1DA3B, 0X1DA6C}, ! {0X1DA75, 0X1DA75}, ! {0X1DA84, 0X1DA84}, ! {0X1DA9B, 0X1DA9F}, ! {0X1DAA1, 0X1DAAF}, ! {0X1E000, 0X1E006}, ! {0X1E008, 0X1E018}, ! {0X1E01B, 0X1E021}, ! {0X1E023, 0X1E024}, ! {0X1E026, 0X1E02A}, ! {0X1E130, 0X1E136}, ! {0X1E2EC, 0X1E2EF}, ! {0X1E8D0, 0X1E8D6}, ! {0X1E944, 0X1E94A}, ! {0XE0100, 0XE01EF} }; ! // auxiliary function for binary search in interval table static int bisearch(uint32_t ucs, const struct interval *table, int max) { int min = 0; int mid; *************** *** 181,217 **** */ #ifdef WCWIDTH_FUNCTION ! /* use a provided wcwidth() function */ int WCWIDTH_FUNCTION(uint32_t ucs); #else # define WCWIDTH_FUNCTION mk_wcwidth static int mk_wcwidth(uint32_t ucs) { ! /* test for 8-bit control characters */ if (ucs == 0) return 0; if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return -1; ! /* binary search in table of non-spacing characters */ if (bisearch(ucs, combining, sizeof(combining) / sizeof(struct interval) - 1)) return 0; ! /* if we arrive here, ucs is not a combining or C0/C1 control character */ return 1 + (ucs >= 0x1100 && ! (ucs <= 0x115f || /* Hangul Jamo init. consonants */ ucs == 0x2329 || ucs == 0x232a || (ucs >= 0x2e80 && ucs <= 0xa4cf && ! ucs != 0x303f) || /* CJK ... Yi */ ! (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ ! (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ ! (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ ! (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ ! (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ (ucs >= 0xffe0 && ucs <= 0xffe6) || (ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd))); --- 415,451 ---- */ #ifdef WCWIDTH_FUNCTION ! // use a provided wcwidth() function int WCWIDTH_FUNCTION(uint32_t ucs); #else # define WCWIDTH_FUNCTION mk_wcwidth static int mk_wcwidth(uint32_t ucs) { ! // test for 8-bit control characters if (ucs == 0) return 0; if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return -1; ! // binary search in table of non-spacing characters if (bisearch(ucs, combining, sizeof(combining) / sizeof(struct interval) - 1)) return 0; ! // if we arrive here, ucs is not a combining or C0/C1 control character return 1 + (ucs >= 0x1100 && ! (ucs <= 0x115f || // Hangul Jamo init. consonants ucs == 0x2329 || ucs == 0x232a || (ucs >= 0x2e80 && ucs <= 0xa4cf && ! ucs != 0x303f) || // CJK ... Yi ! (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables ! (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compatibility Ideographs ! (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms ! (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compatibility Forms ! (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms (ucs >= 0xffe0 && ucs <= 0xffe6) || (ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd))); *************** *** 301,307 **** { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } }; ! /* binary search in table of non-spacing characters */ if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; --- 535,541 ---- { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD } }; ! // binary search in table of non-spacing characters if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; *************** *** 324,330 **** #endif #ifdef IS_COMBINING_FUNCTION ! /* Use a provided is_combining() function. */ int IS_COMBINING_FUNCTION(uint32_t codepoint); #else # define IS_COMBINING_FUNCTION vterm_is_combining --- 558,564 ---- #endif #ifdef IS_COMBINING_FUNCTION ! // Use a provided is_combining() function. int IS_COMBINING_FUNCTION(uint32_t codepoint); #else # define IS_COMBINING_FUNCTION vterm_is_combining *** ../vim-8.1.1884/src/libvterm/src/utf8.h 2018-04-24 18:22:56.000000000 +0200 --- src/libvterm/src/utf8.h 2019-08-18 20:14:39.692353764 +0200 *************** *** 16,22 **** } #endif ! /* Does NOT NUL-terminate the buffer */ int fill_utf8(long codepoint, char *str); #if defined(DEFINE_INLINES) || USE_INLINE --- 16,22 ---- } #endif ! // Does NOT NUL-terminate the buffer int fill_utf8(long codepoint, char *str); #if defined(DEFINE_INLINES) || USE_INLINE *************** *** 44,47 **** return nbytes; } #endif ! /* end copy */ --- 44,47 ---- return nbytes; } #endif ! // end copy *** ../vim-8.1.1884/src/libvterm/src/vterm.c 2018-12-24 21:38:40.814173687 +0100 --- src/libvterm/src/vterm.c 2019-08-18 20:29:24.531128558 +0200 *************** *** 1,6 **** #define DEFINE_INLINES ! /* vim: set sw=2 : */ #include "vterm_internal.h" #include --- 1,6 ---- #define DEFINE_INLINES ! // vim: set sw=2 : #include "vterm_internal.h" #include *************** *** 39,45 **** VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata) { ! /* Need to bootstrap using the allocator function directly */ VTerm *vt = (*funcs->malloc)(sizeof(VTerm), allocdata); if (vt == NULL) --- 39,45 ---- VTerm *vterm_new_with_allocator(int rows, int cols, VTermAllocatorFunctions *funcs, void *allocdata) { ! // Need to bootstrap using the allocator function directly VTerm *vt = (*funcs->malloc)(sizeof(VTerm), allocdata); if (vt == NULL) *************** *** 55,61 **** vt->parser.callbacks = NULL; vt->parser.cbdata = NULL; ! vt->parser.strbuffer_len = 500; /* should be able to hold an OSC string */ vt->parser.strbuffer_cur = 0; vt->parser.strbuffer = vterm_allocator_malloc(vt, vt->parser.strbuffer_len); if (vt->parser.strbuffer == NULL) --- 55,61 ---- vt->parser.callbacks = NULL; vt->parser.cbdata = NULL; ! vt->parser.strbuffer_len = 500; // should be able to hold an OSC string vt->parser.strbuffer_cur = 0; vt->parser.strbuffer = vterm_allocator_malloc(vt, vt->parser.strbuffer_len); if (vt->parser.strbuffer == NULL) *************** *** 154,160 **** # define VSNPRINTF vsnprintf #else # ifdef VSNPRINTF ! /* Use a provided vsnprintf() function. */ int VSNPRINTF(char *str, size_t str_m, const char *fmt, va_list ap); # endif #endif --- 154,160 ---- # define VSNPRINTF vsnprintf #else # ifdef VSNPRINTF ! // Use a provided vsnprintf() function. int VSNPRINTF(char *str, size_t str_m, const char *fmt, va_list ap); # endif #endif *************** *** 164,171 **** { int written; #ifndef VSNPRINTF ! /* When vsnprintf() is not available (C90) fall back to vsprintf(). */ ! char buffer[1024]; /* 1Kbyte is enough for everybody, right? */ #endif if(outbuffer_is_full(vt)) { --- 164,171 ---- { int written; #ifndef VSNPRINTF ! // When vsnprintf() is not available (C90) fall back to vsprintf(). ! char buffer[1024]; // 1Kbyte is enough for everybody, right? #endif if(outbuffer_is_full(vt)) { *************** *** 179,185 **** format, args); if(written == (int)(vt->outbuffer_len - vt->outbuffer_cur)) { ! /* output was truncated */ vt->outbuffer_cur = vt->outbuffer_len - 1; } else --- 179,185 ---- format, args); if(written == (int)(vt->outbuffer_len - vt->outbuffer_cur)) { ! // output was truncated vt->outbuffer_cur = vt->outbuffer_len - 1; } else *************** *** 188,194 **** written = vsprintf(buffer, format, args); if(written >= (int)(vt->outbuffer_len - vt->outbuffer_cur - 1)) { ! /* output was truncated */ written = vt->outbuffer_len - vt->outbuffer_cur - 1; } if (written > 0) --- 188,194 ---- written = vsprintf(buffer, format, args); if(written >= (int)(vt->outbuffer_len - vt->outbuffer_cur - 1)) { ! // output was truncated written = vt->outbuffer_len - vt->outbuffer_cur - 1; } if (written > 0) *************** *** 290,296 **** case VTERM_N_ATTRS: return 0; } ! return 0; /* UNREACHABLE */ } VTermValueType vterm_get_prop_type(VTermProp prop) --- 290,296 ---- case VTERM_N_ATTRS: return 0; } ! return 0; // UNREACHABLE } VTermValueType vterm_get_prop_type(VTermProp prop) *************** *** 308,314 **** case VTERM_N_PROPS: return 0; } ! return 0; /* UNREACHABLE */ } void vterm_scroll_rect(VTermRect rect, --- 308,314 ---- case VTERM_N_PROPS: return 0; } ! return 0; // UNREACHABLE } void vterm_scroll_rect(VTermRect rect, *************** *** 323,348 **** if(abs(downward) >= rect.end_row - rect.start_row || abs(rightward) >= rect.end_col - rect.start_col) { ! /* Scroll more than area; just erase the lot */ (*eraserect)(rect, 0, user); return; } if(rightward >= 0) { ! /* rect: [XXX................] ! * src: [----------------] ! * dest: [----------------] ! */ dest.start_col = rect.start_col; dest.end_col = rect.end_col - rightward; src.start_col = rect.start_col + rightward; src.end_col = rect.end_col; } else { ! /* rect: [................XXX] ! * src: [----------------] ! * dest: [----------------] ! */ int leftward = -rightward; dest.start_col = rect.start_col + leftward; dest.end_col = rect.end_col; --- 323,346 ---- if(abs(downward) >= rect.end_row - rect.start_row || abs(rightward) >= rect.end_col - rect.start_col) { ! // Scroll more than area; just erase the lot (*eraserect)(rect, 0, user); return; } if(rightward >= 0) { ! // rect: [XXX................] ! // src: [----------------] ! // dest: [----------------] dest.start_col = rect.start_col; dest.end_col = rect.end_col - rightward; src.start_col = rect.start_col + rightward; src.end_col = rect.end_col; } else { ! // rect: [................XXX] ! // src: [----------------] ! // dest: [----------------] int leftward = -rightward; dest.start_col = rect.start_col + leftward; dest.end_col = rect.end_col; *************** *** 398,404 **** test_row = dest.start_row - 1; inc_row = -1; } ! else /* downward >= 0 */ { init_row = dest.start_row; test_row = dest.end_row; inc_row = +1; --- 396,403 ---- test_row = dest.start_row - 1; inc_row = -1; } ! else { ! // downward >= 0 init_row = dest.start_row; test_row = dest.end_row; inc_row = +1; *************** *** 409,415 **** test_col = dest.start_col - 1; inc_col = -1; } ! else /* rightward >= 0 */ { init_col = dest.start_col; test_col = dest.end_col; inc_col = +1; --- 408,415 ---- test_col = dest.start_col - 1; inc_col = -1; } ! else { ! // rightward >= 0 init_col = dest.start_col; test_col = dest.end_col; inc_col = +1; *** ../vim-8.1.1884/src/libvterm/src/vterm_internal.h 2018-04-24 18:37:30.000000000 +0200 --- src/libvterm/src/vterm_internal.h 2019-08-18 20:15:00.920230005 +0200 *************** *** 51,57 **** unsigned int blink:1; unsigned int reverse:1; unsigned int strike:1; ! unsigned int font:4; /* To store 0-9 */ }; int vterm_color_equal(VTermColor a, VTermColor b); --- 51,57 ---- unsigned int blink:1; unsigned int reverse:1; unsigned int strike:1; ! unsigned int font:4; // To store 0-9 }; int vterm_color_equal(VTermColor a, VTermColor b); *************** *** 76,109 **** int rows; int cols; ! /* Current cursor position */ VTermPos pos; ! int at_phantom; /* True if we're on the "81st" phantom column to defer a wraparound */ int scrollregion_top; ! int scrollregion_bottom; /* -1 means unbounded */ #define SCROLLREGION_BOTTOM(state) ((state)->scrollregion_bottom > -1 ? (state)->scrollregion_bottom : (state)->rows) int scrollregion_left; #define SCROLLREGION_LEFT(state) ((state)->mode.leftrightmargin ? (state)->scrollregion_left : 0) ! int scrollregion_right; /* -1 means unbounded */ #define SCROLLREGION_RIGHT(state) ((state)->mode.leftrightmargin && (state)->scrollregion_right > -1 ? (state)->scrollregion_right : (state)->cols) ! /* Bitvector of tab stops */ unsigned char *tabstops; VTermLineInfo *lineinfo; #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols) #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row) ! /* Mouse state */ int mouse_col, mouse_row; int mouse_buttons; int mouse_flags; enum { MOUSE_X10, MOUSE_UTF8, MOUSE_SGR, MOUSE_RXVT } mouse_protocol; ! /* Last glyph output, for Unicode recombining purposes */ uint32_t *combine_chars; size_t combine_chars_size; // Number of ELEMENTS in the above int combine_width; // The width of the glyph above --- 76,109 ---- int rows; int cols; ! // Current cursor position VTermPos pos; ! int at_phantom; // True if we're on the "81st" phantom column to defer a wraparound int scrollregion_top; ! int scrollregion_bottom; // -1 means unbounded #define SCROLLREGION_BOTTOM(state) ((state)->scrollregion_bottom > -1 ? (state)->scrollregion_bottom : (state)->rows) int scrollregion_left; #define SCROLLREGION_LEFT(state) ((state)->mode.leftrightmargin ? (state)->scrollregion_left : 0) ! int scrollregion_right; // -1 means unbounded #define SCROLLREGION_RIGHT(state) ((state)->mode.leftrightmargin && (state)->scrollregion_right > -1 ? (state)->scrollregion_right : (state)->cols) ! // Bitvector of tab stops unsigned char *tabstops; VTermLineInfo *lineinfo; #define ROWWIDTH(state,row) ((state)->lineinfo[(row)].doublewidth ? ((state)->cols / 2) : (state)->cols) #define THISROWWIDTH(state) ROWWIDTH(state, (state)->pos.row) ! // Mouse state int mouse_col, mouse_row; int mouse_buttons; int mouse_flags; enum { MOUSE_X10, MOUSE_UTF8, MOUSE_SGR, MOUSE_RXVT } mouse_protocol; ! // Last glyph output, for Unicode recombining purposes uint32_t *combine_chars; size_t combine_chars_size; // Number of ELEMENTS in the above int combine_width; // The width of the glyph above *************** *** 141,147 **** unsigned int protected_cell : 1; ! /* Saved state under DEC mode 1048/1049 */ struct { VTermPos pos; struct VTermPen pen; --- 141,147 ---- unsigned int protected_cell : 1; ! // Saved state under DEC mode 1048/1049 struct { VTermPos pos; struct VTermPen pen; *************** *** 181,187 **** CSI_ARGS, CSI_INTERMED, ESC, ! /* below here are the "string states" */ STRING, ESC_IN_STRING, } state; --- 181,187 ---- CSI_ARGS, CSI_INTERMED, ESC, ! // below here are the "string states" STRING, ESC_IN_STRING, } state; *************** *** 204,210 **** size_t strbuffer_cur; } parser; ! /* len == malloc()ed size; cur == number of valid bytes */ char *outbuffer; size_t outbuffer_len; --- 204,210 ---- size_t strbuffer_cur; } parser; ! // len == malloc()ed size; cur == number of valid bytes char *outbuffer; size_t outbuffer_len; *** ../vim-8.1.1884/src/libvterm/src/termscreen.c 2019-04-27 22:06:33.352200698 +0200 --- src/libvterm/src/termscreen.c 2019-08-18 20:21:31.864089777 +0200 *************** *** 1,6 **** #include "vterm_internal.h" ! /* vim: set sw=2 : */ #include #include --- 1,6 ---- #include "vterm_internal.h" ! // vim: set sw=2 : #include #include *************** *** 10,19 **** #define UNICODE_SPACE 0x20 #define UNICODE_LINEFEED 0x0a ! /* State of the pen at some moment in time, also used in a cell */ typedef struct { ! /* After the bitfield */ VTermColor fg, bg; unsigned int bold : 1; --- 10,19 ---- #define UNICODE_SPACE 0x20 #define UNICODE_LINEFEED 0x0a ! // State of the pen at some moment in time, also used in a cell typedef struct { ! // After the bitfield VTermColor fg, bg; unsigned int bold : 1; *************** *** 22,36 **** unsigned int blink : 1; unsigned int reverse : 1; unsigned int strike : 1; ! unsigned int font : 4; /* 0 to 9 */ ! /* Extra state storage that isn't strictly pen-related */ unsigned int protected_cell : 1; ! unsigned int dwl : 1; /* on a DECDWL or DECDHL line */ ! unsigned int dhl : 2; /* on a DECDHL line (1=top 2=bottom) */ } ScreenPen; ! /* Internal representation of a screen cell */ typedef struct { uint32_t chars[VTERM_MAX_CHARS_PER_CELL]; --- 22,36 ---- unsigned int blink : 1; unsigned int reverse : 1; unsigned int strike : 1; ! unsigned int font : 4; // 0 to 9 ! // Extra state storage that isn't strictly pen-related unsigned int protected_cell : 1; ! unsigned int dwl : 1; // on a DECDWL or DECDHL line ! unsigned int dhl : 2; // on a DECDHL line (1=top 2=bottom) } ScreenPen; ! // Internal representation of a screen cell typedef struct { uint32_t chars[VTERM_MAX_CHARS_PER_CELL]; *************** *** 48,54 **** void *cbdata; VTermDamageSize damage_merge; ! /* start_row == -1 => no damage */ VTermRect damaged; VTermRect pending_scrollrect; int pending_scroll_downward, pending_scroll_rightward; --- 48,54 ---- void *cbdata; VTermDamageSize damage_merge; ! // start_row == -1 => no damage VTermRect damaged; VTermRect pending_scrollrect; int pending_scroll_downward, pending_scroll_rightward; *************** *** 57,69 **** int cols; int global_reverse; ! /* Primary and Altscreen. buffers[1] is lazily allocated as needed */ ScreenCell *buffers[2]; ! /* buffer will == buffers[0] or buffers[1], depending on altscreen */ ScreenCell *buffer; ! /* buffer for a single screen row used in scrollback storage callbacks */ VTermScreenCell *sb_buffer; ScreenPen pen; --- 57,69 ---- int cols; int global_reverse; ! // Primary and Altscreen. buffers[1] is lazily allocated as needed ScreenCell *buffers[2]; ! // buffer will == buffers[0] or buffers[1], depending on altscreen ScreenCell *buffer; ! // buffer for a single screen row used in scrollback storage callbacks VTermScreenCell *sb_buffer; ScreenPen pen; *************** *** 109,121 **** switch(screen->damage_merge) { case VTERM_DAMAGE_CELL: ! /* Always emit damage event */ emit = rect; break; case VTERM_DAMAGE_ROW: ! /* Emit damage longer than one row. Try to merge with existing damage in ! * the same row */ if(rect.end_row > rect.start_row + 1) { // Bigger than 1 line - flush existing, emit this vterm_screen_flush_damage(screen); --- 109,121 ---- switch(screen->damage_merge) { case VTERM_DAMAGE_CELL: ! // Always emit damage event emit = rect; break; case VTERM_DAMAGE_ROW: ! // Emit damage longer than one row. Try to merge with existing damage in ! // the same row if(rect.end_row > rect.start_row + 1) { // Bigger than 1 line - flush existing, emit this vterm_screen_flush_damage(screen); *************** *** 143,149 **** case VTERM_DAMAGE_SCREEN: case VTERM_DAMAGE_SCROLL: ! /* Never emit damage event */ if(screen->damaged.start_row == -1) screen->damaged = rect; else { --- 143,149 ---- case VTERM_DAMAGE_SCREEN: case VTERM_DAMAGE_SCROLL: ! // Never emit damage event if(screen->damaged.start_row == -1) screen->damaged = rect; else { *************** *** 352,366 **** return 1; if(rect_contains(&rect, &screen->damaged)) { ! /* Scroll region entirely contains the damage; just move it */ vterm_rect_move(&screen->damaged, -downward, -rightward); rect_clip(&screen->damaged, &rect); } ! /* There are a number of possible cases here, but lets restrict this to only ! * the common case where we might actually gain some performance by ! * optimising it. Namely, a vertical scroll that neatly cuts the damage ! * region in half. ! */ else if(rect.start_col <= screen->damaged.start_col && rect.end_col >= screen->damaged.end_col && rightward == 0) { --- 352,365 ---- return 1; if(rect_contains(&rect, &screen->damaged)) { ! // Scroll region entirely contains the damage; just move it vterm_rect_move(&screen->damaged, -downward, -rightward); rect_clip(&screen->damaged, &rect); } ! // There are a number of possible cases here, but lets restrict this to only ! // the common case where we might actually gain some performance by ! // optimising it. Namely, a vertical scroll that neatly cuts the damage ! // region in half. else if(rect.start_col <= screen->damaged.start_col && rect.end_col >= screen->damaged.end_col && rightward == 0) { *************** *** 449,457 **** return 0; screen->buffer = val->boolean ? screen->buffers[1] : screen->buffers[0]; ! /* only send a damage event on disable; because during enable there's an ! * erase that sends a damage anyway ! */ if(!val->boolean) damagescreen(screen); break; --- 448,455 ---- return 0; screen->buffer = val->boolean ? screen->buffers[1] : screen->buffers[0]; ! // only send a damage event on disable; because during enable there's an ! // erase that sends a damage anyway if(!val->boolean) damagescreen(screen); break; *************** *** 460,466 **** damagescreen(screen); break; default: ! ; /* ignore */ } if(screen->callbacks && screen->callbacks->settermprop) --- 458,464 ---- damagescreen(screen); break; default: ! ; // ignore } if(screen->callbacks && screen->callbacks->settermprop) *************** *** 607,623 **** } static VTermStateCallbacks state_cbs = { ! &putglyph, /* putglyph */ ! &movecursor, /* movecursor */ ! &scrollrect, /* scrollrect */ ! NULL, /* moverect */ ! &erase, /* erase */ ! NULL, /* initpen */ ! &setpenattr, /* setpenattr */ ! &settermprop, /* settermprop */ ! &bell, /* bell */ ! &resize, /* resize */ ! &setlineinfo /* setlineinfo */ }; /* --- 605,621 ---- } static VTermStateCallbacks state_cbs = { ! &putglyph, // putglyph ! &movecursor, // movecursor ! &scrollrect, // scrollrect ! NULL, // moverect ! &erase, // erase ! NULL, // initpen ! &setpenattr, // setpenattr ! &settermprop, // settermprop ! &bell, // bell ! &resize, // resize ! &setlineinfo // setlineinfo }; /* *************** *** 743,749 **** return _get_chars(screen, 1, str, len, rect); } ! /* Copy internal to external representation of a screen cell */ int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell) { ScreenCell *intcell = getcell(screen, pos.row, pos.col); --- 741,747 ---- return _get_chars(screen, 1, str, len, rect); } ! // Copy internal to external representation of a screen cell int vterm_screen_get_cell(const VTermScreen *screen, VTermPos pos, VTermScreenCell *cell) { ScreenCell *intcell = getcell(screen, pos.row, pos.col); *************** *** 781,787 **** return 1; } ! /* Copy external to internal representation of a screen cell */ /* static because it's only used internally for sb_popline during resize */ static int vterm_screen_set_cell(VTermScreen *screen, VTermPos pos, const VTermScreenCell *cell) { --- 779,785 ---- return 1; } ! // Copy external to internal representation of a screen cell /* static because it's only used internally for sb_popline during resize */ static int vterm_screen_set_cell(VTermScreen *screen, VTermPos pos, const VTermScreenCell *cell) { *************** *** 816,822 **** int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos) { ! /* This cell is EOL if this and every cell to the right is black */ for(; pos.col < screen->cols; pos.col++) { ScreenCell *cell = getcell(screen, pos.row, pos.col); if(cell->chars[0] != 0) --- 814,820 ---- int vterm_screen_is_eol(const VTermScreen *screen, VTermPos pos) { ! // This cell is EOL if this and every cell to the right is black for(; pos.col < screen->cols; pos.col++) { ScreenCell *cell = getcell(screen, pos.row, pos.col); if(cell->chars[0] != 0) *** ../vim-8.1.1884/src/version.c 2019-08-18 19:23:41.525729980 +0200 --- src/version.c 2019-08-18 20:36:02.909751409 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 1885, /**/ -- From "know your smileys": :~) A man with a tape recorder up his nose /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///