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