mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #9906 from janlazo/vim-8.0.0647
vim-patch:8.0.{647,768,797,1085,1092,1107,1133,1408}
This commit is contained in:
commit
24a9516ff4
@ -4528,10 +4528,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'redrawtime' 'rdt' number (default 2000)
|
||||
global
|
||||
Time in milliseconds for redrawing the display. Applies to
|
||||
'hlsearch', 'inccommand' and |:match| highlighting.
|
||||
'hlsearch', 'inccommand', |:match| highlighting and syntax
|
||||
highlighting.
|
||||
When redrawing takes more than this many milliseconds no further
|
||||
matches will be highlighted. This is used to avoid that Vim hangs
|
||||
when using a very complicated pattern.
|
||||
matches will be highlighted.
|
||||
For syntax highlighting the time applies per window. When over the
|
||||
limit syntax highlighting is disabled until |CTRL-L| is used.
|
||||
This is used to avoid that Vim hangs when using a very complicated
|
||||
pattern.
|
||||
|
||||
*'regexpengine'* *'re'*
|
||||
'regexpengine' 're' number (default 0)
|
||||
|
255
runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
vendored
255
runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
vendored
@ -25,32 +25,44 @@ endif
|
||||
command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>)
|
||||
|
||||
" Name of the gdb command, defaults to "gdb".
|
||||
if !exists('debugger')
|
||||
let debugger = 'gdb'
|
||||
if !exists('termdebugger')
|
||||
let termdebugger = 'gdb'
|
||||
endif
|
||||
|
||||
" Sign used to highlight the line where the program has stopped.
|
||||
sign define debugPC linehl=debugPC
|
||||
if &background == 'light'
|
||||
hi debugPC term=reverse ctermbg=lightblue guibg=lightblue
|
||||
else
|
||||
hi debugPC term=reverse ctermbg=darkblue guibg=darkblue
|
||||
endif
|
||||
let s:pc_id = 12
|
||||
let s:break_id = 13
|
||||
|
||||
if &background == 'light'
|
||||
hi default debugPC term=reverse ctermbg=lightblue guibg=lightblue
|
||||
else
|
||||
hi default debugPC term=reverse ctermbg=darkblue guibg=darkblue
|
||||
endif
|
||||
hi default debugBreakpoint term=reverse ctermbg=red guibg=red
|
||||
|
||||
func s:StartDebug(cmd)
|
||||
let s:startwin = win_getid(winnr())
|
||||
let s:startsigncolumn = &signcolumn
|
||||
|
||||
if exists('g:termdebug_wide') && &columns < g:termdebug_wide
|
||||
let s:save_columns = &columns
|
||||
let &columns = g:termdebug_wide
|
||||
let vertical = 1
|
||||
else
|
||||
let s:save_columns = 0
|
||||
let vertical = 0
|
||||
endif
|
||||
|
||||
" Open a terminal window without a job, to run the debugged program
|
||||
let s:ptybuf = term_start('NONE', {
|
||||
\ 'term_name': 'gdb program',
|
||||
\ 'vertical': vertical,
|
||||
\ })
|
||||
if s:ptybuf == 0
|
||||
echoerr 'Failed to open the program terminal window'
|
||||
return
|
||||
endif
|
||||
let pty = job_info(term_getjob(s:ptybuf))['tty_out']
|
||||
let s:ptywin = win_getid(winnr())
|
||||
|
||||
" Create a hidden terminal window to communicate with gdb
|
||||
let s:commbuf = term_start('NONE', {
|
||||
@ -66,7 +78,7 @@ func s:StartDebug(cmd)
|
||||
let commpty = job_info(term_getjob(s:commbuf))['tty_out']
|
||||
|
||||
" Open a terminal window to run the debugger.
|
||||
let cmd = [g:debugger, '-tty', pty, a:cmd]
|
||||
let cmd = [g:termdebugger, '-tty', pty, a:cmd]
|
||||
echomsg 'executing "' . join(cmd) . '"'
|
||||
let gdbbuf = term_start(cmd, {
|
||||
\ 'exit_cb': function('s:EndDebug'),
|
||||
@ -78,15 +90,41 @@ func s:StartDebug(cmd)
|
||||
exe 'bwipe! ' . s:commbuf
|
||||
return
|
||||
endif
|
||||
let s:gdbwin = win_getid(winnr())
|
||||
|
||||
" Connect gdb to the communication pty, using the GDB/MI interface
|
||||
call term_sendkeys(gdbbuf, 'new-ui mi ' . commpty . "\r")
|
||||
|
||||
" Sign used to highlight the line where the program has stopped.
|
||||
" There can be only one.
|
||||
sign define debugPC linehl=debugPC
|
||||
|
||||
" Sign used to indicate a breakpoint.
|
||||
" Can be used multiple times.
|
||||
sign define debugBreakpoint text=>> texthl=debugBreakpoint
|
||||
|
||||
" Install debugger commands in the text window.
|
||||
call win_gotoid(s:startwin)
|
||||
call s:InstallCommands()
|
||||
call win_gotoid(s:gdbwin)
|
||||
|
||||
let s:breakpoints = {}
|
||||
endfunc
|
||||
|
||||
func s:EndDebug(job, status)
|
||||
exe 'bwipe! ' . s:ptybuf
|
||||
exe 'bwipe! ' . s:commbuf
|
||||
call setwinvar(s:startwin, '&signcolumn', s:startsigncolumn)
|
||||
|
||||
let curwinid = win_getid(winnr())
|
||||
|
||||
call win_gotoid(s:startwin)
|
||||
let &signcolumn = s:startsigncolumn
|
||||
call s:DeleteCommands()
|
||||
|
||||
call win_gotoid(curwinid)
|
||||
if s:save_columns > 0
|
||||
let &columns = s:save_columns
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Handle a message received from gdb on the GDB/MI interface.
|
||||
@ -100,34 +138,175 @@ func s:CommOutput(chan, msg)
|
||||
endif
|
||||
if msg != ''
|
||||
if msg =~ '^\*\(stopped\|running\)'
|
||||
let wid = win_getid(winnr())
|
||||
|
||||
if win_gotoid(s:startwin)
|
||||
if msg =~ '^\*stopped'
|
||||
" TODO: proper parsing
|
||||
let fname = substitute(msg, '.*fullname="\([^"]*\)".*', '\1', '')
|
||||
let lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '')
|
||||
if lnum =~ '^[0-9]*$'
|
||||
if expand('%:h') != fname
|
||||
if &modified
|
||||
" TODO: find existing window
|
||||
exe 'split ' . fnameescape(fname)
|
||||
let s:startwin = win_getid(winnr())
|
||||
else
|
||||
exe 'edit ' . fnameescape(fname)
|
||||
endif
|
||||
endif
|
||||
exe lnum
|
||||
exe 'sign place ' . s:pc_id . ' line=' . lnum . ' name=debugPC file=' . fnameescape(fname)
|
||||
setlocal signcolumn=yes
|
||||
endif
|
||||
else
|
||||
exe 'sign unplace ' . s:pc_id
|
||||
endif
|
||||
|
||||
call win_gotoid(wid)
|
||||
endif
|
||||
call s:HandleCursor(msg)
|
||||
elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,'
|
||||
call s:HandleNewBreakpoint(msg)
|
||||
elseif msg =~ '^=breakpoint-deleted,'
|
||||
call s:HandleBreakpointDelete(msg)
|
||||
elseif msg =~ '^\^done,value='
|
||||
call s:HandleEvaluate(msg)
|
||||
elseif msg =~ '^\^error,msg='
|
||||
call s:HandleError(msg)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
" Install commands in the current window to control the debugger.
|
||||
func s:InstallCommands()
|
||||
command Break call s:SetBreakpoint()
|
||||
command Delete call s:DeleteBreakpoint()
|
||||
command Step call s:SendCommand('-exec-step')
|
||||
command Over call s:SendCommand('-exec-next')
|
||||
command Finish call s:SendCommand('-exec-finish')
|
||||
command Continue call s:SendCommand('-exec-continue')
|
||||
command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
|
||||
command Gdb call win_gotoid(s:gdbwin)
|
||||
command Program call win_gotoid(s:ptywin)
|
||||
|
||||
" TODO: can the K mapping be restored?
|
||||
nnoremap K :Evaluate<CR>
|
||||
endfunc
|
||||
|
||||
" Delete installed debugger commands in the current window.
|
||||
func s:DeleteCommands()
|
||||
delcommand Break
|
||||
delcommand Delete
|
||||
delcommand Step
|
||||
delcommand Over
|
||||
delcommand Finish
|
||||
delcommand Continue
|
||||
delcommand Evaluate
|
||||
delcommand Gdb
|
||||
delcommand Program
|
||||
|
||||
nunmap K
|
||||
exe 'sign unplace ' . s:pc_id
|
||||
for key in keys(s:breakpoints)
|
||||
exe 'sign unplace ' . (s:break_id + key)
|
||||
endfor
|
||||
sign undefine debugPC
|
||||
sign undefine debugBreakpoint
|
||||
unlet s:breakpoints
|
||||
endfunc
|
||||
|
||||
" :Break - Set a breakpoint at the cursor position.
|
||||
func s:SetBreakpoint()
|
||||
call term_sendkeys(s:commbuf, '-break-insert --source '
|
||||
\ . fnameescape(expand('%:p')) . ' --line ' . line('.') . "\r")
|
||||
endfunc
|
||||
|
||||
" :Delete - Delete a breakpoint at the cursor position.
|
||||
func s:DeleteBreakpoint()
|
||||
let fname = fnameescape(expand('%:p'))
|
||||
let lnum = line('.')
|
||||
for [key, val] in items(s:breakpoints)
|
||||
if val['fname'] == fname && val['lnum'] == lnum
|
||||
call term_sendkeys(s:commbuf, '-break-delete ' . key . "\r")
|
||||
" Assume this always wors, the reply is simply "^done".
|
||||
exe 'sign unplace ' . (s:break_id + key)
|
||||
unlet s:breakpoints[key]
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
" :Next, :Continue, etc - send a command to gdb
|
||||
func s:SendCommand(cmd)
|
||||
call term_sendkeys(s:commbuf, a:cmd . "\r")
|
||||
endfunc
|
||||
|
||||
" :Evaluate - evaluate what is under the cursor
|
||||
func s:Evaluate(range, arg)
|
||||
if a:arg != ''
|
||||
let expr = a:arg
|
||||
elseif a:range == 2
|
||||
let pos = getcurpos()
|
||||
let reg = getreg('v', 1, 1)
|
||||
let regt = getregtype('v')
|
||||
normal! gv"vy
|
||||
let expr = @v
|
||||
call setpos('.', pos)
|
||||
call setreg('v', reg, regt)
|
||||
else
|
||||
let expr = expand('<cexpr>')
|
||||
endif
|
||||
call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . expr . "\"\r")
|
||||
let s:evalexpr = expr
|
||||
endfunc
|
||||
|
||||
" Handle the result of data-evaluate-expression
|
||||
func s:HandleEvaluate(msg)
|
||||
echomsg '"' . s:evalexpr . '": ' . substitute(a:msg, '.*value="\(.*\)"', '\1', '')
|
||||
endfunc
|
||||
|
||||
" Handle an error.
|
||||
func s:HandleError(msg)
|
||||
echoerr substitute(a:msg, '.*msg="\(.*\)"', '\1', '')
|
||||
endfunc
|
||||
|
||||
" Handle stopping and running message from gdb.
|
||||
" Will update the sign that shows the current position.
|
||||
func s:HandleCursor(msg)
|
||||
let wid = win_getid(winnr())
|
||||
|
||||
if win_gotoid(s:startwin)
|
||||
let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '')
|
||||
if a:msg =~ '^\*stopped' && filereadable(fname)
|
||||
let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '')
|
||||
if lnum =~ '^[0-9]*$'
|
||||
if expand('%:h') != fname
|
||||
if &modified
|
||||
" TODO: find existing window
|
||||
exe 'split ' . fnameescape(fname)
|
||||
let s:startwin = win_getid(winnr())
|
||||
else
|
||||
exe 'edit ' . fnameescape(fname)
|
||||
endif
|
||||
endif
|
||||
exe lnum
|
||||
exe 'sign place ' . s:pc_id . ' line=' . lnum . ' name=debugPC file=' . fnameescape(fname)
|
||||
setlocal signcolumn=yes
|
||||
endif
|
||||
else
|
||||
exe 'sign unplace ' . s:pc_id
|
||||
endif
|
||||
|
||||
call win_gotoid(wid)
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Handle setting a breakpoint
|
||||
" Will update the sign that shows the breakpoint
|
||||
func s:HandleNewBreakpoint(msg)
|
||||
let nr = substitute(a:msg, '.*number="\([0-9]\)*\".*', '\1', '') + 0
|
||||
if nr == 0
|
||||
return
|
||||
endif
|
||||
|
||||
if has_key(s:breakpoints, nr)
|
||||
let entry = s:breakpoints[nr]
|
||||
else
|
||||
let entry = {}
|
||||
let s:breakpoints[nr] = entry
|
||||
endif
|
||||
|
||||
let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '')
|
||||
let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '')
|
||||
|
||||
exe 'sign place ' . (s:break_id + nr) . ' line=' . lnum . ' name=debugBreakpoint file=' . fnameescape(fname)
|
||||
|
||||
let entry['fname'] = fname
|
||||
let entry['lnum'] = lnum
|
||||
endfunc
|
||||
|
||||
" Handle deleting a breakpoint
|
||||
" Will remove the sign that shows the breakpoint
|
||||
func s:HandleBreakpointDelete(msg)
|
||||
let nr = substitute(a:msg, '.*id="\([0-9]*\)\".*', '\1', '') + 0
|
||||
if nr == 0
|
||||
return
|
||||
endif
|
||||
exe 'sign unplace ' . (s:break_id + nr)
|
||||
unlet s:breakpoints[nr]
|
||||
endfunc
|
||||
|
@ -5211,8 +5211,8 @@ char_u *buf_spname(buf_T *buf)
|
||||
return (char_u *)_(msg_qflist);
|
||||
}
|
||||
}
|
||||
/* There is no _file_ when 'buftype' is "nofile", b_sfname
|
||||
* contains the name as specified by the user */
|
||||
// There is no _file_ when 'buftype' is "nofile", b_sfname
|
||||
// contains the name as specified by the user.
|
||||
if (bt_nofile(buf)) {
|
||||
if (buf->b_sfname != NULL) {
|
||||
return buf->b_sfname;
|
||||
|
@ -388,24 +388,25 @@ typedef struct {
|
||||
* a window may have its own instance.
|
||||
*/
|
||||
typedef struct {
|
||||
hashtab_T b_keywtab; /* syntax keywords hash table */
|
||||
hashtab_T b_keywtab_ic; /* idem, ignore case */
|
||||
int b_syn_error; /* TRUE when error occurred in HL */
|
||||
int b_syn_ic; /* ignore case for :syn cmds */
|
||||
int b_syn_spell; /* SYNSPL_ values */
|
||||
garray_T b_syn_patterns; /* table for syntax patterns */
|
||||
garray_T b_syn_clusters; /* table for syntax clusters */
|
||||
int b_spell_cluster_id; /* @Spell cluster ID or 0 */
|
||||
int b_nospell_cluster_id; /* @NoSpell cluster ID or 0 */
|
||||
int b_syn_containedin; /* TRUE when there is an item with a
|
||||
"containedin" argument */
|
||||
int b_syn_sync_flags; /* flags about how to sync */
|
||||
short b_syn_sync_id; /* group to sync on */
|
||||
long b_syn_sync_minlines; /* minimal sync lines offset */
|
||||
long b_syn_sync_maxlines; /* maximal sync lines offset */
|
||||
long b_syn_sync_linebreaks; /* offset for multi-line pattern */
|
||||
char_u *b_syn_linecont_pat; /* line continuation pattern */
|
||||
regprog_T *b_syn_linecont_prog; /* line continuation program */
|
||||
hashtab_T b_keywtab; // syntax keywords hash table
|
||||
hashtab_T b_keywtab_ic; // idem, ignore case
|
||||
int b_syn_error; // TRUE when error occurred in HL
|
||||
bool b_syn_slow; // true when 'redrawtime' reached
|
||||
int b_syn_ic; // ignore case for :syn cmds
|
||||
int b_syn_spell; // SYNSPL_ values
|
||||
garray_T b_syn_patterns; // table for syntax patterns
|
||||
garray_T b_syn_clusters; // table for syntax clusters
|
||||
int b_spell_cluster_id; // @Spell cluster ID or 0
|
||||
int b_nospell_cluster_id; // @NoSpell cluster ID or 0
|
||||
int b_syn_containedin; // TRUE when there is an item with a
|
||||
// "containedin" argument
|
||||
int b_syn_sync_flags; // flags about how to sync
|
||||
int16_t b_syn_sync_id; // group to sync on
|
||||
long b_syn_sync_minlines; // minimal sync lines offset
|
||||
long b_syn_sync_maxlines; // maximal sync lines offset
|
||||
long b_syn_sync_linebreaks; // offset for multi-line pattern
|
||||
char_u *b_syn_linecont_pat; // line continuation pattern
|
||||
regprog_T *b_syn_linecont_prog; // line continuation program
|
||||
syn_time_T b_syn_linecont_time;
|
||||
int b_syn_linecont_ic; /* ignore-case flag for above */
|
||||
int b_syn_topgrp; /* for ":syntax include" */
|
||||
|
@ -4642,6 +4642,9 @@ static void nv_clear(cmdarg_T *cap)
|
||||
if (!checkclearop(cap->oap)) {
|
||||
/* Clear all syntax states to force resyncing. */
|
||||
syn_stack_free_all(curwin->w_s);
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
wp->w_s->b_syn_slow = false;
|
||||
}
|
||||
redraw_later(CLEAR);
|
||||
}
|
||||
}
|
||||
|
@ -5098,8 +5098,6 @@ static int regmatch(
|
||||
printf("Premature EOL\n");
|
||||
#endif
|
||||
}
|
||||
if (status == RA_FAIL)
|
||||
got_int = TRUE;
|
||||
return status == RA_MATCH;
|
||||
}
|
||||
|
||||
@ -7226,7 +7224,8 @@ static void report_re_switch(char_u *pat)
|
||||
/// @param nl
|
||||
///
|
||||
/// @return TRUE if there is a match, FALSE if not.
|
||||
static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
|
||||
static int vim_regexec_string(regmatch_T *rmp, char_u *line, colnr_T col,
|
||||
bool nl)
|
||||
{
|
||||
regexec_T rex_save;
|
||||
bool rex_in_use_save = rex_in_use;
|
||||
@ -7275,8 +7274,8 @@ static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
|
||||
int vim_regexec_prog(regprog_T **prog, bool ignore_case, char_u *line,
|
||||
colnr_T col)
|
||||
{
|
||||
regmatch_T regmatch = {.regprog = *prog, .rm_ic = ignore_case};
|
||||
int r = vim_regexec_both(®match, line, col, false);
|
||||
regmatch_T regmatch = { .regprog = *prog, .rm_ic = ignore_case };
|
||||
int r = vim_regexec_string(®match, line, col, false);
|
||||
*prog = regmatch.regprog;
|
||||
return r;
|
||||
}
|
||||
@ -7285,7 +7284,7 @@ int vim_regexec_prog(regprog_T **prog, bool ignore_case, char_u *line,
|
||||
// Return TRUE if there is a match, FALSE if not.
|
||||
int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col)
|
||||
{
|
||||
return vim_regexec_both(rmp, line, col, false);
|
||||
return vim_regexec_string(rmp, line, col, false);
|
||||
}
|
||||
|
||||
// Like vim_regexec(), but consider a "\n" in "line" to be a line break.
|
||||
@ -7293,7 +7292,7 @@ int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col)
|
||||
// Return TRUE if there is a match, FALSE if not.
|
||||
int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
|
||||
{
|
||||
return vim_regexec_both(rmp, line, col, true);
|
||||
return vim_regexec_string(rmp, line, col, true);
|
||||
}
|
||||
|
||||
/// Match a regexp against multiple lines.
|
||||
|
@ -1135,6 +1135,9 @@ static void win_update(win_T *wp)
|
||||
/* reset got_int, otherwise regexp won't work */
|
||||
save_got_int = got_int;
|
||||
got_int = 0;
|
||||
// Set the time limit to 'redrawtime'.
|
||||
proftime_T syntax_tm = profile_setlimit(p_rdt);
|
||||
syn_set_timeout(&syntax_tm);
|
||||
win_foldinfo.fi_level = 0;
|
||||
|
||||
/*
|
||||
@ -1493,6 +1496,7 @@ static void win_update(win_T *wp)
|
||||
if (wp->w_redr_type >= REDRAW_TOP) {
|
||||
draw_vsep_win(wp, 0);
|
||||
}
|
||||
syn_set_timeout(NULL);
|
||||
|
||||
/* Reset the type of redrawing required, the window has been updated. */
|
||||
wp->w_redr_type = 0;
|
||||
@ -2189,7 +2193,7 @@ win_line (
|
||||
// To speed up the loop below, set extra_check when there is linebreak,
|
||||
// trailing white space and/or syntax processing to be done.
|
||||
extra_check = wp->w_p_lbr;
|
||||
if (syntax_present(wp) && !wp->w_s->b_syn_error) {
|
||||
if (syntax_present(wp) && !wp->w_s->b_syn_error && !wp->w_s->b_syn_slow) {
|
||||
// Prepare for syntax highlighting in this line. When there is an
|
||||
// error, stop syntax highlighting.
|
||||
save_did_emsg = did_emsg;
|
||||
@ -2199,8 +2203,10 @@ win_line (
|
||||
wp->w_s->b_syn_error = true;
|
||||
} else {
|
||||
did_emsg = save_did_emsg;
|
||||
has_syntax = true;
|
||||
extra_check = true;
|
||||
if (!wp->w_s->b_syn_slow) {
|
||||
has_syntax = true;
|
||||
extra_check = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2539,9 +2545,10 @@ win_line (
|
||||
}
|
||||
wp->w_cursor = pos;
|
||||
|
||||
/* Need to restart syntax highlighting for this line. */
|
||||
if (has_syntax)
|
||||
// Need to restart syntax highlighting for this line.
|
||||
if (has_syntax) {
|
||||
syntax_start(wp, lnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2587,6 +2594,9 @@ win_line (
|
||||
}
|
||||
next_search_hl(wp, shl, lnum, (colnr_T)v,
|
||||
shl == &search_hl ? NULL : cur);
|
||||
if (wp->w_s->b_syn_slow) {
|
||||
has_syntax = false;
|
||||
}
|
||||
|
||||
// Need to get the line again, a multi-line regexp may have made it
|
||||
// invalid.
|
||||
@ -4821,13 +4831,13 @@ static void win_redr_status(win_T *wp)
|
||||
p = NameBuff;
|
||||
len = (int)STRLEN(p);
|
||||
|
||||
if (wp->w_buffer->b_help
|
||||
if (bt_help(wp->w_buffer)
|
||||
|| wp->w_p_pvw
|
||||
|| bufIsChanged(wp->w_buffer)
|
||||
|| wp->w_buffer->b_p_ro) {
|
||||
*(p + len++) = ' ';
|
||||
}
|
||||
if (wp->w_buffer->b_help) {
|
||||
if (bt_help(wp->w_buffer)) {
|
||||
STRCPY(p + len, _("[Help]"));
|
||||
len += (int)STRLEN(p + len);
|
||||
}
|
||||
|
@ -356,15 +356,16 @@ static reg_extmatch_T *next_match_extmatch = NULL;
|
||||
* The current state (within the line) of the recognition engine.
|
||||
* When current_state.ga_itemsize is 0 the current state is invalid.
|
||||
*/
|
||||
static win_T *syn_win; /* current window for highlighting */
|
||||
static buf_T *syn_buf; /* current buffer for highlighting */
|
||||
static synblock_T *syn_block; /* current buffer for highlighting */
|
||||
static linenr_T current_lnum = 0; /* lnum of current state */
|
||||
static colnr_T current_col = 0; /* column of current state */
|
||||
static int current_state_stored = 0; /* TRUE if stored current state
|
||||
* after setting current_finished */
|
||||
static int current_finished = 0; /* current line has been finished */
|
||||
static garray_T current_state /* current stack of state_items */
|
||||
static win_T *syn_win; // current window for highlighting
|
||||
static buf_T *syn_buf; // current buffer for highlighting
|
||||
static synblock_T *syn_block; // current buffer for highlighting
|
||||
static proftime_T *syn_tm; // timeout limit
|
||||
static linenr_T current_lnum = 0; // lnum of current state
|
||||
static colnr_T current_col = 0; // column of current state
|
||||
static int current_state_stored = 0; // TRUE if stored current state
|
||||
// after setting current_finished
|
||||
static int current_finished = 0; // current line has been finished
|
||||
static garray_T current_state // current stack of state_items
|
||||
= GA_EMPTY_INIT_VALUE;
|
||||
static int16_t *current_next_list = NULL; // when non-zero, nextgroup list
|
||||
static int current_next_flags = 0; // flags for current_next_list
|
||||
@ -375,7 +376,12 @@ static int current_line_id = 0; // unique number for current line
|
||||
static int syn_time_on = FALSE;
|
||||
# define IF_SYN_TIME(p) (p)
|
||||
|
||||
|
||||
// Set the timeout used for syntax highlighting.
|
||||
// Use NULL to reset, no timeout.
|
||||
void syn_set_timeout(proftime_T *tm)
|
||||
{
|
||||
syn_tm = tm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the syntax recognition for a line. This function is normally called
|
||||
@ -2887,6 +2893,7 @@ static char_u *syn_getcurline(void)
|
||||
static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T *st)
|
||||
{
|
||||
int r;
|
||||
int timed_out = 0;
|
||||
proftime_T pt;
|
||||
const int l_syn_time_on = syn_time_on;
|
||||
|
||||
@ -2902,7 +2909,8 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
|
||||
}
|
||||
|
||||
rmp->rmm_maxcol = syn_buf->b_p_smc;
|
||||
r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL, NULL);
|
||||
r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col,
|
||||
syn_tm, &timed_out);
|
||||
|
||||
if (l_syn_time_on) {
|
||||
pt = profile_end(pt);
|
||||
@ -2914,6 +2922,9 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
|
||||
if (r > 0)
|
||||
++st->match;
|
||||
}
|
||||
if (timed_out) {
|
||||
syn_win->w_s->b_syn_slow = true;
|
||||
}
|
||||
|
||||
if (r > 0) {
|
||||
rmp->startpos[0].lnum += lnum;
|
||||
@ -3144,6 +3155,7 @@ static void syn_cmd_iskeyword(exarg_T *eap, int syncing)
|
||||
void syntax_clear(synblock_T *block)
|
||||
{
|
||||
block->b_syn_error = false; // clear previous error
|
||||
block->b_syn_slow = false; // clear previous timeout
|
||||
block->b_syn_ic = false; // Use case, by default
|
||||
block->b_syn_spell = SYNSPL_DEFAULT; // default spell checking
|
||||
block->b_syn_containedin = false;
|
||||
@ -5756,8 +5768,10 @@ int syn_get_foldlevel(win_T *wp, long lnum)
|
||||
{
|
||||
int level = 0;
|
||||
|
||||
/* Return quickly when there are no fold items at all. */
|
||||
if (wp->w_s->b_syn_folditems != 0) {
|
||||
// Return quickly when there are no fold items at all.
|
||||
if (wp->w_s->b_syn_folditems != 0
|
||||
&& !wp->w_s->b_syn_error
|
||||
&& !wp->w_s->b_syn_slow) {
|
||||
syntax_start(wp, lnum);
|
||||
|
||||
for (int i = 0; i < current_state.ga_len; ++i) {
|
||||
|
@ -1379,6 +1379,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')
|
||||
@ -2649,6 +2654,15 @@ func Test_qf_id()
|
||||
call Xqfid_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
|
||||
|
||||
" Test for shortening/simplifying the file name when opening the
|
||||
" quickfix window or when displaying the quickfix list
|
||||
func Test_shorten_fname()
|
||||
|
@ -503,3 +503,37 @@ func Test_syn_wrong_z_one()
|
||||
" call test_override("ALL", 0)
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_syntax_hangs()
|
||||
if !has('reltime') || !has('float') || !has('syntax')
|
||||
return
|
||||
endif
|
||||
|
||||
" This pattern takes a long time to match, it should timeout.
|
||||
new
|
||||
call setline(1, ['aaa', repeat('abc ', 1000), 'ccc'])
|
||||
let start = reltime()
|
||||
set nolazyredraw redrawtime=101
|
||||
syn match Error /\%#=1a*.*X\@<=b*/
|
||||
redraw
|
||||
let elapsed = reltimefloat(reltime(start))
|
||||
call assert_true(elapsed > 0.1)
|
||||
call assert_true(elapsed < 1.0)
|
||||
|
||||
" second time syntax HL is disabled
|
||||
let start = reltime()
|
||||
redraw
|
||||
let elapsed = reltimefloat(reltime(start))
|
||||
call assert_true(elapsed < 0.1)
|
||||
|
||||
" after CTRL-L the timeout flag is reset
|
||||
let start = reltime()
|
||||
exe "normal \<C-L>"
|
||||
redraw
|
||||
let elapsed = reltimefloat(reltime(start))
|
||||
call assert_true(elapsed > 0.1)
|
||||
call assert_true(elapsed < 1.0)
|
||||
|
||||
set redrawtime&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
Loading…
Reference in New Issue
Block a user