Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2018-08-21 23:20:37 -07:00
52 changed files with 1654 additions and 659 deletions
+49
View File
@@ -2409,6 +2409,7 @@ submatch({nr} [, {list}]) String or List
specific match in ":s" or substitute()
substitute({expr}, {pat}, {sub}, {flags})
String all {pat} in {expr} replaced with {sub}
swapinfo({fname}) Dict information about swap file {fname}
synID({lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
synIDattr({synID}, {what} [, {mode}])
String attribute {what} of syntax ID {synID}
@@ -2497,6 +2498,7 @@ win_screenpos({nr}) List get screen position of window {nr}
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr}
winlayout([{tabnr}]) List layout of windows in tab {tabnr}
winline() Number window line of the cursor
winnr([{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes
@@ -8000,6 +8002,24 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
|submatch()| returns. Example: >
:echo substitute(s, '%\(\x\x\)', {m -> '0x' . m[1]}, 'g')
swapinfo({fname}) swapinfo()
The result is a dictionary, which holds information about the
swapfile {fname}. The available fields are:
version VIM version
user user name
host host name
fname original file name
pid PID of the VIM process that created the swap
file
mtime last modification time in seconds
inode Optional: INODE number of the file
dirty 1 if file was modified, 0 if not
In case of failure an "error" item is added with the reason:
Cannot open file: file not found or in accessible
Cannot read file: cannot read first block
Not a swap file: does not contain correct block ID
Magic number mismatch: Info in first block is invalid
synID({lnum}, {col}, {trans}) *synID()*
The result is a Number, which is the syntax ID at the position
{lnum} and {col} in the current window.
@@ -9087,6 +9107,35 @@ winheight({nr}) *winheight()*
This excludes any window toolbar line.
Examples: >
:echo "The current window has " . winheight(0) . " lines."
<
winlayout([{tabnr}]) *winlayout()*
The result is a nested List containing the layout of windows
in a tabpage.
Without {tabnr} use the current tabpage, otherwise the tabpage
with number {tabnr}. If the tabpage {tabnr} is not found,
returns an empty list.
For a leaf window, it returns:
['leaf', {winid}]
For horizontally split windows, which form a column, it
returns:
['col', [{nested list of windows}]]
For vertically split windows, which form a row, it returns:
['row', [{nested list of windows}]]
Example: >
" Only one window in the tab page
:echo winlayout()
['leaf', 1000]
" Two horizontally split windows
:echo winlayout()
['col', [['leaf', 1000], ['leaf', 1001]]]
" Three horizontally split windows, with two
" vertically split windows in the middle window
:echo winlayout(2)
['col', [['leaf', 1002], ['row', ['leaf', 1003],
['leaf', 1001]]], ['leaf', 1000]]
<
*winline()*
winline() The result is a Number, which is the screen line of the cursor
+16
View File
@@ -1551,6 +1551,22 @@ The backslashes before the pipe character are required to avoid it to be
recognized as a command separator. The backslash before each space is
required for the set command.
*cfilter-plugin*
If you have too many matching messages, you can use the cfilter plugin to
reduce the number of entries. Load the plugin with: >
packadd cfilter
Then you can use these command: >
:Cfilter[!] {pat}
:Lfilter[!] {pat}
:Cfilter creates a new quickfix list from entries matching {pat} in the
current quickfix list. Both the file name and the text of the entries are
matched against {pat}. If ! is supplied, then entries not matching {pat} are
used.
:Lfilter does the same as :Cfilter but operates on the current location list.
=============================================================================
8. The directory stack *quickfix-directory-stack*
+43
View File
@@ -0,0 +1,43 @@
" cfilter.vim: Plugin to filter entries from a quickfix/location list
" Last Change: May 12, 2018
" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
" Version: 1.0
"
" Commands to filter the quickfix list:
" :Cfilter[!] {pat}
" Create a new quickfix list from entries matching {pat} in the current
" quickfix list. Both the file name and the text of the entries are
" matched against {pat}. If ! is supplied, then entries not matching
" {pat} are used.
" :Lfilter[!] {pat}
" Same as :Cfilter but operates on the current location list.
"
if exists("loaded_cfilter")
finish
endif
let loaded_cfilter = 1
func s:Qf_filter(qf, pat, bang)
if a:qf
let Xgetlist = function('getqflist')
let Xsetlist = function('setqflist')
let cmd = ':Cfilter' . a:bang
else
let Xgetlist = function('getloclist', [0])
let Xsetlist = function('setloclist', [0])
let cmd = ':Lfilter' . a:bang
endif
if a:bang == '!'
let cond = 'v:val.text !~# a:pat && bufname(v:val.bufnr) !~# a:pat'
else
let cond = 'v:val.text =~# a:pat || bufname(v:val.bufnr) =~# a:pat'
endif
let items = filter(Xgetlist(), cond)
let title = cmd . ' ' . a:pat
call Xsetlist([], ' ', {'title' : title, 'items' : items})
endfunc
com! -nargs=+ -bang Cfilter call s:Qf_filter(1, <q-args>, <q-bang>)
com! -nargs=+ -bang Lfilter call s:Qf_filter(0, <q-args>, <q-bang>)
+17 -27
View File
@@ -1039,7 +1039,14 @@ handle_swap_exists(bufref_T *old_curbuf)
buf = old_curbuf->br_buf;
if (buf != NULL)
{
int old_msg_silent = msg_silent;
if (shortmess(SHM_FILEINFO))
msg_silent = 1; // prevent fileinfo message
enter_buffer(buf);
// restore msg_silent, so that the command line will be shown
msg_silent = old_msg_silent;
# ifdef FEAT_SYN_HL
if (old_tw != curbuf->b_p_tw)
check_colorcolumn(curwin);
@@ -1178,26 +1185,14 @@ do_bufdel(
else if (deleted >= p_report)
{
if (command == DOBUF_UNLOAD)
{
if (deleted == 1)
MSG(_("1 buffer unloaded"));
else
smsg((char_u *)_("%d buffers unloaded"), deleted);
}
smsg((char_u *)NGETTEXT("%d buffer unloaded",
"%d buffers unloaded", deleted), deleted);
else if (command == DOBUF_DEL)
{
if (deleted == 1)
MSG(_("1 buffer deleted"));
else
smsg((char_u *)_("%d buffers deleted"), deleted);
}
smsg((char_u *)NGETTEXT("%d buffer deleted",
"%d buffers deleted", deleted), deleted);
else
{
if (deleted == 1)
MSG(_("1 buffer wiped out"));
else
smsg((char_u *)_("%d buffers wiped out"), deleted);
}
smsg((char_u *)NGETTEXT("%d buffer wiped out",
"%d buffers wiped out", deleted), deleted);
}
}
@@ -3489,19 +3484,14 @@ fileinfo(
n = (int)(((long)curwin->w_cursor.lnum * 100L) /
(long)curbuf->b_ml.ml_line_count);
if (curbuf->b_ml.ml_flags & ML_EMPTY)
{
vim_snprintf_add((char *)buffer, IOSIZE, "%s", _(no_lines_msg));
}
#ifdef FEAT_CMDL_INFO
else if (p_ru)
{
/* Current line and column are already on the screen -- webb */
if (curbuf->b_ml.ml_line_count == 1)
vim_snprintf_add((char *)buffer, IOSIZE, _("1 line --%d%%--"), n);
else
vim_snprintf_add((char *)buffer, IOSIZE, _("%ld lines --%d%%--"),
(long)curbuf->b_ml.ml_line_count, n);
}
vim_snprintf_add((char *)buffer, IOSIZE,
NGETTEXT("%ld line --%d%%--", "%ld lines --%d%%--",
curbuf->b_ml.ml_line_count),
(long)curbuf->b_ml.ml_line_count, n);
#endif
else
{
+1 -6
View File
@@ -1575,18 +1575,13 @@ install_registry(void)
}
printf("Creating an uninstall entry\n");
sprintf(display_name, "Vim " VIM_VERSION_SHORT);
/* For the NSIS installer use the generated uninstaller. */
if (interactive)
{
sprintf(display_name, "Vim " VIM_VERSION_SHORT);
sprintf(uninstall_string, "%s\\uninstal.exe", installdir);
}
else
{
sprintf(display_name, "Vim " VIM_VERSION_SHORT " (self-installing)");
sprintf(uninstall_string, "%s\\uninstall-gui.exe", installdir);
}
lRet = register_uninstall(
HKEY_LOCAL_MACHINE,
+37
View File
@@ -398,6 +398,7 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
static void f_strwidth(typval_T *argvars, typval_T *rettv);
static void f_submatch(typval_T *argvars, typval_T *rettv);
static void f_substitute(typval_T *argvars, typval_T *rettv);
static void f_swapinfo(typval_T *argvars, typval_T *rettv);
static void f_synID(typval_T *argvars, typval_T *rettv);
static void f_synIDattr(typval_T *argvars, typval_T *rettv);
static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
@@ -463,6 +464,7 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv);
static void f_winbufnr(typval_T *argvars, typval_T *rettv);
static void f_wincol(typval_T *argvars, typval_T *rettv);
static void f_winheight(typval_T *argvars, typval_T *rettv);
static void f_winlayout(typval_T *argvars, typval_T *rettv);
static void f_winline(typval_T *argvars, typval_T *rettv);
static void f_winnr(typval_T *argvars, typval_T *rettv);
static void f_winrestcmd(typval_T *argvars, typval_T *rettv);
@@ -858,6 +860,7 @@ static struct fst
{"strwidth", 1, 1, f_strwidth},
{"submatch", 1, 2, f_submatch},
{"substitute", 4, 4, f_substitute},
{"swapinfo", 1, 1, f_swapinfo},
{"synID", 3, 3, f_synID},
{"synIDattr", 2, 3, f_synIDattr},
{"synIDtrans", 1, 1, f_synIDtrans},
@@ -952,6 +955,7 @@ static struct fst
{"winbufnr", 1, 1, f_winbufnr},
{"wincol", 0, 0, f_wincol},
{"winheight", 1, 1, f_winheight},
{"winlayout", 0, 1, f_winlayout},
{"winline", 0, 0, f_winline},
{"winnr", 0, 1, f_winnr},
{"winrestcmd", 0, 0, f_winrestcmd},
@@ -12342,6 +12346,16 @@ f_substitute(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg);
}
/*
* "swapinfo(swap_filename)" function
*/
static void
f_swapinfo(typval_T *argvars, typval_T *rettv)
{
if (rettv_dict_alloc(rettv) == OK)
get_b0_dict(get_tv_string(argvars), rettv->vval.v_dict);
}
/*
* "synID(lnum, col, trans)" function
*/
@@ -13773,6 +13787,29 @@ f_winheight(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = wp->w_height;
}
/*
* "winlayout()" function
*/
static void
f_winlayout(typval_T *argvars, typval_T *rettv)
{
tabpage_T *tp;
if (rettv_list_alloc(rettv) != OK)
return;
if (argvars[0].v_type == VAR_UNKNOWN)
tp = curtab;
else
{
tp = find_tabpage((int)get_tv_number(&argvars[0]));
if (tp == NULL)
return;
}
get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE);
}
/*
* "winline()" function
*/
+21 -19
View File
@@ -985,12 +985,8 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest)
ml_delete(line1 + extra, TRUE);
if (!global_busy && num_lines > p_report)
{
if (num_lines == 1)
MSG(_("1 line moved"));
else
smsg((char_u *)_("%ld lines moved"), num_lines);
}
smsg((char_u *)NGETTEXT("%ld line moved", "%ld lines moved", num_lines),
(long)num_lines);
/*
* Leave the cursor on the last of the moved lines.
@@ -5940,23 +5936,29 @@ do_sub_msg(
|| count_only)
&& messaging())
{
char *msg_single;
char *msg_plural;
if (got_int)
STRCPY(msg_buf, _("(Interrupted) "));
else
*msg_buf = NUL;
if (sub_nsubs == 1)
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
"%s", count_only ? _("1 match") : _("1 substitution"));
else
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
count_only ? _("%ld matches") : _("%ld substitutions"),
sub_nsubs);
if (sub_nlines == 1)
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
"%s", _(" on 1 line"));
else
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
_(" on %ld lines"), (long)sub_nlines);
msg_single = count_only
? NGETTEXT("%ld match on %ld line",
"%ld matches on %ld line", sub_nsubs)
: NGETTEXT("%ld substitution on %ld line",
"%ld substitutions on %ld line", sub_nsubs);
msg_plural = count_only
? NGETTEXT("%ld match on %ld lines",
"%ld matches on %ld lines", sub_nsubs)
: NGETTEXT("%ld substitution on %ld lines",
"%ld substitutions on %ld lines", sub_nsubs);
vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
NGETTEXT(msg_single, msg_plural, sub_nlines),
sub_nsubs, (long)sub_nlines);
if (msg(msg_buf))
/* save message to display it after redraw */
set_keep_msg(msg_buf, 0);
+6
View File
@@ -1797,6 +1797,12 @@ struct exarg
void *cookie; /* argument for getline() */
#ifdef FEAT_EVAL
struct condstack *cstack; /* condition stack for ":if" etc. */
#endif
long verbose_save; // saved value of p_verbose
int save_msg_silent; // saved value of msg_silent
int did_esilent; // how many times emsg_silent was incremented
#ifdef HAVE_SANDBOX
int did_sandbox; // when TRUE did ++sandbox
#endif
};
+369 -287
View File
@@ -68,6 +68,7 @@ static char_u *do_one_cmd(char_u **, int, struct condstack *, char_u *(*fgetline
static char_u *do_one_cmd(char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie);
static int if_level = 0; /* depth in :if */
#endif
static void free_cmdmod(void);
static void append_command(char_u *cmd);
static char_u *find_command(exarg_T *eap, int *full);
@@ -1716,13 +1717,7 @@ do_one_cmd(
char_u *errormsg = NULL; /* error message */
char_u *after_modifier = NULL;
exarg_T ea; /* Ex command arguments */
long verbose_save = -1;
int save_msg_scroll = msg_scroll;
int save_msg_silent = -1;
int did_esilent = 0;
#ifdef HAVE_SANDBOX
int did_sandbox = FALSE;
#endif
cmdmod_T save_cmdmod;
int ni; /* set when Not Implemented */
char_u *cmd;
@@ -1749,236 +1744,26 @@ do_one_cmd(
* recursive calls.
*/
save_cmdmod = cmdmod;
vim_memset(&cmdmod, 0, sizeof(cmdmod));
/* "#!anything" is handled like a comment. */
if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!')
goto doend;
/*
* Repeat until no more command modifiers are found.
*/
ea.cmd = *cmdlinep;
for (;;)
{
/*
* 1. Skip comment lines and leading white space and colons.
*/
while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')
++ea.cmd;
/* in ex mode, an empty line works like :+ */
if (*ea.cmd == NUL && exmode_active
&& (getline_equal(fgetline, cookie, getexmodeline)
|| getline_equal(fgetline, cookie, getexline))
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
{
ea.cmd = (char_u *)"+";
ex_pressedreturn = TRUE;
}
/* ignore comment and empty lines */
if (*ea.cmd == '"')
goto doend;
if (*ea.cmd == NUL)
{
ex_pressedreturn = TRUE;
goto doend;
}
/*
* 2. Handle command modifiers.
*/
p = skip_range(ea.cmd, NULL);
switch (*p)
{
/* When adding an entry, also modify cmd_exists(). */
case 'a': if (!checkforcmd(&ea.cmd, "aboveleft", 3))
break;
cmdmod.split |= WSP_ABOVE;
continue;
case 'b': if (checkforcmd(&ea.cmd, "belowright", 3))
{
cmdmod.split |= WSP_BELOW;
continue;
}
if (checkforcmd(&ea.cmd, "browse", 3))
{
#ifdef FEAT_BROWSE_CMD
cmdmod.browse = TRUE;
// The "ea" structure holds the arguments that can be used.
ea.cmd = *cmdlinep;
ea.cmdlinep = cmdlinep;
ea.getline = fgetline;
ea.cookie = cookie;
#ifdef FEAT_EVAL
ea.cstack = cstack;
#endif
continue;
}
if (!checkforcmd(&ea.cmd, "botright", 2))
break;
cmdmod.split |= WSP_BOT;
continue;
if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL)
goto doend;
case 'c': if (!checkforcmd(&ea.cmd, "confirm", 4))
break;
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
cmdmod.confirm = TRUE;
#endif
continue;
case 'k': if (checkforcmd(&ea.cmd, "keepmarks", 3))
{
cmdmod.keepmarks = TRUE;
continue;
}
if (checkforcmd(&ea.cmd, "keepalt", 5))
{
cmdmod.keepalt = TRUE;
continue;
}
if (checkforcmd(&ea.cmd, "keeppatterns", 5))
{
cmdmod.keeppatterns = TRUE;
continue;
}
if (!checkforcmd(&ea.cmd, "keepjumps", 5))
break;
cmdmod.keepjumps = TRUE;
continue;
case 'f': /* only accept ":filter {pat} cmd" */
{
char_u *reg_pat;
if (!checkforcmd(&p, "filter", 4)
|| *p == NUL || ends_excmd(*p))
break;
if (*p == '!')
{
cmdmod.filter_force = TRUE;
p = skipwhite(p + 1);
if (*p == NUL || ends_excmd(*p))
break;
}
p = skip_vimgrep_pat(p, &reg_pat, NULL);
if (p == NULL || *p == NUL)
break;
cmdmod.filter_regmatch.regprog =
vim_regcomp(reg_pat, RE_MAGIC);
if (cmdmod.filter_regmatch.regprog == NULL)
break;
ea.cmd = p;
continue;
}
/* ":hide" and ":hide | cmd" are not modifiers */
case 'h': if (p != ea.cmd || !checkforcmd(&p, "hide", 3)
|| *p == NUL || ends_excmd(*p))
break;
ea.cmd = p;
cmdmod.hide = TRUE;
continue;
case 'l': if (checkforcmd(&ea.cmd, "lockmarks", 3))
{
cmdmod.lockmarks = TRUE;
continue;
}
if (!checkforcmd(&ea.cmd, "leftabove", 5))
break;
cmdmod.split |= WSP_ABOVE;
continue;
case 'n': if (checkforcmd(&ea.cmd, "noautocmd", 3))
{
if (cmdmod.save_ei == NULL)
{
/* Set 'eventignore' to "all". Restore the
* existing option value later. */
cmdmod.save_ei = vim_strsave(p_ei);
set_string_option_direct((char_u *)"ei", -1,
(char_u *)"all", OPT_FREE, SID_NONE);
}
continue;
}
if (!checkforcmd(&ea.cmd, "noswapfile", 3))
break;
cmdmod.noswapfile = TRUE;
continue;
case 'r': if (!checkforcmd(&ea.cmd, "rightbelow", 6))
break;
cmdmod.split |= WSP_BELOW;
continue;
case 's': if (checkforcmd(&ea.cmd, "sandbox", 3))
{
#ifdef HAVE_SANDBOX
if (!did_sandbox)
++sandbox;
did_sandbox = TRUE;
#endif
continue;
}
if (!checkforcmd(&ea.cmd, "silent", 3))
break;
if (save_msg_silent == -1)
save_msg_silent = msg_silent;
++msg_silent;
if (*ea.cmd == '!' && !VIM_ISWHITE(ea.cmd[-1]))
{
/* ":silent!", but not "silent !cmd" */
ea.cmd = skipwhite(ea.cmd + 1);
++emsg_silent;
++did_esilent;
}
continue;
case 't': if (checkforcmd(&p, "tab", 3))
{
long tabnr = get_address(&ea, &ea.cmd, ADDR_TABS,
ea.skip, FALSE, 1);
if (tabnr == MAXLNUM)
cmdmod.tab = tabpage_index(curtab) + 1;
else
{
if (tabnr < 0 || tabnr > LAST_TAB_NR)
{
errormsg = (char_u *)_(e_invrange);
goto doend;
}
cmdmod.tab = tabnr + 1;
}
ea.cmd = p;
continue;
}
if (!checkforcmd(&ea.cmd, "topleft", 2))
break;
cmdmod.split |= WSP_TOP;
continue;
case 'u': if (!checkforcmd(&ea.cmd, "unsilent", 3))
break;
if (save_msg_silent == -1)
save_msg_silent = msg_silent;
msg_silent = 0;
continue;
case 'v': if (checkforcmd(&ea.cmd, "vertical", 4))
{
cmdmod.split |= WSP_VERT;
continue;
}
if (!checkforcmd(&p, "verbose", 4))
break;
if (verbose_save < 0)
verbose_save = p_verbose;
if (vim_isdigit(*ea.cmd))
p_verbose = atoi((char *)ea.cmd);
else
p_verbose = 1;
ea.cmd = p;
continue;
}
break;
}
after_modifier = ea.cmd;
#ifdef FEAT_EVAL
@@ -1988,28 +1773,6 @@ do_one_cmd(
ea.skip = (if_level > 0);
#endif
#ifdef FEAT_EVAL
# ifdef FEAT_PROFILE
/* Count this line for profiling if ea.skip is FALSE. */
if (do_profiling == PROF_YES && !ea.skip)
{
if (getline_equal(fgetline, cookie, get_func_line))
func_line_exec(getline_cookie(fgetline, cookie));
else if (getline_equal(fgetline, cookie, getsourceline))
script_line_exec();
}
#endif
/* May go to debug mode. If this happens and the ">quit" debug command is
* used, throw an interrupt exception and skip the next command. */
dbg_check_breakpoint(&ea);
if (!ea.skip && got_int)
{
ea.skip = TRUE;
(void)do_intthrow(cstack);
}
#endif
/*
* 3. Skip over the range to find the command. Let "p" point to after it.
*
@@ -2021,6 +1784,51 @@ do_one_cmd(
ea.cmd = skipwhite(ea.cmd + 1);
p = find_command(&ea, NULL);
#ifdef FEAT_EVAL
# ifdef FEAT_PROFILE
// Count this line for profiling if skip is TRUE.
if (do_profiling == PROF_YES
&& (!ea.skip || cstack->cs_idx == 0 || (cstack->cs_idx > 0
&& (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE))))
{
int skip = did_emsg || got_int || did_throw;
if (ea.cmdidx == CMD_catch)
skip = !skip && !(cstack->cs_idx >= 0
&& (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN)
&& !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT));
else if (ea.cmdidx == CMD_else || ea.cmdidx == CMD_elseif)
skip = skip || !(cstack->cs_idx >= 0
&& !(cstack->cs_flags[cstack->cs_idx]
& (CSF_ACTIVE | CSF_TRUE)));
else if (ea.cmdidx == CMD_finally)
skip = FALSE;
else if (ea.cmdidx != CMD_endif
&& ea.cmdidx != CMD_endfor
&& ea.cmdidx != CMD_endtry
&& ea.cmdidx != CMD_endwhile)
skip = ea.skip;
if (!skip)
{
if (getline_equal(fgetline, cookie, get_func_line))
func_line_exec(getline_cookie(fgetline, cookie));
else if (getline_equal(fgetline, cookie, getsourceline))
script_line_exec();
}
}
# endif
/* May go to debug mode. If this happens and the ">quit" debug command is
* used, throw an interrupt exception and skip the next command. */
dbg_check_breakpoint(&ea);
if (!ea.skip && got_int)
{
ea.skip = TRUE;
(void)do_intthrow(cstack);
}
#endif
/*
* 4. parse a range specifier of the form: addr [,addr] [;addr] ..
*
@@ -2695,25 +2503,17 @@ do_one_cmd(
/* The :try command saves the emsg_silent flag, reset it here when
* ":silent! try" was used, it should only apply to :try itself. */
if (ea.cmdidx == CMD_try && did_esilent > 0)
if (ea.cmdidx == CMD_try && ea.did_esilent > 0)
{
emsg_silent -= did_esilent;
emsg_silent -= ea.did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
did_esilent = 0;
ea.did_esilent = 0;
}
/*
* 7. Execute the command.
*
* The "ea" structure holds the arguments that can be used.
*/
ea.cmdlinep = cmdlinep;
ea.getline = fgetline;
ea.cookie = cookie;
#ifdef FEAT_EVAL
ea.cstack = cstack;
#endif
#ifdef FEAT_USR_CMDS
if (IS_USER_CMDIDX(ea.cmdidx))
@@ -2782,29 +2582,19 @@ doend:
? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
#endif
if (verbose_save >= 0)
p_verbose = verbose_save;
if (cmdmod.save_ei != NULL)
{
/* Restore 'eventignore' to the value before ":noautocmd". */
set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
OPT_FREE, SID_NONE);
free_string_option(cmdmod.save_ei);
}
if (cmdmod.filter_regmatch.regprog != NULL)
vim_regfree(cmdmod.filter_regmatch.regprog);
if (ea.verbose_save >= 0)
p_verbose = ea.verbose_save;
free_cmdmod();
cmdmod = save_cmdmod;
if (save_msg_silent != -1)
if (ea.save_msg_silent != -1)
{
/* messages could be enabled for a serious error, need to check if the
* counters don't become negative */
if (!did_emsg || msg_silent > save_msg_silent)
msg_silent = save_msg_silent;
emsg_silent -= did_esilent;
if (!did_emsg || msg_silent > ea.save_msg_silent)
msg_silent = ea.save_msg_silent;
emsg_silent -= ea.did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
/* Restore msg_scroll, it's set by file I/O commands, even when no
@@ -2818,7 +2608,7 @@ doend:
}
#ifdef HAVE_SANDBOX
if (did_sandbox)
if (ea.did_sandbox)
--sandbox;
#endif
@@ -2835,6 +2625,290 @@ doend:
#pragma optimize( "", on )
#endif
/*
* Parse and skip over command modifiers:
* - update eap->cmd
* - store flags in "cmdmod".
* - Set ex_pressedreturn for an empty command line.
* - set msg_silent for ":silent"
* - set 'eventignore' to "all" for ":noautocmd"
* - set p_verbose for ":verbose"
* - Increment "sandbox" for ":sandbox"
* When "skip_only" is TRUE the global variables are not changed, except for
* "cmdmod".
* Return FAIL when the command is not to be executed.
* May set "errormsg" to an error message.
*/
int
parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only)
{
char_u *p;
vim_memset(&cmdmod, 0, sizeof(cmdmod));
eap->verbose_save = -1;
eap->save_msg_silent = -1;
// Repeat until no more command modifiers are found.
for (;;)
{
while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':')
++eap->cmd;
/* in ex mode, an empty line works like :+ */
if (*eap->cmd == NUL && exmode_active
&& (getline_equal(eap->getline, eap->cookie, getexmodeline)
|| getline_equal(eap->getline, eap->cookie, getexline))
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
{
eap->cmd = (char_u *)"+";
if (!skip_only)
ex_pressedreturn = TRUE;
}
/* ignore comment and empty lines */
if (*eap->cmd == '"')
return FAIL;
if (*eap->cmd == NUL)
{
if (!skip_only)
ex_pressedreturn = TRUE;
return FAIL;
}
p = skip_range(eap->cmd, NULL);
switch (*p)
{
/* When adding an entry, also modify cmd_exists(). */
case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3))
break;
cmdmod.split |= WSP_ABOVE;
continue;
case 'b': if (checkforcmd(&eap->cmd, "belowright", 3))
{
cmdmod.split |= WSP_BELOW;
continue;
}
if (checkforcmd(&eap->cmd, "browse", 3))
{
#ifdef FEAT_BROWSE_CMD
cmdmod.browse = TRUE;
#endif
continue;
}
if (!checkforcmd(&eap->cmd, "botright", 2))
break;
cmdmod.split |= WSP_BOT;
continue;
case 'c': if (!checkforcmd(&eap->cmd, "confirm", 4))
break;
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
cmdmod.confirm = TRUE;
#endif
continue;
case 'k': if (checkforcmd(&eap->cmd, "keepmarks", 3))
{
cmdmod.keepmarks = TRUE;
continue;
}
if (checkforcmd(&eap->cmd, "keepalt", 5))
{
cmdmod.keepalt = TRUE;
continue;
}
if (checkforcmd(&eap->cmd, "keeppatterns", 5))
{
cmdmod.keeppatterns = TRUE;
continue;
}
if (!checkforcmd(&eap->cmd, "keepjumps", 5))
break;
cmdmod.keepjumps = TRUE;
continue;
case 'f': /* only accept ":filter {pat} cmd" */
{
char_u *reg_pat;
if (!checkforcmd(&p, "filter", 4)
|| *p == NUL || ends_excmd(*p))
break;
if (*p == '!')
{
cmdmod.filter_force = TRUE;
p = skipwhite(p + 1);
if (*p == NUL || ends_excmd(*p))
break;
}
if (skip_only)
p = skip_vimgrep_pat(p, NULL, NULL);
else
// NOTE: This puts a NUL after the pattern.
p = skip_vimgrep_pat(p, &reg_pat, NULL);
if (p == NULL || *p == NUL)
break;
if (!skip_only)
{
cmdmod.filter_regmatch.regprog =
vim_regcomp(reg_pat, RE_MAGIC);
if (cmdmod.filter_regmatch.regprog == NULL)
break;
}
eap->cmd = p;
continue;
}
/* ":hide" and ":hide | cmd" are not modifiers */
case 'h': if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
|| *p == NUL || ends_excmd(*p))
break;
eap->cmd = p;
cmdmod.hide = TRUE;
continue;
case 'l': if (checkforcmd(&eap->cmd, "lockmarks", 3))
{
cmdmod.lockmarks = TRUE;
continue;
}
if (!checkforcmd(&eap->cmd, "leftabove", 5))
break;
cmdmod.split |= WSP_ABOVE;
continue;
case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3))
{
if (cmdmod.save_ei == NULL && !skip_only)
{
/* Set 'eventignore' to "all". Restore the
* existing option value later. */
cmdmod.save_ei = vim_strsave(p_ei);
set_string_option_direct((char_u *)"ei", -1,
(char_u *)"all", OPT_FREE, SID_NONE);
}
continue;
}
if (!checkforcmd(&eap->cmd, "noswapfile", 3))
break;
cmdmod.noswapfile = TRUE;
continue;
case 'r': if (!checkforcmd(&eap->cmd, "rightbelow", 6))
break;
cmdmod.split |= WSP_BELOW;
continue;
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3))
{
#ifdef HAVE_SANDBOX
if (!skip_only)
{
if (!eap->did_sandbox)
++sandbox;
eap->did_sandbox = TRUE;
}
#endif
continue;
}
if (!checkforcmd(&eap->cmd, "silent", 3))
break;
if (!skip_only)
{
if (eap->save_msg_silent == -1)
eap->save_msg_silent = msg_silent;
++msg_silent;
}
if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
{
/* ":silent!", but not "silent !cmd" */
eap->cmd = skipwhite(eap->cmd + 1);
if (!skip_only)
{
++emsg_silent;
++eap->did_esilent;
}
}
continue;
case 't': if (checkforcmd(&p, "tab", 3))
{
long tabnr = get_address(eap, &eap->cmd, ADDR_TABS,
eap->skip, FALSE, 1);
if (tabnr == MAXLNUM)
cmdmod.tab = tabpage_index(curtab) + 1;
else
{
if (tabnr < 0 || tabnr > LAST_TAB_NR)
{
*errormsg = (char_u *)_(e_invrange);
return FAIL;
}
cmdmod.tab = tabnr + 1;
}
eap->cmd = p;
continue;
}
if (!checkforcmd(&eap->cmd, "topleft", 2))
break;
cmdmod.split |= WSP_TOP;
continue;
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
break;
if (!skip_only)
{
if (eap->save_msg_silent == -1)
eap->save_msg_silent = msg_silent;
msg_silent = 0;
}
continue;
case 'v': if (checkforcmd(&eap->cmd, "vertical", 4))
{
cmdmod.split |= WSP_VERT;
continue;
}
if (!checkforcmd(&p, "verbose", 4))
break;
if (!skip_only)
{
if (eap->verbose_save < 0)
eap->verbose_save = p_verbose;
if (vim_isdigit(*eap->cmd))
p_verbose = atoi((char *)eap->cmd);
else
p_verbose = 1;
}
eap->cmd = p;
continue;
}
break;
}
return OK;
}
/*
* Free contents of "cmdmod".
*/
static void
free_cmdmod(void)
{
if (cmdmod.save_ei != NULL)
{
/* Restore 'eventignore' to the value before ":noautocmd". */
set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
OPT_FREE, SID_NONE);
free_string_option(cmdmod.save_ei);
}
if (cmdmod.filter_regmatch.regprog != NULL)
vim_regfree(cmdmod.filter_regmatch.regprog);
}
/*
* Parse the address range, if any, in "eap".
* Return FAIL and set "errormsg" or return OK.
@@ -5714,22 +5788,16 @@ check_more(
{
char_u buff[DIALOG_MSG_SIZE];
if (n == 1)
vim_strncpy(buff,
(char_u *)_("1 more file to edit. Quit anyway?"),
DIALOG_MSG_SIZE - 1);
else
vim_snprintf((char *)buff, DIALOG_MSG_SIZE,
_("%d more files to edit. Quit anyway?"), n);
vim_snprintf((char *)buff, DIALOG_MSG_SIZE,
NGETTEXT("%d more file to edit. Quit anyway?",
"%d more files to edit. Quit anyway?", n), n);
if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES)
return OK;
return FAIL;
}
#endif
if (n == 1)
EMSG(_("E173: 1 more file to edit"));
else
EMSGN(_("E173: %ld more files to edit"), n);
EMSGN(NGETTEXT("E173: %ld more file to edit",
"E173: %ld more files to edit", n), n);
quitmore = 2; /* next try to quit is allowed */
}
return FAIL;
@@ -12512,6 +12580,20 @@ ex_folddo(exarg_T *eap)
}
#endif
#ifdef FEAT_QUICKFIX
/*
* Returns TRUE if the supplied Ex cmdidx is for a location list command
* instead of a quickfix command.
*/
int
is_loclist_cmd(int cmdidx)
{
if (cmdidx < 0 || cmdidx > CMD_SIZE)
return FALSE;
return cmdnames[cmdidx].cmd_name[0] == 'l';
}
#endif
# if defined(FEAT_TIMERS) || defined(PROTO)
int
get_pressedreturn(void)
+118 -75
View File
@@ -13,6 +13,10 @@
#include "vim.h"
#ifndef MAX
# define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
* These need to be saved when using CTRL-R |, that's why they are in a
@@ -231,6 +235,7 @@ typedef struct {
pos_T match_end;
int did_incsearch;
int incsearch_postponed;
int magic_save;
} incsearch_state_T;
static void
@@ -239,6 +244,7 @@ init_incsearch_state(incsearch_state_T *is_state)
is_state->match_start = curwin->w_cursor;
is_state->did_incsearch = FALSE;
is_state->incsearch_postponed = FALSE;
is_state->magic_save = p_magic;
CLEAR_POS(&is_state->match_end);
is_state->save_cursor = curwin->w_cursor; // may be restored later
is_state->search_start = curwin->w_cursor;
@@ -270,92 +276,125 @@ set_search_match(pos_T *t)
do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
int *skiplen, int *patlen)
{
char_u *cmd;
cmdmod_T save_cmdmod = cmdmod;
char_u *p;
int delim_optional = FALSE;
int delim;
char_u *end;
char_u *dummy;
exarg_T ea;
pos_T save_cursor;
*skiplen = 0;
*patlen = ccline.cmdlen;
if (p_is && !cmd_silent)
if (!p_is || cmd_silent)
return FALSE;
// by default search all lines
search_first_line = 0;
search_last_line = MAXLNUM;
if (firstc == '/' || firstc == '?')
return TRUE;
if (firstc != ':')
return FALSE;
vim_memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
ea.line2 = 1;
ea.cmd = ccline.cmdbuff;
ea.addr_type = ADDR_LINES;
parse_command_modifiers(&ea, &dummy, TRUE);
cmdmod = save_cmdmod;
cmd = skip_range(ea.cmd, NULL);
if (vim_strchr((char_u *)"sgvl", *cmd) == NULL)
return FALSE;
// Skip over "substitute" to find the pattern separator.
for (p = cmd; ASCII_ISALPHA(*p); ++p)
;
if (*skipwhite(p) == NUL)
return FALSE;
if (STRNCMP(cmd, "substitute", p - cmd) == 0
|| STRNCMP(cmd, "smagic", p - cmd) == 0
|| STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0
|| STRNCMP(cmd, "vglobal", p - cmd) == 0)
{
// by default search all lines
search_first_line = 0;
search_last_line = MAXLNUM;
if (firstc == '/' || firstc == '?')
return TRUE;
if (firstc == ':')
if (*cmd == 's' && cmd[1] == 'm')
p_magic = TRUE;
else if (*cmd == 's' && cmd[1] == 'n')
p_magic = FALSE;
}
else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0)
{
// skip over flags
while (ASCII_ISALPHA(*(p = skipwhite(p))))
++p;
if (*p == NUL)
return FALSE;
}
else if (STRNCMP(cmd, "vimgrep", MAX(p - cmd, 3)) == 0
|| STRNCMP(cmd, "vimgrepadd", MAX(p - cmd, 8)) == 0
|| STRNCMP(cmd, "lvimgrep", MAX(p - cmd, 2)) == 0
|| STRNCMP(cmd, "lvimgrepadd", MAX(p - cmd, 9)) == 0
|| STRNCMP(cmd, "global", p - cmd) == 0)
{
// skip over "!"
if (*p == '!')
{
char_u *cmd = skip_range(ccline.cmdbuff, NULL);
char_u *p;
int delim;
char_u *end;
p++;
if (*skipwhite(p) == NUL)
return FALSE;
}
if (*cmd != 'g')
delim_optional = TRUE;
}
else
return FALSE;
if (*cmd == 's' || *cmd == 'g' || *cmd == 'v')
{
// Skip over "substitute" to find the pattern separator.
for (p = cmd; ASCII_ISALPHA(*p); ++p)
;
if (*skipwhite(p) != NUL
&& (STRNCMP(cmd, "substitute", p - cmd) == 0
|| STRNCMP(cmd, "global", p - cmd) == 0
|| STRNCMP(cmd, "vglobal", p - cmd) == 0))
{
// Check for "global!/".
if (*cmd == 'g' && *p == '!')
{
p++;
if (*skipwhite(p) == NUL)
return FALSE;
}
p = skipwhite(p);
delim = *p++;
end = skip_regexp(p, delim, p_magic, NULL);
if (end > p || *end == delim)
{
char_u *dummy;
exarg_T ea;
pos_T save_cursor = curwin->w_cursor;
p = skipwhite(p);
delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
end = skip_regexp(p, delim, p_magic, NULL);
// found a non-empty pattern
*skiplen = (int)(p - ccline.cmdbuff);
*patlen = (int)(end - p);
if (end == p && *end != delim)
return FALSE;
// found a non-empty pattern or //
// parse the address range
vim_memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
ea.line2 = 1;
ea.cmd = ccline.cmdbuff;
ea.addr_type = ADDR_LINES;
curwin->w_cursor = is_state->search_start;
parse_cmd_address(&ea, &dummy);
if (ea.addr_count > 0)
{
// Allow for reverse match.
if (ea.line2 < ea.line1)
{
search_first_line = ea.line2;
search_last_line = ea.line1;
}
else
{
search_first_line = ea.line1;
search_last_line = ea.line2;
}
}
else if (*cmd == 's')
{
// :s defaults to the current line
search_first_line = curwin->w_cursor.lnum;
search_last_line = curwin->w_cursor.lnum;
}
*skiplen = (int)(p - ccline.cmdbuff);
*patlen = (int)(end - p);
curwin->w_cursor = save_cursor;
return TRUE;
}
}
}
// parse the address range
save_cursor = curwin->w_cursor;
curwin->w_cursor = is_state->search_start;
parse_cmd_address(&ea, &dummy);
if (ea.addr_count > 0)
{
// Allow for reverse match.
if (ea.line2 < ea.line1)
{
search_first_line = ea.line2;
search_last_line = ea.line1;
}
else
{
search_first_line = ea.line1;
search_last_line = ea.line2;
}
}
else if (cmd[0] == 's' && cmd[1] != 'o')
{
// :s defaults to the current line
search_first_line = curwin->w_cursor.lnum;
search_last_line = curwin->w_cursor.lnum;
}
return FALSE;
curwin->w_cursor = save_cursor;
return TRUE;
}
static void
@@ -386,6 +425,7 @@ finish_incsearch_highlighting(
update_screen(SOME_VALID);
else
redraw_all_later(SOME_VALID);
p_magic = is_state->magic_save;
}
}
@@ -474,8 +514,11 @@ may_do_incsearch_highlighting(
if (curwin->w_cursor.lnum < search_first_line
|| curwin->w_cursor.lnum > search_last_line)
{
// match outside of address range
i = 0;
curwin->w_cursor = is_state->search_start;
}
// if interrupted while searching, behave like it failed
if (got_int)
@@ -571,7 +614,7 @@ may_adjust_incsearch_highlighting(
{
pat = last_search_pattern();
skiplen = 0;
patlen = STRLEN(pat);
patlen = (int)STRLEN(pat);
}
else
pat = ccline.cmdbuff + skiplen;
+4
View File
@@ -355,6 +355,10 @@
# endif
#endif
#ifdef FEAT_EVAL
# define HAVE_SANDBOX
#endif
/*
* +profile Profiling for functions and scripts.
*/
+4 -9
View File
@@ -5353,16 +5353,11 @@ msg_add_lines(
"%ldL, %lldC", lnum, (long long)nchars);
else
{
if (lnum == 1)
STRCPY(p, _("1 line, "));
else
sprintf((char *)p, _("%ld lines, "), lnum);
sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
p += STRLEN(p);
if (nchars == 1)
STRCPY(p, _("1 character"));
else
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
_("%lld characters"), (long long)nchars);
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
NGETTEXT("%lld character", "%lld characters", nchars),
(long long)nchars);
}
}
+6 -7
View File
@@ -518,7 +518,7 @@ EXTERN char *foreground_argument INIT(= NULL);
*
* volatile because it is used in signal handler sig_sysmouse().
*/
EXTERN volatile int hold_gui_events INIT(= 0);
EXTERN volatile sig_atomic_t hold_gui_events INIT(= 0);
/*
* When resizing the shell is postponed, remember the new size, and call
@@ -655,7 +655,7 @@ EXTERN int entered_free_all_mem INIT(= FALSE);
/* TRUE when in or after free_all_mem() */
#endif
/* volatile because it is used in signal handler deathtrap(). */
EXTERN volatile int full_screen INIT(= FALSE);
EXTERN volatile sig_atomic_t full_screen INIT(= FALSE);
/* TRUE when doing full-screen output
* otherwise only writing some messages */
@@ -678,8 +678,7 @@ EXTERN int allbuf_lock INIT(= 0);
* changed, no buffer can be deleted and
* current directory can't be changed.
* Used for SwapExists et al. */
#ifdef FEAT_EVAL
# define HAVE_SANDBOX
#ifdef HAVE_SANDBOX
EXTERN int sandbox INIT(= 0);
/* Non-zero when evaluating an expression in a
* "sandbox". Several things are not allowed
@@ -801,11 +800,11 @@ EXTERN JMP_BUF x_jump_env;
EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */
# ifdef SIGHASARG
/* volatile because it is used in signal handlers. */
EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal
EXTERN volatile sig_atomic_t lc_signal; /* caught signal number, 0 when no was signal
caught; used for mch_libcall() */
# endif
/* volatile because it is used in signal handler deathtrap(). */
EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
EXTERN volatile sig_atomic_t lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
#endif
#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
@@ -1040,7 +1039,7 @@ EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */
/* volatile because it is used in signal handler catch_sigint(). */
EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
EXTERN volatile sig_atomic_t got_int INIT(= FALSE); /* set to TRUE when interrupt
signal occurred */
#ifdef USE_TERM_CONSOLE
EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
+10 -6
View File
@@ -944,6 +944,8 @@ drawBalloon(BalloonEval *beval)
GtkRequisition requisition;
int screen_w;
int screen_h;
int screen_x;
int screen_y;
int x;
int y;
int x_offset = EVAL_OFFSET_X;
@@ -956,8 +958,8 @@ drawBalloon(BalloonEval *beval)
screen = gtk_widget_get_screen(beval->target);
gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
# endif
gui_gtk_get_screen_size_of_win(beval->balloonShell,
&screen_w, &screen_h);
gui_gtk_get_screen_geom_of_win(beval->balloonShell,
&screen_x, &screen_y, &screen_w, &screen_h);
# if !GTK_CHECK_VERSION(3,0,0)
gtk_widget_ensure_style(beval->balloonShell);
gtk_widget_ensure_style(beval->balloonLabel);
@@ -998,14 +1000,16 @@ drawBalloon(BalloonEval *beval)
y += beval->y;
/* Get out of the way of the mouse pointer */
if (x + x_offset + requisition.width > screen_w)
if (x + x_offset + requisition.width > screen_x + screen_w)
y_offset += 15;
if (y + y_offset + requisition.height > screen_h)
if (y + y_offset + requisition.height > screen_y + screen_h)
y_offset = -requisition.height - EVAL_OFFSET_Y;
/* Sanitize values */
x = CLAMP(x + x_offset, 0, MAX(0, screen_w - requisition.width));
y = CLAMP(y + y_offset, 0, MAX(0, screen_h - requisition.height));
x = CLAMP(x + x_offset, 0,
MAX(0, screen_x + screen_w - requisition.width));
y = CLAMP(y + y_offset, 0,
MAX(0, screen_y + screen_h - requisition.height));
/* Show the balloon */
# if GTK_CHECK_VERSION(3,0,0)
+18 -8
View File
@@ -5008,27 +5008,35 @@ gui_mch_set_shellsize(int width, int height,
}
void
gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height)
gui_gtk_get_screen_geom_of_win(
GtkWidget *wid,
int *screen_x,
int *screen_y,
int *width,
int *height)
{
GdkRectangle geometry;
GdkWindow *win = gtk_widget_get_window(wid);
#if GTK_CHECK_VERSION(3,22,0)
GdkDisplay *dpy = gtk_widget_get_display(wid);
GdkWindow *win = gtk_widget_get_window(wid);
GdkMonitor *monitor = gdk_display_get_monitor_at_window(dpy, win);
GdkRectangle geometry;
gdk_monitor_get_geometry(monitor, &geometry);
*width = geometry.width;
*height = geometry.height;
#else
GdkScreen* screen;
int monitor;
if (wid != NULL && gtk_widget_has_screen(wid))
screen = gtk_widget_get_screen(wid);
else
screen = gdk_screen_get_default();
*width = gdk_screen_get_width(screen);
*height = gdk_screen_get_height(screen);
monitor = gdk_screen_get_monitor_at_window(screen, win);
gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
#endif
*screen_x = geometry.x;
*screen_y = geometry.y;
*width = geometry.width;
*height = geometry.height;
}
/*
@@ -5039,7 +5047,9 @@ gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height)
void
gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
{
gui_gtk_get_screen_size_of_win(gui.mainwin, screen_w, screen_h);
int x, y;
gui_gtk_get_screen_geom_of_win(gui.mainwin, &x, &y, screen_w, screen_h);
/* Subtract 'guiheadroom' from the height to allow some room for the
* window manager (task list and window title bar). */
+13 -1
View File
@@ -164,7 +164,11 @@ static luaV_Funcref *luaV_pushfuncref(lua_State *L, typval_T *tv);
#define lua_rawget dll_lua_rawget
#define lua_rawgeti dll_lua_rawgeti
#define lua_createtable dll_lua_createtable
#define lua_newuserdata dll_lua_newuserdata
#if LUA_VERSION_NUM >= 504
#define lua_newuserdatauv dll_lua_newuserdatauv
#else
#define lua_newuserdata dll_lua_newuserdata
#endif
#define lua_getmetatable dll_lua_getmetatable
#define lua_setfield dll_lua_setfield
#define lua_rawset dll_lua_rawset
@@ -261,7 +265,11 @@ int (*dll_lua_rawget) (lua_State *L, int idx);
int (*dll_lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
#endif
void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
#if LUA_VERSION_NUM >= 504
void *(*dll_lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue);
#else
void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
#endif
int (*dll_lua_getmetatable) (lua_State *L, int objindex);
void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
void (*dll_lua_rawset) (lua_State *L, int idx);
@@ -362,7 +370,11 @@ static const luaV_Reg luaV_dll[] = {
{"lua_rawget", (luaV_function) &dll_lua_rawget},
{"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
{"lua_createtable", (luaV_function) &dll_lua_createtable},
#if LUA_VERSION_NUM >= 504
{"lua_newuserdatauv", (luaV_function) &dll_lua_newuserdatauv},
#else
{"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
#endif
{"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
{"lua_setfield", (luaV_function) &dll_lua_setfield},
{"lua_rawset", (luaV_function) &dll_lua_rawset},
+9 -7
View File
@@ -4975,24 +4975,26 @@ im_add_to_input(char_u *str, int len)
static void
im_preedit_window_set_position(void)
{
int x, y, w, h, sw, sh;
int x, y, width, height;
int screen_x, screen_y, screen_width, screen_height;
if (preedit_window == NULL)
return;
gui_gtk_get_screen_size_of_win(preedit_window, &sw, &sh);
gui_gtk_get_screen_geom_of_win(gui.drawarea,
&screen_x, &screen_y, &screen_width, &screen_height);
#if GTK_CHECK_VERSION(3,0,0)
gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y);
#else
gdk_window_get_origin(gui.drawarea->window, &x, &y);
#endif
gtk_window_get_size(GTK_WINDOW(preedit_window), &w, &h);
gtk_window_get_size(GTK_WINDOW(preedit_window), &width, &height);
x = x + FILL_X(gui.col);
y = y + FILL_Y(gui.row);
if (x + w > sw)
x = sw - w;
if (y + h > sh)
y = sh - h;
if (x + width > screen_x + screen_width)
x = screen_x + screen_width - width;
if (y + height > screen_y + screen_height)
y = screen_y + screen_height - height;
gtk_window_move(GTK_WINDOW(preedit_window), x, y);
}
+52 -2
View File
@@ -828,10 +828,13 @@ ml_open_file(buf_T *buf)
*/
void
check_need_swap(
int newfile) /* reading file into new buffer */
int newfile) // reading file into new buffer
{
int old_msg_silent = msg_silent; // might be reset by an E325 message
if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
ml_open_file(curbuf);
msg_silent = old_msg_silent;
}
/*
@@ -2038,6 +2041,53 @@ make_percent_swname(char_u *dir, char_u *name)
static int process_still_running;
#endif
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* Return information found in swapfile "fname" in dictionary "d".
* This is used by the swapinfo() function.
*/
void
get_b0_dict(char_u *fname, dict_T *d)
{
int fd;
struct block0 b0;
if ((fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0)
{
if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
{
if (ml_check_b0_id(&b0) == FAIL)
dict_add_string(d, "error",
vim_strsave((char_u *)"Not a swap file"));
else if (b0_magic_wrong(&b0))
dict_add_string(d, "error",
vim_strsave((char_u *)"Magic number mismatch"));
else
{
/* we have swap information */
dict_add_string(d, "version", vim_strsave(b0.b0_version));
dict_add_string(d, "user", vim_strsave(b0.b0_uname));
dict_add_string(d, "host", vim_strsave(b0.b0_hname));
dict_add_string(d, "fname", vim_strsave(b0.b0_fname));
dict_add_number(d, "pid", char_to_long(b0.b0_pid));
dict_add_number(d, "mtime", char_to_long(b0.b0_mtime));
dict_add_number(d, "dirty", b0.b0_dirty ? 1 : 0);
# ifdef CHECK_INODE
dict_add_number(d, "inode", char_to_long(b0.b0_ino));
# endif
}
}
else
dict_add_string(d, "error",
vim_strsave((char_u *)"Cannot read file"));
close(fd);
}
else
dict_add_string(d, "error", vim_strsave((char_u *)"Cannot open file"));
}
#endif
/*
* Give information about an existing swap file.
* Returns timestamp (0 when unknown).
@@ -5267,7 +5317,7 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
/* Don't count the last line break if 'noeol' and ('bin' or
* 'nofixeol'). */
if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
&& buf->b_ml.ml_line_count == lnum)
&& lnum > buf->b_ml.ml_line_count)
size -= ffdos + 1;
}
+5 -17
View File
@@ -3809,24 +3809,12 @@ msgmore(long n)
if (pn > p_report)
{
if (pn == 1)
{
if (n > 0)
vim_strncpy(msg_buf, (char_u *)_("1 more line"),
MSG_BUF_LEN - 1);
else
vim_strncpy(msg_buf, (char_u *)_("1 line less"),
MSG_BUF_LEN - 1);
}
if (n > 0)
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
NGETTEXT("%ld more line", "%ld more lines", pn), pn);
else
{
if (n > 0)
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
_("%ld more lines"), pn);
else
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
_("%ld fewer lines"), pn);
}
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
NGETTEXT("%ld line less", "%ld fewer lines", pn), pn);
if (got_int)
vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN);
if (msg(msg_buf))
+28 -45
View File
@@ -244,7 +244,6 @@ op_shift(oparg_T *oap, int curs_top, int amount)
{
long i;
int first_char;
char_u *s;
int block_col = 0;
if (u_save((linenr_T)(oap->start.lnum - 1),
@@ -297,26 +296,21 @@ op_shift(oparg_T *oap, int curs_top, int amount)
if (oap->line_count > p_report)
{
char *op;
char *msg_line_single;
char *msg_line_plural;
if (oap->op_type == OP_RSHIFT)
s = (char_u *)">";
op = ">";
else
s = (char_u *)"<";
if (oap->line_count == 1)
{
if (amount == 1)
sprintf((char *)IObuff, _("1 line %sed 1 time"), s);
else
sprintf((char *)IObuff, _("1 line %sed %d times"), s, amount);
}
else
{
if (amount == 1)
sprintf((char *)IObuff, _("%ld lines %sed 1 time"),
oap->line_count, s);
else
sprintf((char *)IObuff, _("%ld lines %sed %d times"),
oap->line_count, s, amount);
}
op = "<";
msg_line_single = NGETTEXT("%ld line %sed %d time",
"%ld line %sed %d times", amount);
msg_line_plural = NGETTEXT("%ld lines %sed %d time",
"%ld lines %sed %d times", amount);
vim_snprintf((char *)IObuff, IOSIZE,
NGETTEXT(msg_line_single, msg_line_plural, oap->line_count),
oap->line_count, op, amount);
msg(IObuff);
}
@@ -789,10 +783,8 @@ op_reindent(oparg_T *oap, int (*how)(void))
if (oap->line_count > p_report)
{
i = oap->line_count - (i + 1);
if (i == 1)
MSG(_("1 line indented "));
else
smsg((char_u *)_("%ld lines indented "), i);
smsg((char_u *)NGETTEXT("%ld line indented ",
"%ld lines indented ", i), i);
}
/* set '[ and '] marks */
curbuf->b_op_start = oap->start;
@@ -2529,12 +2521,8 @@ op_tilde(oparg_T *oap)
curbuf->b_op_end = oap->end;
if (oap->line_count > p_report)
{
if (oap->line_count == 1)
MSG(_("1 line changed"));
else
smsg((char_u *)_("%ld lines changed"), oap->line_count);
}
smsg((char_u *)NGETTEXT("%ld line changed", "%ld lines changed",
oap->line_count), oap->line_count);
}
/*
@@ -3348,19 +3336,18 @@ op_yank(oparg_T *oap, int deleting, int mess)
/* redisplay now, so message is not deleted */
update_topline_redraw();
if (yanklines == 1)
if (oap->block_mode)
{
if (oap->block_mode)
smsg((char_u *)_("block of 1 line yanked%s"), namebuf);
else
smsg((char_u *)_("1 line yanked%s"), namebuf);
smsg((char_u *)NGETTEXT("block of %ld line yanked%s",
"block of %ld lines yanked%s", yanklines),
yanklines, namebuf);
}
else if (oap->block_mode)
smsg((char_u *)_("block of %ld lines yanked%s"),
yanklines, namebuf);
else
smsg((char_u *)_("%ld lines yanked%s"), yanklines,
namebuf);
{
smsg((char_u *)NGETTEXT("%ld line yanked%s",
"%ld lines yanked%s", yanklines),
yanklines, namebuf);
}
}
}
@@ -5653,12 +5640,8 @@ op_addsub(
curbuf->b_op_start = startpos;
if (change_cnt > p_report)
{
if (change_cnt == 1)
MSG(_("1 line changed"));
else
smsg((char_u *)_("%ld lines changed"), change_cnt);
}
smsg((char_u *)NGETTEXT("%ld line changed", "%ld lines changed",
change_cnt), change_cnt);
}
}
+40 -46
View File
@@ -161,6 +161,7 @@ static int get_x11_title(int);
static int get_x11_icon(int);
static char_u *oldtitle = NULL;
static volatile sig_atomic_t oldtitle_outdated = FALSE;
static int did_set_title = FALSE;
static char_u *oldicon = NULL;
static int did_set_icon = FALSE;
@@ -204,7 +205,7 @@ static RETSIGTYPE catch_sigpwr SIGPROTOARG;
# define SET_SIG_ALARM
static RETSIGTYPE sig_alarm SIGPROTOARG;
/* volatile because it is used in signal handler sig_alarm(). */
static volatile int sig_alarm_called;
static volatile sig_atomic_t sig_alarm_called;
#endif
static RETSIGTYPE deathtrap SIGPROTOARG;
@@ -230,13 +231,13 @@ static int save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***fil
#endif
/* volatile because it is used in signal handler sig_winch(). */
static volatile int do_resize = FALSE;
static volatile sig_atomic_t do_resize = FALSE;
static char_u *extra_shell_arg = NULL;
static int show_shell_mess = TRUE;
/* volatile because it is used in signal handler deathtrap(). */
static volatile int deadly_signal = 0; /* The signal we caught */
static volatile sig_atomic_t deadly_signal = 0; /* The signal we caught */
/* volatile because it is used in signal handler deathtrap(). */
static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */
static volatile sig_atomic_t in_mch_delay = FALSE; /* sleeping in mch_delay() */
#if defined(FEAT_JOB_CHANNEL) && !defined(USE_SYSTEM)
static int dont_check_job_ended = 0;
@@ -1227,12 +1228,17 @@ deathtrap SIGDEFARG(sigarg)
SIGRETURN;
}
/*
* Invoked after receiving SIGCONT. We don't know what happened while
* sleeping, deal with part of that.
*/
static void
after_sigcont(void)
{
# ifdef FEAT_TITLE
// Set oldtitle to NULL, so the current title is obtained again.
VIM_CLEAR(oldtitle);
// Don't change "oldtitle" in a signal handler, set a flag to obtain it
// again later.
oldtitle_outdated = TRUE;
# endif
settmode(TMODE_RAW);
need_check_timestamps = TRUE;
@@ -1241,21 +1247,21 @@ after_sigcont(void)
#if defined(SIGCONT)
static RETSIGTYPE sigcont_handler SIGPROTOARG;
static int in_mch_suspend = FALSE;
static volatile sig_atomic_t in_mch_suspend = FALSE;
# if defined(_REENTRANT) && defined(SIGCONT)
/*
* On Solaris with multi-threading, suspending might not work immediately.
* Catch the SIGCONT signal, which will be used as an indication whether the
* suspending has been done or not.
* With multi-threading, suspending might not work immediately. Catch the
* SIGCONT signal, which will be used as an indication whether the suspending
* has been done or not.
*
* On Linux, signal is not always handled immediately either.
* See https://bugs.launchpad.net/bugs/291373
* Probably because the signal is handled in another thread.
*
* volatile because it is used in signal handler sigcont_handler().
*/
static volatile int sigcont_received;
# endif
static volatile sig_atomic_t sigcont_received;
static RETSIGTYPE sigcont_handler SIGPROTOARG;
/*
* signal handler for SIGCONT
@@ -1265,32 +1271,16 @@ sigcont_handler SIGDEFARG(sigarg)
{
if (in_mch_suspend)
{
# if defined(_REENTRANT) && defined(SIGCONT)
sigcont_received = TRUE;
# endif
}
else
{
// We didn't suspend ourselves, assume we were stopped by a SIGSTOP
// signal (which can't be intercepted) and get a SIGCONT. Need to get
// back to a sane mode and redraw.
// back to a sane mode. We should redraw, but we can't really do that
// in a signal handler, do a redraw later.
after_sigcont();
update_screen(CLEAR);
if (State & CMDLINE)
redrawcmdline();
else if (State == HITRETURN || State == SETWSIZE || State == ASKMORE
|| State == EXTERNCMD || State == CONFIRM || exmode_active)
repeat_message();
else if (redrawing())
setcursor();
#if defined(FEAT_INS_EXPAND)
if (pum_visible())
{
redraw_later(NOT_VALID);
ins_compl_show_pum();
}
#endif
redraw_later(CLEAR);
cursor_on_force();
out_flush();
}
@@ -1386,27 +1376,26 @@ mch_suspend(void)
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
loose_clipboard();
# endif
# if defined(_REENTRANT) && defined(SIGCONT)
# if defined(SIGCONT)
sigcont_received = FALSE;
# endif
kill(0, SIGTSTP); /* send ourselves a STOP signal */
# if defined(_REENTRANT) && defined(SIGCONT)
# if defined(SIGCONT)
/*
* Wait for the SIGCONT signal to be handled. It generally happens
* immediately, but somehow not all the time. Do not call pause()
* because there would be race condition which would hang Vim if
* signal happened in between the test of sigcont_received and the
* call to pause(). If signal is not yet received, call sleep(0)
* to just yield CPU. Signal should then be received. If somehow
* it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
* further if signal is not received after 1+2+3+4 ms (not expected
* to happen).
* immediately, but somehow not all the time, probably because it's handled
* in another thread. Do not call pause() because there would be race
* condition which would hang Vim if signal happened in between the test of
* sigcont_received and the call to pause(). If signal is not yet received,
* sleep 0, 1, 2, 3 ms. Don't bother waiting further if signal is not
* received after 1+2+3 ms (not expected to happen).
*/
{
long wait_time;
for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
/* Loop is not entered most of the time */
mch_delay(wait_time, FALSE);
}
# endif
@@ -1511,7 +1500,7 @@ catch_int_signal(void)
reset_signals(void)
{
catch_signals(SIG_DFL, SIG_DFL);
#if defined(_REENTRANT) && defined(SIGCONT)
#if defined(SIGCONT)
/* SIGCONT isn't in the list, because its default action is ignore */
signal(SIGCONT, SIG_DFL);
#endif
@@ -1574,7 +1563,7 @@ block_signals(sigset_t *set)
for (i = 0; signal_info[i].sig != -1; i++)
sigaddset(&newset, signal_info[i].sig);
# if defined(_REENTRANT) && defined(SIGCONT)
# if defined(SIGCONT)
/* SIGCONT isn't in the list, because its default action is ignore */
sigaddset(&newset, SIGCONT);
# endif
@@ -2282,6 +2271,11 @@ mch_settitle(char_u *title, char_u *icon)
*/
if ((type || *T_TS != NUL) && title != NULL)
{
if (oldtitle_outdated)
{
oldtitle_outdated = FALSE;
VIM_CLEAR(oldtitle);
}
if (oldtitle == NULL
#ifdef FEAT_GUI
&& !gui.in_use
+28 -2
View File
@@ -3108,6 +3108,9 @@ mch_dirname(
char_u *buf,
int len)
{
char_u abuf[_MAX_PATH + 1];
DWORD lfnlen;
/*
* Originally this was:
* return (getcwd(buf, len) != NULL ? OK : FAIL);
@@ -3121,7 +3124,21 @@ mch_dirname(
if (GetCurrentDirectoryW(_MAX_PATH, wbuf) != 0)
{
char_u *p = utf16_to_enc(wbuf, NULL);
WCHAR wcbuf[_MAX_PATH + 1];
char_u *p = NULL;
if (GetLongPathNameW(wbuf, wcbuf, _MAX_PATH) != 0)
{
p = utf16_to_enc(wcbuf, NULL);
if (STRLEN(p) >= (size_t)len)
{
// long path name is too long, fall back to short one
vim_free(p);
p = NULL;
}
}
if (p == NULL)
p = utf16_to_enc(wbuf, NULL);
if (p != NULL)
{
@@ -3133,7 +3150,16 @@ mch_dirname(
return FAIL;
}
#endif
return (GetCurrentDirectory(len, (LPSTR)buf) != 0 ? OK : FAIL);
if (GetCurrentDirectory(len, (LPSTR)buf) == 0)
return FAIL;
lfnlen = GetLongPathNameA((LPCSTR)buf, (LPSTR)abuf, _MAX_PATH);
if (lfnlen == 0 || lfnlen >= (DWORD)len)
// Failed to get long path name or it's too long: fall back to the
// short path name.
return OK;
STRCPY(buf, abuf);
return OK;
}
/*
+1
View File
@@ -89,6 +89,7 @@
#define FNAME_ILLEGAL "\"*?><|" /* illegal characters in a file name */
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
+2
View File
@@ -4,6 +4,7 @@ int do_cmdline_cmd(char_u *cmd);
int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int), void *cookie, int flags);
int getline_equal(char_u *(*fgetline)(int, void *, int), void *cookie, char_u *(*func)(int, void *, int));
void *getline_cookie(char_u *(*fgetline)(int, void *, int), void *cookie);
int parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only);
int parse_cmd_address(exarg_T *eap, char_u **errormsg);
int checkforcmd(char_u **pp, char *cmd, int len);
int modifier_len(char_u *cmd);
@@ -69,6 +70,7 @@ char_u *get_behave_arg(expand_T *xp, int idx);
char_u *get_messages_arg(expand_T *xp, int idx);
char_u *get_mapclear_arg(expand_T *xp, int idx);
void set_no_hlsearch(int flag);
int is_loclist_cmd(int cmdidx);
int get_pressedreturn(void);
void set_pressedreturn(int val);
/* vim: set ft=c : */
+1 -1
View File
@@ -25,7 +25,7 @@ int gui_mch_maximized(void);
void gui_mch_unmaximize(void);
void gui_mch_newfont(void);
void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction);
void gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height);
void gui_gtk_get_screen_geom_of_win(GtkWidget *wid, int *screen_x, int *screen_y, int *width, int *height);
void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h);
void gui_mch_settitle(char_u *title, char_u *icon);
void gui_mch_enable_menu(int showit);
+2 -1
View File
@@ -11,6 +11,8 @@ void ml_close_notmod(void);
void ml_timestamp(buf_T *buf);
void ml_recover(void);
int recover_names(char_u *fname, int list, int nr, char_u **fname_out);
char_u *make_percent_swname(char_u *dir, char_u *name);
void get_b0_dict(char_u *fname, dict_T *d);
void ml_sync_all(int check_file, int check_char);
void ml_preserve(buf_T *buf, int message);
char_u *ml_get(linenr_T lnum);
@@ -34,5 +36,4 @@ char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned siz
void ml_decrypt_data(memfile_T *mfp, char_u *data, off_T offset, unsigned size);
long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp);
void goto_byte(long cnt);
char_u *make_percent_swname (char_u *dir, char_u *name);
/* vim: set ft=c : */
+1
View File
@@ -94,4 +94,5 @@ void win_id2tabwin(typval_T *argvars, list_T *list);
win_T *win_id2wp(typval_T *argvars);
int win_id2win(typval_T *argvars);
void win_findbuf(typval_T *argvars, list_T *list);
void get_framelayout(frame_T *fr, list_T *l, int topframe);
/* vim: set ft=c : */
+83 -84
View File
@@ -159,6 +159,11 @@ static qf_info_T *ll_get_or_alloc_list(win_T *);
#define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
/* Location list window check helper macro */
#define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
// Quickfix and location list stack check helper macros
#define IS_QF_STACK(qi) (qi == &ql_info)
#define IS_LL_STACK(qi) (qi != &ql_info)
/*
* Return location list for window 'wp'
* For location list window, return the referenced location list
@@ -1940,7 +1945,7 @@ qf_add_entry(
qfp->qf_fnum = bufnum;
if (buf != NULL)
buf->b_has_qf_entry |=
(qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
IS_QF_STACK(qi) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
}
else
qfp->qf_fnum = qf_get_fnum(qi, qf_idx, dir, fname);
@@ -2224,7 +2229,7 @@ qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *directory, char_u *fname)
return 0;
buf->b_has_qf_entry =
(qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
IS_QF_STACK(qi) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
return buf->b_fnum;
}
@@ -2631,7 +2636,7 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80)
flags |= WSP_TOP;
if (qi != &ql_info)
if (IS_LL_STACK(qi))
flags |= WSP_NEWLOC; /* don't copy the location list */
if (win_split(0, flags) == FAIL)
@@ -2642,7 +2647,7 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (curwin->w_height < p_hh)
win_setheight((int)p_hh);
if (qi != &ql_info) /* not a quickfix list */
if (IS_LL_STACK(qi)) // not a quickfix list
{
/* The new window should use the supplied location list */
curwin->w_llist = qi;
@@ -2918,7 +2923,7 @@ qf_jump_edit_buffer(
retval = buflist_getfile(qf_ptr->qf_fnum,
(linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
if (qi != &ql_info)
if (IS_LL_STACK(qi))
{
/*
* Location list. Check whether the associated window is still
@@ -2939,7 +2944,7 @@ qf_jump_edit_buffer(
else if (old_qf_curlist != qi->qf_curlist
|| !is_qf_entry_present(qi, qf_ptr))
{
if (qi == &ql_info)
if (IS_QF_STACK(qi))
EMSG(_("E925: Current quickfix was changed"));
else
EMSG(_(e_loc_list_changed));
@@ -3010,6 +3015,7 @@ qf_jump_goto_line(
++screen_col;
}
}
curwin->w_set_curswant = TRUE;
check_cursor();
}
else
@@ -3330,7 +3336,7 @@ qf_list(exarg_T *eap)
recognised errors */
qf_info_T *qi = &ql_info;
if (eap->cmdidx == CMD_llist)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3478,7 +3484,7 @@ qf_age(exarg_T *eap)
qf_info_T *qi = &ql_info;
int count;
if (eap->cmdidx == CMD_lolder || eap->cmdidx == CMD_lnewer)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3526,7 +3532,7 @@ qf_history(exarg_T *eap)
qf_info_T *qi = &ql_info;
int i;
if (eap->cmdidx == CMD_lhistory)
if (is_loclist_cmd(eap->cmdidx))
qi = GET_LOC_LIST(curwin);
if (qi == NULL || (qi->qf_listcount == 0
&& qf_list_empty(qi, qi->qf_curlist)))
@@ -3745,7 +3751,7 @@ ex_cwindow(exarg_T *eap)
qf_info_T *qi = &ql_info;
win_T *win;
if (eap->cmdidx == CMD_lwindow)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3781,7 +3787,7 @@ ex_cclose(exarg_T *eap)
win_T *win = NULL;
qf_info_T *qi = &ql_info;
if (eap->cmdidx == CMD_lclose || eap->cmdidx == CMD_lwindow)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3808,7 +3814,7 @@ ex_copen(exarg_T *eap)
buf_T *qf_buf;
win_T *oldwin = curwin;
if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3953,12 +3959,12 @@ qf_win_goto(win_T *win, linenr_T lnum)
* :cbottom/:lbottom commands.
*/
void
ex_cbottom(exarg_T *eap UNUSED)
ex_cbottom(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
win_T *win;
if (eap->cmdidx == CMD_lbottom)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -4039,8 +4045,8 @@ is_qf_win(win_T *win, qf_info_T *qi)
* pointing to the location list.
*/
if (bt_quickfix(win->w_buffer))
if ((qi == &ql_info && win->w_llist_ref == NULL)
|| (qi != &ql_info && win->w_llist_ref == qi))
if ((IS_QF_STACK(qi) && win->w_llist_ref == NULL)
|| (IS_LL_STACK(qi) && win->w_llist_ref == qi))
return TRUE;
return FALSE;
@@ -4430,8 +4436,7 @@ ex_make(exarg_T *eap)
enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
#endif
if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
|| eap->cmdidx == CMD_lgrepadd)
if (is_loclist_cmd(eap->cmdidx))
wp = curwin;
autowrite_all();
@@ -4570,7 +4575,7 @@ qf_get_size(exarg_T *eap)
int i, sz = 0;
int prev_fnum = 0;
if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo)
if (is_loclist_cmd(eap->cmdidx))
{
/* Location list */
qi = GET_LOC_LIST(curwin);
@@ -4607,7 +4612,7 @@ qf_get_cur_idx(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo)
if (is_loclist_cmd(eap->cmdidx))
{
/* Location list */
qi = GET_LOC_LIST(curwin);
@@ -4631,7 +4636,7 @@ qf_get_cur_valid_idx(exarg_T *eap)
int i, eidx = 0;
int prev_fnum = 0;
if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo)
if (is_loclist_cmd(eap->cmdidx))
{
/* Location list */
qi = GET_LOC_LIST(curwin);
@@ -4724,12 +4729,7 @@ ex_cc(exarg_T *eap)
qf_info_T *qi = &ql_info;
int errornr;
if (eap->cmdidx == CMD_ll
|| eap->cmdidx == CMD_lrewind
|| eap->cmdidx == CMD_lfirst
|| eap->cmdidx == CMD_llast
|| eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_lfdo)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -4743,13 +4743,18 @@ ex_cc(exarg_T *eap)
errornr = (int)eap->line2;
else
{
if (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll)
errornr = 0;
else if (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind
|| eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst)
errornr = 1;
else
errornr = 32767;
switch (eap->cmdidx)
{
case CMD_cc: case CMD_ll:
errornr = 0;
break;
case CMD_crewind: case CMD_lrewind: case CMD_cfirst:
case CMD_lfirst:
errornr = 1;
break;
default:
errornr = 32767;
}
}
/* For cdo and ldo commands, jump to the nth valid error.
@@ -4774,15 +4779,9 @@ ex_cnext(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
int errornr;
int dir;
if (eap->cmdidx == CMD_lnext
|| eap->cmdidx == CMD_lNext
|| eap->cmdidx == CMD_lprevious
|| eap->cmdidx == CMD_lnfile
|| eap->cmdidx == CMD_lNfile
|| eap->cmdidx == CMD_lpfile
|| eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_lfdo)
if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -4799,17 +4798,28 @@ ex_cnext(exarg_T *eap)
else
errornr = 1;
qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext
|| eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo)
? FORWARD
: (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile
|| eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
? FORWARD_FILE
: (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile
|| eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile)
? BACKWARD_FILE
: BACKWARD,
errornr, eap->forceit);
// Depending on the command jump to either next or previous entry/file.
switch (eap->cmdidx)
{
case CMD_cnext: case CMD_lnext: case CMD_cdo: case CMD_ldo:
dir = FORWARD;
break;
case CMD_cprevious: case CMD_lprevious: case CMD_cNext:
case CMD_lNext:
dir = BACKWARD;
break;
case CMD_cnfile: case CMD_lnfile: case CMD_cfdo: case CMD_lfdo:
dir = FORWARD_FILE;
break;
case CMD_cpfile: case CMD_lpfile: case CMD_cNfile: case CMD_lNfile:
dir = BACKWARD_FILE;
break;
default:
dir = FORWARD;
break;
}
qf_jump(qi, dir, errornr, eap->forceit);
}
/*
@@ -4857,9 +4867,7 @@ ex_cfile(exarg_T *eap)
if (*eap->arg != NUL)
set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE, 0);
if (eap->cmdidx == CMD_lfile
|| eap->cmdidx == CMD_lgetfile
|| eap->cmdidx == CMD_laddfile)
if (is_loclist_cmd(eap->cmdidx))
wp = curwin;
/*
@@ -5178,10 +5186,7 @@ ex_vimgrep(exarg_T *eap)
#endif
}
if (eap->cmdidx == CMD_lgrep
|| eap->cmdidx == CMD_lvimgrep
|| eap->cmdidx == CMD_lgrepadd
|| eap->cmdidx == CMD_lvimgrepadd)
if (is_loclist_cmd(eap->cmdidx))
{
qi = ll_get_or_alloc_list(curwin);
if (qi == NULL)
@@ -5380,7 +5385,7 @@ ex_vimgrep(exarg_T *eap)
if (qf_restore_list(qi, save_qfid) == FAIL)
goto theend;
/* Jump to first match. */
// Jump to first match.
if (!qf_list_empty(qi, qi->qf_curlist))
{
if ((flags & VGR_NOJUMP) == 0)
@@ -6525,9 +6530,7 @@ ex_cbuffer(exarg_T *eap)
}
/* Must come after autocommands. */
if (eap->cmdidx == CMD_lbuffer
|| eap->cmdidx == CMD_lgetbuffer
|| eap->cmdidx == CMD_laddbuffer)
if (is_loclist_cmd(eap->cmdidx))
{
qi = ll_get_or_alloc_list(curwin);
if (qi == NULL)
@@ -6631,9 +6634,7 @@ ex_cexpr(exarg_T *eap)
#endif
}
if (eap->cmdidx == CMD_lexpr
|| eap->cmdidx == CMD_lgetexpr
|| eap->cmdidx == CMD_laddexpr)
if (is_loclist_cmd(eap->cmdidx))
{
qi = ll_get_or_alloc_list(curwin);
if (qi == NULL)
@@ -6843,16 +6844,13 @@ hgr_search_files_in_dir(
/*
* Search for a pattern in all the help files in the 'runtimepath'
* and add the matches to a quickfix list.
* 'arg' is the language specifier. If supplied, then only matches in the
* 'lang' is the language specifier. If supplied, then only matches in the
* specified language are found.
*/
static void
hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *arg)
hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *lang)
{
char_u *p;
#ifdef FEAT_MULTI_LANG
char_u *lang;
#endif
#ifdef FEAT_MBYTE
vimconv_T vc;
@@ -6864,10 +6862,6 @@ hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *arg)
convert_setup(&vc, (char_u *)"utf-8", p_enc);
#endif
#ifdef FEAT_MULTI_LANG
/* Check for a specified language */
lang = check_help_lang(arg);
#endif
/* Go through all the directories in 'runtimepath' */
p = p_rtp;
@@ -6902,6 +6896,7 @@ ex_helpgrep(exarg_T *eap)
qf_info_T *qi = &ql_info;
int new_qi = FALSE;
char_u *au_name = NULL;
char_u *lang = NULL;
switch (eap->cmdidx)
{
@@ -6918,25 +6913,29 @@ ex_helpgrep(exarg_T *eap)
#endif
}
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
// Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
p_cpo = empty_option;
if (eap->cmdidx == CMD_lhelpgrep)
if (is_loclist_cmd(eap->cmdidx))
{
qi = hgr_get_ll(&new_qi);
if (qi == NULL)
return;
}
#ifdef FEAT_MULTI_LANG
// Check for a specified language
lang = check_help_lang(eap->arg);
#endif
regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
regmatch.rm_ic = FALSE;
if (regmatch.regprog != NULL)
{
/* create a new quickfix list */
// create a new quickfix list
qf_new_list(qi, qf_cmdtitle(*eap->cmdlinep));
hgr_search_in_rtp(qi, &regmatch, eap->arg);
hgr_search_in_rtp(qi, &regmatch, lang);
vim_regfree(regmatch.regprog);
@@ -6949,7 +6948,7 @@ ex_helpgrep(exarg_T *eap)
if (p_cpo == empty_option)
p_cpo = save_cpo;
else
/* Darn, some plugin changed the value. */
// Darn, some plugin changed the value.
free_string_option(save_cpo);
qf_list_changed(qi, qi->qf_curlist);
@@ -6959,7 +6958,7 @@ ex_helpgrep(exarg_T *eap)
{
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf);
if (!new_qi && qi != &ql_info && qf_find_buf(qi) == NULL)
if (!new_qi && IS_LL_STACK(qi) && qf_find_buf(qi) == NULL)
/* autocommands made "qi" invalid */
return;
}
@@ -6972,8 +6971,8 @@ ex_helpgrep(exarg_T *eap)
if (eap->cmdidx == CMD_lhelpgrep)
{
/* If the help window is not opened or if it already points to the
* correct location list, then free the new location list. */
// If the help window is not opened or if it already points to the
// correct location list, then free the new location list.
if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi)
{
if (new_qi)
+4 -3
View File
@@ -4115,9 +4115,10 @@ again:
}
curwin->w_cursor = end_pos;
/* If we now have the same text as before reset "do_include" and try
* again. */
if (EQUAL_POS(start_pos, old_start) && EQUAL_POS(end_pos, old_end))
// If we are in Visual mode and now have the same text as before set
// "do_include" and try again.
if (VIsual_active && EQUAL_POS(start_pos, old_start)
&& EQUAL_POS(end_pos, old_end))
{
do_include = TRUE;
curwin->w_cursor = old_start;
+1 -1
View File
@@ -3850,7 +3850,7 @@ cursor_on_force(void)
}
/*
* Enable the cursor.
* Enable the cursor if it's currently off.
*/
void
cursor_on(void)
@@ -0,0 +1,9 @@
|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
|~+0#4040ff13&| @68
|~| @68
|~| @68
|~| @68
|~| @68
|:+0#0000000&|s|o|r|t| |n|i| |u| |/|o|n> @55
@@ -0,0 +1,9 @@
|f+0&#ffffff0|o@1| |3| @64
|f+1&&|o@1| +0&&|4| @64
|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
|f|o@1| |6| @64
|f|o@1| |7| @64
|f|o@1| |8| @64
|:|a|b|o|v|e| |b|e|l|o|w| |b|r|o|w|s|e| |b|o|t|r| |c|o|n|f|i|r|m| |k|e@1|p|m|a|r| |k|e@1|p|a|l|t| |k|e@1|p@1|a|t| |k|e@1|p|j|u|m| |f|i|l|t|e
|r| |x@2| |h|i|d|e| |l|o|c|k|m| |l|e|f|t|a|b|o|v|e| |n|o|a|u| |n|o|s|w|a|p| |r|i|g|h|t|b|e|l| |s|a|n|d|b|o|x| |s|i|l|e|n|t| |s|i|l|e|n|t|!
| |$|t|a|b| |t|o|p| |u|n|s|i|l| |v|e|r|t| |v|e|r|b|o|s|e| |4|,|5|s|/|f|o|.> @32
@@ -0,0 +1,9 @@
|f+0&#ffffff0|o@1| |4| @64
|f|o@1| |5| @64
|f|o@1| |6| @64
|f|o@1| |7| @64
|f|o@1| |8| @64
|f|o@1| |9| @64
|f|o@1| |1|0| @63
|b+9&&|a|r| +8&&|1@1| @63
|:+0&&|9|,|1@1|s|/|b|a|r> @59
@@ -0,0 +1,9 @@
|f+0&#ffffff0|o@1| |4| @64
|f|o@1| |5| @64
|f|o@1| |6| @64
|f|o@1| |7| @64
|f|o@1| |8| @64
|f+8&&|o@1| |9| @64
|f+0&&|o@1| |1|0| @63
|b|a|r| |1@1| @63
|:|9|,|1|0|s|/|b|a|r> @59
@@ -0,0 +1,9 @@
|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
|~+0#4040ff13&| @68
|~| @68
|~| @68
|~| @68
|~| @68
|:+0#0000000&|v|i|m|g|r|e|p| |o|n> @58
@@ -0,0 +1,9 @@
|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
|~+0#4040ff13&| @68
|~| @68
|~| @68
|~| @68
|~| @68
|:+0#0000000&|v|i|m|g| |/|o|n|/| |*|.|t|x|t> @53
@@ -0,0 +1,9 @@
|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
|~+0#4040ff13&| @68
|~| @68
|~| @68
|~| @68
|~| @68
|:+0#0000000&|v|i|m|g|r|e|p|a|d@1| |"|\|<|o|n> @52
@@ -0,0 +1,9 @@
|a+0&#ffffff0|n|o|t|h|e|r| |o|n|e| |2| @56
|t+1&&|h|a|t+0&&| |o|n|e| |3| @59
|t|h|e| |o|n|e| |1| @60
|~+0#4040ff13&| @68
|~| @68
|~| @68
|~| @68
|~| @68
|:+0#0000000&|l|v| |"|t|h|a> @61
@@ -0,0 +1,9 @@
|a+0&#ffffff0|n|o|t+1&&|h|e|r+0&&| |o|n|e| |2| @56
|t|h|a|t| |o|n|e| |3| @59
|t+0&#ffff4012|h|e| +0&#ffffff0|o|n|e| |1| @60
|~+0#4040ff13&| @68
|~| @68
|~| @68
|~| @68
|~| @68
|:+0#0000000&|l|v|i|m|g|r|e|p|a| |"|t|h|e|"| |*@1|/|*|.|t|x|t> @44
+1
View File
@@ -272,6 +272,7 @@ let s:flaky = [
\ 'Test_paused()',
\ 'Test_pipe_through_sort_all()',
\ 'Test_pipe_through_sort_some()',
\ 'Test_popup_and_window_resize()',
\ 'Test_quoteplus()',
\ 'Test_quotestar()',
\ 'Test_reltime()',
+11 -1
View File
@@ -682,6 +682,7 @@ endfunc
func Test_byte2line_line2byte()
new
set endofline
call setline(1, ['a', 'bc', 'd'])
set fileformat=unix
@@ -702,7 +703,16 @@ func Test_byte2line_line2byte()
call assert_equal([-1, -1, 1, 4, 8, 11, -1],
\ map(range(-1, 5), 'line2byte(v:val)'))
set fileformat&
bw!
set noendofline nofixendofline
normal a-
for ff in ["unix", "mac", "dos"]
let &fileformat = ff
call assert_equal(1, line2byte(1))
call assert_equal(2, line2byte(2)) " line2byte(line("$") + 1) is the buffer size plus one (as per :help line2byte).
endfor
set endofline& fixendofline& fileformat&
bw!
endfunc
+21
View File
@@ -414,3 +414,24 @@ func Test_shortmess_F()
set shortmess&
bwipe
endfunc
func Test_shortmess_F2()
e file1
e file2
call assert_match('file1', execute('bn', ''))
call assert_match('file2', execute('bn', ''))
set shortmess+=F
call assert_true(empty(execute('bn', '')))
call assert_true(empty(execute('bn', '')))
set hidden
call assert_true(empty(execute('bn', '')))
call assert_true(empty(execute('bn', '')))
set nohidden
call assert_true(empty(execute('bn', '')))
call assert_true(empty(execute('bn', '')))
set shortmess&
call assert_match('file1', execute('bn', ''))
call assert_match('file2', execute('bn', ''))
bwipe
bwipe
endfunc
+223 -2
View File
@@ -67,7 +67,7 @@ func Test_profile_func()
call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13])
call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14])
call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15])
call assert_match('^\s*100\s\+.*\sendwhile$', lines[16])
call assert_match('^\s*101\s\+.*\sendwhile$', lines[16])
call assert_equal('', lines[17])
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18])
call assert_equal('count total (s) self (s) function', lines[19])
@@ -84,6 +84,227 @@ func Test_profile_func()
call delete('Xprofile_func.log')
endfunc
func Test_profile_func_with_ifelse()
let lines = [
\ "func! Foo1()",
\ " if 1",
\ " let x = 0",
\ " elseif 1",
\ " let x = 1",
\ " else",
\ " let x = 2",
\ " endif",
\ "endfunc",
\ "func! Foo2()",
\ " if 0",
\ " let x = 0",
\ " elseif 1",
\ " let x = 1",
\ " else",
\ " let x = 2",
\ " endif",
\ "endfunc",
\ "func! Foo3()",
\ " if 0",
\ " let x = 0",
\ " elseif 0",
\ " let x = 1",
\ " else",
\ " let x = 2",
\ " endif",
\ "endfunc",
\ "call Foo1()",
\ "call Foo2()",
\ "call Foo3()",
\ ]
call writefile(lines, 'Xprofile_func.vim')
call system(v:progpath
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
\ . ' -c "profile start Xprofile_func.log"'
\ . ' -c "profile func Foo*"'
\ . ' -c "so Xprofile_func.vim"'
\ . ' -c "qall!"')
call assert_equal(0, v:shell_error)
let lines = readfile('Xprofile_func.log')
" - Foo1() should pass 'if' block.
" - Foo2() should pass 'elseif' block.
" - Foo3() should pass 'else' block.
call assert_equal(54, len(lines))
call assert_equal('FUNCTION Foo1()', lines[0])
call assert_equal('Called 1 time', lines[1])
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
call assert_equal('', lines[4])
call assert_equal('count total (s) self (s)', lines[5])
call assert_match('^\s*1\s\+.*\sif 1$', lines[6])
call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7])
call assert_match( '^\s\+elseif 1$', lines[8])
call assert_match( '^\s\+let x = 1$', lines[9])
call assert_match( '^\s\+else$', lines[10])
call assert_match( '^\s\+let x = 2$', lines[11])
call assert_match('^\s*1\s\+.*\sendif$', lines[12])
call assert_equal('', lines[13])
call assert_equal('FUNCTION Foo2()', lines[14])
call assert_equal('Called 1 time', lines[15])
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16])
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17])
call assert_equal('', lines[18])
call assert_equal('count total (s) self (s)', lines[19])
call assert_match('^\s*1\s\+.*\sif 0$', lines[20])
call assert_match( '^\s\+let x = 0$', lines[21])
call assert_match('^\s*1\s\+.*\selseif 1$', lines[22])
call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23])
call assert_match( '^\s\+else$', lines[24])
call assert_match( '^\s\+let x = 2$', lines[25])
call assert_match('^\s*1\s\+.*\sendif$', lines[26])
call assert_equal('', lines[27])
call assert_equal('FUNCTION Foo3()', lines[28])
call assert_equal('Called 1 time', lines[29])
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30])
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31])
call assert_equal('', lines[32])
call assert_equal('count total (s) self (s)', lines[33])
call assert_match('^\s*1\s\+.*\sif 0$', lines[34])
call assert_match( '^\s\+let x = 0$', lines[35])
call assert_match('^\s*1\s\+.*\selseif 0$', lines[36])
call assert_match( '^\s\+let x = 1$', lines[37])
call assert_match('^\s*1\s\+.*\selse$', lines[38])
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39])
call assert_match('^\s*1\s\+.*\sendif$', lines[40])
call assert_equal('', lines[41])
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42])
call assert_equal('count total (s) self (s) function', lines[43])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46])
call assert_equal('', lines[47])
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48])
call assert_equal('count total (s) self (s) function', lines[49])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52])
call assert_equal('', lines[53])
call delete('Xprofile_func.vim')
call delete('Xprofile_func.log')
endfunc
func Test_profile_func_with_trycatch()
let lines = [
\ "func! Foo1()",
\ " try",
\ " let x = 0",
\ " catch",
\ " let x = 1",
\ " finally",
\ " let x = 2",
\ " endtry",
\ "endfunc",
\ "func! Foo2()",
\ " try",
\ " throw 0",
\ " catch",
\ " let x = 1",
\ " finally",
\ " let x = 2",
\ " endtry",
\ "endfunc",
\ "func! Foo3()",
\ " try",
\ " throw 0",
\ " catch",
\ " throw 1",
\ " finally",
\ " let x = 2",
\ " endtry",
\ "endfunc",
\ "call Foo1()",
\ "call Foo2()",
\ "try",
\ " call Foo3()",
\ "catch",
\ "endtry",
\ ]
call writefile(lines, 'Xprofile_func.vim')
call system(v:progpath
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
\ . ' -c "profile start Xprofile_func.log"'
\ . ' -c "profile func Foo*"'
\ . ' -c "so Xprofile_func.vim"'
\ . ' -c "qall!"')
call assert_equal(0, v:shell_error)
let lines = readfile('Xprofile_func.log')
" - Foo1() should pass 'try' 'finally' blocks.
" - Foo2() should pass 'catch' 'finally' blocks.
" - Foo3() should not pass 'endtry'.
call assert_equal(54, len(lines))
call assert_equal('FUNCTION Foo1()', lines[0])
call assert_equal('Called 1 time', lines[1])
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
call assert_equal('', lines[4])
call assert_equal('count total (s) self (s)', lines[5])
call assert_match('^\s*1\s\+.*\stry$', lines[6])
call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7])
call assert_match( '^\s\+catch$', lines[8])
call assert_match( '^\s\+let x = 1$', lines[9])
call assert_match('^\s*1\s\+.*\sfinally$', lines[10])
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[11])
call assert_match('^\s*1\s\+.*\sendtry$', lines[12])
call assert_equal('', lines[13])
call assert_equal('FUNCTION Foo2()', lines[14])
call assert_equal('Called 1 time', lines[15])
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16])
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17])
call assert_equal('', lines[18])
call assert_equal('count total (s) self (s)', lines[19])
call assert_match('^\s*1\s\+.*\stry$', lines[20])
call assert_match('^\s*1\s\+.*\s throw 0$', lines[21])
call assert_match('^\s*1\s\+.*\scatch$', lines[22])
call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23])
call assert_match('^\s*1\s\+.*\sfinally$', lines[24])
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[25])
call assert_match('^\s*1\s\+.*\sendtry$', lines[26])
call assert_equal('', lines[27])
call assert_equal('FUNCTION Foo3()', lines[28])
call assert_equal('Called 1 time', lines[29])
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30])
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31])
call assert_equal('', lines[32])
call assert_equal('count total (s) self (s)', lines[33])
call assert_match('^\s*1\s\+.*\stry$', lines[34])
call assert_match('^\s*1\s\+.*\s throw 0$', lines[35])
call assert_match('^\s*1\s\+.*\scatch$', lines[36])
call assert_match('^\s*1\s\+.*\s throw 1$', lines[37])
call assert_match('^\s*1\s\+.*\sfinally$', lines[38])
call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39])
call assert_match( '^\s\+endtry$', lines[40])
call assert_equal('', lines[41])
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42])
call assert_equal('count total (s) self (s) function', lines[43])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46])
call assert_equal('', lines[47])
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48])
call assert_equal('count total (s) self (s) function', lines[49])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51])
call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52])
call assert_equal('', lines[53])
call delete('Xprofile_func.vim')
call delete('Xprofile_func.log')
endfunc
func Test_profile_file()
let lines = [
\ 'func! Foo()',
@@ -123,7 +344,7 @@ func Test_profile_file()
call assert_equal(' " a comment', lines[9])
" if self and total are equal we only get one number
call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10])
call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$', lines[11])
call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$', lines[11])
" if self and total are equal we only get one number
call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
call assert_equal('', lines[13])
+23
View File
@@ -3091,6 +3091,20 @@ func Test_qf_tick()
call Xqftick_tests('l')
endfunc
" Test helpgrep with lang specifier
func Xtest_helpgrep_with_lang_specifier(cchar)
call s:setup_commands(a:cchar)
Xhelpgrep Vim@en
call assert_equal('help', &filetype)
call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
new | only
endfunc
func Test_helpgrep_with_lang_specifier()
call Xtest_helpgrep_with_lang_specifier('c')
call Xtest_helpgrep_with_lang_specifier('l')
endfunc
" The following test used to crash Vim.
" Open the location list window and close the regular window associated with
" the location list. When the garbage collection runs now, it incorrectly
@@ -3546,3 +3560,12 @@ func Test_view_result_split()
call Xview_result_split_tests('c')
call Xview_result_split_tests('l')
endfunc
" Test that :cc sets curswant
func Test_curswant()
helpgrep quickfix
normal! llll
1cc
call assert_equal(getcurpos()[4], virtcol('.'))
cclose | helpclose
endfunc
+103
View File
@@ -384,6 +384,14 @@ func Test_search_cmdline3s()
undo
call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
call assert_equal(' 2 xxxe', getline('.'))
undo
call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
call assert_equal(' 2 xxx', getline('.'))
undo
call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486')
"
call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
call assert_equal(' 2 xxx', getline('.'))
call Incsearch_cleanup()
endfunc
@@ -839,6 +847,7 @@ func Test_incsearch_substitute_dump()
\ 'for n in range(1, 10)',
\ ' call setline(n, "foo " . n)',
\ 'endfor',
\ 'call setline(11, "bar 11")',
\ '3',
\ ], 'Xis_subst_script')
let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
@@ -884,10 +893,104 @@ func Test_incsearch_substitute_dump()
call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
call term_sendkeys(buf, "\<Esc>")
" Command modifiers are skipped
call term_sendkeys(buf, ':above below browse botr confirm keepmar keepalt keeppat keepjum filter xxx hide lockm leftabove noau noswap rightbel sandbox silent silent! $tab top unsil vert verbose 4,5s/fo.')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
call term_sendkeys(buf, "\<Esc>")
" Cursorline highlighting at match
call term_sendkeys(buf, ":set cursorline\<CR>")
call term_sendkeys(buf, 'G9G')
call term_sendkeys(buf, ':9,11s/bar')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
call term_sendkeys(buf, "\<Esc>")
" Cursorline highlighting at cursor when no match
call term_sendkeys(buf, ':9,10s/bar')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('Xis_subst_script')
endfunc
" Similar to Test_incsearch_substitute_dump() for :sort
func Test_incsearch_ssort_dump()
if !exists('+incsearch')
return
endif
if !CanRunVimInTerminal()
return
endif
call writefile([
\ 'set incsearch hlsearch scrolloff=0',
\ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
\ ], 'Xis_sort_script')
let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
" Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
" the 'ambiwidth' check.
sleep 100m
" Need to send one key at a time to force a redraw.
call term_sendkeys(buf, ':sort ni u /on')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('Xis_sort_script')
endfunc
" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
func Test_incsearch_vimgrep_dump()
if !exists('+incsearch')
return
endif
if !CanRunVimInTerminal()
return
endif
call writefile([
\ 'set incsearch hlsearch scrolloff=0',
\ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
\ ], 'Xis_vimgrep_script')
let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
" Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
" the 'ambiwidth' check.
sleep 100m
" Need to send one key at a time to force a redraw.
call term_sendkeys(buf, ':vimgrep on')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
call term_sendkeys(buf, "\<Esc>")
call term_sendkeys(buf, ':vimg /on/ *.txt')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
call term_sendkeys(buf, "\<Esc>")
call term_sendkeys(buf, ':vimgrepadd "\<on')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
call term_sendkeys(buf, "\<Esc>")
call term_sendkeys(buf, ':lv "tha')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
call term_sendkeys(buf, "\<Esc>")
call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
sleep 100m
call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('Xis_vimgrep_script')
endfunc
func Test_search_undefined_behaviour()
if !has("terminal")
return
+35
View File
@@ -97,3 +97,38 @@ func Test_missing_dir()
set directory&
call delete('Xswapdir', 'rf')
endfunc
func Test_swapinfo()
new Xswapinfo
call setline(1, ['one', 'two', 'three'])
w
let fname = trim(execute('swapname'))
call assert_match('Xswapinfo', fname)
let info = swapinfo(fname)
call assert_match('8\.', info.version)
call assert_match('\w', info.user)
call assert_equal(hostname(), info.host)
call assert_match('Xswapinfo', info.fname)
call assert_match(0, info.dirty)
call assert_equal(getpid(), info.pid)
call assert_match('^\d*$', info.mtime)
if has_key(info, 'inode')
call assert_match('\d', info.inode)
endif
bwipe!
call delete(fname)
call delete('Xswapinfo')
let info = swapinfo('doesnotexist')
call assert_equal('Cannot open file', info.error)
call writefile(['burp'], 'Xnotaswapfile')
let info = swapinfo('Xnotaswapfile')
call assert_equal('Cannot read file', info.error)
call delete('Xnotaswapfile')
call writefile([repeat('x', 10000)], 'Xnotaswapfile')
let info = swapinfo('Xnotaswapfile')
call assert_equal('Not a swap file', info.error)
call delete('Xnotaswapfile')
endfunc
+17
View File
@@ -121,6 +121,23 @@ func Test_string_html_objects()
enew!
endfunc
func Test_empty_html_tag()
new
call setline(1, '<div></div>')
normal 0citxxx
call assert_equal('<div>xxx</div>', getline(1))
call setline(1, '<div></div>')
normal 0f<cityyy
call assert_equal('<div>yyy</div>', getline(1))
call setline(1, '<div></div>')
normal 0f<vitsaaa
call assert_equal('aaa', getline(1))
bwipe!
endfunc
" Tests for match() and matchstr()
func Test_match()
call assert_equal("b", matchstr("abcd", ".", 0, 2))
+20
View File
@@ -101,3 +101,23 @@ func Test_win_getid_curtab()
call assert_equal(win_getid(1), win_getid(1, 1))
tabclose!
endfunc
func Test_winlayout()
let w1 = win_getid()
call assert_equal(['leaf', w1], winlayout())
split
let w2 = win_getid()
call assert_equal(['col', [['leaf', w2], ['leaf', w1]]], winlayout())
split
let w3 = win_getid()
call assert_equal(['col', [['leaf', w3], ['leaf', w2], ['leaf', w1]]], winlayout())
2wincmd w
vsplit
let w4 = win_getid()
call assert_equal(['col', [['leaf', w3], ['row', [['leaf', w4], ['leaf', w2]]], ['leaf', w1]]], winlayout())
only!
endfunc
+7 -2
View File
@@ -3124,8 +3124,13 @@ u_add_time(char_u *buf, size_t buflen, time_t tt)
}
else
#endif
vim_snprintf((char *)buf, buflen, _("%ld seconds ago"),
(long)(vim_time() - tt));
{
long seconds = (long)(vim_time() - tt);
vim_snprintf((char *)buf, buflen,
NGETTEXT("%ld second ago", "%ld seconds ago", seconds),
seconds);
}
}
/*
+70
View File
@@ -809,6 +809,76 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
315,
/**/
314,
/**/
313,
/**/
312,
/**/
311,
/**/
310,
/**/
309,
/**/
308,
/**/
307,
/**/
306,
/**/
305,
/**/
304,
/**/
303,
/**/
302,
/**/
301,
/**/
300,
/**/
299,
/**/
298,
/**/
297,
/**/
296,
/**/
295,
/**/
294,
/**/
293,
/**/
292,
/**/
291,
/**/
290,
/**/
289,
/**/
288,
/**/
287,
/**/
286,
/**/
285,
/**/
284,
/**/
283,
/**/
282,
/**/
281,
/**/
280,
/**/
+4
View File
@@ -554,6 +554,10 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
/*
* The _() stuff is for using gettext(). It is a no-op when libintl.h is not
* found or the +multilang feature is disabled.
* Use NGETTEXT(single, multi, number) to get plural behavior:
* - single - message for singular form
* - multi - message for plural form
* - number - the count
*/
#ifdef FEAT_GETTEXT
# ifdef DYNAMIC_GETTEXT
+49
View File
@@ -7249,4 +7249,53 @@ win_findbuf(typval_T *argvars, list_T *list)
list_append_number(list, wp->w_id);
}
/*
* Get the layout of the given tab page for winlayout().
*/
void
get_framelayout(frame_T *fr, list_T *l, int outer)
{
frame_T *child;
list_T *fr_list;
list_T *win_list;
if (fr == NULL)
return;
if (outer)
// outermost call from f_winlayout()
fr_list = l;
else
{
fr_list = list_alloc();
if (fr_list == NULL)
return;
list_append_list(l, fr_list);
}
if (fr->fr_layout == FR_LEAF)
{
if (fr->fr_win != NULL)
{
list_append_string(fr_list, (char_u *)"leaf", -1);
list_append_number(fr_list, fr->fr_win->w_id);
}
}
else
{
list_append_string(fr_list,
fr->fr_layout == FR_ROW ? (char_u *)"row" : (char_u *)"col", -1);
win_list = list_alloc();
if (win_list == NULL)
return;
list_append_list(fr_list, win_list);
child = fr->fr_child;
while (child != NULL)
{
get_framelayout(child, win_list, FALSE);
child = child->fr_next;
}
}
}
#endif