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 -- b...@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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202005222006.04MK6fVZ011594%40masaka.moolenaar.net.

Raspunde prin e-mail lui