Compare commits

...

17 Commits

Author SHA1 Message Date
Bram Moolenaar
2b2207ba69 patch 8.0.0218: no completion for :cexpr and similar commands
Problem:    No command line completion for :cexpr, :cgetexpr, :caddexpr, etc.
Solution:   Make completion work. (Yegappan Lakshmanan)  Add a test.
2017-01-22 16:46:56 +01:00
Bram Moolenaar
e2d74dbe19 patch 8.0.0217: build fails without cscope feature
Problem:    Build fails without the cscope feature.
Solution:   Add #ifdef.
2017-01-22 16:13:35 +01:00
Bram Moolenaar
e2c6037da3 patch 8.0.0216: decoding js style json may fail
Problem:    When decoding JSON with a JS style object the JSON test may use a
            NULL pointer. (Coverity)
Solution:   Check for a NULL pointer.
2017-01-22 15:56:26 +01:00
Bram Moolenaar
e362c3d2c3 patch 8.0.0215: NULL pointer use if cscope line looks like emacs tag
Problem:    When a Cscope line contains CTRL-L a NULL pointer may be used.
            (Coverity)
Solution:   Don't check for an emacs tag in a cscope line.
2017-01-22 15:40:00 +01:00
Bram Moolenaar
d7a96151e0 patch 8.0.0214: leaking memory when syntax cluster id is unknown
Problem:    Leaking memory when syntax cluster id is unknown. (Coverity)
Solution:   Free the memory.
2017-01-22 15:28:55 +01:00
Bram Moolenaar
ca24e2cfcf patch 8.0.0213: Netbeans specialKeys command does not check argument length
Problem:    The Netbeans "specialKeys" command does not check if the argument
            fits in the buffer. (Coverity)
Solution:   Add a length check.
2017-01-22 15:19:22 +01:00
Bram Moolenaar
423977d3ce patch 8.0.0212: buffer for key name may be too small
Problem:    The buffer used to store a key name theoreticaly could be too
            small. (Coverity)
Solution:   Count all possible modifier characters.  Add a check for the
            length just in case.
2017-01-22 15:05:12 +01:00
Bram Moolenaar
560379d7ae patch 8.0.0211: cannot build without the multi-byte feature
Problem:    Build fails if the multi-byte feature is disabled.
Solution:   Change #ifdef around ins_char_bytes.
2017-01-21 22:50:00 +01:00
Bram Moolenaar
ec2da36ca4 patch 8.0.0210: no support for bracketed paste
Problem:    Vim does not support bracketed paste, as implemented by xterm and
            other terminals.
Solution:   Add t_BE, t_BD, t_PS and t_PE.
2017-01-21 20:04:22 +01:00
Bram Moolenaar
41baa7983a patch 8.0.0209: cursor binding does not work with :substitute
Problem:    When using :substitute with the "c" flag and 'cursorbind' is set
            the cursor is not updated in other windows.
Solution:   Call do_check_cursorbind(). (Masanori Misono)
2017-01-21 14:45:09 +01:00
Bram Moolenaar
25b0e6b701 patch 8.0.0208: internally used commands end up in history
Problem:    Internally used commands for CTRL-Z and mouse click end up in
            history. (Matthew Malcomson)
Solution:   Use do_cmdline_cmd() instead of stuffing them in the readahead
            buffer. (James McCoy, closes #1395)
2017-01-20 21:51:53 +01:00
Bram Moolenaar
23c9e8b3bc patch 8.0.0207: leaking file descriptor when system() fails
Problem:    Leaking file descriptor when system() cannot find the buffer.
            (Coverity)
Solution:   Close the file descriptor.  (Dominique Pelle, closes #1398)
2017-01-20 19:59:54 +01:00
Bram Moolenaar
8822744b4d patch 8.0.0206: test coverage for :retab insufficient
Problem:    Test coverage for :retab insufficient.
Solution:   Add test for :retab. (Dominique Pelle, closes #1391)
2017-01-17 22:16:00 +01:00
Bram Moolenaar
5e4e1b1299 patch 8.0.0205: wrong behavior after :undojoin
Problem:    After :undojoin some commands don't work properly, such as :redo.
            (Matthew Malcomson)
Solution:   Don't set curbuf->b_u_curhead. (closes #1390)
2017-01-17 22:09:45 +01:00
Bram Moolenaar
eb46f8fa14 patch 8.0.0204: compiler warns for uninitialized variable
Problem:    Compiler warns for uninitialized variable. (Tony Mechelynck)
Solution:   When skipping set "id" to -1.
2017-01-17 19:48:53 +01:00
Bram Moolenaar
6e78e27b8a patch 8.0.0203: order of complication flags is sometimes wrong
Problem:    Order of complication flags is sometimes wrong.
Solution:   Put interface-specific flags before ALL_CFLAGS. (idea by Yousong
            Zhou, closes #1100)
2017-01-17 19:20:15 +01:00
Bram Moolenaar
4007ed4a5e patch 8.0.0202: no test for invalid syntax group name
Problem:    No test for invalid syntax group name.
Solution:   Add a test for group name error and warning.
2017-01-17 18:14:54 +01:00
28 changed files with 429 additions and 60 deletions

View File

@@ -89,6 +89,18 @@ an external command (e.g., "!!"), the terminal will be put into Normal mode
for a moment. This means that you can stop the output to the screen by
hitting a printing key. Output resumes when you hit <BS>.
*xterm-bracketed-paste*
When the 't_BE' option is set then 't_BE' will be sent to the
terminal when entering "raw" mode and 't_BD' when leaving "raw" mode. The
terminal is then expected to put 't_PS' before pasted text and 't_PE' after
pasted text. This way Vim can separate text that is pasted from characters
that are typed. The pasted text is handled like when the middle mouse button
is used.
Note that in some situations Vim will not recognize the bracketed paste and
you will get the raw text. In other situations Vim will only get the first
pasted character and drop the rest, e.g. when using the "r" command.
*cs7-problem*
Note: If the terminal settings are changed after running Vim, you might have
an illegal combination of settings. This has been reported on Solaris 2.5
@@ -306,6 +318,10 @@ Added by Vim (there are no standard codes for these):
|xterm-true-color|
t_8b set background color (R, G, B) *t_8b* *'t_8b'*
|xterm-true-color|
t_BE enable bracketed paste mode *t_BE* *'t_BE'*
|xterm-bracketed-paste|
t_BD disable bracketed paste mode *t_BD* *'t_BD'*
|xterm-bracketed-paste|
KEY CODES
Note: Use the <> form if possible
@@ -398,6 +414,8 @@ Note: Use the <> form if possible
t_KK <k8> keypad 8 *<k8>* *t_KK* *'t_KK'*
t_KL <k9> keypad 9 *<k9>* *t_KL* *'t_KL'*
<Mouse> leader of mouse code *<Mouse>*
t_PS start of brackted paste |xterm-bracketed-paste| *t_PS* 't_PS'
t_PE end of bracketed paste |xterm-bracketed-paste| *t_PE* 't_PE'
Note about t_so and t_mr: When the termcap entry "so" is not present the
entry for "mr" is used. And vice versa. The same is done for "se" and "me".

View File

@@ -1877,7 +1877,9 @@ myself:
# The normal command to compile a .c file to its .o file.
CCC = $(CC) -c -I$(srcdir) $(ALL_CFLAGS)
# Without or with ALL_CFLAGS.
CCC_NF = $(CC) -c -I$(srcdir)
CCC = $(CCC_NF) $(ALL_CFLAGS)
# Link the target for normal use or debugging.
@@ -2152,6 +2154,7 @@ test_arglist \
test_regexp_latin \
test_regexp_utf8 \
test_reltime \
test_retab \
test_ruby \
test_search \
test_searchpos \
@@ -2976,7 +2979,7 @@ objects/gui_gtk_f.o: gui_gtk_f.c
$(CCC) -o $@ gui_gtk_f.c
objects/gui_gtk_gresources.o: auto/gui_gtk_gresources.c
$(CCC) $(PERL_CFLAGS) -o $@ auto/gui_gtk_gresources.c
$(CCC_NF) $(PERL_CFLAGS) $(ALL_CFLAGS) -o $@ auto/gui_gtk_gresources.c
objects/gui_gtk_x11.o: gui_gtk_x11.c
$(CCC) -o $@ gui_gtk_x11.c
@@ -3009,7 +3012,7 @@ objects/if_xcmdsrv.o: if_xcmdsrv.c
$(CCC) -o $@ if_xcmdsrv.c
objects/if_lua.o: if_lua.c
$(CCC) $(LUA_CFLAGS) -o $@ if_lua.c
$(CCC_NF) $(LUA_CFLAGS) $(ALL_CFLAGS) -o $@ if_lua.c
objects/if_mzsch.o: if_mzsch.c $(MZSCHEME_EXTRA)
$(CCC) -o $@ $(MZSCHEME_CFLAGS_EXTRA) if_mzsch.c
@@ -3018,27 +3021,28 @@ mzscheme_base.c:
$(MZSCHEME_MZC) --c-mods mzscheme_base.c ++lib scheme/base
objects/if_perl.o: auto/if_perl.c
$(CCC) $(PERL_CFLAGS) -o $@ auto/if_perl.c
$(CCC_NF) $(PERL_CFLAGS) $(ALL_CFLAGS) -o $@ auto/if_perl.c
objects/if_perlsfio.o: if_perlsfio.c
$(CCC) $(PERL_CFLAGS) -o $@ if_perlsfio.c
$(CCC_NF) $(PERL_CFLAGS) $(ALL_CFLAGS) -o $@ if_perlsfio.c
objects/py_getpath.o: $(PYTHON_CONFDIR)/getpath.c
$(CCC) $(PYTHON_CFLAGS) -o $@ $(PYTHON_CONFDIR)/getpath.c \
$(CCC_NF) $(PYTHON_CFLAGS) $(ALL_CFLAGS) -o $@ \
$(PYTHON_CONFDIR)/getpath.c \
-I$(PYTHON_CONFDIR) -DHAVE_CONFIG_H -DNO_MAIN \
$(PYTHON_GETPATH_CFLAGS)
objects/if_python.o: if_python.c if_py_both.h
$(CCC) $(PYTHON_CFLAGS) $(PYTHON_CFLAGS_EXTRA) -o $@ if_python.c
$(CCC_NF) $(PYTHON_CFLAGS) $(PYTHON_CFLAGS_EXTRA) $(ALL_CFLAGS) -o $@ if_python.c
objects/if_python3.o: if_python3.c if_py_both.h
$(CCC) $(PYTHON3_CFLAGS) $(PYTHON3_CFLAGS_EXTRA) -o $@ if_python3.c
$(CCC_NF) $(PYTHON3_CFLAGS) $(PYTHON3_CFLAGS_EXTRA) $(ALL_CFLAGS) -o $@ if_python3.c
objects/if_ruby.o: if_ruby.c
$(CCC) $(RUBY_CFLAGS) -o $@ if_ruby.c
$(CCC_NF) $(RUBY_CFLAGS) $(ALL_CFLAGS) -o $@ if_ruby.c
objects/if_tcl.o: if_tcl.c
$(CCC) $(TCL_CFLAGS) -o $@ if_tcl.c
$(CCC_NF) $(TCL_CFLAGS) $(ALL_CFLAGS) -o $@ if_tcl.c
objects/integration.o: integration.c
$(CCC) -o $@ integration.c
@@ -3095,7 +3099,7 @@ objects/ops.o: ops.c
$(CCC) -o $@ ops.c
objects/option.o: option.c
$(CCC) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(RUBY_CFLAGS) $(TCL_CFLAGS) -o $@ option.c
$(CCC_NF) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) $(PYTHON3_CFLAGS) $(RUBY_CFLAGS) $(TCL_CFLAGS) $(ALL_CFLAGS) -o $@ option.c
objects/os_beos.o: os_beos.c
$(CCC) -o $@ os_beos.c

View File

@@ -309,6 +309,7 @@ static int dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for
* "cmdchar" can be:
* 'i' normal insert command
* 'a' normal append command
* K_PS bracketed paste
* 'R' replace command
* 'r' "r<CR>" command: insert one <CR>. Note: count can be > 1, for redo,
* but still only one <CR> is inserted. The <Esc> is not used for redo.
@@ -782,10 +783,14 @@ edit(
dont_sync_undo = TRUE;
else
dont_sync_undo = FALSE;
do
{
c = safe_vgetc();
} while (c == K_IGNORE);
if (cmdchar == K_PS)
/* Got here from normal mode when bracketed paste started. */
c = K_PS;
else
do
{
c = safe_vgetc();
} while (c == K_IGNORE);
#ifdef FEAT_AUTOCMD
/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
@@ -1025,7 +1030,7 @@ doESCkey:
case Ctrl_Z: /* suspend when 'insertmode' set */
if (!p_im)
goto normalchar; /* insert CTRL-Z as normal char */
stuffReadbuff((char_u *)":st\r");
do_cmdline_cmd((char_u *)"stop");
c = Ctrl_O;
/*FALLTHROUGH*/
@@ -1193,6 +1198,16 @@ doESCkey:
ins_mousescroll(MSCR_RIGHT);
break;
#endif
case K_PS:
bracketed_paste(PASTE_INSERT, FALSE, NULL);
if (cmdchar == K_PS)
/* invoked from normal mode, bail out */
goto doESCkey;
break;
case K_PE:
/* Got K_PE without K_PS, ignore. */
break;
#ifdef FEAT_GUI_TABLINE
case K_TABLINE:
case K_TABMENU:
@@ -9424,6 +9439,91 @@ ins_mousescroll(int dir)
}
#endif
/*
* Handle receiving P_PS: start paste mode. Inserts the following text up to
* P_PE literally.
* When "drop" is TRUE then consume the text and drop it.
*/
int
bracketed_paste(paste_mode_T mode, int drop, garray_T *gap)
{
int c;
char_u buf[NUMBUFLEN + MB_MAXBYTES];
int idx = 0;
char_u *end = find_termcode((char_u *)"PE");
int ret_char = -1;
int save_allow_keys = allow_keys;
/* If the end code is too long we can't detect it, read everything. */
if (STRLEN(end) >= NUMBUFLEN)
end = NULL;
++no_mapping;
allow_keys = 0;
for (;;)
{
/* When the end is not defined read everything. */
if (end == NULL && vpeekc() == NUL)
break;
c = plain_vgetc();
#ifdef FEAT_MBYTE
if (has_mbyte)
idx += (*mb_char2bytes)(c, buf + idx);
else
#endif
buf[idx++] = c;
buf[idx] = NUL;
if (end != NUL && STRNCMP(buf, end, idx) == 0)
{
if (end[idx] == NUL)
break; /* Found the end of paste code. */
continue;
}
if (!drop)
{
switch (mode)
{
case PASTE_CMDLINE:
put_on_cmdline(buf, idx, TRUE);
break;
case PASTE_EX:
if (gap != NULL && ga_grow(gap, idx) == OK)
{
mch_memmove((char *)gap->ga_data + gap->ga_len,
buf, (size_t)idx);
gap->ga_len += idx;
}
break;
case PASTE_INSERT:
if (stop_arrow() == OK)
{
ins_char_bytes(buf, idx);
AppendToRedobuffLit(buf, idx);
}
break;
case PASTE_ONE_CHAR:
if (ret_char == -1)
{
#ifdef FEAT_MBYTE
if (has_mbyte)
ret_char = (*mb_ptr2char)(buf);
else
#endif
ret_char = buf[0];
}
break;
}
}
idx = 0;
}
--no_mapping;
allow_keys = save_allow_keys;
return ret_char;
}
#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
static void
ins_tabline(int c)

View File

@@ -4231,7 +4231,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
{
if (argvars[0].v_type == VAR_UNKNOWN)
/* getchar(): blocking wait. */
n = safe_vgetc();
n = plain_vgetc();
else if (get_tv_number_chk(&argvars[0], &error) == 1)
/* getchar(1): only check if char avail */
n = vpeekc_any();
@@ -4240,7 +4240,7 @@ f_getchar(typval_T *argvars, typval_T *rettv)
n = 0;
else
/* getchar(0) and char avail: return char */
n = safe_vgetc();
n = plain_vgetc();
if (n == K_IGNORE)
continue;
@@ -11832,6 +11832,7 @@ get_cmd_output_as_rettv(
if (buf == NULL)
{
EMSGN(_(e_nobufnr), argvars[1].vval.v_number);
fclose(fd);
goto errret;
}

View File

@@ -5263,6 +5263,10 @@ do_sub(exarg_T *eap)
setmouse(); /* disable mouse in xterm */
#endif
curwin->w_cursor.col = regmatch.startpos[0].col;
#ifdef FEAT_CURSORBIND
if (curwin->w_p_crb)
do_check_cursorbind();
#endif
/* When 'cpoptions' contains "u" don't sync undo when
* asking for confirmation. */

View File

@@ -4109,6 +4109,12 @@ set_one_cmd_context(
case CMD_echoerr:
case CMD_call:
case CMD_return:
case CMD_cexpr:
case CMD_caddexpr:
case CMD_cgetexpr:
case CMD_lexpr:
case CMD_laddexpr:
case CMD_lgetexpr:
set_context_for_expression(xp, arg, ea.cmdidx);
break;

View File

@@ -1817,6 +1817,12 @@ plain_vgetc(void)
{
c = safe_vgetc();
} while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
if (c == K_PS)
/* Only handle the first pasted character. Drop the rest, since we
* don't know what to do with it. */
c = bracketed_paste(PASTE_ONE_CHAR, FALSE, NULL);
return c;
}
@@ -1906,7 +1912,7 @@ vungetc(int c)
}
/*
* get a character:
* Get a character:
* 1. from the stuffbuffer
* This is used for abbreviated commands like "D" -> "d$".
* Also used to redo a command for ".".

View File

@@ -629,10 +629,13 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
key = p = reader->js_buf + reader->js_used;
while (*p != NUL && *p != ':' && *p > ' ')
++p;
cur_item->v_type = VAR_STRING;
cur_item->vval.v_string = vim_strnsave(key, (int)(p - key));
if (cur_item != NULL)
{
cur_item->v_type = VAR_STRING;
cur_item->vval.v_string = vim_strnsave(key, (int)(p - key));
top_item->jd_key = cur_item->vval.v_string;
}
reader->js_used += (int)(p - key);
top_item->jd_key = cur_item->vval.v_string;
}
else
{
@@ -1053,7 +1056,8 @@ json_decode(js_read_T *reader, typval_T *res, int options)
/*
* Decode the JSON from "reader" to find the end of the message.
* "options" can be JSON_JS or zero;
* "options" can be JSON_JS or zero.
* This is only used for testing.
* Return FAIL if the message has a decoding error.
* Return MAYBE if the message is truncated, need to read more.
* This only works reliable if the message contains an object, array or

View File

@@ -107,6 +107,12 @@ test_decode_find_end(void)
reader.js_buf = (char_u *)" { ";
assert(json_find_end(&reader, 0) == MAYBE);
/* JS object with white space */
reader.js_buf = (char_u *)" { a : 123 } ";
assert(json_find_end(&reader, JSON_JS) == OK);
reader.js_buf = (char_u *)" { a : ";
assert(json_find_end(&reader, JSON_JS) == MAYBE);
/* array without white space */
reader.js_buf = (char_u *)"[\"a\",123]";
assert(json_find_end(&reader, 0) == OK);

View File

@@ -391,6 +391,8 @@ enum key_extra
#define K_KMULTIPLY TERMCAP2KEY('K', '9') /* keypad * */
#define K_KENTER TERMCAP2KEY('K', 'A') /* keypad Enter */
#define K_KPOINT TERMCAP2KEY('K', 'B') /* keypad . or ,*/
#define K_PS TERMCAP2KEY('P', 'S') /* paste start */
#define K_PE TERMCAP2KEY('P', 'E') /* paste end */
#define K_K0 TERMCAP2KEY('K', 'C') /* keypad 0 */
#define K_K1 TERMCAP2KEY('K', 'D') /* keypad 1 */
@@ -480,9 +482,10 @@ enum key_extra
/*
* The length of the longest special key name, including modifiers.
* Current longest is <M-C-S-T-4-MiddleRelease> (length includes '<' and '>').
* Current longest is <M-C-S-T-D-A-4-ScrollWheelRight> (length includes '<' and
* '>').
*/
#define MAX_KEY_NAME_LEN 25
#define MAX_KEY_NAME_LEN 32
/* Maximum length of a special key event as tokens. This includes modifiers.
* The longest event is something like <M-C-S-T-4-LeftDrag> which would be the

View File

@@ -2177,16 +2177,19 @@ ins_bytes_len(char_u *p, int len)
void
ins_char(int c)
{
#if defined(FEAT_MBYTE) || defined(PROTO)
char_u buf[MB_MAXBYTES + 1];
int n;
int n = 1;
#if defined(FEAT_MBYTE) || defined(PROTO)
n = (*mb_char2bytes)(c, buf);
/* When "c" is 0x100, 0x200, etc. we don't want to insert a NUL byte.
* Happens for CTRL-Vu9900. */
if (buf[0] == 0)
buf[0] = '\n';
#else
buf[0] = c;
#endif
ins_char_bytes(buf, n);
}
@@ -2195,7 +2198,6 @@ ins_char(int c)
ins_char_bytes(char_u *buf, int charlen)
{
int c = buf[0];
#endif
int newlen; /* nr of bytes inserted */
int oldlen; /* nr of bytes deleted (0 when not replacing) */
char_u *p;
@@ -2218,11 +2220,7 @@ ins_char_bytes(char_u *buf, int charlen)
/* The lengths default to the values for when not replacing. */
oldlen = 0;
#ifdef FEAT_MBYTE
newlen = charlen;
#else
newlen = 1;
#endif
if (State & REPLACE_FLAG)
{

View File

@@ -2162,6 +2162,7 @@ static struct modmasktable
/* 'A' must be the last one */
{MOD_MASK_ALT, MOD_MASK_ALT, (char_u)'A'},
{0, 0, NUL}
/* NOTE: when adding an entry, update MAX_KEY_NAME_LEN! */
};
/*
@@ -2294,6 +2295,8 @@ static struct key_name_entry
{K_XDOWN, (char_u *)"xDown"},
{K_XLEFT, (char_u *)"xLeft"},
{K_XRIGHT, (char_u *)"xRight"},
{K_PS, (char_u *)"PasteStart"},
{K_PE, (char_u *)"PasteEnd"},
{K_F1, (char_u *)"F1"},
{K_F2, (char_u *)"F2"},
@@ -2429,6 +2432,7 @@ static struct key_name_entry
{K_PLUG, (char_u *)"Plug"},
{K_CURSORHOLD, (char_u *)"CursorHold"},
{0, NULL}
/* NOTE: When adding a long name update MAX_KEY_NAME_LEN. */
};
#define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
@@ -2657,8 +2661,13 @@ get_special_key_name(int c, int modifiers)
}
else /* use name of special key */
{
STRCPY(string + idx, key_names_table[table_idx].name);
idx = (int)STRLEN(string);
size_t len = STRLEN(key_names_table[table_idx].name);
if (len + idx + 2 <= MAX_KEY_NAME_LEN)
{
STRCPY(string + idx, key_names_table[table_idx].name);
idx += (int)len;
}
}
string[idx++] = '>';
string[idx] = NUL;

View File

@@ -2332,7 +2332,8 @@ special_keys(char_u *args)
char *save_str = nb_unquote(args, NULL);
char *tok = strtok(save_str, " ");
char *sep;
char keybuf[64];
#define KEYBUFLEN 64
char keybuf[KEYBUFLEN];
char cmdbuf[256];
while (tok != NULL)
@@ -2359,10 +2360,13 @@ special_keys(char_u *args)
tok++;
}
strcpy(&keybuf[i], tok);
vim_snprintf(cmdbuf, sizeof(cmdbuf),
"<silent><%s> :nbkey %s<CR>", keybuf, keybuf);
do_map(0, (char_u *)cmdbuf, NORMAL, FALSE);
if (strlen(tok) + i < KEYBUFLEN)
{
strcpy(&keybuf[i], tok);
vim_snprintf(cmdbuf, sizeof(cmdbuf),
"<silent><%s> :nbkey %s<CR>", keybuf, keybuf);
do_map(0, (char_u *)cmdbuf, NORMAL, FALSE);
}
tok = strtok(NULL, " ");
}
vim_free(save_str);

View File

@@ -426,6 +426,7 @@ static const struct nv_cmd
#ifdef FEAT_AUTOCMD
{K_CURSORHOLD, nv_cursorhold, NV_KEEPREG, 0},
#endif
{K_PS, nv_edit, 0, 0},
};
/* Number of commands in nv_cmds[]. */
@@ -2982,9 +2983,9 @@ do_mouse(
if (State & INSERT)
stuffcharReadbuff(Ctrl_O);
if (curwin->w_llist_ref == NULL) /* quickfix window */
stuffReadbuff((char_u *)":.cc\n");
do_cmdline_cmd((char_u *)".cc");
else /* location list window */
stuffReadbuff((char_u *)":.ll\n");
do_cmdline_cmd((char_u *)".ll");
got_click = FALSE; /* ignore drag&release now */
}
#endif
@@ -3858,7 +3859,7 @@ add_to_showcmd(int c)
K_VER_SCROLLBAR, K_HOR_SCROLLBAR,
K_LEFTMOUSE_NM, K_LEFTRELEASE_NM,
# endif
K_IGNORE,
K_IGNORE, K_PS,
K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
@@ -9015,6 +9016,7 @@ nv_esc(cmdarg_T *cap)
/*
* Handle "A", "a", "I", "i" and <Insert> commands.
* Also handle K_PS, start bracketed paste.
*/
static void
nv_edit(cmdarg_T *cap)
@@ -9042,6 +9044,9 @@ nv_edit(cmdarg_T *cap)
/* Only give this error when 'insertmode' is off. */
EMSG(_(e_modifiable));
clearop(cap->oap);
if (cap->cmdchar == K_PS)
/* drop the pasted text */
bracketed_paste(PASTE_INSERT, TRUE, NULL);
}
else if (!checkclearopq(cap->oap))
{
@@ -9073,6 +9078,7 @@ nv_edit(cmdarg_T *cap)
break;
case 'a': /* "a"ppend is like "i"nsert on the next character. */
case K_PS: /* bracketed paste works like "a"ppend */
#ifdef FEAT_VIRTUALEDIT
/* increment coladd when in virtual space, increment the
* column otherwise, also to append after an unprintable char */
@@ -9103,6 +9109,9 @@ nv_edit(cmdarg_T *cap)
invoke_edit(cap, FALSE, cap->cmdchar, FALSE);
}
else if (cap->cmdchar == K_PS)
/* drop the pasted text */
bracketed_paste(PASTE_INSERT, TRUE, NULL);
}
/*

View File

@@ -3040,6 +3040,8 @@ static struct vimoption options[] =
p_term("t_ZR", T_CZR)
p_term("t_8f", T_8F)
p_term("t_8b", T_8B)
p_term("t_BE", T_BE)
p_term("t_BD", T_BD)
/* terminal key codes are not in here */

View File

@@ -38,6 +38,7 @@ void fixthisline(int (*get_the_indent)(void));
void fix_indent(void);
int in_cinkeys(int keytyped, int when, int line_is_empty);
int hkmap(int c);
int bracketed_paste(paste_mode_T mode, int drop, garray_T *gap);
void ins_scroll(void);
void ins_horscroll(void);
int ins_copychar(linenr_T lnum);

View File

@@ -5668,6 +5668,8 @@ syn_cmd_cluster(exarg_T *eap, int syncing UNUSED)
if (scl_id >= 0)
syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
&clstr_list, list_op);
else
vim_free(clstr_list);
got_clstr = TRUE;
}
@@ -6034,7 +6036,8 @@ get_id_list(
}
if (count != 0)
{
EMSG2(_("E408: %s must be first in contains list"), name + 1);
EMSG2(_("E408: %s must be first in contains list"),
name + 1);
failed = TRUE;
vim_free(name);
break;
@@ -6049,7 +6052,9 @@ get_id_list(
}
else if (name[1] == '@')
{
if (!skip)
if (skip)
id = -1;
else
id = syn_check_cluster(name + 2, (int)(end - p - 1));
}
else

View File

@@ -1752,8 +1752,13 @@ line_read_in:
/*
* Emacs tags line with CTRL-L: New file name on next line.
* The file name is followed by a ','.
* Remember etag file name in ebuf.
*/
if (*lbuf == Ctrl_L) /* remember etag file name in ebuf */
if (*lbuf == Ctrl_L
# ifdef FEAT_CSCOPE
&& !use_cscope
# endif
)
{
is_etag = 1; /* in case at the start */
state = TS_LINEAR;

View File

@@ -857,6 +857,8 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_8F, IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")},
{(int)KS_8B, IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")},
# endif
{(int)KS_CBE, IF_EB("\033[?2004h", ESC_STR "[?2004h")},
{(int)KS_CBD, IF_EB("\033[?2004l", ESC_STR "[?2004l")},
{K_UP, IF_EB("\033O*A", ESC_STR "O*A")},
{K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")},
@@ -902,13 +904,15 @@ static struct builtin_term builtin_termcaps[] =
{K_ZEND, IF_EB("\033[8;*~", ESC_STR "[8;*~")},
{K_PAGEUP, IF_EB("\033[5;*~", ESC_STR "[5;*~")},
{K_PAGEDOWN, IF_EB("\033[6;*~", ESC_STR "[6;*~")},
{K_KPLUS, IF_EB("\033O*k", ESC_STR "O*k")}, /* keypad plus */
{K_KMINUS, IF_EB("\033O*m", ESC_STR "O*m")}, /* keypad minus */
{K_KDIVIDE, IF_EB("\033O*o", ESC_STR "O*o")}, /* keypad / */
{K_KMULTIPLY, IF_EB("\033O*j", ESC_STR "O*j")}, /* keypad * */
{K_KENTER, IF_EB("\033O*M", ESC_STR "O*M")}, /* keypad Enter */
{K_KPOINT, IF_EB("\033O*n", ESC_STR "O*n")}, /* keypad . */
{K_KDEL, IF_EB("\033[3;*~", ESC_STR "[3;*~")}, /* keypad Del */
{K_KPLUS, IF_EB("\033O*k", ESC_STR "O*k")}, /* keypad plus */
{K_KMINUS, IF_EB("\033O*m", ESC_STR "O*m")}, /* keypad minus */
{K_KDIVIDE, IF_EB("\033O*o", ESC_STR "O*o")}, /* keypad / */
{K_KMULTIPLY, IF_EB("\033O*j", ESC_STR "O*j")}, /* keypad * */
{K_KENTER, IF_EB("\033O*M", ESC_STR "O*M")}, /* keypad Enter */
{K_KPOINT, IF_EB("\033O*n", ESC_STR "O*n")}, /* keypad . */
{K_KDEL, IF_EB("\033[3;*~", ESC_STR "[3;*~")}, /* keypad Del */
{K_PS, IF_EB("\033[200~", ESC_STR "[200~")}, /* paste start */
{K_PE, IF_EB("\033[201~", ESC_STR "[201~")}, /* paste end */
{BT_EXTRA_KEYS, ""},
{TERMCAP2KEY('k', '0'), IF_EB("\033[10;*~", ESC_STR "[10;*~")}, /* F0 */
@@ -1224,6 +1228,8 @@ static struct builtin_term builtin_termcaps[] =
{K_KMULTIPLY, "[KMULTIPLY]"},
{K_KENTER, "[KENTER]"},
{K_KPOINT, "[KPOINT]"},
{K_PS, "[PASTE-START]"},
{K_PE, "[PASTE-END]"},
{K_K0, "[K0]"},
{K_K1, "[K1]"},
{K_K2, "[K2]"},
@@ -1538,6 +1544,8 @@ set_termname(char_u *term)
{KS_CSI, "SI"}, {KS_CEI, "EI"},
{KS_U7, "u7"}, {KS_RBG, "RB"},
{KS_8F, "8f"}, {KS_8B, "8b"},
{KS_CBE, "BE"}, {KS_CBD, "BD"},
{KS_CPS, "PS"}, {KS_CPE, "PE"},
{(enum SpecialKey)0, NULL}
};
@@ -3140,6 +3148,7 @@ starttermcap(void)
{
out_str(T_TI); /* start termcap mode */
out_str(T_KS); /* start "keypad transmit" mode */
out_str(T_BE); /* enable bracketed paste moe */
out_flush();
termcap_active = TRUE;
screen_start(); /* don't know where cursor is now */
@@ -3189,6 +3198,7 @@ stoptermcap(void)
check_for_codes_from_term();
}
#endif
out_str(T_BD); /* disable bracketed paste moe */
out_str(T_KE); /* stop "keypad transmit" mode */
out_flush();
termcap_active = FALSE;

View File

@@ -89,10 +89,14 @@ enum SpecialKey
KS_OP, /* original color pair */
KS_U7, /* request cursor position */
KS_8F, /* set foreground color (RGB) */
KS_8B /* set background color (RGB) */
KS_8B, /* set background color (RGB) */
KS_CBE, /* enable bracketed paste mode */
KS_CBD, /* disable bracketed paste mode */
KS_CPS, /* start of brackted paste */
KS_CPE /* end of brackted paste */
};
#define KS_LAST KS_8B
#define KS_LAST KS_CPE
/*
* the terminal capabilities are stored in this array
@@ -170,6 +174,10 @@ extern char_u *(term_strings[]); /* current terminal strings */
#define T_U7 (term_str(KS_U7)) /* request cursor position */
#define T_8F (term_str(KS_8F)) /* set foreground color (RGB) */
#define T_8B (term_str(KS_8B)) /* set background color (RGB) */
#define T_BE (term_str(KS_CBE)) /* enable bracketed paste mode */
#define T_BD (term_str(KS_CBD)) /* disable bracketed paste mode */
#define T_PS (term_str(KS_CPS)) /* start of bracketed paste */
#define T_PE (term_str(KS_CPE)) /* end of bracketed paste */
#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */
#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */

View File

@@ -177,6 +177,7 @@ NEW_TESTS = test_arglist.res \
test_perl.res \
test_profile.res \
test_quickfix.res \
test_retab.res \
test_ruby.res \
test_search.res \
test_signs.res \

View File

@@ -25,6 +25,34 @@ func Test_complete_wildmenu()
set nowildmenu
endfunc
func Test_expr_completion()
if !(has('cmdline_compl') && has('eval'))
return
endif
for cmd in [
\ 'let a = ',
\ 'if',
\ 'elseif',
\ 'while',
\ 'for',
\ 'echo',
\ 'echon',
\ 'execute',
\ 'echomsg',
\ 'echoerr',
\ 'call',
\ 'return',
\ 'cexpr',
\ 'caddexpr',
\ 'cgetexpr',
\ 'lexpr',
\ 'laddexpr',
\ 'lgetexpr']
call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
call assert_equal('"' . cmd . ' getline(', getreg(':'))
endfor
endfunc
func Test_getcompletion()
if !has('cmdline_compl')
return

View File

@@ -0,0 +1,77 @@
" Test :retab
func SetUp()
new
call setline(1, "\ta \t b c ")
endfunc
func TearDown()
bwipe!
endfunc
func Retab(bang, n)
let l:old_tabstop = &tabstop
let l:old_line = getline(1)
exe "retab" . a:bang . a:n
let l:line = getline(1)
call setline(1, l:old_line)
if a:n > 0
" :retab changes 'tabstop' to n with argument n > 0.
call assert_equal(a:n, &tabstop)
exe 'set tabstop=' . l:old_tabstop
else
" :retab does not change 'tabstop' with empty or n <= 0.
call assert_equal(l:old_tabstop, &tabstop)
endif
return l:line
endfunc
func Test_retab()
set tabstop=8 noexpandtab
call assert_equal("\ta\t b c ", Retab('', ''))
call assert_equal("\ta\t b c ", Retab('', 0))
call assert_equal("\ta\t b c ", Retab('', 8))
call assert_equal("\ta\t b\t c\t ", Retab('!', ''))
call assert_equal("\ta\t b\t c\t ", Retab('!', 0))
call assert_equal("\ta\t b\t c\t ", Retab('!', 8))
call assert_equal("\t\ta\t\t\tb c ", Retab('', 4))
call assert_equal("\t\ta\t\t\tb\t\t c\t ", Retab('!', 4))
call assert_equal(" a\t\tb c ", Retab('', 10))
call assert_equal(" a\t\tb c ", Retab('!', 10))
set tabstop=8 expandtab
call assert_equal(" a b c ", Retab('', ''))
call assert_equal(" a b c ", Retab('', 0))
call assert_equal(" a b c ", Retab('', 8))
call assert_equal(" a b c ", Retab('!', ''))
call assert_equal(" a b c ", Retab('!', 0))
call assert_equal(" a b c ", Retab('!', 8))
call assert_equal(" a b c ", Retab(' ', 4))
call assert_equal(" a b c ", Retab('!', 4))
call assert_equal(" a b c ", Retab(' ', 10))
call assert_equal(" a b c ", Retab('!', 10))
set tabstop=4 noexpandtab
call assert_equal("\ta\t\tb c ", Retab('', ''))
call assert_equal("\ta\t\tb\t\t c\t ", Retab('!', ''))
call assert_equal("\t a\t\t\tb c ", Retab('', 3))
call assert_equal("\t a\t\t\tb\t\t\tc\t ", Retab('!', 3))
call assert_equal(" a\t b c ", Retab('', 5))
call assert_equal(" a\t b\t\t c\t ", Retab('!', 5))
set tabstop=4 expandtab
call assert_equal(" a b c ", Retab('', ''))
call assert_equal(" a b c ", Retab('!', ''))
call assert_equal(" a b c ", Retab('', 3))
call assert_equal(" a b c ", Retab('!', 3))
call assert_equal(" a b c ", Retab('', 5))
call assert_equal(" a b c ", Retab('!', 5))
endfunc
func Test_retab_error()
call assert_fails('retab -1', 'E487:')
call assert_fails('retab! -1', 'E487:')
endfunc

View File

@@ -335,3 +335,14 @@ func Test_syn_clear()
hi clear Foo
hi clear Bar
endfunc
func Test_invalid_name()
syn clear
syn keyword Nop yes
call assert_fails("syntax keyword Wr\x17ong bar", 'E669:')
syntax keyword @Wrong bar
call assert_match('W18:', execute('1messages'))
syn clear
hi clear Nop
hi clear @Wrong
endfunc

View File

@@ -176,7 +176,17 @@ func Test_undojoin()
call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
call feedkeys("u", 'xt')
call assert_equal(['aaaa'], getline(2, '$'))
close!
bwipe!
endfunc
func Test_undojoin_redo()
new
call setline(1, ['first line', 'second line'])
call feedkeys("ixx\<Esc>", 'xt')
call feedkeys(":undojoin | redo\<CR>", 'xt')
call assert_equal('xxfirst line', getline(1))
call assert_equal('second line', getline(2))
bwipe!
endfunc
func Test_undo_write()

View File

@@ -3136,11 +3136,8 @@ ex_undojoin(exarg_T *eap UNUSED)
if (get_undolevel() < 0)
return; /* no entries, nothing to do */
else
{
/* Go back to the last entry */
curbuf->b_u_curhead = curbuf->b_u_newhead;
curbuf->b_u_synced = FALSE; /* no entries, nothing to do */
}
/* Append next change to the last entry */
curbuf->b_u_synced = FALSE;
}
/*

View File

@@ -764,6 +764,40 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
218,
/**/
217,
/**/
216,
/**/
215,
/**/
214,
/**/
213,
/**/
212,
/**/
211,
/**/
210,
/**/
209,
/**/
208,
/**/
207,
/**/
206,
/**/
205,
/**/
204,
/**/
203,
/**/
202,
/**/
201,
/**/

View File

@@ -2108,6 +2108,14 @@ typedef enum
ASSERT_OTHER
} assert_type_T;
/* Mode for bracketed_paste(). */
typedef enum {
PASTE_INSERT, /* insert mode */
PASTE_CMDLINE, /* command line */
PASTE_EX, /* ex mode line */
PASTE_ONE_CHAR /* return first character */
} paste_mode_T;
#include "ex_cmds.h" /* Ex command defines */
#include "spell.h" /* spell checking stuff */