To: vim_dev@googlegroups.com Subject: Patch 8.2.0813 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0813 Problem: libvterm code is slightly different from upstream. Solution: Use upstream text to avoid future merge problems. Mainly comment style changes. Files: src/libvterm/include/vterm.h, src/libvterm/src/rect.h, src/libvterm/src/utf8.h, src/libvterm/src/vterm_internal.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/screen.c, src/libvterm/src/state.c, src/libvterm/src/unicode.c, src/libvterm/src/vterm.c *** ../vim-8.2.0812/src/libvterm/include/vterm.h 2020-05-21 20:10:00.285336763 +0200 --- src/libvterm/include/vterm.h 2020-05-22 20:59:25.001252440 +0200 *************** *** 35,43 **** int col; } VTermPos; ! /* ! * Some small utility functions; we can just keep these static here. ! */ /* * Order points by on-screen flow order: --- 35,41 ---- int col; } VTermPos; ! /* some small utility functions; we can just keep these static here */ /* * Order points by on-screen flow order: *************** *** 62,68 **** 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 --- 60,66 ---- int end_col; } VTermRect; ! /* true if the rect contains the point */ int vterm_rect_contains(VTermRect r, VTermPos p); #if defined(DEFINE_INLINES) || USE_INLINE *************** *** 73,78 **** --- 71,77 ---- } #endif + /* move a rect */ // 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); *************** *** 185,193 **** */ int vterm_color_is_equal(const VTermColor *a, const VTermColor *b); - typedef enum { ! // VTERM_VALUETYPE_NONE = 0 VTERM_VALUETYPE_BOOL = 1, VTERM_VALUETYPE_INT, VTERM_VALUETYPE_STRING, --- 184,191 ---- */ int vterm_color_is_equal(const VTermColor *a, const VTermColor *b); typedef enum { ! /* VTERM_VALUETYPE_NONE = 0 */ VTERM_VALUETYPE_BOOL = 1, VTERM_VALUETYPE_INT, VTERM_VALUETYPE_STRING, *************** *** 211,217 **** } 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 --- 209,215 ---- } 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 *************** *** 227,233 **** } VTermAttr; typedef enum { ! // VTERM_PROP_NONE = 0 VTERM_PROP_CURSORVISIBLE = 1, // bool VTERM_PROP_CURSORBLINK, // bool VTERM_PROP_ALTSCREEN, // bool --- 225,231 ---- } VTermAttr; typedef enum { ! /* VTERM_PROP_NONE = 0 */ VTERM_PROP_CURSORVISIBLE = 1, // bool VTERM_PROP_CURSORBLINK, // bool VTERM_PROP_ALTSCREEN, // bool *************** *** 261,269 **** 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 { --- 259,267 ---- 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 { *************** *** 272,280 **** unsigned int continuation:1; /* Line is a flow continuation of the previous */ } 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; --- 270,287 ---- unsigned int continuation:1; /* Line is a flow continuation of the previous */ } VTermLineInfo; + /* Copies of VTermState fields that the 'resize' callback might have reason to + * edit. 'resize' callback gets total control of these fields and may + * free-and-reallocate them if required. They will be copied back from the + * struct after the callback has returned. + */ + typedef struct { + VTermPos pos; /* current cursor position */ + } VTermStateFields; + typedef struct { ! /* libvterm relies on this 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; *************** *** 329,348 **** // Parser layer // ------------ ! // Flag to indicate non-final subparameters in a single CSI parameter. ! // Consider ! // CSI 1;2:3:4;5a ! // 1 4 and 5 are final. ! // 2 and 3 are non-final and will have this bit set ! // ! // Don't confuse this with the final byte of the CSI escape; 'a' in this case. #define CSI_ARG_FLAG_MORE (1U<<31) #define CSI_ARG_MASK (~(1U<<31)) #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) --- 336,356 ---- // Parser layer // ------------ ! /* Flag to indicate non-final subparameters in a single CSI parameter. ! * Consider ! * CSI 1;2:3:4;5a ! * 1 4 and 5 are final. ! * 2 and 3 are non-final and will have this bit set ! * ! * Don't confuse this with the final byte of the CSI escape; 'a' in this case. ! */ #define CSI_ARG_FLAG_MORE (1U<<31) #define CSI_ARG_MASK (~(1U<<31)) #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) *************** *** 366,380 **** // State layer // ----------- - /* Copies of VTermState fields that the 'resize' callback might have reason to - * edit. 'resize' callback gets total control of these fields and may - * free-and-reallocate them if required. They will be copied back from the - * struct after the callback has returned. - */ - typedef struct { - VTermPos pos; /* current cursor position */ - } VTermStateFields; - typedef struct { int (*putglyph)(VTermGlyphInfo *info, VTermPos pos, void *user); int (*movecursor)(VTermPos pos, VTermPos oldpos, int visible, void *user); --- 374,379 ---- *************** *** 459,467 **** unsigned int reverse : 1; unsigned int conceal : 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; enum { --- 458,466 ---- unsigned int reverse : 1; unsigned int conceal : 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; enum { *************** *** 513,522 **** 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; --- 512,521 ---- 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; *************** *** 532,538 **** */ 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); --- 531,537 ---- */ 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.2.0812/src/libvterm/src/rect.h 2019-08-18 20:58:44.000000000 +0200 --- src/libvterm/src/rect.h 2020-05-22 21:04:47.192095951 +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.2.0812/src/libvterm/src/utf8.h 2019-08-18 20:58:44.000000000 +0200 --- src/libvterm/src/utf8.h 2020-05-22 21:06:09.207797602 +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.2.0812/src/libvterm/src/vterm_internal.h 2020-05-21 20:10:00.285336763 +0200 --- src/libvterm/src/vterm_internal.h 2020-05-22 21:11:41.598579873 +0200 *************** *** 55,61 **** unsigned int reverse:1; unsigned int conceal:1; unsigned int strike:1; ! unsigned int font:4; // To store 0-9 }; struct VTermState --- 55,61 ---- unsigned int reverse:1; unsigned int conceal:1; unsigned int strike:1; ! unsigned int font:4; /* To store 0-9 */ }; struct VTermState *************** *** 71,90 **** 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; /* Primary and Altscreen; lineinfos[1] is lazily allocated as needed */ --- 71,90 ---- 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; /* Primary and Altscreen; lineinfos[1] is lazily allocated as needed */ *************** *** 95,108 **** #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 --- 95,108 ---- #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 *************** *** 139,145 **** unsigned int protected_cell : 1; ! // Saved state under DEC mode 1048/1049 struct { VTermPos pos; struct VTermPen pen; --- 139,145 ---- unsigned int protected_cell : 1; ! /* Saved state under DEC mode 1048/1049 */ struct { VTermPos pos; struct VTermPen pen; *************** *** 211,217 **** int string_initial; } parser; ! // len == malloc()ed size; cur == number of valid bytes VTermOutputCallback *outfunc; void *outdata; --- 211,217 ---- int string_initial; } parser; ! /* len == malloc()ed size; cur == number of valid bytes */ VTermOutputCallback *outfunc; void *outdata; *** ../vim-8.2.0812/src/libvterm/src/encoding.c 2019-08-18 20:58:44.000000000 +0200 --- src/libvterm/src/encoding.c 2020-05-22 21:14:56.546263466 +0200 *************** *** 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.2.0812/src/libvterm/src/keyboard.c 2020-05-17 20:52:40.733955160 +0200 --- src/libvterm/src/keyboard.c 2020-05-22 21:19:33.382019196 +0200 *************** *** 19,26 **** return; } ! // The shift modifier is never important for Unicode characters ! // apart from Space if(c != ' ') mod &= ~VTERM_MOD_SHIFT; --- 19,27 ---- return; } ! /* The shift modifier is never important for Unicode characters ! * apart from Space ! */ if(c != ' ') mod &= ~VTERM_MOD_SHIFT; *************** *** 33,56 **** } 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; --- 34,57 ---- } 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; *************** *** 165,171 **** 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) --- 166,172 ---- 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) *************** *** 175,181 **** 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 --- 176,182 ---- 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.2.0812/src/libvterm/src/mouse.c 2019-09-21 20:13:48.000000000 +0200 --- src/libvterm/src/mouse.c 2020-05-22 21:20:43.217908604 +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.2.0812/src/libvterm/src/parser.c 2020-05-20 19:30:13.828123549 +0200 --- src/libvterm/src/parser.c 2020-05-22 21:25:05.325375284 +0200 *************** *** 34,40 **** if(vt->parser.callbacks && vt->parser.callbacks->csi) if((*vt->parser.callbacks->csi)( ! vt->parser.v.csi.leaderlen ? vt->parser.v.csi.leader : NULL, vt->parser.v.csi.args, vt->parser.v.csi.argi, vt->parser.intermedlen ? vt->parser.intermed : NULL, --- 34,40 ---- if(vt->parser.callbacks && vt->parser.callbacks->csi) if((*vt->parser.callbacks->csi)( ! vt->parser.v.csi.leaderlen ? vt->parser.v.csi.leader : NULL, vt->parser.v.csi.args, vt->parser.v.csi.argi, vt->parser.intermedlen ? vt->parser.intermed : NULL, *************** *** 187,209 **** switch(vt->parser.state) { case CSI_LEADER: ! // Extract leader bytes 0x3c to 0x3f if(c >= 0x3c && c <= 0x3f) { if(vt->parser.v.csi.leaderlen < CSI_LEADER_MAX-1) vt->parser.v.csi.leader[vt->parser.v.csi.leaderlen++] = c; break; } ! // else fallthrough vt->parser.v.csi.leader[vt->parser.v.csi.leaderlen] = 0; vt->parser.v.csi.argi = 0; vt->parser.v.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.v.csi.args[vt->parser.v.csi.argi] == CSI_ARG_MISSING) vt->parser.v.csi.args[vt->parser.v.csi.argi] = 0; --- 187,209 ---- switch(vt->parser.state) { case CSI_LEADER: ! /* Extract leader bytes 0x3c to 0x3f */ if(c >= 0x3c && c <= 0x3f) { if(vt->parser.v.csi.leaderlen < CSI_LEADER_MAX-1) vt->parser.v.csi.leader[vt->parser.v.csi.leaderlen++] = c; break; } ! /* else fallthrough */ vt->parser.v.csi.leader[vt->parser.v.csi.leaderlen] = 0; vt->parser.v.csi.argi = 0; vt->parser.v.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.v.csi.args[vt->parser.v.csi.argi] == CSI_ARG_MISSING) vt->parser.v.csi.args[vt->parser.v.csi.argi] = 0; *************** *** 221,227 **** break; } ! // else fallthrough vt->parser.v.csi.argi++; vt->parser.intermedlen = 0; vt->parser.state = CSI_INTERMED; --- 221,227 ---- break; } ! /* else fallthrough */ vt->parser.v.csi.argi++; vt->parser.intermedlen = 0; vt->parser.state = CSI_INTERMED; *************** *** 233,245 **** 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; --- 233,245 ---- 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; *************** *** 330,336 **** if(!eaten) { DEBUG_LOG("libvterm: Text callback did not consume any input\n"); ! // force it to make progress eaten = 1; } --- 330,336 ---- if(!eaten) { DEBUG_LOG("libvterm: Text callback did not consume any input\n"); ! /* force it to make progress */ eaten = 1; } *** ../vim-8.2.0812/src/libvterm/src/pen.c 2020-05-21 20:10:00.285336763 +0200 --- src/libvterm/src/pen.c 2020-05-22 21:57:20.647122323 +0200 *************** *** 11,17 **** } VTermRGB; static const VTermRGB ansi_colors[] = { ! // R G B { 0, 0, 0 }, // black { 224, 0, 0 }, // red { 0, 224, 0 }, // green --- 11,17 ---- } VTermRGB; static const VTermRGB ansi_colors[] = { ! /* R G B */ { 0, 0, 0 }, // black { 224, 0, 0 }, // red { 0, 224, 0 }, // green *************** *** 465,476 **** break; } ! if (!done) { DEBUG_LOG1("libvterm: Unhandled CSI SGR %ld\n", arg); } ! while (CSI_ARG_HAS_MORE(args[argi++])) ; } } --- 465,476 ---- break; } ! if(!done) { DEBUG_LOG1("libvterm: Unhandled CSI SGR %ld\n", arg); } ! while(CSI_ARG_HAS_MORE(args[argi++])) ; } } *** ../vim-8.2.0812/src/libvterm/src/screen.c 2020-05-21 20:10:00.285336763 +0200 --- src/libvterm/src/screen.c 2020-05-22 21:36:07.235567346 +0200 *************** *** 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; *************** *** 23,37 **** unsigned int reverse : 1; unsigned int conceal : 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]; --- 23,37 ---- unsigned int reverse : 1; unsigned int conceal : 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]; *************** *** 47,53 **** void *cbdata; VTermDamageSize damage_merge; ! // start_row == -1 => no damage VTermRect damaged; VTermRect pending_scrollrect; int pending_scroll_downward, pending_scroll_rightward; --- 47,53 ---- void *cbdata; VTermDamageSize damage_merge; ! /* start_row == -1 => no damage */ VTermRect damaged; VTermRect pending_scrollrect; int pending_scroll_downward, pending_scroll_rightward; *************** *** 56,68 **** 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; --- 56,68 ---- 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; *************** *** 106,118 **** 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); --- 106,118 ---- 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); *************** *** 140,146 **** case VTERM_DAMAGE_SCREEN: case VTERM_DAMAGE_SCROLL: ! // Never emit damage event if(screen->damaged.start_row == -1) screen->damaged = rect; else { --- 140,146 ---- case VTERM_DAMAGE_SCREEN: case VTERM_DAMAGE_SCROLL: ! /* Never emit damage event */ if(screen->damaged.start_row == -1) screen->damaged = rect; else { *************** *** 355,368 **** 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) { --- 355,369 ---- 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) { *************** *** 454,461 **** return 0; screen->buffer = val->boolean ? screen->buffers[BUFIDX_ALTSCREEN] : screen->buffers[BUFIDX_PRIMARY]; ! // 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; --- 455,463 ---- return 0; screen->buffer = val->boolean ? screen->buffers[BUFIDX_ALTSCREEN] : screen->buffers[BUFIDX_PRIMARY]; ! /* 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; *************** *** 464,470 **** damagescreen(screen); break; default: ! ; // ignore } if(screen->callbacks && screen->callbacks->settermprop) --- 466,472 ---- damagescreen(screen); break; default: ! ; /* ignore */ } if(screen->callbacks && screen->callbacks->settermprop) *************** *** 491,497 **** ScreenCell *old_buffer = screen->buffers[bufidx]; ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols); ! /* Find the final row of old buffer content */ int old_row = old_rows - 1; int new_row = new_rows - 1; int col; --- 493,499 ---- ScreenCell *old_buffer = screen->buffers[bufidx]; ScreenCell *new_buffer = vterm_allocator_malloc(screen->vt, sizeof(ScreenCell) * new_rows * new_cols); ! // Find the final row of old buffer content int old_row = old_rows - 1; int new_row = new_rows - 1; int col; *************** *** 573,582 **** memmove(&new_buffer[0], &new_buffer[(new_row + 1) * new_cols], moverows * new_cols * sizeof(ScreenCell)); for(new_row = moverows; new_row < new_rows; new_row++) - { for(col = 0; col < new_cols; col++) clearcell(screen, &new_buffer[new_row * new_cols + col]); - } } vterm_allocator_free(screen->vt, old_buffer); --- 575,582 ---- *************** *** 729,734 **** --- 729,735 ---- vterm_allocator_free(screen->vt, screen->buffers[BUFIDX_ALTSCREEN]); vterm_allocator_free(screen->vt, screen->sb_buffer); + vterm_allocator_free(screen->vt, screen); } *************** *** 802,808 **** 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); --- 803,809 ---- 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); *************** *** 860,866 **** 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) --- 861,867 ---- 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.2.0812/src/libvterm/src/state.c 2020-05-21 20:10:00.285336763 +0200 --- src/libvterm/src/state.c 2020-05-22 21:46:36.909610029 +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) { *************** *** 299,306 **** 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); --- 299,307 ---- 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); *************** *** 310,319 **** 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; --- 311,320 ---- 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; *************** *** 323,334 **** 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); --- 324,335 ---- 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); *************** *** 344,350 **** printf("}\n"); #endif ! // Now render it putglyph(state, state->combine_chars, state->combine_width, state->combine_pos); } else { --- 345,351 ---- printf("}\n"); #endif ! /* Now render it */ putglyph(state, state->combine_chars, state->combine_width, state->combine_pos); } else { *************** *** 418,425 **** 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) --- 419,426 ---- 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) *************** *** 619,626 **** { 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) --- 620,628 ---- { 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) *************** *** 1338,1344 **** case 2: case 4: break; ! // TODO: 1, 2 and 4 aren't meaningful yet without line tab stops default: return 0; } --- 1340,1346 ---- case 2: case 4: break; ! /* TODO: 1, 2 and 4 aren't meaningful yet without line tab stops */ default: return 0; } *************** *** 1773,1779 **** 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) --- 1775,1781 ---- 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) *************** *** 2012,2019 **** 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; --- 2014,2021 ---- 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.2.0812/src/libvterm/src/unicode.c 2020-05-17 14:59:24.063410405 +0200 --- src/libvterm/src/unicode.c 2020-05-22 21:50:28.160693260 +0200 *************** *** 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 --- 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 *************** *** 75,82 **** #if !defined(WCWIDTH_FUNCTION) || !defined(IS_COMBINING_FUNCTION) ! // 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}, --- 74,81 ---- #if !defined(WCWIDTH_FUNCTION) || !defined(IS_COMBINING_FUNCTION) ! /* 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}, *************** *** 362,368 **** }; #endif ! // 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; --- 361,367 ---- }; #endif ! /* 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; *************** *** 382,387 **** --- 381,387 ---- return 0; } + /* The following two functions define the column width of an ISO 10646 * character as follows: * *************** *** 422,451 **** 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))); --- 422,451 ---- 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))); *************** *** 479,486 **** static int mk_wcwidth_cjk(uint32_t ucs) { #endif ! // sorted list of non-overlapping intervals of East Asian Ambiguous ! // characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" static const struct interval ambiguous[] = { { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, --- 479,486 ---- static int mk_wcwidth_cjk(uint32_t ucs) { #endif ! /* sorted list of non-overlapping intervals of East Asian Ambiguous ! * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */ static const struct interval ambiguous[] = { { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 }, { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 }, *************** *** 537,543 **** }; #if 0 ! // binary search in table of non-spacing characters if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; --- 537,543 ---- }; #if 0 ! /* binary search in table of non-spacing characters */ if (bisearch(ucs, ambiguous, sizeof(ambiguous) / sizeof(struct interval) - 1)) return 2; *************** *** 545,550 **** --- 545,551 ---- return mk_wcwidth(ucs); } + static int mk_wcswidth_cjk(const uint32_t *pwcs, size_t n) { int w, width = 0; *** ../vim-8.2.0812/src/libvterm/src/vterm.c 2020-05-20 18:41:37.157258608 +0200 --- src/libvterm/src/vterm.c 2020-05-22 21:56:00.583417031 +0200 *************** *** 10,18 **** #include "utf8.h" ! /////////////////// ! // API functions // ! /////////////////// static void *default_malloc(size_t size, void *allocdata UNUSED) { --- 10,18 ---- #include "utf8.h" ! /***************** ! * API functions * ! *****************/ static void *default_malloc(size_t size, void *allocdata UNUSED) { *************** *** 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) *************** *** 269,275 **** case VTERM_N_ATTRS: return 0; } ! return 0; // UNREACHABLE } VTermValueType vterm_get_prop_type(VTermProp prop) --- 269,275 ---- case VTERM_N_ATTRS: return 0; } ! return 0; /* UNREACHABLE */ } VTermValueType vterm_get_prop_type(VTermProp prop) *************** *** 287,293 **** case VTERM_N_PROPS: return 0; } ! return 0; // UNREACHABLE } void vterm_scroll_rect(VTermRect rect, --- 287,293 ---- case VTERM_N_PROPS: return 0; } ! return 0; /* UNREACHABLE */ } void vterm_scroll_rect(VTermRect rect, *************** *** 302,325 **** 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; --- 302,327 ---- 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; *************** *** 375,382 **** 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; --- 377,383 ---- 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; *************** *** 387,394 **** 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; --- 388,394 ---- 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.2.0812/src/version.c 2020-05-22 20:01:02.424452078 +0200 --- src/version.c 2020-05-22 22:04:20.793624534 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 813, /**/ -- hundred-and-one symptoms of being an internet addict: 166. You have been on your computer soo long that you didn't realize you had grandchildren. /// 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 ///