Patch 8.0.1639
Problem:    Libvterm code lags behind master.
Solution:   Sync to head, solve merge problems.
Files:      src/libvterm/README, src/libvterm/bin/unterm.c,
            src/libvterm/bin/vterm-ctrl.c, src/libvterm/bin/vterm-dump.c,
            src/libvterm/doc/URLs, src/libvterm/doc/seqs.txt,
            src/libvterm/include/vterm.h,
            src/libvterm/include/vterm_keycodes.h, 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/vterm.c, src/libvterm/src/vterm_internal.h,
            src/libvterm/t/10state_putglyph.test,
            src/libvterm/t/25state_input.test, src/libvterm/t/harness.c,
            src/libvterm/t/26state_query.test


*** ../vim-8.0.1638/src/libvterm/README 2017-07-23 22:07:23.041277153 +0200
--- src/libvterm/README 2018-03-25 15:51:01.967096196 +0200
***************
*** 10,12 ****
--- 10,30 ----
  - Add a .gitignore file.
  - Convert from C99 to C90.
  - Other changes to support embedding in Vim.
+ 
+ 
+ To merge in changes from Github, do this:
+ - Commit any pending changes.
+ - Setup the merge tool:
+     git config merge.tool vimdiff
+     git config merge.conflictstyle diff3
+     git config mergetool.prompt false
+ - Run the merge tool:
+     git mergetool
+   This will open a four-way diff between:
+      LOCAL  - your current version
+      BASE   - version as it was at your last sync
+      REMOTE - version at head on Github
+      MERGED - best-effort merge of LOCAL and REMOTE
+   Now find places where automatic merge didn't work, they are marked with
+   <<<<<<<<, ======= and >>>>>>>
+   Fix those places in MERGED, remove the markers, and save the file :wqall.
*** ../vim-8.0.1638/src/libvterm/bin/unterm.c   2017-07-25 21:34:42.065132676 
+0200
--- src/libvterm/bin/unterm.c   2018-03-25 15:04:33.706954390 +0200
***************
*** 95,102 ****
              sgr[sgri++] = 90 + (index - 8);
            else {
              sgr[sgri++] = 38;
!             sgr[sgri++] = 5 | (1<<31);
!             sgr[sgri++] = index | (1<<31);
            }
          }
  
--- 95,102 ----
              sgr[sgri++] = 90 + (index - 8);
            else {
              sgr[sgri++] = 38;
!             sgr[sgri++] = 5 | CSI_ARG_FLAG_MORE;
!             sgr[sgri++] = index | CSI_ARG_FLAG_MORE;
            }
          }
  
***************
*** 112,119 ****
              sgr[sgri++] = 100 + (index - 8);
            else {
              sgr[sgri++] = 48;
!             sgr[sgri++] = 5 | (1<<31);
!             sgr[sgri++] = index | (1<<31);
            }
          }
  
--- 112,119 ----
              sgr[sgri++] = 100 + (index - 8);
            else {
              sgr[sgri++] = 48;
!             sgr[sgri++] = 5 | CSI_ARG_FLAG_MORE;
!             sgr[sgri++] = index | CSI_ARG_FLAG_MORE;
            }
          }
  
***************
*** 125,133 ****
          int i;
          for(i = 0; i < sgri; i++)
            printf(!i               ? "%d" :
!               sgr[i] & (1<<31) ? ":%d" :
                ";%d",
!               sgr[i] & ~(1<<31));
        }
          printf("m");
        }
--- 125,133 ----
          int i;
          for(i = 0; i < sgri; i++)
            printf(!i               ? "%d" :
!               CSI_ARG_HAS_MORE(sgr[i]) ? ":%d" :
                ";%d",
!               CSI_ARG(sgr[i]));
        }
          printf("m");
        }
***************
*** 283,287 ****
--- 283,288 ----
    close(fd);
  
    vterm_free(vt);
+ 
    return 0;
  }
*** ../vim-8.0.1638/src/libvterm/bin/vterm-ctrl.c       2017-07-24 
22:26:39.757774872 +0200
--- src/libvterm/bin/vterm-ctrl.c       2018-03-25 15:12:40.460260840 +0200
***************
*** 53,58 ****
--- 53,59 ----
    "curblink [off|on|query]",
    "curshape [block|under|bar|query]",
    "mouse [off|click|clickdrag|motion]",
+   "reportfocus [off|on|query]",
    "altscreen [off|on|query]",
    "bracketpaste [off|on|query]",
    "icontitle [STR]",
***************
*** 81,89 ****
    return ret;
  }
  
! static void await_c1(int c1)
  {
!   int c;
  
    /* await CSI - 8bit or 2byte 7bit form */
    int in_esc = FALSE;
--- 82,90 ----
    return ret;
  }
  
! static void await_c1(unsigned char c1)
  {
!   unsigned char c;
  
    /* await CSI - 8bit or 2byte 7bit form */
    int in_esc = FALSE;
***************
*** 340,345 ****
--- 341,349 ----
          printf("\x1b[?1003h"); break;
        }
      }
+     else if(streq(arg, "reportfocus")) {
+       do_dec_mode(1004, getboolq(&argi, argc, argv), "reportfocus");
+     }
      else if(streq(arg, "altscreen")) {
        do_dec_mode(1049, getboolq(&argi, argc, argv), "altscreen");
      }
*** ../vim-8.0.1638/src/libvterm/bin/vterm-dump.c       2017-07-07 
11:53:29.515876528 +0200
--- src/libvterm/bin/vterm-dump.c       2018-03-25 15:13:04.920126272 +0200
***************
*** 227,231 ****
--- 227,232 ----
  
    close(fd);
    vterm_free(vt);
+ 
    return 0;
  }
*** ../vim-8.0.1638/src/libvterm/doc/URLs       2017-07-07 11:53:29.515876528 
+0200
--- src/libvterm/doc/URLs       2018-03-25 14:54:41.670318525 +0200
***************
*** 9,11 ****
--- 9,14 ----
  
  Digital VT220 Programmer Reference Manual
    http://vt100.net/docs/vt220-rm/
+ 
+ Summary of ANSI standards for ASCII terminals
+   http://www.inwap.com/pdp10/ansicode.txt
*** ../vim-8.0.1638/src/libvterm/doc/seqs.txt   2017-07-07 11:53:29.515876528 
+0200
--- src/libvterm/doc/seqs.txt   2018-03-25 14:54:41.670318525 +0200
***************
*** 151,156 ****
--- 151,157 ----
        DECSM 1000       = Mouse click/release tracking
        DECSM 1002       = Mouse click/release/drag tracking
        DECSM 1003       = Mouse all movements tracking
+       DECSM 1004       = Focus in/out reporting
        DECSM 1005       = Mouse protocol extended (UTF-8) - not recommended
        DECSM 1006       = Mouse protocol SGR
        DECSM 1015       = Mouse protocol rxvt
*** ../vim-8.0.1638/src/libvterm/include/vterm.h        2018-03-11 
19:30:40.124142765 +0100
--- src/libvterm/include/vterm.h        2018-03-25 15:17:15.922747952 +0200
***************
*** 96,102 ****
    VTERM_VALUETYPE_BOOL = 1,
    VTERM_VALUETYPE_INT,
    VTERM_VALUETYPE_STRING,
!   VTERM_VALUETYPE_COLOR
  } VTermValueType;
  
  typedef union {
--- 96,104 ----
    VTERM_VALUETYPE_BOOL = 1,
    VTERM_VALUETYPE_INT,
    VTERM_VALUETYPE_STRING,
!   VTERM_VALUETYPE_COLOR,
! 
!   VTERM_N_VALUETYPES
  } VTermValueType;
  
  typedef union {
***************
*** 116,122 ****
    VTERM_ATTR_STRIKE,     /* bool:   9, 29 */
    VTERM_ATTR_FONT,       /* number: 10-19 */
    VTERM_ATTR_FOREGROUND, /* color:  30-39 90-97 */
!   VTERM_ATTR_BACKGROUND  /* color:  40-49 100-107 */
  } VTermAttr;
  
  typedef enum {
--- 118,126 ----
    VTERM_ATTR_STRIKE,     /* bool:   9, 29 */
    VTERM_ATTR_FONT,       /* number: 10-19 */
    VTERM_ATTR_FOREGROUND, /* color:  30-39 90-97 */
!   VTERM_ATTR_BACKGROUND, /* color:  40-49 100-107 */
! 
!   VTERM_N_ATTRS
  } VTermAttr;
  
  typedef enum {
***************
*** 129,148 ****
    VTERM_PROP_REVERSE,           /* bool */
    VTERM_PROP_CURSORSHAPE,       /* number */
    VTERM_PROP_MOUSE,             /* number */
!   VTERM_PROP_CURSORCOLOR        /* string */
  } VTermProp;
  
  enum {
    VTERM_PROP_CURSORSHAPE_BLOCK = 1,
    VTERM_PROP_CURSORSHAPE_UNDERLINE,
!   VTERM_PROP_CURSORSHAPE_BAR_LEFT
  };
  
  enum {
    VTERM_PROP_MOUSE_NONE = 0,
    VTERM_PROP_MOUSE_CLICK,
    VTERM_PROP_MOUSE_DRAG,
!   VTERM_PROP_MOUSE_MOVE
  };
  
  typedef struct {
--- 133,158 ----
    VTERM_PROP_REVERSE,           /* bool */
    VTERM_PROP_CURSORSHAPE,       /* number */
    VTERM_PROP_MOUSE,             /* number */
!   VTERM_PROP_CURSORCOLOR,       /* string */
! 
!   VTERM_N_PROPS
  } VTermProp;
  
  enum {
    VTERM_PROP_CURSORSHAPE_BLOCK = 1,
    VTERM_PROP_CURSORSHAPE_UNDERLINE,
!   VTERM_PROP_CURSORSHAPE_BAR_LEFT,
! 
!   VTERM_N_PROP_CURSORSHAPES
  };
  
  enum {
    VTERM_PROP_MOUSE_NONE = 0,
    VTERM_PROP_MOUSE_CLICK,
    VTERM_PROP_MOUSE_DRAG,
!   VTERM_PROP_MOUSE_MOVE,
! 
!   VTERM_N_PROP_MOUSES
  };
  
  typedef struct {
***************
*** 213,220 ****
   *
   * Don't confuse this with the final byte of the CSI escape; 'a' in this case.
   */
! #define CSI_ARG_FLAG_MORE (1<<30)
! #define CSI_ARG_MASK      (~(1<<30))
  
  #define CSI_ARG_HAS_MORE(a) ((a) & CSI_ARG_FLAG_MORE)
  #define CSI_ARG(a)          ((a) & CSI_ARG_MASK)
--- 223,230 ----
   *
   * 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)
***************
*** 293,298 ****
--- 303,310 ----
  void vterm_state_set_bold_highbright(VTermState *state, int 
bold_is_highbright);
  int  vterm_state_get_penattr(const VTermState *state, VTermAttr attr, 
VTermValue *val);
  int  vterm_state_set_termprop(VTermState *state, VTermProp prop, VTermValue 
*val);
+ void vterm_state_focus_in(VTermState *state);
+ void vterm_state_focus_out(VTermState *state);
  const VTermLineInfo *vterm_state_get_lineinfo(const VTermState *state, int 
row);
  
  /* ------------
***************
*** 357,363 ****
    VTERM_DAMAGE_CELL,    /* every cell */
    VTERM_DAMAGE_ROW,     /* entire rows */
    VTERM_DAMAGE_SCREEN,  /* entire screen */
!   VTERM_DAMAGE_SCROLL   /* entire screen + scrollrect */
  } VTermDamageSize;
  
  /* Invoke the relevant callbacks to update the screen. */
--- 369,377 ----
    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. */
***************
*** 384,390 ****
    VTERM_ATTR_STRIKE_MASK     = 1 << 5,
    VTERM_ATTR_FONT_MASK       = 1 << 6,
    VTERM_ATTR_FOREGROUND_MASK = 1 << 7,
!   VTERM_ATTR_BACKGROUND_MASK = 1 << 8
  } VTermAttrMask;
  
  int vterm_screen_get_attrs_extent(const VTermScreen *screen, VTermRect 
*extent, VTermPos pos, VTermAttrMask attrs);
--- 398,406 ----
    VTERM_ATTR_STRIKE_MASK     = 1 << 5,
    VTERM_ATTR_FONT_MASK       = 1 << 6,
    VTERM_ATTR_FOREGROUND_MASK = 1 << 7,
!   VTERM_ATTR_BACKGROUND_MASK = 1 << 8,
! 
!   VTERM_ALL_ATTRS_MASK = (1 << 9) - 1
  } VTermAttrMask;
  
  int vterm_screen_get_attrs_extent(const VTermScreen *screen, VTermRect 
*extent, VTermPos pos, VTermAttrMask attrs);
*** ../vim-8.0.1638/src/libvterm/include/vterm_keycodes.h       2018-02-27 
17:25:48.012151938 +0100
--- src/libvterm/include/vterm_keycodes.h       2018-03-25 15:17:54.606535872 
+0200
***************
*** 5,11 ****
    VTERM_MOD_NONE  = 0x00,
    VTERM_MOD_SHIFT = 0x01,
    VTERM_MOD_ALT   = 0x02,
!   VTERM_MOD_CTRL  = 0x04
  } VTermModifier;
  
  /* The order here must match keycodes[] in src/keyboard.c! */
--- 5,13 ----
    VTERM_MOD_NONE  = 0x00,
    VTERM_MOD_SHIFT = 0x01,
    VTERM_MOD_ALT   = 0x02,
!   VTERM_MOD_CTRL  = 0x04,
! 
!   VTERM_ALL_MODS_MASK = 0x07 
  } VTermModifier;
  
  /* The order here must match keycodes[] in src/keyboard.c! */
***************
*** 53,59 ****
    VTERM_KEY_KP_ENTER,
    VTERM_KEY_KP_EQUAL,
  
!   VTERM_KEY_MAX /* Must be last */
  } VTermKey;
  
  #define VTERM_KEY_FUNCTION(n) (VTERM_KEY_FUNCTION_0+(n))
--- 55,62 ----
    VTERM_KEY_KP_ENTER,
    VTERM_KEY_KP_EQUAL,
  
!   VTERM_KEY_MAX, /* Must be last */
!   VTERM_N_KEYS = VTERM_KEY_MAX
  } VTermKey;
  
  #define VTERM_KEY_FUNCTION(n) (VTERM_KEY_FUNCTION_0+(n))
*** ../vim-8.0.1638/src/libvterm/src/mouse.c    2017-08-05 18:02:17.162202692 
+0200
--- src/libvterm/src/mouse.c    2018-03-11 17:55:59.250467734 +0100
***************
*** 63,71 ****
  
    if((state->mouse_flags & MOUSE_WANT_DRAG && state->mouse_buttons) ||
       (state->mouse_flags & MOUSE_WANT_MOVE)) {
!     int button = state->mouse_buttons & 0x01 ? 1 :
!                  state->mouse_buttons & 0x02 ? 2 :
!                  state->mouse_buttons & 0x04 ? 3 : 4;
      output_mouse(state, button-1 + 0x20, 1, mod, col, row);
    }
  }
--- 63,71 ----
  
    if((state->mouse_flags & MOUSE_WANT_DRAG && state->mouse_buttons) ||
       (state->mouse_flags & MOUSE_WANT_MOVE)) {
!     int button = state->mouse_buttons & MOUSE_BUTTON_LEFT ? 1 :
!                  state->mouse_buttons & MOUSE_BUTTON_MIDDLE ? 2 :
!                  state->mouse_buttons & MOUSE_BUTTON_RIGHT ? 3 : 4;
      output_mouse(state, button-1 + 0x20, 1, mod, col, row);
    }
  }
*** ../vim-8.0.1638/src/libvterm/src/parser.c   2017-07-23 22:07:23.041277153 
+0200
--- src/libvterm/src/parser.c   2018-03-25 16:07:46.489469961 +0200
***************
*** 3,190 ****
  #include <stdio.h>
  #include <string.h>
  
! #define CSI_ARGS_MAX 16
! #define CSI_LEADER_MAX 16
! #define CSI_INTERMED_MAX 16
  
  static void do_control(VTerm *vt, unsigned char control)
  {
!   if(vt->parser_callbacks && vt->parser_callbacks->control)
!     if((*vt->parser_callbacks->control)(control, vt->cbdata))
        return;
  
    DEBUG_LOG1("libvterm: Unhandled control 0x%02x\n", control);
  }
  
! static void do_string_csi(VTerm *vt, const char *args, size_t arglen, char 
command)
  {
!   int i = 0;
! 
!   int leaderlen = 0;
!   char leader[CSI_LEADER_MAX];
!   int argcount = 1; /* Always at least 1 arg */
!   long csi_args[CSI_ARGS_MAX];
!   int argi;
!   int intermedlen = 0;
!   char intermed[CSI_INTERMED_MAX];
! 
!   /* Extract leader bytes 0x3c to 0x3f */
!   for( ; i < (int)arglen; i++) {
!     if(args[i] < 0x3c || args[i] > 0x3f)
!       break;
!     if(leaderlen < CSI_LEADER_MAX-1)
!       leader[leaderlen++] = args[i];
!   }
! 
!   leader[leaderlen] = 0;
! 
!   for( ; i < (int)arglen; i++)
!     if(args[i] == 0x3b || args[i] == 0x3a) /* ; or : */
!       argcount++;
! 
!   /* TODO: Consider if these buffers should live in the VTerm struct itself */
!   if(argcount > CSI_ARGS_MAX)
!     argcount = CSI_ARGS_MAX;
! 
!   for(argi = 0; argi < argcount; argi++)
!     csi_args[argi] = CSI_ARG_MISSING;
! 
!   argi = 0;
!   for(i = leaderlen; i < (int)arglen && argi < argcount; i++) {
!     switch(args[i]) {
!     case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
!     case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
!       if(csi_args[argi] == CSI_ARG_MISSING)
!         csi_args[argi] = 0;
!       csi_args[argi] *= 10;
!       csi_args[argi] += args[i] - '0';
!       break;
!     case 0x3a:
!       csi_args[argi] |= CSI_ARG_FLAG_MORE;
!       /* FALLTHROUGH */
!     case 0x3b:
!       argi++;
!       break;
!     default:
!       goto done_leader;
!     }
    }
! done_leader: ;
! 
!   for( ; i < (int)arglen; i++) {
!     if((args[i] & 0xf0) != 0x20)
!       break;
  
!     if(intermedlen < CSI_INTERMED_MAX-1)
!       intermed[intermedlen++] = args[i];
!   }
  
!   intermed[intermedlen] = 0;
  
!   if(i < (int)arglen) {
!     DEBUG_LOG2("libvterm: TODO unhandled CSI bytes \"%.*s\"\n", (int)(arglen 
- i), args + i);
!   }
  
! #if 0
!   printf("Parsed CSI args %.*s as:\n", arglen, args);
!   printf(" leader: %s\n", leader);
!   for(argi = 0; argi < argcount; argi++) {
!     printf(" %lu", CSI_ARG(csi_args[argi]));
!     if(!CSI_ARG_HAS_MORE(csi_args[argi]))
!       printf("\n");
!   printf(" intermed: %s\n", intermed);
!   }
! #endif
  
!   if(vt->parser_callbacks && vt->parser_callbacks->csi)
!     if((*vt->parser_callbacks->csi)(leaderlen ? leader : NULL, csi_args, 
argcount, intermedlen ? intermed : NULL, command, vt->cbdata))
        return;
  
!   DEBUG_LOG3("libvterm: Unhandled CSI %.*s %c\n", (int)arglen, args, command);
  }
  
  static void append_strbuffer(VTerm *vt, const char *str, size_t len)
  {
!   if(len > vt->strbuffer_len - vt->strbuffer_cur) {
!     len = vt->strbuffer_len - vt->strbuffer_cur;
      DEBUG_LOG1("Truncating strbuffer preserve to %zd bytes\n", len);
    }
  
    if(len > 0) {
!     strncpy(vt->strbuffer + vt->strbuffer_cur, str, len);
!     vt->strbuffer_cur += len;
    }
  }
  
! static size_t do_string(VTerm *vt, const char *str_frag, size_t len)
  {
!   size_t eaten;
  
!   if(vt->strbuffer_cur) {
!     if(str_frag)
!       append_strbuffer(vt, str_frag, len);
  
!     str_frag = vt->strbuffer;
!     len = vt->strbuffer_cur;
    }
!   else if(!str_frag) {
      DEBUG_LOG("parser.c: TODO: No strbuffer _and_ no final fragment???\n");
      len = 0;
    }
  
!   vt->strbuffer_cur = 0;
! 
!   switch(vt->parser_state) {
!   case NORMAL:
!     if(vt->parser_callbacks && vt->parser_callbacks->text)
!       if((eaten = (*vt->parser_callbacks->text)(str_frag, len, vt->cbdata)))
!         return eaten;
! 
!     DEBUG_LOG1("libvterm: Unhandled text (%zu chars)\n", len);
!     return 0;
  
!   case ESC:
!     if(len == 1 && str_frag[0] >= 0x40 && str_frag[0] < 0x60) {
!       /* C1 emulations using 7bit clean */
!       /* ESC 0x40 == 0x80 */
!       do_control(vt, str_frag[0] + 0x40);
!       return 0;
!     }
  
!     if(vt->parser_callbacks && vt->parser_callbacks->escape)
!       if((*vt->parser_callbacks->escape)(str_frag, len, vt->cbdata))
!         return 0;
! 
!     DEBUG_LOG1("libvterm: Unhandled escape ESC 0x%02x\n", str_frag[len-1]);
!     return 0;
! 
!   case CSI:
!     do_string_csi(vt, str_frag, len - 1, str_frag[len - 1]);
!     return 0;
! 
!   case OSC:
!     if(vt->parser_callbacks && vt->parser_callbacks->osc)
!       if((*vt->parser_callbacks->osc)(str_frag, len, vt->cbdata))
!         return 0;
! 
!     DEBUG_LOG2("libvterm: Unhandled OSC %.*s\n", (int)len, str_frag);
!     return 0;
! 
!   case DCS:
!     if(vt->parser_callbacks && vt->parser_callbacks->dcs)
!       if((*vt->parser_callbacks->dcs)(str_frag, len, vt->cbdata))
!         return 0;
! 
!     DEBUG_LOG2("libvterm: Unhandled DCS %.*s\n", (int)len, str_frag);
!     return 0;
! 
!   case ESC_IN_OSC:
!   case ESC_IN_DCS:
!     DEBUG_LOG("libvterm: ARGH! Should never do_string() in 
ESC_IN_{OSC,DCS}\n");
!     return 0;
    }
- 
-   return 0;
  }
  
  size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
--- 3,125 ----
  #include <stdio.h>
  #include <string.h>
  
! #undef DEBUG_PARSER
! 
! static int is_intermed(unsigned char c)
! {
!   return c >= 0x20 && c <= 0x2f;
! }
  
  static void do_control(VTerm *vt, unsigned char control)
  {
!   if(vt->parser.callbacks && vt->parser.callbacks->control)
!     if((*vt->parser.callbacks->control)(control, vt->parser.cbdata))
        return;
  
    DEBUG_LOG1("libvterm: Unhandled control 0x%02x\n", control);
  }
  
! static void do_csi(VTerm *vt, char command)
  {
! #ifdef DEBUG_PARSER
!   printf("Parsed CSI args as:\n", arglen, args);
!   printf(" leader: %s\n", vt->parser.csi_leader);
!   for(int argi = 0; argi < vt->parser.csi_argi; argi++) {
!     printf(" %lu", CSI_ARG(vt->parser.csi_args[argi]));
!     if(!CSI_ARG_HAS_MORE(vt->parser.csi_args[argi]))
!       printf("\n");
!   printf(" intermed: %s\n", vt->parser.intermed);
    }
! #endif
  
!   if(vt->parser.callbacks && vt->parser.callbacks->csi)
!     if((*vt->parser.callbacks->csi)(
!           vt->parser.csi_leaderlen ? vt->parser.csi_leader : NULL,
!           vt->parser.csi_args,
!           vt->parser.csi_argi,
!           vt->parser.intermedlen ? vt->parser.intermed : NULL,
!           command,
!           vt->parser.cbdata))
!       return;
  
!   DEBUG_LOG1("libvterm: Unhandled CSI %c\n", command);
! }
  
! static void do_escape(VTerm *vt, char command)
! {
!   char seq[INTERMED_MAX+1];
  
!   size_t len = vt->parser.intermedlen;
!   strncpy(seq, vt->parser.intermed, len);
!   seq[len++] = command;
!   seq[len]   = 0;
  
!   if(vt->parser.callbacks && vt->parser.callbacks->escape)
!     if((*vt->parser.callbacks->escape)(seq, len, vt->parser.cbdata))
        return;
  
!   DEBUG_LOG1("libvterm: Unhandled escape ESC 0x%02x\n", command);
  }
  
  static void append_strbuffer(VTerm *vt, const char *str, size_t len)
  {
!   if(len > vt->parser.strbuffer_len - vt->parser.strbuffer_cur) {
!     len = vt->parser.strbuffer_len - vt->parser.strbuffer_cur;
      DEBUG_LOG1("Truncating strbuffer preserve to %zd bytes\n", len);
    }
  
    if(len > 0) {
!     strncpy(vt->parser.strbuffer + vt->parser.strbuffer_cur, str, len);
!     vt->parser.strbuffer_cur += len;
    }
  }
  
! static void start_string(VTerm *vt, VTermParserStringType type)
  {
!   vt->parser.stringtype = type;
  
!   vt->parser.strbuffer_cur = 0;
! }
! 
! static void more_string(VTerm *vt, const char *str, size_t len)
! {
!   append_strbuffer(vt, str, len);
! }
  
! static void done_string(VTerm *vt, const char *str, size_t len)
! {
!   if(vt->parser.strbuffer_cur) {
!     if(str)
!       append_strbuffer(vt, str, len);
! 
!     str = vt->parser.strbuffer;
!     len = vt->parser.strbuffer_cur;
    }
!   else if(!str) {
      DEBUG_LOG("parser.c: TODO: No strbuffer _and_ no final fragment???\n");
      len = 0;
    }
  
!   switch(vt->parser.stringtype) {
!   case VTERM_PARSER_OSC:
!     if(vt->parser.callbacks && vt->parser.callbacks->osc)
!       if((*vt->parser.callbacks->osc)(str, len, vt->parser.cbdata))
!         return;
! 
!     DEBUG_LOG2("libvterm: Unhandled OSC %.*s\n", (int)len, str);
!     return;
! 
!   case VTERM_PARSER_DCS:
!     if(vt->parser.callbacks && vt->parser.callbacks->dcs)
!       if((*vt->parser.callbacks->dcs)(str, len, vt->parser.cbdata))
!         return;
  
!     DEBUG_LOG2("libvterm: Unhandled DCS %.*s\n", (int)len, str);
!     return;
  
!   case VTERM_N_PARSER_TYPES:
!     return;
    }
  }
  
  size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
***************
*** 192,220 ****
    size_t pos = 0;
    const char *string_start = NULL;  /* init to avoid gcc warning */
  
!   switch(vt->parser_state) {
    case NORMAL:
      string_start = NULL;
      break;
!   case ESC:
!   case ESC_IN_OSC:
!   case ESC_IN_DCS:
!   case CSI:
!   case OSC:
!   case DCS:
      string_start = bytes;
      break;
    }
  
! #define ENTER_STRING_STATE(st) do { vt->parser_state = st; string_start = 
bytes + pos + 1; } while(0)
! #define ENTER_NORMAL_STATE()   do { vt->parser_state = NORMAL; string_start = 
NULL; } while(0)
  
    for( ; pos < len; pos++) {
      unsigned char c = bytes[pos];
  
      if(c == 0x00 || c == 0x7f) { /* NUL, DEL */
!       if(vt->parser_state != NORMAL) {
!         append_strbuffer(vt, string_start, bytes + pos - string_start);
          string_start = bytes + pos + 1;
        }
        continue;
--- 127,156 ----
    size_t pos = 0;
    const char *string_start = NULL;  /* init to avoid gcc warning */
  
!   switch(vt->parser.state) {
    case NORMAL:
+   case CSI_LEADER:
+   case CSI_ARGS:
+   case CSI_INTERMED:
+   case ESC:
      string_start = NULL;
      break;
!   case STRING:
!   case ESC_IN_STRING:
      string_start = bytes;
      break;
    }
  
! #define ENTER_STRING_STATE(st) do { vt->parser.state = STRING; string_start = 
bytes + pos + 1; } while(0)
! #define ENTER_STATE(st)        do { vt->parser.state = st; string_start = 
NULL; } while(0)
! #define ENTER_NORMAL_STATE()   ENTER_STATE(NORMAL)
  
    for( ; pos < len; pos++) {
      unsigned char c = bytes[pos];
  
      if(c == 0x00 || c == 0x7f) { /* NUL, DEL */
!       if(vt->parser.state >= STRING) {
!         more_string(vt, string_start, bytes + pos - string_start);
          string_start = bytes + pos + 1;
        }
        continue;
***************
*** 224,287 ****
        continue;
      }
      else if(c == 0x1b) { /* ESC */
!       if(vt->parser_state == OSC)
!         vt->parser_state = ESC_IN_OSC;
!       else if(vt->parser_state == DCS)
!         vt->parser_state = ESC_IN_DCS;
        else
!         ENTER_STRING_STATE(ESC);
        continue;
      }
      else if(c == 0x07 &&  /* BEL, can stand for ST in OSC or DCS state */
!             (vt->parser_state == OSC || vt->parser_state == DCS)) {
        /* fallthrough */
      }
      else if(c < 0x20) { /* other C0 */
!       if(vt->parser_state != NORMAL)
!         append_strbuffer(vt, string_start, bytes + pos - string_start);
        do_control(vt, c);
!       if(vt->parser_state != NORMAL)
          string_start = bytes + pos + 1;
        continue;
      }
      /* else fallthrough */
  
!     switch(vt->parser_state) {
!     case ESC_IN_OSC:
!     case ESC_IN_DCS:
        if(c == 0x5c) { /* ST */
!         switch(vt->parser_state) {
!           case ESC_IN_OSC: vt->parser_state = OSC; break;
!           case ESC_IN_DCS: vt->parser_state = DCS; break;
!           default: break;
!         }
!         do_string(vt, string_start, bytes + pos - string_start - 1);
          ENTER_NORMAL_STATE();
          break;
        }
!       vt->parser_state = ESC;
!       string_start = bytes + pos;
        /* else fallthrough */
  
      case ESC:
        switch(c) {
        case 0x50: /* DCS */
!         ENTER_STRING_STATE(DCS);
          break;
        case 0x5b: /* CSI */
!         ENTER_STRING_STATE(CSI);
          break;
        case 0x5d: /* OSC */
!         ENTER_STRING_STATE(OSC);
          break;
        default:
!         if(c >= 0x30 && c < 0x7f) {
!           /* +1 to pos because we want to include this command byte as well */
!           do_string(vt, string_start, bytes + pos - string_start + 1);
            ENTER_NORMAL_STATE();
          }
!         else if(c >= 0x20 && c < 0x30) {
!           /* intermediate byte */
          }
          else {
            DEBUG_LOG1("TODO: Unhandled byte %02x in Escape\n", c);
--- 160,223 ----
        continue;
      }
      else if(c == 0x1b) { /* ESC */
!       vt->parser.intermedlen = 0;
!       if(vt->parser.state == STRING)
!         vt->parser.state = ESC_IN_STRING;
        else
!         ENTER_STATE(ESC);
        continue;
      }
      else if(c == 0x07 &&  /* BEL, can stand for ST in OSC or DCS state */
!             vt->parser.state == STRING) {
        /* fallthrough */
      }
      else if(c < 0x20) { /* other C0 */
!       if(vt->parser.state >= STRING)
!         more_string(vt, string_start, bytes + pos - string_start);
        do_control(vt, c);
!       if(vt->parser.state >= STRING)
          string_start = bytes + pos + 1;
        continue;
      }
      /* else fallthrough */
  
!     switch(vt->parser.state) {
!     case ESC_IN_STRING:
        if(c == 0x5c) { /* ST */
!         vt->parser.state = STRING;
!         done_string(vt, string_start, bytes + pos - string_start - 1);
          ENTER_NORMAL_STATE();
          break;
        }
!       vt->parser.state = ESC;
        /* else fallthrough */
  
      case ESC:
        switch(c) {
        case 0x50: /* DCS */
!         start_string(vt, VTERM_PARSER_DCS);
!         ENTER_STRING_STATE();
          break;
        case 0x5b: /* CSI */
!         vt->parser.csi_leaderlen = 0;
!         ENTER_STATE(CSI_LEADER);
          break;
        case 0x5d: /* OSC */
!         start_string(vt, VTERM_PARSER_OSC);
!         ENTER_STRING_STATE();
          break;
        default:
!         if(is_intermed(c)) {
!           if(vt->parser.intermedlen < INTERMED_MAX-1)
!             vt->parser.intermed[vt->parser.intermedlen++] = c;
!         }
!         else if(!vt->parser.intermedlen && c >= 0x40 && c < 0x60) {
!           do_control(vt, c + 0x40);
            ENTER_NORMAL_STATE();
          }
!         else if(c >= 0x30 && c < 0x7f) {
!           do_escape(vt, c);
!           ENTER_NORMAL_STATE();
          }
          else {
            DEBUG_LOG1("TODO: Unhandled byte %02x in Escape\n", c);
***************
*** 289,306 ****
        }
        break;
  
!     case CSI:
!       if(c >= 0x40 && c <= 0x7f) {
!         /* +1 to pos because we want to include this command byte as well */
!         do_string(vt, string_start, bytes + pos - string_start + 1);
!         ENTER_NORMAL_STATE();
        }
        break;
  
!     case OSC:
!     case DCS:
        if(c == 0x07 || (c == 0x9c && !vt->mode.utf8)) {
!         do_string(vt, string_start, bytes + pos - string_start);
          ENTER_NORMAL_STATE();
        }
        break;
--- 225,291 ----
        }
        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;
!         vt->parser.csi_args[vt->parser.csi_argi] *= 10;
!         vt->parser.csi_args[vt->parser.csi_argi] += c - '0';
!         break;
        }
+       if(c == ':') {
+         vt->parser.csi_args[vt->parser.csi_argi] |= CSI_ARG_FLAG_MORE;
+         c = ';';
+       }
+       if(c == ';') {
+         vt->parser.csi_argi++;
+         vt->parser.csi_args[vt->parser.csi_argi] = CSI_ARG_MISSING;
+         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)
+           vt->parser.intermed[vt->parser.intermedlen++] = c;
+         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;
  
!     case STRING:
        if(c == 0x07 || (c == 0x9c && !vt->mode.utf8)) {
!         done_string(vt, string_start, bytes + pos - string_start);
          ENTER_NORMAL_STATE();
        }
        break;
***************
*** 309,321 ****
        if(c >= 0x80 && c < 0xa0 && !vt->mode.utf8) {
          switch(c) {
          case 0x90: /* DCS */
!           ENTER_STRING_STATE(DCS);
            break;
          case 0x9b: /* CSI */
!           ENTER_STRING_STATE(CSI);
            break;
          case 0x9d: /* OSC */
!           ENTER_STRING_STATE(OSC);
            break;
          default:
            do_control(vt, c);
--- 294,308 ----
        if(c >= 0x80 && c < 0xa0 && !vt->mode.utf8) {
          switch(c) {
          case 0x90: /* DCS */
!           start_string(vt, VTERM_PARSER_DCS);
!           ENTER_STRING_STATE();
            break;
          case 0x9b: /* CSI */
!           ENTER_STATE(CSI_LEADER);
            break;
          case 0x9d: /* OSC */
!           start_string(vt, VTERM_PARSER_OSC);
!           ENTER_STRING_STATE();
            break;
          default:
            do_control(vt, c);
***************
*** 323,346 ****
          }
        }
        else {
!         size_t text_eaten = do_string(vt, bytes + pos, len - pos);
! 
!         if(text_eaten == 0) {
!           string_start = bytes + pos;
!           goto pause;
          }
  
!         pos += (text_eaten - 1); /* we'll ++ it again in a moment */
        }
        break;
      }
    }
  
- pause:
-   if(string_start && string_start < len + bytes) {
-     size_t remaining = len - (string_start - bytes);
-     append_strbuffer(vt, string_start, remaining);
-   }
- 
    return len;
  }
--- 310,341 ----
          }
        }
        else {
!         size_t eaten = 0;
!         if(vt->parser.callbacks && vt->parser.callbacks->text)
!           eaten = (*vt->parser.callbacks->text)(bytes + pos, len - pos, 
vt->parser.cbdata);
! 
!         if(!eaten) {
!           DEBUG_LOG("libvterm: Text callback did not consume any input\n");
!           /* force it to make progress */
!           eaten = 1;
          }
  
!         pos += (eaten - 1); /* we'll ++ it again in a moment */
        }
        break;
      }
    }
  
    return len;
  }
+ 
+ void vterm_parser_set_callbacks(VTerm *vt, const VTermParserCallbacks 
*callbacks, void *user)
+ {
+   vt->parser.callbacks = callbacks;
+   vt->parser.cbdata = user;
+ }
+ 
+ void *vterm_parser_get_cbdata(VTerm *vt)
+ {
+   return vt->parser.cbdata;
+ }
*** ../vim-8.0.1638/src/libvterm/src/pen.c      2017-12-01 21:07:16.220989905 
+0100
--- src/libvterm/src/pen.c      2018-03-25 14:54:41.690318409 +0200
***************
*** 507,512 ****
--- 507,515 ----
    case VTERM_ATTR_BACKGROUND:
      val->color = state->pen.bg;
      return 1;
+ 
+   case VTERM_N_ATTRS:
+     return 0;
    }
  
    return 0;
*** ../vim-8.0.1638/src/libvterm/src/screen.c   2017-09-05 23:29:29.025108125 
+0200
--- src/libvterm/src/screen.c   2018-03-25 14:54:41.686318433 +0200
***************
*** 429,434 ****
--- 429,437 ----
    case VTERM_ATTR_BACKGROUND:
      screen->pen.bg = val->color;
      return 1;
+ 
+   case VTERM_N_ATTRS:
+     return 0;
    }
  
    return 0;
*** ../vim-8.0.1638/src/libvterm/src/state.c    2018-03-11 19:30:40.124142765 
+0100
--- src/libvterm/src/state.c    2018-03-25 15:33:22.025090186 +0200
***************
*** 268,274 ****
    if(!npoints)
    {
      vterm_allocator_free(state->vt, codepoints);
!     return 0;
    }
  
    if(state->gsingle_set && npoints)
--- 268,274 ----
    if(!npoints)
    {
      vterm_allocator_free(state->vt, codepoints);
!     return eaten;
    }
  
    if(state->gsingle_set && npoints)
***************
*** 781,786 ****
--- 781,790 ----
                          VTERM_PROP_MOUSE_MOVE);
      break;
  
+   case 1004:
+     state->mode.report_focus = val;
+     break;
+ 
    case 1005:
      state->mouse_protocol = val ? MOUSE_UTF8 : MOUSE_X10;
      break;
***************
*** 861,866 ****
--- 865,874 ----
        reply = state->mouse_flags == (MOUSE_WANT_CLICK|MOUSE_WANT_MOVE);
        break;
  
+     case 1004:
+       reply = state->mode.report_focus;
+       break;
+ 
      case 1005:
        reply = state->mouse_protocol == MOUSE_UTF8;
        break;
***************
*** 1728,1733 ****
--- 1736,1742 ----
    state->mode.origin          = 0;
    state->mode.leftrightmargin = 0;
    state->mode.bracketpaste    = 0;
+   state->mode.report_focus    = 0;
  
    state->vt->mode.ctrl8bit   = 0;
  
***************
*** 1882,1892 ****
--- 1891,1916 ----
      if(val->number == VTERM_PROP_MOUSE_MOVE)
        state->mouse_flags |= MOUSE_WANT_MOVE;
      return 1;
+ 
+   case VTERM_N_PROPS:
+     return 0;
    }
  
    return 0;
  }
  
+ void vterm_state_focus_in(VTermState *state)
+ {
+   if(state->mode.report_focus)
+     vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "I");
+ }
+ 
+ void vterm_state_focus_out(VTermState *state)
+ {
+   if(state->mode.report_focus)
+     vterm_push_output_sprintf_ctrl(state->vt, C1_CSI, "O");
+ }
+ 
  const VTermLineInfo *vterm_state_get_lineinfo(const VTermState *state, int 
row)
  {
    return state->lineinfo + row;
*** ../vim-8.0.1638/src/libvterm/src/vterm.c    2018-02-24 14:03:49.748678084 
+0100
--- src/libvterm/src/vterm.c    2018-03-25 15:33:57.116888731 +0200
***************
*** 47,60 ****
    vt->rows = rows;
    vt->cols = cols;
  
!   vt->parser_state = NORMAL;
  
!   vt->parser_callbacks = NULL;
!   vt->cbdata           = NULL;
  
!   vt->strbuffer_len = 64;
!   vt->strbuffer_cur = 0;
!   vt->strbuffer = vterm_allocator_malloc(vt, vt->strbuffer_len);
  
    vt->outbuffer_len = 200;
    vt->outbuffer_cur = 0;
--- 47,60 ----
    vt->rows = rows;
    vt->cols = cols;
  
!   vt->parser.state = NORMAL;
  
!   vt->parser.callbacks = NULL;
!   vt->parser.cbdata    = NULL;
  
!   vt->parser.strbuffer_len = 64;
!   vt->parser.strbuffer_cur = 0;
!   vt->parser.strbuffer = vterm_allocator_malloc(vt, vt->parser.strbuffer_len);
  
    vt->outbuffer_len = 200;
    vt->outbuffer_cur = 0;
***************
*** 71,77 ****
    if(vt->state)
      vterm_state_free(vt->state);
  
!   vterm_allocator_free(vt, vt->strbuffer);
    vterm_allocator_free(vt, vt->outbuffer);
  
    vterm_allocator_free(vt, vt);
--- 71,77 ----
    if(vt->state)
      vterm_state_free(vt->state);
  
!   vterm_allocator_free(vt, vt->parser.strbuffer);
    vterm_allocator_free(vt, vt->outbuffer);
  
    vterm_allocator_free(vt, vt);
***************
*** 100,107 ****
    vt->rows = rows;
    vt->cols = cols;
  
!   if(vt->parser_callbacks && vt->parser_callbacks->resize)
!     (*vt->parser_callbacks->resize)(rows, cols, vt->cbdata);
  }
  
  int vterm_get_utf8(const VTerm *vt)
--- 100,107 ----
    vt->rows = rows;
    vt->cols = cols;
  
!   if(vt->parser.callbacks && vt->parser.callbacks->resize)
!     (*vt->parser.callbacks->resize)(rows, cols, vt->parser.cbdata);
  }
  
  int vterm_get_utf8(const VTerm *vt)
***************
*** 257,273 ****
    return len;
  }
  
- void vterm_parser_set_callbacks(VTerm *vt, const VTermParserCallbacks 
*callbacks, void *user)
- {
-   vt->parser_callbacks = callbacks;
-   vt->cbdata = user;
- }
- 
- void *vterm_parser_get_cbdata(VTerm *vt)
- {
-   return vt->cbdata;
- }
- 
  VTermValueType vterm_get_attr_type(VTermAttr attr)
  {
    switch(attr) {
--- 257,262 ----
***************
*** 280,285 ****
--- 269,276 ----
      case VTERM_ATTR_FONT:       return VTERM_VALUETYPE_INT;
      case VTERM_ATTR_FOREGROUND: return VTERM_VALUETYPE_COLOR;
      case VTERM_ATTR_BACKGROUND: return VTERM_VALUETYPE_COLOR;
+ 
+     case VTERM_N_ATTRS: return 0;
    }
    return 0; /* UNREACHABLE */
  }
***************
*** 296,301 ****
--- 287,294 ----
      case VTERM_PROP_CURSORSHAPE:   return VTERM_VALUETYPE_INT;
      case VTERM_PROP_MOUSE:         return VTERM_VALUETYPE_INT;
      case VTERM_PROP_CURSORCOLOR:   return VTERM_VALUETYPE_STRING;
+ 
+     case VTERM_N_PROPS: return 0;
    }
    return 0; /* UNREACHABLE */
  }
*** ../vim-8.0.1638/src/libvterm/src/vterm_internal.h   2018-03-22 
20:26:46.706263857 +0100
--- src/libvterm/src/vterm_internal.h   2018-03-25 15:35:30.664353360 +0200
***************
*** 27,32 ****
--- 27,37 ----
  
  #define ESC_S "\x1b"
  
+ #define INTERMED_MAX 16
+ 
+ #define CSI_ARGS_MAX 16
+ #define CSI_LEADER_MAX 16
+ 
  typedef struct VTermEncoding VTermEncoding;
  
  typedef struct {
***************
*** 118,123 ****
--- 123,129 ----
      unsigned int screen:1;
      unsigned int leftrightmargin:1;
      unsigned int bracketpaste:1;
+     unsigned int report_focus:1;
    } mode;
  
    VTermEncodingInstance encoding[4], encoding_utf8;
***************
*** 148,153 ****
--- 154,166 ----
    } saved;
  };
  
+ typedef enum {
+   VTERM_PARSER_OSC,
+   VTERM_PARSER_DCS,
+ 
+   VTERM_N_PARSER_TYPES
+ } VTermParserStringType;
+ 
  struct VTerm
  {
    VTermAllocatorFunctions *allocator;
***************
*** 161,182 ****
      unsigned int ctrl8bit:1;
    } mode;
  
!   enum VTermParserState {
!     NORMAL,
!     CSI,
!     OSC,
!     DCS,
!     ESC,
!     ESC_IN_OSC,
!     ESC_IN_DCS
!   } parser_state;
!   const VTermParserCallbacks *parser_callbacks;
!   void *cbdata;
  
    /* len == malloc()ed size; cur == number of valid bytes */
-   char  *strbuffer;
-   size_t strbuffer_len;
-   size_t strbuffer_cur;
  
    char  *outbuffer;
    size_t outbuffer_len;
--- 174,210 ----
      unsigned int ctrl8bit:1;
    } mode;
  
!   struct {
!     enum VTermParserState {
!       NORMAL,
!       CSI_LEADER,
!       CSI_ARGS,
!       CSI_INTERMED,
!       ESC,
!       /* below here are the "string states" */
!       STRING,
!       ESC_IN_STRING
!     } state;
! 
!     int intermedlen;
!     char intermed[INTERMED_MAX];
! 
!     int csi_leaderlen;
!     char csi_leader[CSI_LEADER_MAX];
! 
!     int csi_argi;
!     long csi_args[CSI_ARGS_MAX];
! 
!     const VTermParserCallbacks *callbacks;
!     void *cbdata;
! 
!     VTermParserStringType stringtype;
!     char  *strbuffer;
!     size_t strbuffer_len;
!     size_t strbuffer_cur;
!   } parser;
  
    /* len == malloc()ed size; cur == number of valid bytes */
  
    char  *outbuffer;
    size_t outbuffer_len;
*** ../vim-8.0.1638/src/libvterm/t/10state_putglyph.test        2017-07-07 
11:53:29.523876467 +0200
--- src/libvterm/t/10state_putglyph.test        2018-03-25 14:54:41.670318525 
+0200
***************
*** 17,22 ****
--- 17,28 ----
    putglyph 0xc1 1 0,0
    putglyph 0xe9 1 0,1
  
+ !UTF-8 split writes
+ RESET
+ PUSH "\xC3"
+ PUSH "\x81"
+   putglyph 0xc1 1 0,0
+ 
  !UTF-8 wide char
  # U+FF10 = 0xEF 0xBC 0x90  name: FULLWIDTH DIGIT ZERO
  RESET
*** ../vim-8.0.1638/src/libvterm/t/25state_input.test   2017-07-07 
11:53:29.523876467 +0200
--- src/libvterm/t/25state_input.test   2018-03-25 14:54:41.670318525 +0200
***************
*** 130,132 ****
--- 130,143 ----
    output "\e[200~"
  PASTE END
    output "\e[201~"
+ 
+ !Focus reporting disabled
+ FOCUS IN
+ FOCUS OUT
+ 
+ !Focus reporting enabled
+ PUSH "\e[?1004h"
+ FOCUS IN
+   output "\e[I"
+ FOCUS OUT
+   output "\e[O"
*** ../vim-8.0.1638/src/libvterm/t/harness.c    2017-07-25 21:34:42.061132703 
+0200
--- src/libvterm/t/harness.c    2018-03-25 15:36:08.652136578 +0200
***************
*** 233,238 ****
--- 233,241 ----
    case VTERM_VALUETYPE_COLOR:
      printf("settermprop %d rgb(%d,%d,%d)\n", prop, val->color.red, 
val->color.green, val->color.blue);
      return 1;
+ 
+   case VTERM_N_VALUETYPES:
+     return 0;
    }
  
    return 0;
***************
*** 316,321 ****
--- 319,327 ----
    case VTERM_ATTR_BACKGROUND:
      state_pen.background = val->color;
      break;
+ 
+   case VTERM_N_ATTRS:
+     return 0;
    }
  
    return 1;
***************
*** 650,655 ****
--- 656,671 ----
        else
          goto abort_line;
      }
+ 
+     else if(strstartswith(line, "FOCUS ")) {
+       char *linep = line + 6;
+       if(streq(linep, "IN"))
+         vterm_state_focus_in(state);
+       else if(streq(linep, "OUT"))
+         vterm_state_focus_out(state);
+       else
+         goto abort_line;
+     }
  
      else if(strstartswith(line, "MOUSEMOVE ")) {
        char *linep = line + 10;
*** ../vim-8.0.1638/src/libvterm/t/26state_query.test   2017-07-07 
11:53:29.523876467 +0200
--- src/libvterm/t/26state_query.test   2018-03-25 16:14:58.151055521 +0200
***************
*** 58,62 ****
  PUSH "\e F"
  
  !Truncation on attempted buffer overflow
! PUSH "\e[6n" x 20
!   output "\e[10;10R" x 7
--- 58,62 ----
  PUSH "\e F"
  
  !Truncation on attempted buffer overflow
! PUSH "\e[6n" x 30
!   output "\e[10;10R" x 24
*** ../vim-8.0.1638/src/version.c       2018-03-24 17:56:09.205107399 +0100
--- src/version.c       2018-03-25 15:50:04.035421169 +0200
***************
*** 768,769 ****
--- 768,771 ----
  {   /* Add new patch number below this line */
+ /**/
+     1639,
  /**/

-- 
ERROR 047: Keyboard not found.  Press RETURN to continue.

 /// 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.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui