Patch 8.1.1885
Problem:    Comments in libvterm are inconsistent.
Solution:   Use // comments.  Als update the table of combining characters.
Files:      src/libvterm/bin/unterm.c, src/libvterm/bin/vterm-ctrl.c,
            src/libvterm/bin/vterm-dump.c, src/libvterm/include/vterm.h,
            src/libvterm/include/vterm_keycodes.h,
            src/libvterm/src/encoding.c, src/libvterm/src/keyboard.c,
            src/libvterm/src/mouse.c, src/libvterm/src/parser.c,
            src/libvterm/src/pen.c, src/libvterm/src/rect.h,
            src/libvterm/src/state.c, src/libvterm/src/unicode.c,
            src/libvterm/src/utf8.h, src/libvterm/src/vterm.c,
            src/libvterm/src/vterm_internal.h, src/libvterm/src/termscreen.c


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

-- 
>From "know your smileys":
 :~)    A man with a tape recorder up his nose

 /// Bram Moolenaar -- [email protected] -- 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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201908181844.x7IIiocB025825%40masaka.moolenaar.net.

Raspunde prin e-mail lui