mirror of
https://github.com/zoriya/vim.git
synced 2025-12-06 23:36:16 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de04654ddc | ||
|
|
9e3dfc6501 | ||
|
|
2095148277 | ||
|
|
df980db69b | ||
|
|
a47ebdbd22 | ||
|
|
fabaf753e2 | ||
|
|
45a0000d5c | ||
|
|
e6640ad44e | ||
|
|
3c09722600 | ||
|
|
b73fa629d6 | ||
|
|
ae6f865125 | ||
|
|
1bd999f982 | ||
|
|
8ada6aa929 | ||
|
|
4ce46c2a6b | ||
|
|
14a4deb064 | ||
|
|
aaf6e43b7a | ||
|
|
1223744849 | ||
|
|
2efb323e87 | ||
|
|
338e47fdfd | ||
|
|
132f75255e | ||
|
|
a0ca7d002d | ||
|
|
4af031dbc8 | ||
|
|
b254af312d | ||
|
|
c9e649ae81 | ||
|
|
606d45ccd8 | ||
|
|
4fb921e388 | ||
|
|
9bca805ec4 |
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Dec 16
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Dec 19
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -3338,8 +3338,8 @@ count({comp}, {expr} [, {ic} [, {start}]]) *count()*
|
||||
When {ic} is given and it's |TRUE| then case is ignored.
|
||||
|
||||
When {comp} is a string then the number of not overlapping
|
||||
occurrences of {expr} is returned.
|
||||
|
||||
occurrences of {expr} is returned. Zero is returned when
|
||||
{expr} is an empty string.
|
||||
|
||||
*cscope_connection()*
|
||||
cscope_connection([{num} , {dbpath} [, {prepend}]])
|
||||
@@ -4674,6 +4674,8 @@ getqflist([{what}]) *getqflist()*
|
||||
If the optional {what} dictionary argument is supplied, then
|
||||
returns only the items listed in {what} as a dictionary. The
|
||||
following string items are supported in {what}:
|
||||
changedtick get the total number of changes made
|
||||
to the list
|
||||
context get the context stored with |setqflist()|
|
||||
efm errorformat to use when parsing "lines". If
|
||||
not present, then the 'errorformat' option
|
||||
@@ -4707,6 +4709,8 @@ getqflist([{what}]) *getqflist()*
|
||||
"items" with the list of entries.
|
||||
|
||||
The returned dictionary contains the following entries:
|
||||
changedtick total number of changes made to the
|
||||
list |quickfix-changedtick|
|
||||
context context information stored with |setqflist()|.
|
||||
If not present, set to "".
|
||||
id quickfix list ID |quickfix-ID|. If not
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*options.txt* For Vim version 8.0. Last change: 2017 Dec 01
|
||||
*options.txt* For Vim version 8.0. Last change: 2017 Dec 21
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -5749,11 +5749,11 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
copy of the original file will be kept. The name of the copy is the
|
||||
name of the original file with the string in the 'patchmode' option
|
||||
appended. This option should start with a dot. Use a string like
|
||||
".org". 'backupdir' must not be empty for this to work (Detail: The
|
||||
backup file is renamed to the patchmode file after the new file has
|
||||
been successfully written, that's why it must be possible to write a
|
||||
backup file). If there was no file to be backed up, an empty file is
|
||||
created.
|
||||
".orig" or ".org". 'backupdir' must not be empty for this to work
|
||||
(Detail: The backup file is renamed to the patchmode file after the
|
||||
new file has been successfully written, that's why it must be possible
|
||||
to write a backup file). If there was no file to be backed up, an
|
||||
empty file is created.
|
||||
When the 'backupskip' pattern matches, a patchmode file is not made.
|
||||
Using 'patchmode' for compressed files appends the extension at the
|
||||
end (e.g., "file.gz.orig"), thus the resulting name isn't always
|
||||
|
||||
@@ -64,6 +64,14 @@ When a window with a location list is split, the new window gets a copy of the
|
||||
location list. When there are no longer any references to a location list,
|
||||
the location list is destroyed.
|
||||
|
||||
*quickfix-changedtick*
|
||||
Every quickfix and location list has a read-only changedtick variable that
|
||||
tracks the total number of changes made to the list. Every time the quickfix
|
||||
list is modified, this count is incremented. This can be used to perform an
|
||||
action only when the list has changed. The getqflist() and getloclist()
|
||||
functions can be used to query the current value of changedtick. You cannot
|
||||
change the changedtick variable.
|
||||
|
||||
The following quickfix commands can be used. The location list commands are
|
||||
similar to the quickfix commands, replacing the 'c' prefix in the quickfix
|
||||
command with 'l'.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*syntax.txt* For Vim version 8.0. Last change: 2017 Sep 30
|
||||
*syntax.txt* For Vim version 8.0. Last change: 2017 Dec 22
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -5031,6 +5031,8 @@ TabLine tab pages line, not active tab page label
|
||||
TabLineFill tab pages line, where there are no labels
|
||||
*hl-TabLineSel*
|
||||
TabLineSel tab pages line, active tab page label
|
||||
*hl-Terminal*
|
||||
Terminal |terminal| window (see |terminal-size-color|)
|
||||
*hl-Title*
|
||||
Title titles for output from ":set all", ":autocmd" etc.
|
||||
*hl-Visual*
|
||||
|
||||
@@ -6828,6 +6828,7 @@ hl-StatusLineNC syntax.txt /*hl-StatusLineNC*
|
||||
hl-TabLine syntax.txt /*hl-TabLine*
|
||||
hl-TabLineFill syntax.txt /*hl-TabLineFill*
|
||||
hl-TabLineSel syntax.txt /*hl-TabLineSel*
|
||||
hl-Terminal syntax.txt /*hl-Terminal*
|
||||
hl-Title syntax.txt /*hl-Title*
|
||||
hl-Tooltip syntax.txt /*hl-Tooltip*
|
||||
hl-User1 syntax.txt /*hl-User1*
|
||||
@@ -8064,6 +8065,7 @@ quake.vim syntax.txt /*quake.vim*
|
||||
quickfix quickfix.txt /*quickfix*
|
||||
quickfix-6 version6.txt /*quickfix-6*
|
||||
quickfix-ID quickfix.txt /*quickfix-ID*
|
||||
quickfix-changedtick quickfix.txt /*quickfix-changedtick*
|
||||
quickfix-context quickfix.txt /*quickfix-context*
|
||||
quickfix-directory-stack quickfix.txt /*quickfix-directory-stack*
|
||||
quickfix-error-lists quickfix.txt /*quickfix-error-lists*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*terminal.txt* For Vim version 8.0. Last change: 2017 Dec 17
|
||||
*terminal.txt* For Vim version 8.0. Last change: 2017 Dec 22
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -122,7 +122,8 @@ and background colors are taken from Vim, the Normal highlight group.
|
||||
For a color terminal the 'background' option is used to decide whether the
|
||||
terminal window will start with a white or black background.
|
||||
|
||||
To use a different color the Terminal highlight group can be used: >
|
||||
To use a different color the Terminal highlight group can be used, for
|
||||
example: >
|
||||
hi Terminal ctermbg=lightgrey ctermfg=blue guibg=lightgrey guifg=blue
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.0. Last change: 2017 Dec 17
|
||||
*todo.txt* For Vim version 8.0. Last change: 2017 Dec 23
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -142,11 +142,19 @@ Suggested by Hiroki Kokubun:
|
||||
Include solarized color scheme?, it does not support termguicolors.
|
||||
- Sanitized version of pablo (Lifepillar, 2017 Nov 21)
|
||||
|
||||
heap use after free. (gy741, #2447)
|
||||
heap use after free in set_bufref (gy741, #2448)
|
||||
reproduces with valgrind (Dominique)
|
||||
heap use after free in getout. (gy741, #2449)
|
||||
reproduces with valgrind (Dominique)
|
||||
Reproducible:
|
||||
invalid memory access in regexp with zero-width.
|
||||
reproduced by Dominique, 2017 Dec 23
|
||||
heap-use-after-free in win_equal_rec (#2467)
|
||||
au* 0 vs¡
|
||||
ar0
|
||||
arga
|
||||
al
|
||||
al
|
||||
|
||||
Errors found with random data:
|
||||
heap-buffer-overflow in alist_add (#2472)
|
||||
heap-buffer-overflow in del_bytes (#2466)
|
||||
|
||||
Compiler warnings (geeknik, 2017 Oct 26):
|
||||
- signed integer overflow in do_sub() (#2249)
|
||||
@@ -155,20 +163,13 @@ Compiler warnings (geeknik, 2017 Oct 26):
|
||||
- signed integer overflow in nfa_regatom() (#2251)
|
||||
- undefined left shift in get_string_tv() (#2250)
|
||||
|
||||
Triggering CursorHoldI happens too often in the GUI. (#2451).
|
||||
Should move code from os_unix.c mch_inchar() up into common use, it's not
|
||||
really machine specific. Also the part of WaitForChar(), it deals with timers
|
||||
and is also for all machines.
|
||||
|
||||
When starting with --clean packages under "start" are not loaded. Make this
|
||||
work: :packadd START {name} similar to :runtime START name
|
||||
balloon_show() does not work properly in the terminal. (Ben Jackson, 2017 Dec
|
||||
20, #2481)
|
||||
Also see #2352, want better control over balloon, perhaps set the position.
|
||||
|
||||
When using :packadd files under "later" are not used, which is inconsistent
|
||||
with packages under "start". (xtal8, #1994)
|
||||
|
||||
Patch to add changedtick var to quickfix list. (Yegappan Lakshmanan, 2017 Nov
|
||||
18, #2391)
|
||||
|
||||
7 Add a watchpoint in the debug mode: An expression that breaks execution
|
||||
when evaluating to non-zero. Add the "watchadd expr" command, stop when
|
||||
the value of the expression changes. ":watchdel" deletes an item,
|
||||
@@ -212,6 +213,9 @@ Error in emsg with buggy script. (Dominique, 2017 Apr 30)
|
||||
Patch to avoid clearing the intro message on Win32 console.
|
||||
(Ken Takata, 2017 Nov 14)
|
||||
|
||||
Patch to fix encoding in print document name (Yasuhiro Matsumoto, 2017 Dec 20,
|
||||
#2478)
|
||||
|
||||
Patch to copy buffer-local options before buffer leaves the window. (Bjorn
|
||||
Linse, 2017 Nov 14, #2336)
|
||||
|
||||
@@ -233,6 +237,9 @@ Ask whether to use Windows or Vim key behavior?
|
||||
Patch for improving detecting Ruby on Mac in configure. (Ilya Mikhaltsou, 2017
|
||||
Nov 21)
|
||||
|
||||
Add a ModeChanged autocommand that has an argument indicating the old and new
|
||||
mode. Also used for switching Terminal mode.
|
||||
|
||||
When using command line window, CmdlineLeave is triggered without
|
||||
CmdlineEnter. (xtal8, 2017 Oct 30, #2263)
|
||||
Add some way to get the nested state. Although CmdwinEnter is obviously
|
||||
@@ -271,6 +278,7 @@ The ":move" command does not honor closed folds. (Ryan Lue, #2351)
|
||||
Memory leaks in test_channel? (or is it because of fork())
|
||||
Memory leak in test_arabic.
|
||||
Using uninitialized value in test_crypt.
|
||||
Memory leaks in test_escaped_glob
|
||||
|
||||
Patch to clear background when "guibg=NONE" is used and 'termguicolors' is
|
||||
set.
|
||||
@@ -1052,8 +1060,6 @@ Patch to open folds for 'incsearch'. (Christian Brabandt, 2015 Jan 6)
|
||||
Patch for building a 32bit Vim with 64bit MingW compiler.
|
||||
(Michael Soyka, 2014 Oct 15)
|
||||
|
||||
Delete old code in os_msdos.c, mch_FullName().
|
||||
|
||||
Patch: On MS-Windows shellescape() may have to triple double quotes.
|
||||
(Ingo Karkat, 2015 Jan 16)
|
||||
|
||||
|
||||
16
runtime/ftplugin/cmake.vim
Normal file
16
runtime/ftplugin/cmake.vim
Normal file
@@ -0,0 +1,16 @@
|
||||
" Vim filetype plugin
|
||||
" Language: CMake
|
||||
" Maintainer: Keith Smiley <keithbsmiley@gmail.com>
|
||||
" Last Change: 2017 Dec 24
|
||||
|
||||
" Only do this when not done yet for this buffer
|
||||
if exists("b:did_ftplugin")
|
||||
finish
|
||||
endif
|
||||
|
||||
" Don't load another plugin for this buffer
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
let b:undo_ftplugin = "setl commentstring<"
|
||||
|
||||
setlocal commentstring=#\ %s
|
||||
@@ -2,7 +2,7 @@
|
||||
" Language: MIX (Donald Knuth's assembly language used in TAOCP)
|
||||
" Maintainer: Wu Yongwei <wuyongwei@gmail.com>
|
||||
" Filenames: *.mixal *.mix
|
||||
" Last Change: 2013 Nov 13
|
||||
" Last Change: 2017-11-26 15:21:36 +0800
|
||||
|
||||
" Quit when a syntax file was already loaded
|
||||
if exists("b:current_syntax")
|
||||
@@ -16,7 +16,7 @@ syn case ignore
|
||||
|
||||
" Special processing of ALF directive: implementations vary whether quotation
|
||||
" marks are needed
|
||||
syn match mixAlfParam #\s\{1,2\}"\?[^"]\{,5\}"\?# contains=mixAlfDirective,mixString nextgroup=mixEndComment contained
|
||||
syn match mixAlfParam #\s\{1,2\}"\?[^"]\{,5\}"\?# contains=mixString nextgroup=mixEndComment contained
|
||||
|
||||
" Region for parameters
|
||||
syn match mixParam #[-+*/:=0-9a-z,()"]\+# contains=mixIdentifier,mixSpecial,mixNumber,mixString,mixLabel nextgroup=mixEndComment contained
|
||||
@@ -46,6 +46,7 @@ syn keyword mixDirective ALF nextgroup=mixAlfParam contained
|
||||
" Opcodes
|
||||
syn keyword mixOpcode NOP HLT NUM CHAR FLOT FIX nextgroup=mixEndComment contained
|
||||
syn keyword mixOpcode FADD FSUB FMUL FDIV FCMP MOVE ADD SUB MUL DIV IOC IN OUT JRED JBUS JMP JSJ JOV JNOV JL JE JG JLE JNE JGE SLA SRA SLAX SRAX SLC SRC nextgroup=mixParam contained skipwhite
|
||||
syn keyword mixOpcode SLB SRB JAE JAO JXE JXO nextgroup=mixParam contained skipwhite
|
||||
|
||||
syn match mixOpcode "LD[AX1-6]N\?\>" nextgroup=mixParam contained skipwhite
|
||||
syn match mixOpcode "ST[AX1-6JZ]\>" nextgroup=mixParam contained skipwhite
|
||||
@@ -58,7 +59,7 @@ syn match mixOpcode "J[AX1-6]N\?[NZP]\>" nextgroup=mixParam contained skipwhite
|
||||
" Switch back to being case sensitive
|
||||
syn case match
|
||||
|
||||
" Registers (only to used in comments now)
|
||||
" Registers (only to be used in comments now)
|
||||
syn keyword mixRegister rA rX rI1 rI2 rI3 rI4 rI5 rI6 rJ contained
|
||||
|
||||
" The default highlighting
|
||||
|
||||
@@ -2147,6 +2147,7 @@ test_arglist \
|
||||
test_edit \
|
||||
test_erasebackword \
|
||||
test_escaped_glob \
|
||||
test_eval_stuff \
|
||||
test_ex_undo \
|
||||
test_ex_z \
|
||||
test_exec_while_if \
|
||||
|
||||
23
src/buffer.c
23
src/buffer.c
@@ -1665,7 +1665,8 @@ set_curbuf(buf_T *buf, int action)
|
||||
#ifdef FEAT_SYN_HL
|
||||
long old_tw = curbuf->b_p_tw;
|
||||
#endif
|
||||
bufref_T bufref;
|
||||
bufref_T newbufref;
|
||||
bufref_T prevbufref;
|
||||
|
||||
setpcmark();
|
||||
if (!cmdmod.keepalt)
|
||||
@@ -1675,18 +1676,22 @@ set_curbuf(buf_T *buf, int action)
|
||||
/* Don't restart Select mode after switching to another buffer. */
|
||||
VIsual_reselect = FALSE;
|
||||
|
||||
/* close_windows() or apply_autocmds() may change curbuf */
|
||||
/* close_windows() or apply_autocmds() may change curbuf and wipe out "buf"
|
||||
*/
|
||||
prevbuf = curbuf;
|
||||
set_bufref(&bufref, prevbuf);
|
||||
set_bufref(&prevbufref, prevbuf);
|
||||
set_bufref(&newbufref, buf);
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Autocommands may delete the curren buffer and/or the buffer we wan to go
|
||||
* to. In those cases don't close the buffer. */
|
||||
if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf)
|
||||
|| (bufref_valid(&prevbufref)
|
||||
&& bufref_valid(&newbufref)
|
||||
# ifdef FEAT_EVAL
|
||||
|| (bufref_valid(&bufref) && !aborting())
|
||||
# else
|
||||
|| bufref_valid(&bufref)
|
||||
&& !aborting()
|
||||
# endif
|
||||
)
|
||||
))
|
||||
#endif
|
||||
{
|
||||
#ifdef FEAT_SYN_HL
|
||||
@@ -1696,9 +1701,9 @@ set_curbuf(buf_T *buf, int action)
|
||||
if (unload)
|
||||
close_windows(prevbuf, FALSE);
|
||||
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
|
||||
if (bufref_valid(&bufref) && !aborting())
|
||||
if (bufref_valid(&prevbufref) && !aborting())
|
||||
#else
|
||||
if (bufref_valid(&bufref))
|
||||
if (bufref_valid(&prevbufref))
|
||||
#endif
|
||||
{
|
||||
win_T *previouswin = curwin;
|
||||
|
||||
@@ -2382,7 +2382,7 @@ f_count(typval_T *argvars, typval_T *rettv)
|
||||
char_u *p = argvars[0].vval.v_string;
|
||||
char_u *next;
|
||||
|
||||
if (!error && expr != NULL && p != NULL)
|
||||
if (!error && expr != NULL && *expr != NUL && p != NULL)
|
||||
{
|
||||
if (ic)
|
||||
{
|
||||
@@ -2886,6 +2886,7 @@ f_execute(typval_T *argvars, typval_T *rettv)
|
||||
int save_emsg_silent = emsg_silent;
|
||||
int save_emsg_noredir = emsg_noredir;
|
||||
int save_redir_execute = redir_execute;
|
||||
int save_redir_off = redir_off;
|
||||
garray_T save_ga;
|
||||
|
||||
rettv->vval.v_string = NULL;
|
||||
@@ -2928,6 +2929,7 @@ f_execute(typval_T *argvars, typval_T *rettv)
|
||||
save_ga = redir_execute_ga;
|
||||
ga_init2(&redir_execute_ga, (int)sizeof(char), 500);
|
||||
redir_execute = TRUE;
|
||||
redir_off = FALSE;
|
||||
|
||||
if (cmd != NULL)
|
||||
do_cmdline_cmd(cmd);
|
||||
@@ -2958,6 +2960,7 @@ f_execute(typval_T *argvars, typval_T *rettv)
|
||||
redir_execute = save_redir_execute;
|
||||
if (redir_execute)
|
||||
redir_execute_ga = save_ga;
|
||||
redir_off = save_redir_off;
|
||||
|
||||
/* "silent reg" or "silent echo x" leaves msg_col somewhere in the
|
||||
* line. Put it back in the first column. */
|
||||
@@ -11173,7 +11176,10 @@ f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv)
|
||||
/* Find the start and length of the badly spelled word. */
|
||||
len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
|
||||
if (len != 0)
|
||||
{
|
||||
word = ml_get_cursor();
|
||||
curwin->w_set_curswant = TRUE;
|
||||
}
|
||||
}
|
||||
else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL)
|
||||
{
|
||||
|
||||
@@ -4521,13 +4521,14 @@ get_address(
|
||||
if (lnum != MAXLNUM)
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
/*
|
||||
* Start a forward search at the end of the line.
|
||||
* Start a forward search at the end of the line (unless
|
||||
* before the first line).
|
||||
* Start a backward search at the start of the line.
|
||||
* This makes sure we never match in the current
|
||||
* line, and can match anywhere in the
|
||||
* next/previous line.
|
||||
*/
|
||||
if (c == '/')
|
||||
if (c == '/' && curwin->w_cursor.lnum > 0)
|
||||
curwin->w_cursor.col = MAXCOL;
|
||||
else
|
||||
curwin->w_cursor.col = 0;
|
||||
|
||||
77
src/gui.c
77
src/gui.c
@@ -2885,6 +2885,20 @@ gui_insert_lines(int row, int count)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEAT_TIMERS
|
||||
/*
|
||||
* Passed to ui_wait_for_chars_or_timer(), ignoring extra arguments.
|
||||
*/
|
||||
static int
|
||||
gui_wait_for_chars_3(
|
||||
long wtime,
|
||||
int *interrupted UNUSED,
|
||||
int ignore_input UNUSED)
|
||||
{
|
||||
return gui_mch_wait_for_chars(wtime);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns OK if a character was found to be available within the given time,
|
||||
* or FAIL otherwise.
|
||||
@@ -2893,32 +2907,7 @@ gui_insert_lines(int row, int count)
|
||||
gui_wait_for_chars_or_timer(long wtime)
|
||||
{
|
||||
#ifdef FEAT_TIMERS
|
||||
int due_time;
|
||||
long remaining = wtime;
|
||||
int tb_change_cnt = typebuf.tb_change_cnt;
|
||||
|
||||
/* When waiting very briefly don't trigger timers. */
|
||||
if (wtime >= 0 && wtime < 10L)
|
||||
return gui_mch_wait_for_chars(wtime);
|
||||
|
||||
while (wtime < 0 || remaining > 0)
|
||||
{
|
||||
/* Trigger timers and then get the time in wtime until the next one is
|
||||
* due. Wait up to that time. */
|
||||
due_time = check_due_timer();
|
||||
if (typebuf.tb_change_cnt != tb_change_cnt)
|
||||
{
|
||||
/* timer may have used feedkeys() */
|
||||
return FAIL;
|
||||
}
|
||||
if (due_time <= 0 || (wtime > 0 && due_time > remaining))
|
||||
due_time = remaining;
|
||||
if (gui_mch_wait_for_chars(due_time))
|
||||
return OK;
|
||||
if (wtime > 0)
|
||||
remaining -= due_time;
|
||||
}
|
||||
return FAIL;
|
||||
return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0);
|
||||
#else
|
||||
return gui_mch_wait_for_chars(wtime);
|
||||
#endif
|
||||
@@ -2933,10 +2922,12 @@ gui_wait_for_chars_or_timer(long wtime)
|
||||
* or FAIL otherwise.
|
||||
*/
|
||||
int
|
||||
gui_wait_for_chars(long wtime)
|
||||
gui_wait_for_chars(long wtime, int tb_change_cnt)
|
||||
{
|
||||
int retval;
|
||||
int tb_change_cnt = typebuf.tb_change_cnt;
|
||||
#if defined(ELAPSED_FUNC) && defined(FEAT_AUTOCMD)
|
||||
ELAPSED_TYPE start_tv;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_MENU
|
||||
/*
|
||||
@@ -2966,6 +2957,10 @@ gui_wait_for_chars(long wtime)
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if defined(ELAPSED_FUNC) && defined(FEAT_AUTOCMD)
|
||||
ELAPSED_INIT(start_tv);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* While we are waiting indefinitely for a character, blink the cursor.
|
||||
*/
|
||||
@@ -2974,13 +2969,17 @@ gui_wait_for_chars(long wtime)
|
||||
retval = FAIL;
|
||||
/*
|
||||
* We may want to trigger the CursorHold event. First wait for
|
||||
* 'updatetime' and if nothing is typed within that time put the
|
||||
* K_CURSORHOLD key in the input buffer.
|
||||
* 'updatetime' and if nothing is typed within that time, and feedkeys()
|
||||
* wasn't used, put the K_CURSORHOLD key in the input buffer.
|
||||
*/
|
||||
if (gui_wait_for_chars_or_timer(p_ut) == OK)
|
||||
retval = OK;
|
||||
#ifdef FEAT_AUTOCMD
|
||||
else if (trigger_cursorhold())
|
||||
else if (trigger_cursorhold()
|
||||
# ifdef ELAPSED_FUNC
|
||||
&& ELAPSED_FUNC(start_tv) >= p_ut
|
||||
# endif
|
||||
&& typebuf.tb_change_cnt == tb_change_cnt)
|
||||
{
|
||||
char_u buf[3];
|
||||
|
||||
@@ -3005,6 +3004,22 @@ gui_wait_for_chars(long wtime)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Equivalent of mch_inchar() for the GUI.
|
||||
*/
|
||||
int
|
||||
gui_inchar(
|
||||
char_u *buf,
|
||||
int maxlen,
|
||||
long wtime, /* milli seconds */
|
||||
int tb_change_cnt)
|
||||
{
|
||||
if (gui_wait_for_chars(wtime, tb_change_cnt)
|
||||
&& !typebuf_changed(tb_change_cnt))
|
||||
return read_from_input_buf(buf, (long)maxlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill p[4] with mouse coordinates encoded for check_termcode().
|
||||
*/
|
||||
|
||||
@@ -619,7 +619,7 @@ vim_main2(void)
|
||||
# ifdef FEAT_SUN_WORKSHOP
|
||||
if (!usingSunWorkShop)
|
||||
# endif
|
||||
gui_wait_for_chars(50L);
|
||||
gui_wait_for_chars(50L, typebuf.tb_change_cnt);
|
||||
TIME_MSG("GUI delay");
|
||||
}
|
||||
#endif
|
||||
@@ -1432,9 +1432,14 @@ getout(int exitval)
|
||||
buf = wp->w_buffer;
|
||||
if (CHANGEDTICK(buf) != -1)
|
||||
{
|
||||
bufref_T bufref;
|
||||
|
||||
set_bufref(&bufref, buf);
|
||||
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
|
||||
buf->b_fname, FALSE, buf);
|
||||
CHANGEDTICK(buf) = -1; /* note that we did it already */
|
||||
if (bufref_valid(&bufref))
|
||||
CHANGEDTICK(buf) = -1; /* note we did it already */
|
||||
|
||||
/* start all over, autocommands may mess up the lists */
|
||||
next_tp = first_tabpage;
|
||||
break;
|
||||
|
||||
@@ -2650,8 +2650,12 @@ del_lines(
|
||||
int
|
||||
gchar_pos(pos_T *pos)
|
||||
{
|
||||
char_u *ptr = ml_get_pos(pos);
|
||||
char_u *ptr;
|
||||
|
||||
/* When searching columns is sometimes put at the end of a line. */
|
||||
if (pos->col == MAXCOL)
|
||||
return NUL;
|
||||
ptr = ml_get_pos(pos);
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
return (*mb_ptr2char)(ptr);
|
||||
|
||||
66
src/misc2.c
66
src/misc2.c
@@ -348,24 +348,29 @@ inc_cursor(void)
|
||||
int
|
||||
inc(pos_T *lp)
|
||||
{
|
||||
char_u *p = ml_get_pos(lp);
|
||||
char_u *p;
|
||||
|
||||
if (*p != NUL) /* still within line, move to next char (may be NUL) */
|
||||
/* when searching position may be set to end of a line */
|
||||
if (lp->col != MAXCOL)
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
p = ml_get_pos(lp);
|
||||
if (*p != NUL) /* still within line, move to next char (may be NUL) */
|
||||
{
|
||||
int l = (*mb_ptr2len)(p);
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
{
|
||||
int l = (*mb_ptr2len)(p);
|
||||
|
||||
lp->col += l;
|
||||
return ((p[l] != NUL) ? 0 : 2);
|
||||
}
|
||||
lp->col += l;
|
||||
return ((p[l] != NUL) ? 0 : 2);
|
||||
}
|
||||
#endif
|
||||
lp->col++;
|
||||
lp->col++;
|
||||
#ifdef FEAT_VIRTUALEDIT
|
||||
lp->coladd = 0;
|
||||
lp->coladd = 0;
|
||||
#endif
|
||||
return ((p[1] != NUL) ? 0 : 2);
|
||||
return ((p[1] != NUL) ? 0 : 2);
|
||||
}
|
||||
}
|
||||
if (lp->lnum != curbuf->b_ml.ml_line_count) /* there is a next line */
|
||||
{
|
||||
@@ -412,8 +417,21 @@ dec(pos_T *lp)
|
||||
#ifdef FEAT_VIRTUALEDIT
|
||||
lp->coladd = 0;
|
||||
#endif
|
||||
if (lp->col > 0) /* still within line */
|
||||
if (lp->col == MAXCOL)
|
||||
{
|
||||
/* past end of line */
|
||||
p = ml_get(lp->lnum);
|
||||
lp->col = (colnr_T)STRLEN(p);
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
lp->col -= (*mb_head_off)(p, p + lp->col);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lp->col > 0)
|
||||
{
|
||||
/* still within line */
|
||||
lp->col--;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
@@ -424,8 +442,10 @@ dec(pos_T *lp)
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if (lp->lnum > 1) /* there is a prior line */
|
||||
|
||||
if (lp->lnum > 1)
|
||||
{
|
||||
/* there is a prior line */
|
||||
lp->lnum--;
|
||||
p = ml_get(lp->lnum);
|
||||
lp->col = (colnr_T)STRLEN(p);
|
||||
@@ -435,7 +455,9 @@ dec(pos_T *lp)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return -1; /* at start of file */
|
||||
|
||||
/* at start of file */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1600,11 +1622,17 @@ strup_save(char_u *orig)
|
||||
char_u *s;
|
||||
|
||||
c = utf_ptr2char(p);
|
||||
l = utf_ptr2len(p);
|
||||
if (c == 0)
|
||||
{
|
||||
/* overlong sequence, use only the first byte */
|
||||
c = *p;
|
||||
l = 1;
|
||||
}
|
||||
uc = utf_toupper(c);
|
||||
|
||||
/* Reallocate string when byte count changes. This is rare,
|
||||
* thus it's OK to do another malloc()/free(). */
|
||||
l = utf_ptr2len(p);
|
||||
newl = utf_char2len(uc);
|
||||
if (newl != l)
|
||||
{
|
||||
@@ -1663,11 +1691,17 @@ strlow_save(char_u *orig)
|
||||
char_u *s;
|
||||
|
||||
c = utf_ptr2char(p);
|
||||
l = utf_ptr2len(p);
|
||||
if (c == 0)
|
||||
{
|
||||
/* overlong sequence, use only the first byte */
|
||||
c = *p;
|
||||
l = 1;
|
||||
}
|
||||
lc = utf_tolower(c);
|
||||
|
||||
/* Reallocate string when byte count changes. This is rare,
|
||||
* thus it's OK to do another malloc()/free(). */
|
||||
l = utf_ptr2len(p);
|
||||
newl = utf_char2len(lc);
|
||||
if (newl != l)
|
||||
{
|
||||
|
||||
@@ -6814,6 +6814,8 @@ nv_brackets(cmdarg_T *cap)
|
||||
clearopbeep(cap->oap);
|
||||
break;
|
||||
}
|
||||
else
|
||||
curwin->w_set_curswant = TRUE;
|
||||
# ifdef FEAT_FOLDING
|
||||
if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
|
||||
foldOpenCursor();
|
||||
@@ -7850,8 +7852,12 @@ n_start_visual_mode(int c)
|
||||
nv_window(cmdarg_T *cap)
|
||||
{
|
||||
if (cap->nchar == ':')
|
||||
{
|
||||
/* "CTRL-W :" is the same as typing ":"; useful in a terminal window */
|
||||
cap->cmdchar = ':';
|
||||
cap->nchar = NUL;
|
||||
nv_colon(cap);
|
||||
}
|
||||
else if (!checkclearop(cap->oap))
|
||||
do_window(cap->nchar, cap->count0, NUL); /* everything is in window.c */
|
||||
}
|
||||
|
||||
@@ -183,8 +183,15 @@ get_op_type(int char1, int char2)
|
||||
if (char1 == 'g' && char2 == Ctrl_X) /* subtract */
|
||||
return OP_NR_SUB;
|
||||
for (i = 0; ; ++i)
|
||||
{
|
||||
if (opchars[i][0] == char1 && opchars[i][1] == char2)
|
||||
break;
|
||||
if (i == (int)(sizeof(opchars) / sizeof(char [3]) - 1))
|
||||
{
|
||||
internal_error("get_op_type()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@@ -5790,36 +5790,8 @@ mch_breakcheck(int force)
|
||||
WaitForChar(long msec, int *interrupted, int ignore_input)
|
||||
{
|
||||
#ifdef FEAT_TIMERS
|
||||
long due_time;
|
||||
long remaining = msec;
|
||||
int tb_change_cnt = typebuf.tb_change_cnt;
|
||||
|
||||
/* When waiting very briefly don't trigger timers. */
|
||||
if (msec >= 0 && msec < 10L)
|
||||
return WaitForCharOrMouse(msec, NULL, ignore_input);
|
||||
|
||||
while (msec < 0 || remaining > 0)
|
||||
{
|
||||
/* Trigger timers and then get the time in msec until the next one is
|
||||
* due. Wait up to that time. */
|
||||
due_time = check_due_timer();
|
||||
if (typebuf.tb_change_cnt != tb_change_cnt)
|
||||
{
|
||||
/* timer may have used feedkeys() */
|
||||
return FALSE;
|
||||
}
|
||||
if (due_time <= 0 || (msec > 0 && due_time > remaining))
|
||||
due_time = remaining;
|
||||
if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
|
||||
return TRUE;
|
||||
if (interrupted != NULL && *interrupted)
|
||||
/* Nothing available, but need to return so that side effects get
|
||||
* handled, such as handling a message on a channel. */
|
||||
return FALSE;
|
||||
if (msec > 0)
|
||||
remaining -= due_time;
|
||||
}
|
||||
return FALSE;
|
||||
return ui_wait_for_chars_or_timer(
|
||||
msec, WaitForCharOrMouse, interrupted, ignore_input) == OK;
|
||||
#else
|
||||
return WaitForCharOrMouse(msec, interrupted, ignore_input);
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,8 @@ int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, guicolor_T b
|
||||
void gui_undraw_cursor(void);
|
||||
void gui_redraw(int x, int y, int w, int h);
|
||||
int gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
|
||||
int gui_wait_for_chars(long wtime);
|
||||
int gui_wait_for_chars(long wtime, int tb_change_cnt);
|
||||
int gui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
|
||||
void gui_send_mouse_event(int button, int x, int y, int repeated_click, int_u modifiers);
|
||||
int gui_xy2colrow(int x, int y, int *colp);
|
||||
void gui_menu_cb(vimmenu_T *menu);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
void ui_write(char_u *s, int len);
|
||||
void ui_inchar_undo(char_u *s, int len);
|
||||
int ui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
|
||||
int ui_wait_for_chars_or_timer(long wtime, int (*wait_func)(long wtime, int *interrupted, int ignore_input), int *interrupted, int ignore_input);
|
||||
int ui_char_avail(void);
|
||||
void ui_delay(long msec, int ignoreinput);
|
||||
void ui_suspend(void);
|
||||
|
||||
211
src/quickfix.c
211
src/quickfix.c
@@ -76,6 +76,7 @@ typedef struct qf_list_S
|
||||
int qf_multiline;
|
||||
int qf_multiignore;
|
||||
int qf_multiscan;
|
||||
long qf_changedtick;
|
||||
} qf_list_T;
|
||||
|
||||
/*
|
||||
@@ -143,6 +144,7 @@ static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *);
|
||||
static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack);
|
||||
static char_u *qf_pop_dir(struct dir_stack_T **);
|
||||
static char_u *qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *);
|
||||
static int qflist_valid(win_T *wp, int_u qf_id);
|
||||
static void qf_fmt_text(char_u *text, char_u *buf, int bufsize);
|
||||
static void qf_clean_dir_stack(struct dir_stack_T **);
|
||||
static int qf_win_pos_update(qf_info_T *qi, int old_qf_index);
|
||||
@@ -176,6 +178,9 @@ static qf_info_T *ll_get_or_alloc_list(win_T *);
|
||||
static char_u *qf_last_bufname = NULL;
|
||||
static bufref_T qf_last_bufref = {NULL, 0, 0};
|
||||
|
||||
static char *e_loc_list_changed =
|
||||
N_("E926: Current location list was changed");
|
||||
|
||||
/*
|
||||
* Read the errorfile "efile" into memory, line by line, building the error
|
||||
* list. Set the error list's title to qf_title.
|
||||
@@ -1668,6 +1673,7 @@ copy_loclist(win_T *from, win_T *to)
|
||||
|
||||
/* Assign a new ID for the location list */
|
||||
to_qfl->qf_id = ++last_qf_id;
|
||||
to_qfl->qf_changedtick = 0L;
|
||||
|
||||
/* When no valid entries are present in the list, qf_ptr points to
|
||||
* the first item in the list */
|
||||
@@ -1925,6 +1931,29 @@ qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *filename)
|
||||
return ds_ptr==NULL? NULL: ds_ptr->dirname;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if a quickfix/location list with the given identifier exists.
|
||||
*/
|
||||
static int
|
||||
qflist_valid (win_T *wp, int_u qf_id)
|
||||
{
|
||||
qf_info_T *qi = &ql_info;
|
||||
int i;
|
||||
|
||||
if (wp != NULL)
|
||||
{
|
||||
qi = GET_LOC_LIST(wp); /* Location list */
|
||||
if (qi == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < qi->qf_listcount; ++i)
|
||||
if (qi->qf_lists[i].qf_id == qf_id)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* When loading a file from the quickfix, the auto commands may modify it.
|
||||
* This may invalidate the current quickfix entry. This function checks
|
||||
@@ -2341,14 +2370,28 @@ qf_jump_edit_buffer(
|
||||
else
|
||||
{
|
||||
int old_qf_curlist = qi->qf_curlist;
|
||||
int save_qfid = qi->qf_lists[qi->qf_curlist].qf_id;
|
||||
|
||||
retval = buflist_getfile(qf_ptr->qf_fnum,
|
||||
(linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
|
||||
if (qi != &ql_info && !win_valid_any_tab(oldwin))
|
||||
|
||||
if (qi != &ql_info)
|
||||
{
|
||||
EMSG(_("E924: Current window was closed"));
|
||||
*abort = TRUE;
|
||||
*opened_window = FALSE;
|
||||
/*
|
||||
* Location list. Check whether the associated window is still
|
||||
* present and the list is still valid.
|
||||
*/
|
||||
if (!win_valid_any_tab(oldwin))
|
||||
{
|
||||
EMSG(_("E924: Current window was closed"));
|
||||
*abort = TRUE;
|
||||
*opened_window = FALSE;
|
||||
}
|
||||
else if (!qflist_valid(oldwin, save_qfid))
|
||||
{
|
||||
EMSG(_(e_loc_list_changed));
|
||||
*abort = TRUE;
|
||||
}
|
||||
}
|
||||
else if (old_qf_curlist != qi->qf_curlist
|
||||
|| !is_qf_entry_present(qi, qf_ptr))
|
||||
@@ -2356,7 +2399,7 @@ qf_jump_edit_buffer(
|
||||
if (qi == &ql_info)
|
||||
EMSG(_("E925: Current quickfix was changed"));
|
||||
else
|
||||
EMSG(_("E926: Current location list was changed"));
|
||||
EMSG(_(e_loc_list_changed));
|
||||
*abort = TRUE;
|
||||
}
|
||||
|
||||
@@ -2965,6 +3008,7 @@ qf_free(qf_info_T *qi, int idx)
|
||||
free_tv(qfl->qf_ctx);
|
||||
qfl->qf_ctx = NULL;
|
||||
qfl->qf_id = 0;
|
||||
qfl->qf_changedtick = 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3178,6 +3222,8 @@ ex_copen(exarg_T *eap)
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
qf_buf = qf_find_buf(qi);
|
||||
|
||||
/* The current window becomes the previous window afterwards. */
|
||||
@@ -3185,10 +3231,14 @@ ex_copen(exarg_T *eap)
|
||||
|
||||
if ((eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
|
||||
&& cmdmod.split == 0)
|
||||
/* Create the new window at the very bottom, except when
|
||||
/* Create the new quickfix window at the very bottom, except when
|
||||
* :belowright or :aboveleft is used. */
|
||||
win_goto(lastwin);
|
||||
if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL)
|
||||
/* Default is to open the window below the current window */
|
||||
if (cmdmod.split == 0)
|
||||
flags = WSP_BELOW;
|
||||
flags |= WSP_NEWLOC;
|
||||
if (win_split(height, flags) == FAIL)
|
||||
return; /* not enough room for window */
|
||||
RESET_BINDING(curwin);
|
||||
|
||||
@@ -3604,6 +3654,12 @@ qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
|
||||
KeyTyped = old_KeyTyped;
|
||||
}
|
||||
|
||||
static void
|
||||
qf_list_changed(qf_info_T *qi, int qf_idx)
|
||||
{
|
||||
qi->qf_lists[qf_idx].qf_changedtick++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE when using ":vimgrep" for ":grep".
|
||||
*/
|
||||
@@ -3713,6 +3769,8 @@ ex_make(exarg_T *eap)
|
||||
*eap->cmdlinep, enc);
|
||||
if (wp != NULL)
|
||||
qi = GET_LOC_LIST(wp);
|
||||
if (res >= 0 && qi != NULL)
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
{
|
||||
@@ -4054,13 +4112,10 @@ ex_cfile(exarg_T *eap)
|
||||
qf_info_T *qi = &ql_info;
|
||||
#ifdef FEAT_AUTOCMD
|
||||
char_u *au_name = NULL;
|
||||
int save_qfid;
|
||||
#endif
|
||||
int res;
|
||||
|
||||
if (eap->cmdidx == CMD_lfile || eap->cmdidx == CMD_lgetfile
|
||||
|| eap->cmdidx == CMD_laddfile)
|
||||
wp = curwin;
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
switch (eap->cmdidx)
|
||||
{
|
||||
@@ -4093,6 +4148,11 @@ 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)
|
||||
wp = curwin;
|
||||
|
||||
/*
|
||||
* This function is used by the :cfile, :cgetfile and :caddfile
|
||||
* commands.
|
||||
@@ -4105,14 +4165,23 @@ ex_cfile(exarg_T *eap)
|
||||
*/
|
||||
res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
|
||||
&& eap->cmdidx != CMD_laddfile), *eap->cmdlinep, enc);
|
||||
if (wp != NULL)
|
||||
qi = GET_LOC_LIST(wp);
|
||||
if (res >= 0 && qi != NULL)
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
save_qfid = qi->qf_lists[qi->qf_curlist].qf_id;
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf);
|
||||
/*
|
||||
* Autocmd might have freed the quickfix/location list. Check whether it is
|
||||
* still valid
|
||||
*/
|
||||
if (!qflist_valid(wp, save_qfid))
|
||||
return;
|
||||
#endif
|
||||
if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile))
|
||||
{
|
||||
if (wp != NULL)
|
||||
qi = GET_LOC_LIST(wp);
|
||||
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
}
|
||||
@@ -4135,8 +4204,11 @@ ex_vimgrep(exarg_T *eap)
|
||||
char_u *p;
|
||||
int fi;
|
||||
qf_info_T *qi = &ql_info;
|
||||
int loclist_cmd = FALSE;
|
||||
#ifdef FEAT_AUTOCMD
|
||||
int_u save_qfid;
|
||||
qfline_T *cur_qf_start;
|
||||
win_T *wp;
|
||||
#endif
|
||||
long lnum;
|
||||
buf_T *buf;
|
||||
@@ -4190,6 +4262,7 @@ ex_vimgrep(exarg_T *eap)
|
||||
qi = ll_get_or_alloc_list(curwin);
|
||||
if (qi == NULL)
|
||||
return;
|
||||
loclist_cmd = TRUE;
|
||||
}
|
||||
|
||||
if (eap->addr_count > 0)
|
||||
@@ -4260,8 +4333,9 @@ ex_vimgrep(exarg_T *eap)
|
||||
mch_dirname(dirname_start, MAXPATHL);
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Remember the value of qf_start, so that we can check for autocommands
|
||||
* changing the current quickfix list. */
|
||||
/* Remember the current values of the quickfix list and qf_start, so that
|
||||
* we can check for autocommands changing the current quickfix list. */
|
||||
save_qfid = qi->qf_lists[qi->qf_curlist].qf_id;
|
||||
cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
|
||||
#endif
|
||||
|
||||
@@ -4321,6 +4395,18 @@ ex_vimgrep(exarg_T *eap)
|
||||
using_dummy = FALSE;
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (loclist_cmd)
|
||||
{
|
||||
/*
|
||||
* Verify that the location list is still valid. An autocmd might
|
||||
* have freed the location list.
|
||||
*/
|
||||
if (!qflist_valid(curwin, save_qfid))
|
||||
{
|
||||
EMSG(_(e_loc_list_changed));
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
if (cur_qf_start != qi->qf_lists[qi->qf_curlist].qf_start)
|
||||
{
|
||||
int idx;
|
||||
@@ -4469,6 +4555,7 @@ ex_vimgrep(exarg_T *eap)
|
||||
qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
|
||||
qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
|
||||
qi->qf_lists[qi->qf_curlist].qf_index = 1;
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
|
||||
qf_update_buffer(qi, NULL);
|
||||
|
||||
@@ -4476,6 +4563,13 @@ ex_vimgrep(exarg_T *eap)
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
curbuf->b_fname, TRUE, curbuf);
|
||||
/*
|
||||
* The QuickFixCmdPost autocmd may free the quickfix list. Check the list
|
||||
* is still valid.
|
||||
*/
|
||||
wp = loclist_cmd ? curwin : NULL;
|
||||
if (!qflist_valid(wp, save_qfid))
|
||||
goto theend;
|
||||
#endif
|
||||
|
||||
/* Jump to first match. */
|
||||
@@ -4572,6 +4666,7 @@ load_dummy_buffer(
|
||||
bufref_T newbuf_to_wipe;
|
||||
int failed = TRUE;
|
||||
aco_save_T aco;
|
||||
int readfile_result;
|
||||
|
||||
/* Allocate a buffer without putting it in the buffer list. */
|
||||
newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
|
||||
@@ -4585,6 +4680,9 @@ load_dummy_buffer(
|
||||
/* need to open the memfile before putting the buffer in a window */
|
||||
if (ml_open(newbuf) == OK)
|
||||
{
|
||||
/* Make sure this buffer isn't wiped out by auto commands. */
|
||||
++newbuf->b_locked;
|
||||
|
||||
/* set curwin/curbuf to buf and save a few things */
|
||||
aucmd_prepbuf(&aco, newbuf);
|
||||
|
||||
@@ -4599,9 +4697,11 @@ load_dummy_buffer(
|
||||
curbuf->b_flags &= ~BF_DUMMY;
|
||||
|
||||
newbuf_to_wipe.br_buf = NULL;
|
||||
if (readfile(fname, NULL,
|
||||
readfile_result = readfile(fname, NULL,
|
||||
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
|
||||
NULL, READ_NEW | READ_DUMMY) == OK
|
||||
NULL, READ_NEW | READ_DUMMY);
|
||||
--newbuf->b_locked;
|
||||
if (readfile_result == OK
|
||||
&& !got_int
|
||||
&& !(curbuf->b_flags & BF_NEW))
|
||||
{
|
||||
@@ -4774,7 +4874,8 @@ enum {
|
||||
QF_GETLIST_ID = 0x20,
|
||||
QF_GETLIST_IDX = 0x40,
|
||||
QF_GETLIST_SIZE = 0x80,
|
||||
QF_GETLIST_ALL = 0xFF
|
||||
QF_GETLIST_TICK = 0x100,
|
||||
QF_GETLIST_ALL = 0x1FF
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -4890,6 +4991,9 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
if (dict_find(what, (char_u *)"size", -1) != NULL)
|
||||
flags |= QF_GETLIST_SIZE;
|
||||
|
||||
if (dict_find(what, (char_u *)"changedtick", -1) != NULL)
|
||||
flags |= QF_GETLIST_TICK;
|
||||
|
||||
if (qi != NULL && qi->qf_listcount != 0)
|
||||
{
|
||||
qf_idx = qi->qf_curlist; /* default is the current list */
|
||||
@@ -4906,8 +5010,9 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
qf_idx = -1;
|
||||
}
|
||||
}
|
||||
else if ((di->di_tv.v_type == VAR_STRING)
|
||||
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
|
||||
else if (di->di_tv.v_type == VAR_STRING
|
||||
&& di->di_tv.vval.v_string != NULL
|
||||
&& STRCMP(di->di_tv.vval.v_string, "$") == 0)
|
||||
/* Get the last quickfix list number */
|
||||
qf_idx = qi->qf_listcount - 1;
|
||||
else
|
||||
@@ -4957,6 +5062,8 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
status = dict_add_nr_str(retdict, "idx", 0L, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_SIZE))
|
||||
status = dict_add_nr_str(retdict, "size", 0L, NULL);
|
||||
if ((status == OK) && (flags & QF_GETLIST_TICK))
|
||||
status = dict_add_nr_str(retdict, "changedtick", 0L, NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -5029,6 +5136,10 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
status = dict_add_nr_str(retdict, "size",
|
||||
qi->qf_lists[qf_idx].qf_count, NULL);
|
||||
|
||||
if ((status == OK) && (flags & QF_GETLIST_TICK))
|
||||
status = dict_add_nr_str(retdict, "changedtick",
|
||||
qi->qf_lists[qf_idx].qf_changedtick, NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -5196,7 +5307,8 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
|
||||
newlist = FALSE; /* use the specified list */
|
||||
}
|
||||
else if (di->di_tv.v_type == VAR_STRING
|
||||
&& STRCMP(di->di_tv.vval.v_string, "$") == 0)
|
||||
&& di->di_tv.vval.v_string != NULL
|
||||
&& STRCMP(di->di_tv.vval.v_string, "$") == 0)
|
||||
{
|
||||
if (qi->qf_listcount > 0)
|
||||
qf_idx = qi->qf_listcount - 1;
|
||||
@@ -5298,6 +5410,9 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
|
||||
retval = OK;
|
||||
}
|
||||
|
||||
if (retval == OK)
|
||||
qf_list_changed(qi, qf_idx);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -5401,7 +5516,11 @@ set_errorlist(
|
||||
else if (what != NULL)
|
||||
retval = qf_set_properties(qi, what, action, title);
|
||||
else
|
||||
{
|
||||
retval = qf_add_entries(qi, qi->qf_curlist, list, title, action);
|
||||
if (retval == OK)
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -5447,6 +5566,16 @@ set_ref_in_quickfix(int copyID)
|
||||
if (abort)
|
||||
return abort;
|
||||
}
|
||||
if (IS_LL_WINDOW(win) && (win->w_llist_ref->qf_refcount == 1))
|
||||
{
|
||||
/* In a location list window and none of the other windows is
|
||||
* referring to this location list. Mark the location list
|
||||
* context as still in use.
|
||||
*/
|
||||
abort = mark_quickfix_ctx(win->w_llist_ref, copyID);
|
||||
if (abort)
|
||||
return abort;
|
||||
}
|
||||
}
|
||||
|
||||
return abort;
|
||||
@@ -5471,14 +5600,6 @@ ex_cbuffer(exarg_T *eap)
|
||||
#endif
|
||||
int res;
|
||||
|
||||
if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
|
||||
|| eap->cmdidx == CMD_laddbuffer)
|
||||
{
|
||||
qi = ll_get_or_alloc_list(curwin);
|
||||
if (qi == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
switch (eap->cmdidx)
|
||||
{
|
||||
@@ -5500,6 +5621,16 @@ ex_cbuffer(exarg_T *eap)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Must come after autocommands. */
|
||||
if (eap->cmdidx == CMD_lbuffer
|
||||
|| eap->cmdidx == CMD_lgetbuffer
|
||||
|| eap->cmdidx == CMD_laddbuffer)
|
||||
{
|
||||
qi = ll_get_or_alloc_list(curwin);
|
||||
if (qi == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
if (*eap->arg == NUL)
|
||||
buf = curbuf;
|
||||
else if (*skipwhite(skipdigits(eap->arg)) == NUL)
|
||||
@@ -5534,6 +5665,8 @@ ex_cbuffer(exarg_T *eap)
|
||||
&& eap->cmdidx != CMD_laddbuffer),
|
||||
eap->line1, eap->line2,
|
||||
qf_title, NULL);
|
||||
if (res >= 0)
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
@@ -5561,14 +5694,6 @@ ex_cexpr(exarg_T *eap)
|
||||
#endif
|
||||
int res;
|
||||
|
||||
if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_lgetexpr
|
||||
|| eap->cmdidx == CMD_laddexpr)
|
||||
{
|
||||
qi = ll_get_or_alloc_list(curwin);
|
||||
if (qi == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
switch (eap->cmdidx)
|
||||
{
|
||||
@@ -5590,6 +5715,15 @@ ex_cexpr(exarg_T *eap)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eap->cmdidx == CMD_lexpr
|
||||
|| eap->cmdidx == CMD_lgetexpr
|
||||
|| eap->cmdidx == CMD_laddexpr)
|
||||
{
|
||||
qi = ll_get_or_alloc_list(curwin);
|
||||
if (qi == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Evaluate the expression. When the result is a string or a list we can
|
||||
* use it to fill the errorlist. */
|
||||
tv = eval_expr(eap->arg, NULL);
|
||||
@@ -5603,6 +5737,8 @@ ex_cexpr(exarg_T *eap)
|
||||
&& eap->cmdidx != CMD_laddexpr),
|
||||
(linenr_T)0, (linenr_T)0, *eap->cmdlinep,
|
||||
NULL);
|
||||
if (res >= 0)
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (au_name != NULL)
|
||||
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
|
||||
@@ -5823,6 +5959,7 @@ ex_helpgrep(exarg_T *eap)
|
||||
/* Darn, some plugin changed the value. */
|
||||
free_string_option(save_cpo);
|
||||
|
||||
qf_list_changed(qi, qi->qf_curlist);
|
||||
qf_update_buffer(qi, NULL);
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
|
||||
20
src/screen.c
20
src/screen.c
@@ -8041,7 +8041,7 @@ screen_start_highlight(int attr)
|
||||
else
|
||||
attr = aep->ae_attr;
|
||||
}
|
||||
if ((attr & HL_BOLD) && T_MD != NULL) /* bold */
|
||||
if ((attr & HL_BOLD) && *T_MD != NUL) /* bold */
|
||||
out_str(T_MD);
|
||||
else if (aep != NULL && cterm_normal_fg_bold &&
|
||||
#ifdef FEAT_TERMGUICOLORS
|
||||
@@ -8056,19 +8056,19 @@ screen_start_highlight(int attr)
|
||||
/* If the Normal FG color has BOLD attribute and the new HL
|
||||
* has a FG color defined, clear BOLD. */
|
||||
out_str(T_ME);
|
||||
if ((attr & HL_STANDOUT) && T_SO != NULL) /* standout */
|
||||
if ((attr & HL_STANDOUT) && *T_SO != NUL) /* standout */
|
||||
out_str(T_SO);
|
||||
if ((attr & HL_UNDERCURL) && T_UCS != NULL) /* undercurl */
|
||||
if ((attr & HL_UNDERCURL) && *T_UCS != NUL) /* undercurl */
|
||||
out_str(T_UCS);
|
||||
if (((attr & HL_UNDERLINE) /* underline or undercurl */
|
||||
|| ((attr & HL_UNDERCURL) && T_UCS == NULL))
|
||||
&& T_US != NULL)
|
||||
|| ((attr & HL_UNDERCURL) && *T_UCS == NUL))
|
||||
&& *T_US != NUL)
|
||||
out_str(T_US);
|
||||
if ((attr & HL_ITALIC) && T_CZH != NULL) /* italic */
|
||||
if ((attr & HL_ITALIC) && *T_CZH != NUL) /* italic */
|
||||
out_str(T_CZH);
|
||||
if ((attr & HL_INVERSE) && T_MR != NULL) /* inverse (reverse) */
|
||||
if ((attr & HL_INVERSE) && *T_MR != NUL) /* inverse (reverse) */
|
||||
out_str(T_MR);
|
||||
if ((attr & HL_STRIKETHROUGH) && T_STS != NULL) /* strike */
|
||||
if ((attr & HL_STRIKETHROUGH) && *T_STS != NUL) /* strike */
|
||||
out_str(T_STS);
|
||||
|
||||
/*
|
||||
@@ -8180,7 +8180,7 @@ screen_stop_highlight(void)
|
||||
else
|
||||
out_str(T_SE);
|
||||
}
|
||||
if ((screen_attr & HL_UNDERCURL) && T_UCE != NULL)
|
||||
if ((screen_attr & HL_UNDERCURL) && *T_UCE != NUL)
|
||||
{
|
||||
if (STRCMP(T_UCE, T_ME) == 0)
|
||||
do_ME = TRUE;
|
||||
@@ -8188,7 +8188,7 @@ screen_stop_highlight(void)
|
||||
out_str(T_UCE);
|
||||
}
|
||||
if ((screen_attr & HL_UNDERLINE)
|
||||
|| ((screen_attr & HL_UNDERCURL) && T_UCE == NULL))
|
||||
|| ((screen_attr & HL_UNDERCURL) && *T_UCE == NUL))
|
||||
{
|
||||
if (STRCMP(T_UE, T_ME) == 0)
|
||||
do_ME = TRUE;
|
||||
|
||||
@@ -1130,7 +1130,7 @@ do_tags(exarg_T *eap UNUSED)
|
||||
continue;
|
||||
|
||||
msg_putchar('\n');
|
||||
sprintf((char *)IObuff, "%c%2d %2d %-15s %5ld ",
|
||||
vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld ",
|
||||
i == tagstackidx ? '>' : ' ',
|
||||
i + 1,
|
||||
tagstack[i].cur_match + 1,
|
||||
|
||||
@@ -94,6 +94,7 @@ NEW_TESTS = test_arabic.res \
|
||||
test_edit.res \
|
||||
test_erasebackword.res \
|
||||
test_escaped_glob.res \
|
||||
test_eval_stuff.res \
|
||||
test_exec_while_if.res \
|
||||
test_exists.res \
|
||||
test_exists_autocmd.res \
|
||||
|
||||
@@ -1163,3 +1163,18 @@ func Test_TextYankPost()
|
||||
unlet g:event
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_nocatch_wipe_all_buffers()
|
||||
" Real nasty autocommand: wipe all buffers on any event.
|
||||
au * * bwipe *
|
||||
call assert_fails('next x', 'E93')
|
||||
bwipe
|
||||
au!
|
||||
endfunc
|
||||
|
||||
func Test_nocatch_wipe_dummy_buffer()
|
||||
" Nasty autocommand: wipe buffer on any event.
|
||||
au * x bwipe
|
||||
call assert_fails('lv½ /x', 'E480')
|
||||
au!
|
||||
endfunc
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
Test for various eval features. vim: set ft=vim :
|
||||
|
||||
NOTE: Do not add more here, use new style test test_eval_stuff.vim
|
||||
|
||||
Note: system clipboard is saved, changed and restored.
|
||||
|
||||
clipboard contents
|
||||
@@ -134,10 +136,10 @@ if has('clipboard')
|
||||
let _clipreg = ['*', getreg('*'), getregtype('*')]
|
||||
let _clipopt = &cb
|
||||
let &cb='unnamed'
|
||||
5y
|
||||
7y
|
||||
AR *
|
||||
tabdo :windo :echo "hi"
|
||||
6y
|
||||
8y
|
||||
AR *
|
||||
let &cb=_clipopt
|
||||
call call('setreg', _clipreg)
|
||||
|
||||
13
src/testdir/test_eval_stuff.vim
Normal file
13
src/testdir/test_eval_stuff.vim
Normal file
@@ -0,0 +1,13 @@
|
||||
" Tests for various eval things.
|
||||
|
||||
function s:foo() abort
|
||||
try
|
||||
return [] == 0
|
||||
catch
|
||||
return 1
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
func Test_catch_return_with_error()
|
||||
call assert_equal(1, s:foo())
|
||||
endfunc
|
||||
@@ -268,6 +268,11 @@ func Test_tolower()
|
||||
" Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
|
||||
" in length (2 to 3 bytes) when lowercased. So let's test them.
|
||||
call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
|
||||
|
||||
" This call to tolower with invalid utf8 sequence used to cause access to
|
||||
" invalid memory.
|
||||
call tolower("\xC0\x80\xC0")
|
||||
call tolower("123\xC0\x80\xC0")
|
||||
endfunc
|
||||
|
||||
func Test_toupper()
|
||||
@@ -338,6 +343,11 @@ func Test_toupper()
|
||||
call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
|
||||
|
||||
call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
|
||||
|
||||
" This call to toupper with invalid utf8 sequence used to cause access to
|
||||
" invalid memory.
|
||||
call toupper("\xC0\x80\xC0")
|
||||
call toupper("123\xC0\x80\xC0")
|
||||
endfunc
|
||||
|
||||
" Tests for the mode() function
|
||||
@@ -692,6 +702,7 @@ func Test_count()
|
||||
call assert_equal(0, count("foo", "O"))
|
||||
call assert_equal(2, count("foo", "O", 1))
|
||||
call assert_equal(2, count("fooooo", "oo"))
|
||||
call assert_equal(0, count("foo", ""))
|
||||
endfunc
|
||||
|
||||
func Test_changenr()
|
||||
|
||||
@@ -7,7 +7,8 @@ func Test_gf_url()
|
||||
\ "first test for URL://machine.name/tmp/vimtest2a and other text",
|
||||
\ "second test for URL://machine.name/tmp/vimtest2b. And other text",
|
||||
\ "third test for URL:\\\\machine.name\\vimtest2c and other text",
|
||||
\ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text"
|
||||
\ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text",
|
||||
\ "fifth test for URL://machine.name/tmp?q=vim&opt=yes and other text",
|
||||
\ ])
|
||||
call cursor(1,1)
|
||||
call search("^first")
|
||||
@@ -28,6 +29,10 @@ func Test_gf_url()
|
||||
call search("URL")
|
||||
call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("<cfile>"))
|
||||
|
||||
call search("^fifth")
|
||||
call search("URL")
|
||||
call assert_equal("URL://machine.name/tmp?q=vim&opt=yes", expand("<cfile>"))
|
||||
|
||||
set isf&vim
|
||||
enew!
|
||||
endfunc
|
||||
|
||||
@@ -404,6 +404,15 @@ func! Test_normal10_expand()
|
||||
call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
|
||||
endfor
|
||||
|
||||
if executable('echo')
|
||||
" Test expand(`...`) i.e. backticks command expansion.
|
||||
" MS-Windows has a trailing space.
|
||||
call assert_match('^abcde *$', expand('`echo abcde`'))
|
||||
endif
|
||||
|
||||
" Test expand(`=...`) i.e. backticks expression expansion
|
||||
call assert_equal('5', expand('`=2+3`'))
|
||||
|
||||
" clean up
|
||||
bw!
|
||||
endfunc
|
||||
@@ -1537,12 +1546,12 @@ fun! Test_normal29_brace()
|
||||
\ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a',
|
||||
\ 'paragraph boundary |posix|.',
|
||||
\ '{',
|
||||
\ 'This is no paragaraph',
|
||||
\ 'This is no paragraph',
|
||||
\ 'unless the ''{'' is set',
|
||||
\ 'in ''cpoptions''',
|
||||
\ '}',
|
||||
\ '.IP',
|
||||
\ 'The nroff macros IP seperates a paragraph',
|
||||
\ 'The nroff macros IP separates a paragraph',
|
||||
\ 'That means, it must be a ''.''',
|
||||
\ 'followed by IP',
|
||||
\ '.LPIt does not matter, if afterwards some',
|
||||
@@ -1557,7 +1566,7 @@ fun! Test_normal29_brace()
|
||||
1
|
||||
norm! 0d2}
|
||||
call assert_equal(['.IP',
|
||||
\ 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
|
||||
\ 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
|
||||
\ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff',
|
||||
\ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
|
||||
norm! 0d}
|
||||
@@ -1576,21 +1585,21 @@ fun! Test_normal29_brace()
|
||||
set cpo+={
|
||||
1
|
||||
norm! 0d2}
|
||||
call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
|
||||
\ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
|
||||
call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
|
||||
\ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
|
||||
\ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
|
||||
\ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
|
||||
\ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
|
||||
$
|
||||
norm! d}
|
||||
call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
|
||||
\ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
|
||||
call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
|
||||
\ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
|
||||
\ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
|
||||
\ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
|
||||
\ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
|
||||
norm! gg}
|
||||
norm! d5}
|
||||
call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
|
||||
call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
|
||||
|
||||
" clean up
|
||||
set cpo-={
|
||||
|
||||
@@ -1428,6 +1428,11 @@ func XquickfixSetListWithAct(cchar)
|
||||
call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
|
||||
endfunc
|
||||
|
||||
func Test_setqflist_invalid_nr()
|
||||
" The following command used to crash Vim
|
||||
call setqflist([], ' ', {'nr' : $XXX_DOES_NOT_EXIST})
|
||||
endfunc
|
||||
|
||||
func Test_quickfix_set_list_with_act()
|
||||
call XquickfixSetListWithAct('c')
|
||||
call XquickfixSetListWithAct('l')
|
||||
@@ -2132,6 +2137,8 @@ func Test_Autocmd()
|
||||
|
||||
call delete('Xtest')
|
||||
call delete('Xempty')
|
||||
au! QuickFixCmdPre
|
||||
au! QuickFixCmdPost
|
||||
endfunc
|
||||
|
||||
func Test_Autocmd_Exception()
|
||||
@@ -2896,7 +2903,8 @@ func Xgetlist_empty_tests(cchar)
|
||||
call assert_equal(0, g:Xgetlist({'size' : 0}).size)
|
||||
call assert_equal('', g:Xgetlist({'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'all' : 0}))
|
||||
call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick': 0}, g:Xgetlist({'all' : 0}))
|
||||
|
||||
" Empty quickfix list
|
||||
Xexpr ""
|
||||
@@ -2908,6 +2916,7 @@ func Xgetlist_empty_tests(cchar)
|
||||
call assert_equal(0, g:Xgetlist({'size' : 0}).size)
|
||||
call assert_notequal('', g:Xgetlist({'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
|
||||
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
|
||||
let qfid = g:Xgetlist({'id' : 0}).id
|
||||
call g:Xsetlist([], 'f')
|
||||
@@ -2921,7 +2930,8 @@ func Xgetlist_empty_tests(cchar)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
|
||||
call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
|
||||
call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
|
||||
|
||||
" Non-existing quickfix list number
|
||||
call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
|
||||
@@ -2932,10 +2942,166 @@ func Xgetlist_empty_tests(cchar)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
|
||||
call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0}))
|
||||
call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
|
||||
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0}))
|
||||
endfunc
|
||||
|
||||
func Test_getqflist()
|
||||
call Xgetlist_empty_tests('c')
|
||||
call Xgetlist_empty_tests('l')
|
||||
endfunc
|
||||
|
||||
func Test_getqflist_invalid_nr()
|
||||
" The following commands used to crash Vim
|
||||
cexpr ""
|
||||
call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
|
||||
|
||||
" Cleanup
|
||||
call setqflist([], 'r')
|
||||
endfunc
|
||||
|
||||
" Tests for the quickfix/location list changedtick
|
||||
func Xqftick_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
|
||||
Xexpr "F1:10:Line10"
|
||||
let qfid = g:Xgetlist({'id' : 0}).id
|
||||
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
Xaddexpr "F2:20:Line20\nF2:21:Line21"
|
||||
call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
|
||||
call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
|
||||
call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call g:Xsetlist([], 'a', {'title' : 'New Title'})
|
||||
call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
|
||||
enew!
|
||||
call append(0, ["F5:50:L50", "F6:60:L60"])
|
||||
Xaddbuffer
|
||||
call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
enew!
|
||||
|
||||
call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
|
||||
call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
|
||||
\ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
|
||||
call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
|
||||
\ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
|
||||
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
|
||||
\ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
|
||||
call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
|
||||
call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
|
||||
Xfile Xone
|
||||
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
Xaddfile Xone
|
||||
call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
|
||||
" Test case for updating a non-current quickfix list
|
||||
call g:Xsetlist([], 'f')
|
||||
Xexpr "F1:1:L1"
|
||||
Xexpr "F2:2:L2"
|
||||
call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
|
||||
call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
|
||||
call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
|
||||
|
||||
call delete("Xone")
|
||||
endfunc
|
||||
|
||||
func Test_qf_tick()
|
||||
call Xqftick_tests('c')
|
||||
call Xqftick_tests('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
|
||||
" marks the location list context as not in use and frees the context.
|
||||
func Test_ll_window_ctx()
|
||||
call setloclist(0, [], 'f')
|
||||
call setloclist(0, [], 'a', {'context' : []})
|
||||
lopen | only
|
||||
call test_garbagecollect_now()
|
||||
echo getloclist(0, {'context' : 1}).context
|
||||
enew | only
|
||||
endfunc
|
||||
|
||||
" The following test used to crash vim
|
||||
func Test_lfile_crash()
|
||||
sp Xtest
|
||||
au QuickFixCmdPre * bw
|
||||
call assert_fails('lfile', 'E40')
|
||||
au! QuickFixCmdPre
|
||||
endfunc
|
||||
|
||||
" The following test used to crash vim
|
||||
func Test_lbuffer_crash()
|
||||
sv Xtest
|
||||
augroup QF_Test
|
||||
au!
|
||||
au * * bw
|
||||
augroup END
|
||||
lbuffer
|
||||
augroup QF_Test
|
||||
au!
|
||||
augroup END
|
||||
endfunc
|
||||
|
||||
" The following test used to crash vim
|
||||
func Test_lexpr_crash()
|
||||
augroup QF_Test
|
||||
au!
|
||||
au * * call setloclist(0, [], 'f')
|
||||
augroup END
|
||||
lexpr ""
|
||||
augroup QF_Test
|
||||
au!
|
||||
augroup END
|
||||
enew | only
|
||||
endfunc
|
||||
|
||||
" The following test used to crash Vim
|
||||
func Test_lvimgrep_crash()
|
||||
sv Xtest
|
||||
augroup QF_Test
|
||||
au!
|
||||
au * * call setloclist(0, [], 'f')
|
||||
augroup END
|
||||
lvimgrep quickfix test_quickfix.vim
|
||||
augroup QF_Test
|
||||
au!
|
||||
augroup END
|
||||
enew | only
|
||||
endfunc
|
||||
|
||||
" Test for the position of the quickfix and location list window
|
||||
func Test_qfwin_pos()
|
||||
" Open two windows
|
||||
new | only
|
||||
new
|
||||
cexpr ['F1:10:L10']
|
||||
copen
|
||||
" Quickfix window should be the bottom most window
|
||||
call assert_equal(3, winnr())
|
||||
close
|
||||
" Open at the very top
|
||||
wincmd t
|
||||
topleft copen
|
||||
call assert_equal(1, winnr())
|
||||
close
|
||||
" open left of the current window
|
||||
wincmd t
|
||||
below new
|
||||
leftabove copen
|
||||
call assert_equal(2, winnr())
|
||||
close
|
||||
" open right of the current window
|
||||
rightbelow copen
|
||||
call assert_equal(3, winnr())
|
||||
close
|
||||
endfunc
|
||||
|
||||
@@ -729,3 +729,12 @@ func Test_look_behind()
|
||||
call search(getline("."))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_search_sentence()
|
||||
new
|
||||
" this used to cause a crash
|
||||
call assert_fails("/\\%')", 'E486')
|
||||
call assert_fails("/", 'E486')
|
||||
/\%'(
|
||||
/
|
||||
endfunc
|
||||
|
||||
@@ -28,6 +28,37 @@ func Test_wrap_search()
|
||||
set nospell
|
||||
endfunc
|
||||
|
||||
func Test_curswant()
|
||||
new
|
||||
call setline(1, ['Another plong line', 'abcdefghijklmnopq'])
|
||||
set spell wrapscan
|
||||
normal 0]s
|
||||
call assert_equal('plong', expand('<cword>'))
|
||||
normal j
|
||||
call assert_equal(9, getcurpos()[2])
|
||||
normal 0[s
|
||||
call assert_equal('plong', expand('<cword>'))
|
||||
normal j
|
||||
call assert_equal(9, getcurpos()[2])
|
||||
|
||||
normal 0]S
|
||||
call assert_equal('plong', expand('<cword>'))
|
||||
normal j
|
||||
call assert_equal(9, getcurpos()[2])
|
||||
normal 0[S
|
||||
call assert_equal('plong', expand('<cword>'))
|
||||
normal j
|
||||
call assert_equal(9, getcurpos()[2])
|
||||
|
||||
normal 1G0
|
||||
call assert_equal('plong', spellbadword()[0])
|
||||
normal j
|
||||
call assert_equal(9, getcurpos()[2])
|
||||
|
||||
bwipe!
|
||||
set nospell
|
||||
endfunc
|
||||
|
||||
func Test_z_equal_on_invalid_utf8_word()
|
||||
split
|
||||
set spell
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
" test 'taglist' function
|
||||
" test 'taglist' function and :tags command
|
||||
|
||||
func Test_taglist()
|
||||
call writefile([
|
||||
@@ -56,3 +56,8 @@ func Test_taglist_ctags_etags()
|
||||
|
||||
call delete('Xtags')
|
||||
endfunc
|
||||
|
||||
func Test_tags_too_long()
|
||||
call assert_fails('tag ' . repeat('x', 1020), 'E426')
|
||||
tags
|
||||
endfunc
|
||||
|
||||
@@ -122,7 +122,12 @@ func Test_paused()
|
||||
let slept = WaitFor('g:val == 1')
|
||||
call assert_equal(1, g:val)
|
||||
if has('reltime')
|
||||
call assert_inrange(0, 30, slept)
|
||||
if has('mac')
|
||||
" The travis Mac machines appear to be very busy.
|
||||
call assert_inrange(0, 40, slept)
|
||||
else
|
||||
call assert_inrange(0, 30, slept)
|
||||
endif
|
||||
else
|
||||
call assert_inrange(0, 10, slept)
|
||||
endif
|
||||
|
||||
@@ -206,3 +206,15 @@ func Test_CmdCompletion()
|
||||
com! -complete=customlist,CustomComp DoCmd :
|
||||
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
|
||||
endfunc
|
||||
|
||||
func CallExecute(A, L, P)
|
||||
" Drop first '\n'
|
||||
return execute('echo "hi"')[1:]
|
||||
endfunc
|
||||
|
||||
func Test_use_execute_in_completion()
|
||||
command! -nargs=* -complete=custom,CallExecute DoExec :
|
||||
call feedkeys(":DoExec \<C-A>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_equal('"DoExec hi', @:)
|
||||
delcommand DoExec
|
||||
endfunc
|
||||
|
||||
@@ -467,4 +467,9 @@ func Test_window_contents()
|
||||
call test_garbagecollect_now()
|
||||
endfunc
|
||||
|
||||
func Test_window_colon_command()
|
||||
" This was reading invalid memory.
|
||||
exe "norm! v\<C-W>:\<C-U>echo v:version"
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
57
src/ui.c
57
src/ui.c
@@ -32,7 +32,7 @@ ui_write(char_u *s, int len)
|
||||
{
|
||||
gui_write(s, len);
|
||||
if (p_wd)
|
||||
gui_wait_for_chars(p_wd);
|
||||
gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -182,18 +182,13 @@ ui_inchar(
|
||||
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use)
|
||||
{
|
||||
if (gui_wait_for_chars(wtime) && !typebuf_changed(tb_change_cnt))
|
||||
retval = read_from_input_buf(buf, (long)maxlen);
|
||||
}
|
||||
retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
|
||||
#endif
|
||||
#ifndef NO_CONSOLE
|
||||
# ifdef FEAT_GUI
|
||||
else
|
||||
# endif
|
||||
{
|
||||
retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wtime == -1 || wtime > 100L)
|
||||
@@ -212,6 +207,52 @@ theend:
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if defined(FEAT_TIMERS) || defined(PROT)
|
||||
/*
|
||||
* Wait for a timer to fire or "wait_func" to return non-zero.
|
||||
* Returns OK when something was read.
|
||||
* Returns FAIL when it timed out or was interrupted.
|
||||
*/
|
||||
int
|
||||
ui_wait_for_chars_or_timer(
|
||||
long wtime,
|
||||
int (*wait_func)(long wtime, int *interrupted, int ignore_input),
|
||||
int *interrupted,
|
||||
int ignore_input)
|
||||
{
|
||||
int due_time;
|
||||
long remaining = wtime;
|
||||
int tb_change_cnt = typebuf.tb_change_cnt;
|
||||
|
||||
/* When waiting very briefly don't trigger timers. */
|
||||
if (wtime >= 0 && wtime < 10L)
|
||||
return wait_func(wtime, NULL, ignore_input);
|
||||
|
||||
while (wtime < 0 || remaining > 0)
|
||||
{
|
||||
/* Trigger timers and then get the time in wtime until the next one is
|
||||
* due. Wait up to that time. */
|
||||
due_time = check_due_timer();
|
||||
if (typebuf.tb_change_cnt != tb_change_cnt)
|
||||
{
|
||||
/* timer may have used feedkeys() */
|
||||
return FAIL;
|
||||
}
|
||||
if (due_time <= 0 || (wtime > 0 && due_time > remaining))
|
||||
due_time = remaining;
|
||||
if (wait_func(due_time, interrupted, ignore_input))
|
||||
return OK;
|
||||
if (interrupted != NULL && *interrupted)
|
||||
/* Nothing available, but need to return so that side effects get
|
||||
* handled, such as handling a message on a channel. */
|
||||
return FALSE;
|
||||
if (wtime > 0)
|
||||
remaining -= due_time;
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* return non-zero if a character is available
|
||||
*/
|
||||
@@ -245,7 +286,7 @@ ui_delay(long msec, int ignoreinput)
|
||||
{
|
||||
#ifdef FEAT_GUI
|
||||
if (gui.in_use && !ignoreinput)
|
||||
gui_wait_for_chars(msec);
|
||||
gui_wait_for_chars(msec, typebuf.tb_change_cnt);
|
||||
else
|
||||
#endif
|
||||
mch_delay(msec, ignoreinput);
|
||||
|
||||
@@ -2972,6 +2972,9 @@ ex_return(exarg_T *eap)
|
||||
/* It's safer to return also on error. */
|
||||
else if (!eap->skip)
|
||||
{
|
||||
/* In return statement, cause_abort should be force_abort. */
|
||||
update_force_abort();
|
||||
|
||||
/*
|
||||
* Return unless the expression evaluation has been cancelled due to an
|
||||
* aborting error, an interrupt, or an exception.
|
||||
|
||||
@@ -771,6 +771,58 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1427,
|
||||
/**/
|
||||
1426,
|
||||
/**/
|
||||
1425,
|
||||
/**/
|
||||
1424,
|
||||
/**/
|
||||
1423,
|
||||
/**/
|
||||
1422,
|
||||
/**/
|
||||
1421,
|
||||
/**/
|
||||
1420,
|
||||
/**/
|
||||
1419,
|
||||
/**/
|
||||
1418,
|
||||
/**/
|
||||
1417,
|
||||
/**/
|
||||
1416,
|
||||
/**/
|
||||
1415,
|
||||
/**/
|
||||
1414,
|
||||
/**/
|
||||
1413,
|
||||
/**/
|
||||
1412,
|
||||
/**/
|
||||
1411,
|
||||
/**/
|
||||
1410,
|
||||
/**/
|
||||
1409,
|
||||
/**/
|
||||
1408,
|
||||
/**/
|
||||
1407,
|
||||
/**/
|
||||
1406,
|
||||
/**/
|
||||
1405,
|
||||
/**/
|
||||
1404,
|
||||
/**/
|
||||
1403,
|
||||
/**/
|
||||
1402,
|
||||
/**/
|
||||
1401,
|
||||
/**/
|
||||
|
||||
16
src/window.c
16
src/window.c
@@ -6081,7 +6081,6 @@ grab_file_name(long count, linenr_T *file_lnum)
|
||||
count, curbuf->b_ffname);
|
||||
}
|
||||
return file_name_at_cursor(options | FNAME_HYP, count, file_lnum);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6120,6 +6119,8 @@ file_name_in_line(
|
||||
{
|
||||
char_u *ptr;
|
||||
int len;
|
||||
int in_type = TRUE;
|
||||
int is_url = FALSE;
|
||||
|
||||
/*
|
||||
* search forward for what could be the start of a file name
|
||||
@@ -6158,8 +6159,19 @@ file_name_in_line(
|
||||
*/
|
||||
len = 0;
|
||||
while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ')
|
||||
|| ((options & FNAME_HYP) && path_is_url(ptr + len)))
|
||||
|| ((options & FNAME_HYP) && path_is_url(ptr + len))
|
||||
|| (is_url && vim_strchr((char_u *)"?&=", ptr[len]) != NULL))
|
||||
{
|
||||
/* After type:// we also include ?, & and = as valid characters, so that
|
||||
* http://google.com?q=this&that=ok works. */
|
||||
if ((ptr[len] >= 'A' && ptr[len] <= 'Z') || (ptr[len] >= 'a' && ptr[len] <= 'z'))
|
||||
{
|
||||
if (in_type && path_is_url(ptr + len + 1))
|
||||
is_url = TRUE;
|
||||
}
|
||||
else
|
||||
in_type = FALSE;
|
||||
|
||||
if (ptr[len] == '\\')
|
||||
/* Skip over the "\" in "\ ". */
|
||||
++len;
|
||||
|
||||
Reference in New Issue
Block a user