mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-07 15:37:14 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -830,6 +830,11 @@ Also see |`=|.
|
||||
Note: these are typed literally, they are not special keys!
|
||||
<cword> is replaced with the word under the cursor (like |star|)
|
||||
<cWORD> is replaced with the WORD under the cursor (see |WORD|)
|
||||
<cexpr> is replaced with the word under the cursor, including more
|
||||
to form a C expression. E.g., when the cursor is on "arg"
|
||||
of "ptr->arg" then the result is "ptr->arg"; when the
|
||||
cursor is on "]" of "list[idx]" then the result is
|
||||
"list[idx]". This is used for |v:beval_text|.
|
||||
<cfile> is replaced with the path name under the cursor (like what
|
||||
|gf| uses)
|
||||
<afile> When executing autocommands, is replaced with the file name
|
||||
|
||||
+20
-17
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Aug 13
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Sep 11
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1449,7 +1449,7 @@ v:beval_text The text under or after the mouse pointer. Usually a word as
|
||||
but a dot and "->" before the position is included. When on a
|
||||
']' the text before it is used, including the matching '[' and
|
||||
word before it. When on a Visual area within one line the
|
||||
highlighted text is used.
|
||||
highlighted text is used. Also see |<cexpr>|.
|
||||
Only valid while evaluating the 'balloonexpr' option.
|
||||
|
||||
*v:beval_winnr* *beval_winnr-variable*
|
||||
@@ -3301,7 +3301,7 @@ 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
|
||||
occurences of {expr} is returned.
|
||||
occurrences of {expr} is returned.
|
||||
|
||||
|
||||
*cscope_connection()*
|
||||
@@ -3467,7 +3467,7 @@ escape({string}, {chars}) *escape()*
|
||||
:echo escape('c:\program files\vim', ' \')
|
||||
< results in: >
|
||||
c:\\program\ files\\vim
|
||||
< Also see |shellescape()|.
|
||||
< Also see |shellescape()| and |fnameescape()|.
|
||||
|
||||
*eval()*
|
||||
eval({string}) Evaluate {string} and return the result. Especially useful to
|
||||
@@ -3887,7 +3887,7 @@ float2nr({expr}) *float2nr()*
|
||||
When the value of {expr} is out of range for a |Number| the
|
||||
result is truncated to 0x7fffffff or -0x7fffffff (or when
|
||||
64-bit Number support is enabled, 0x7fffffffffffffff or
|
||||
-0x7fffffffffffffff. NaN results in -0x80000000 (or when
|
||||
-0x7fffffffffffffff). NaN results in -0x80000000 (or when
|
||||
64-bit Number support is enabled, -0x8000000000000000).
|
||||
Examples: >
|
||||
echo float2nr(3.95)
|
||||
@@ -4657,12 +4657,12 @@ getqflist([{what}]) *getqflist()*
|
||||
If "nr" is not present then the current quickfix list is used.
|
||||
If both "nr" and a non-zero "id" are specified, then the list
|
||||
specified by "id" is used.
|
||||
To get the number of lists in the quickfix stack, set 'nr' to
|
||||
'$' in {what}. The 'nr' value in the returned dictionary
|
||||
To get the number of lists in the quickfix stack, set "nr" to
|
||||
"$" in {what}. The "nr" value in the returned dictionary
|
||||
contains the quickfix stack size.
|
||||
When 'text' is specified, all the other items are ignored. The
|
||||
returned dictionary contains the entry 'items' with the list
|
||||
of entries.
|
||||
When "lines" is specified, all the other items except "efm"
|
||||
are ignored. The returned dictionary contains the entry
|
||||
"items" with the list of entries.
|
||||
In case of error processing {what}, an empty dictionary is
|
||||
returned.
|
||||
|
||||
@@ -6967,6 +6967,7 @@ setline({lnum}, {text}) *setline()*
|
||||
:for [n, l] in [[5, 'aaa'], [6, 'bbb'], [7, 'ccc']]
|
||||
: call setline(n, l)
|
||||
:endfor
|
||||
|
||||
< Note: The '[ and '] marks are not set.
|
||||
|
||||
setloclist({nr}, {list}[, {action}[, {what}]]) *setloclist()*
|
||||
@@ -7164,16 +7165,17 @@ setreg({regname}, {value} [, {options}])
|
||||
:call setreg('a', "1\n2\n3", 'b5')
|
||||
|
||||
< This example shows using the functions to save and restore a
|
||||
register (note: you may not reliably restore register value
|
||||
without using the third argument to |getreg()| as without it
|
||||
newlines are represented as newlines AND Nul bytes are
|
||||
represented as newlines as well, see |NL-used-for-Nul|). >
|
||||
register: >
|
||||
:let var_a = getreg('a', 1, 1)
|
||||
:let var_amode = getregtype('a')
|
||||
....
|
||||
:call setreg('a', var_a, var_amode)
|
||||
< Note: you may not reliably restore register value
|
||||
without using the third argument to |getreg()| as without it
|
||||
newlines are represented as newlines AND Nul bytes are
|
||||
represented as newlines as well, see |NL-used-for-Nul|.
|
||||
|
||||
< You can also change the type of a register by appending
|
||||
You can also change the type of a register by appending
|
||||
nothing: >
|
||||
:call setreg('a', '', 'al')
|
||||
|
||||
@@ -8145,7 +8147,7 @@ term_start({cmd}, {options}) *term_start()*
|
||||
are supported:
|
||||
all timeout options
|
||||
"stoponexit"
|
||||
"out_cb", "err_cb"
|
||||
"callback", "out_cb", "err_cb"
|
||||
"exit_cb", "close_cb"
|
||||
"in_io", "in_top", "in_bot", "in_name", "in_buf"
|
||||
"out_io", "out_name", "out_buf", "out_modifiable", "out_msg"
|
||||
@@ -8165,6 +8167,7 @@ term_start({cmd}, {options}) *term_start()*
|
||||
"curwin" use the current window, do not split the
|
||||
window; fails if the current buffer
|
||||
cannot be |abandon|ed
|
||||
"hidden" do not open a window
|
||||
"term_finish" What to do when the job is finished:
|
||||
"close": close any windows
|
||||
"open": open window if needed
|
||||
@@ -8562,7 +8565,7 @@ win_getid([{win} [, {tab}]]) *win_getid()*
|
||||
Get the |window-ID| for the specified window.
|
||||
When {win} is missing use the current window.
|
||||
With {win} this is the window number. The top window has
|
||||
number 1.
|
||||
number 1. Use `win_getid(winnr())` for the current window.
|
||||
Without {tab} use the current tab, otherwise the tab with
|
||||
number {tab}. The first tab has number one.
|
||||
Return zero if the window cannot be found.
|
||||
|
||||
@@ -1415,6 +1415,8 @@ The valid escape sequences are
|
||||
<line1> The starting line of the command range.
|
||||
*<line2>*
|
||||
<line2> The final line of the command range.
|
||||
*<range>*
|
||||
<range> The number of items in the command range: 0, 1 or 2
|
||||
*<count>*
|
||||
<count> Any count supplied (as described for the '-range'
|
||||
and '-count' attributes).
|
||||
|
||||
@@ -44,6 +44,18 @@ From inside Vim an easy way to run a command and handle the output is with the
|
||||
The 'errorformat' option should be set to match the error messages from your
|
||||
compiler (see |errorformat| below).
|
||||
|
||||
*quickfix-ID*
|
||||
Each quickfix list has a unique identifier called the quickfix ID and this
|
||||
number will not change within a Vim session. The getqflist() function can be
|
||||
used to get the identifier assigned to a list.
|
||||
|
||||
*quickfix-ID*
|
||||
Each quickfix list has a unique identifier called the quickfix ID and this
|
||||
number will not change within a Vim session. The getqflist() function can be
|
||||
used to get the identifier assigned to a list. There is also a quickfix list
|
||||
number which may change whenever more than ten lists are added to a quickfix
|
||||
stack.
|
||||
|
||||
*location-list* *E776*
|
||||
A location list is a window-local quickfix list. You get one after commands
|
||||
like `:lvimgrep`, `:lgrep`, `:lhelpgrep`, `:lmake`, etc., which create a
|
||||
|
||||
+95
-22
@@ -1,4 +1,4 @@
|
||||
*terminal.txt* For Vim version 8.0. Last change: 2017 Aug 29
|
||||
*terminal.txt* For Vim version 8.0. Last change: 2017 Sep 10
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -30,11 +30,11 @@ This feature is for running a terminal emulator in a Vim window. A job can be
|
||||
started connected to the terminal emulator. For example, to run a shell: >
|
||||
:term bash
|
||||
|
||||
Or to run a debugger: >
|
||||
:term gdb vim
|
||||
Or to run build command: >
|
||||
:term make myprogram
|
||||
|
||||
The job runs asynchronously from Vim, the window will be updated to show
|
||||
output from the job, also while editing in any other window.
|
||||
output from the job, also while editing in another window.
|
||||
|
||||
|
||||
Typing ~
|
||||
@@ -109,7 +109,8 @@ Syntax ~
|
||||
|
||||
If [range] is given the specified lines are used as
|
||||
input for the job. It will not be possible to type
|
||||
keys in the terminal window.
|
||||
keys in the terminal window. For MS-Windows see the
|
||||
++eof argument below.
|
||||
|
||||
Two comma separated numbers are used as "rows,cols".
|
||||
E.g. `:24,80gdb` opens a terminal with 24 rows and 80
|
||||
@@ -133,14 +134,15 @@ Syntax ~
|
||||
height.
|
||||
++cols={width} Use {width} for the terminal window
|
||||
width.
|
||||
++eof={text} when using [range], text to send after
|
||||
the last line was written. The default
|
||||
is to send CTRL-D. A CR is appended.
|
||||
++eof={text} when using [range]: text to send after
|
||||
the last line was written. Cannot
|
||||
contain white space. A CR is
|
||||
appended. For MS-Windows the default
|
||||
is to send CTRL-D.
|
||||
E.g. for a shell use "++eof=exit" and
|
||||
for Python "++eof=exit()". Special
|
||||
codes can be used like with `:map`,
|
||||
e.g. "<C-Z>" for CTRL-Z.
|
||||
{only on MS-Windows}
|
||||
|
||||
If you want to use more options use the |term_start()|
|
||||
function.
|
||||
@@ -303,33 +305,104 @@ term_scrape() inspect terminal screen
|
||||
3. Debugging *terminal-debug*
|
||||
|
||||
The Terminal debugging plugin can be used to debug a program with gdb and view
|
||||
the source code in a Vim window.
|
||||
the source code in a Vim window. Since this is completely contained inside
|
||||
Vim this also works remotely over an ssh connection.
|
||||
|
||||
|
||||
Starting ~
|
||||
|
||||
Load the plugin with this command: >
|
||||
packadd termdebug
|
||||
|
||||
< *:Termdebug*
|
||||
To start debugging use `:TermDebug` folowed by the command name, for example: >
|
||||
:TermDebug vim
|
||||
|
||||
This opens two windows:
|
||||
- A terminal window in which "gdb vim" is executed. Here you can directly
|
||||
interact with gdb.
|
||||
- A terminal window for the executed program. When "run" is used in gdb the
|
||||
program I/O will happen in this window, so that it does not interfere with
|
||||
controlling gdb.
|
||||
The current window is used to show the source code. When gdb jumps to a
|
||||
source file location this window will display the code, if possible. Values
|
||||
of variables can be inspected, breakpoints set and cleared, etc.
|
||||
gdb window A terminal window in which "gdb vim" is executed. Here you
|
||||
can directly interact with gdb. The buffer name is "!gdb".
|
||||
program window A terminal window for the executed program. When "run" is
|
||||
used in gdb the program I/O will happen in this window, so
|
||||
that it does not interfere with controlling gdb. The buffer
|
||||
name is "gdb program".
|
||||
|
||||
When the debugger ends the two opened windows are closed.
|
||||
The current window is used to show the source code. When gdb pauses the
|
||||
source file location will be displayed, if possible. A sign is used to
|
||||
highlight the current position (using highlight group debugPC).
|
||||
|
||||
If the buffer in the current window is modified, another window will be opened
|
||||
to display the current gdb position.
|
||||
|
||||
Focus the terminal of the executed program to interact with it. This works
|
||||
the same as any command running in a terminal window.
|
||||
|
||||
When the debugger ends, typically by typing "quit" in the gdb window, the two
|
||||
opened windows are closed.
|
||||
|
||||
|
||||
Stepping through code ~
|
||||
|
||||
Put focus on the gdb window to type commands there. Some common ones are:
|
||||
- CTRL-C interrupt the program
|
||||
- next execute the current line and stop at the next line
|
||||
- step execute the current line and stop at the next statement, entering
|
||||
functions
|
||||
- finish execute until leaving the current function
|
||||
- where show the stack
|
||||
- frame N go to the Nth stack frame
|
||||
- continue continue execution
|
||||
|
||||
In the window showing the source code some commands can used to control gdb:
|
||||
:Break set a breakpoint at the current line; a sign will be displayed
|
||||
:Delete delete a breakpoint at the current line
|
||||
:Step execute the gdb "step" command
|
||||
:Over execute the gdb "next" command (:Next is a Vim command)
|
||||
:Finish execute the gdb "finish" command
|
||||
:Continue execute the gdb "continue" command
|
||||
|
||||
|
||||
Inspecting variables ~
|
||||
|
||||
:Evaluate evaluate the expression under the cursor
|
||||
K same
|
||||
:Evaluate {expr} evaluate {expr}
|
||||
:'<,'>Evaluate evaluate the Visually selected text
|
||||
|
||||
This is similar to using "print" in the gdb window.
|
||||
|
||||
|
||||
Other commands ~
|
||||
|
||||
:Gdb jump to the gdb window
|
||||
:Program jump to the window with the running program
|
||||
|
||||
|
||||
Communication ~
|
||||
|
||||
There is another, hidden, buffer, which is used for Vim to communicate with
|
||||
gdb. The buffer name is "gdb communication". Do not delete this buffer, it
|
||||
will break the debugger.
|
||||
|
||||
|
||||
Customizing ~
|
||||
|
||||
g:debugger The debugger command. Default "gdb".
|
||||
To change the name of the gdb command, set the "termdebugger" variable before
|
||||
invoking `:Termdebug`: >
|
||||
let termdebugger = "mygdb"
|
||||
Only debuggers fully compatible with gdb will work. Vim uses the GDB/MI
|
||||
interface.
|
||||
|
||||
The color of the signs can be adjusted with these highlight groups:
|
||||
- debugPC the current position
|
||||
- debugBreakpoint a breakpoint
|
||||
|
||||
The defaults are, when 'background' is "light":
|
||||
hi debugPC term=reverse ctermbg=lightblue guibg=lightblue
|
||||
hi debugBreakpoint term=reverse ctermbg=red guibg=red
|
||||
|
||||
When 'background' is "dark":
|
||||
hi debugPC term=reverse ctermbg=darkblue guibg=darkblue
|
||||
hi debugBreakpoint term=reverse ctermbg=red guibg=red
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
vim:tw=78:ts=8:ft=help:norl:
|
||||
|
||||
+201
-36
@@ -20,18 +20,26 @@
|
||||
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.
|
||||
" There can be only one.
|
||||
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
|
||||
|
||||
" Sign used to indicate a breakpoint.
|
||||
" Can be used multiple times.
|
||||
sign define debugBreakpoint text=>> texthl=debugBreakpoint
|
||||
|
||||
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())
|
||||
@@ -46,6 +54,7 @@ func s:StartDebug(cmd)
|
||||
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', {
|
||||
@@ -61,7 +70,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'),
|
||||
@@ -73,15 +82,30 @@ 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")
|
||||
|
||||
" 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)
|
||||
endfunc
|
||||
|
||||
" Handle a message received from gdb on the GDB/MI interface.
|
||||
@@ -95,34 +119,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
|
||||
sign undefine debugPC
|
||||
sign undefine debugBreakpoint
|
||||
exe 'sign unplace ' . s:pc_id
|
||||
for key in keys(s:breakpoints)
|
||||
exe 'sign unplace ' . (s:break_id + key)
|
||||
endfor
|
||||
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)
|
||||
if a:msg =~ '^\*stopped'
|
||||
let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '')
|
||||
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
|
||||
|
||||
@@ -2282,6 +2282,7 @@ test_arglist \
|
||||
test_taglist \
|
||||
test_tcl \
|
||||
test_terminal \
|
||||
test_terminal_fail \
|
||||
test_textobjects \
|
||||
test_timers \
|
||||
test_true_false \
|
||||
|
||||
+24
-13
@@ -2951,14 +2951,27 @@ channel_close_in(channel_T *channel)
|
||||
ch_close_part(channel, PART_IN);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_from_writeque(writeq_T *wq, writeq_T *entry)
|
||||
{
|
||||
ga_clear(&entry->wq_ga);
|
||||
wq->wq_next = entry->wq_next;
|
||||
if (wq->wq_next == NULL)
|
||||
wq->wq_prev = NULL;
|
||||
else
|
||||
wq->wq_next->wq_prev = NULL;
|
||||
vim_free(entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the read buffer on "channel"/"part".
|
||||
*/
|
||||
static void
|
||||
channel_clear_one(channel_T *channel, ch_part_T part)
|
||||
{
|
||||
jsonq_T *json_head = &channel->ch_part[part].ch_json_head;
|
||||
cbq_T *cb_head = &channel->ch_part[part].ch_cb_head;
|
||||
chanpart_T *ch_part = &channel->ch_part[part];
|
||||
jsonq_T *json_head = &ch_part->ch_json_head;
|
||||
cbq_T *cb_head = &ch_part->ch_cb_head;
|
||||
|
||||
while (channel_peek(channel, part) != NULL)
|
||||
vim_free(channel_get(channel, part));
|
||||
@@ -2978,10 +2991,13 @@ channel_clear_one(channel_T *channel, ch_part_T part)
|
||||
remove_json_node(json_head, json_head->jq_next);
|
||||
}
|
||||
|
||||
free_callback(channel->ch_part[part].ch_callback,
|
||||
channel->ch_part[part].ch_partial);
|
||||
channel->ch_part[part].ch_callback = NULL;
|
||||
channel->ch_part[part].ch_partial = NULL;
|
||||
free_callback(ch_part->ch_callback, ch_part->ch_partial);
|
||||
ch_part->ch_callback = NULL;
|
||||
ch_part->ch_partial = NULL;
|
||||
|
||||
while (ch_part->ch_writeque.wq_next != NULL)
|
||||
remove_from_writeque(&ch_part->ch_writeque,
|
||||
ch_part->ch_writeque.wq_next);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2996,7 +3012,7 @@ channel_clear(channel_T *channel)
|
||||
channel_clear_one(channel, PART_SOCK);
|
||||
channel_clear_one(channel, PART_OUT);
|
||||
channel_clear_one(channel, PART_ERR);
|
||||
/* there is no callback or queue for PART_IN */
|
||||
channel_clear_one(channel, PART_IN);
|
||||
free_callback(channel->ch_callback, channel->ch_partial);
|
||||
channel->ch_callback = NULL;
|
||||
channel->ch_partial = NULL;
|
||||
@@ -3744,12 +3760,7 @@ channel_send(
|
||||
if (entry != NULL)
|
||||
{
|
||||
/* Remove the entry from the write queue. */
|
||||
ga_clear(&entry->wq_ga);
|
||||
wq->wq_next = entry->wq_next;
|
||||
if (wq->wq_next == NULL)
|
||||
wq->wq_prev = NULL;
|
||||
else
|
||||
wq->wq_next->wq_prev = NULL;
|
||||
remove_from_writeque(wq, entry);
|
||||
continue;
|
||||
}
|
||||
if (did_use_queue)
|
||||
|
||||
+6
-1
@@ -4833,7 +4833,7 @@ get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv)
|
||||
dict_T *d = what_arg->vval.v_dict;
|
||||
|
||||
if (d != NULL)
|
||||
get_errorlist_properties(wp, d, rettv->vval.v_dict);
|
||||
qf_get_properties(wp, d, rettv->vval.v_dict);
|
||||
}
|
||||
else
|
||||
EMSG(_(e_dictreq));
|
||||
@@ -8659,7 +8659,10 @@ remote_common(typval_T *argvars, typval_T *rettv, int expr)
|
||||
# endif
|
||||
{
|
||||
if (r != NULL)
|
||||
{
|
||||
EMSG(r); /* sending worked but evaluation failed */
|
||||
vim_free(r);
|
||||
}
|
||||
else
|
||||
EMSG2(_("E241: Unable to send to %s"), server_name);
|
||||
return;
|
||||
@@ -8719,6 +8722,8 @@ f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||
argvars[1].v_type = VAR_STRING;
|
||||
argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()");
|
||||
argvars[2].v_type = VAR_UNKNOWN;
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
remote_common(argvars, rettv, TRUE);
|
||||
vim_free(argvars[1].vval.v_string);
|
||||
# endif
|
||||
|
||||
+38
-18
@@ -6348,7 +6348,8 @@ ex_command(exarg_T *eap)
|
||||
{
|
||||
++p;
|
||||
end = skiptowhite(p);
|
||||
if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg, &addr_type_arg)
|
||||
if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl,
|
||||
&compl_arg, &addr_type_arg)
|
||||
== FAIL)
|
||||
return;
|
||||
p = skipwhite(end);
|
||||
@@ -6389,7 +6390,7 @@ ex_command(exarg_T *eap)
|
||||
}
|
||||
else
|
||||
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
|
||||
addr_type_arg, eap->forceit);
|
||||
addr_type_arg, eap->forceit);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6609,8 +6610,18 @@ uc_check_code(
|
||||
char_u *p = code + 1;
|
||||
size_t l = len - 2;
|
||||
int quote = 0;
|
||||
enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_MODS,
|
||||
ct_REGISTER, ct_LT, ct_NONE } type = ct_NONE;
|
||||
enum {
|
||||
ct_ARGS,
|
||||
ct_BANG,
|
||||
ct_COUNT,
|
||||
ct_LINE1,
|
||||
ct_LINE2,
|
||||
ct_RANGE,
|
||||
ct_MODS,
|
||||
ct_REGISTER,
|
||||
ct_LT,
|
||||
ct_NONE
|
||||
} type = ct_NONE;
|
||||
|
||||
if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-')
|
||||
{
|
||||
@@ -6632,6 +6643,8 @@ uc_check_code(
|
||||
type = ct_LINE1;
|
||||
else if (STRNICMP(p, "line2>", l) == 0)
|
||||
type = ct_LINE2;
|
||||
else if (STRNICMP(p, "range>", l) == 0)
|
||||
type = ct_RANGE;
|
||||
else if (STRNICMP(p, "lt>", l) == 0)
|
||||
type = ct_LT;
|
||||
else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
|
||||
@@ -6733,11 +6746,13 @@ uc_check_code(
|
||||
|
||||
case ct_LINE1:
|
||||
case ct_LINE2:
|
||||
case ct_RANGE:
|
||||
case ct_COUNT:
|
||||
{
|
||||
char num_buf[20];
|
||||
long num = (type == ct_LINE1) ? eap->line1 :
|
||||
(type == ct_LINE2) ? eap->line2 :
|
||||
(type == ct_RANGE) ? eap->addr_count :
|
||||
(eap->addr_count > 0) ? eap->line2 : cmd->uc_def;
|
||||
size_t num_len;
|
||||
|
||||
@@ -10662,31 +10677,33 @@ find_cmdline_var(char_u *src, int *usedlen)
|
||||
"%",
|
||||
#define SPEC_PERC 0
|
||||
"#",
|
||||
#define SPEC_HASH 1
|
||||
#define SPEC_HASH (SPEC_PERC + 1)
|
||||
"<cword>", /* cursor word */
|
||||
#define SPEC_CWORD 2
|
||||
#define SPEC_CWORD (SPEC_HASH + 1)
|
||||
"<cWORD>", /* cursor WORD */
|
||||
#define SPEC_CCWORD 3
|
||||
#define SPEC_CCWORD (SPEC_CWORD + 1)
|
||||
"<cexpr>", /* expr under cursor */
|
||||
#define SPEC_CEXPR (SPEC_CCWORD + 1)
|
||||
"<cfile>", /* cursor path name */
|
||||
#define SPEC_CFILE 4
|
||||
#define SPEC_CFILE (SPEC_CEXPR + 1)
|
||||
"<sfile>", /* ":so" file name */
|
||||
#define SPEC_SFILE 5
|
||||
#define SPEC_SFILE (SPEC_CFILE + 1)
|
||||
"<slnum>", /* ":so" file line number */
|
||||
#define SPEC_SLNUM 6
|
||||
#define SPEC_SLNUM (SPEC_SFILE + 1)
|
||||
#ifdef FEAT_AUTOCMD
|
||||
"<afile>", /* autocommand file name */
|
||||
# define SPEC_AFILE 7
|
||||
# define SPEC_AFILE (SPEC_SLNUM + 1)
|
||||
"<abuf>", /* autocommand buffer number */
|
||||
# define SPEC_ABUF 8
|
||||
# define SPEC_ABUF (SPEC_AFILE + 1)
|
||||
"<amatch>", /* autocommand match name */
|
||||
# define SPEC_AMATCH 9
|
||||
# define SPEC_AMATCH (SPEC_ABUF + 1)
|
||||
#endif
|
||||
#ifdef FEAT_CLIENTSERVER
|
||||
"<client>"
|
||||
# ifdef FEAT_AUTOCMD
|
||||
# define SPEC_CLIENT 10
|
||||
# define SPEC_CLIENT (SPEC_AMATCH + 1)
|
||||
# else
|
||||
# define SPEC_CLIENT 7
|
||||
# define SPEC_CLIENT (SPEC_SLNUM + 1)
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
@@ -10774,10 +10791,13 @@ eval_vars(
|
||||
/*
|
||||
* word or WORD under cursor
|
||||
*/
|
||||
if (spec_idx == SPEC_CWORD || spec_idx == SPEC_CCWORD)
|
||||
if (spec_idx == SPEC_CWORD || spec_idx == SPEC_CCWORD
|
||||
|| spec_idx == SPEC_CEXPR)
|
||||
{
|
||||
resultlen = find_ident_under_cursor(&result, spec_idx == SPEC_CWORD ?
|
||||
(FIND_IDENT|FIND_STRING) : FIND_STRING);
|
||||
resultlen = find_ident_under_cursor(&result,
|
||||
spec_idx == SPEC_CWORD ? (FIND_IDENT | FIND_STRING)
|
||||
: spec_idx == SPEC_CEXPR ? (FIND_IDENT | FIND_STRING | FIND_EVAL)
|
||||
: FIND_STRING);
|
||||
if (resultlen == 0)
|
||||
{
|
||||
*errormsg = (char_u *)"";
|
||||
|
||||
+3
-11
@@ -1177,23 +1177,15 @@ drawBalloon(BalloonEval *beval)
|
||||
int x_offset = EVAL_OFFSET_X;
|
||||
int y_offset = EVAL_OFFSET_Y;
|
||||
PangoLayout *layout;
|
||||
# if GTK_CHECK_VERSION(3,22,2)
|
||||
GdkRectangle rect;
|
||||
GdkMonitor * const mon = gdk_display_get_monitor_at_window(
|
||||
gtk_widget_get_display(beval->balloonShell),
|
||||
gtk_widget_get_window(beval->balloonShell));
|
||||
gdk_monitor_get_geometry(mon, &rect);
|
||||
|
||||
screen_w = rect.width;
|
||||
screen_h = rect.height;
|
||||
# else
|
||||
# if !GTK_CHECK_VERSION(3,22,2)
|
||||
GdkScreen *screen;
|
||||
|
||||
screen = gtk_widget_get_screen(beval->target);
|
||||
gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
|
||||
screen_w = gdk_screen_get_width(screen);
|
||||
screen_h = gdk_screen_get_height(screen);
|
||||
# endif
|
||||
gui_gtk_get_screen_size_of_win(beval->balloonShell,
|
||||
&screen_w, &screen_h);
|
||||
# if !GTK_CHECK_VERSION(3,0,0)
|
||||
gtk_widget_ensure_style(beval->balloonShell);
|
||||
gtk_widget_ensure_style(beval->balloonLabel);
|
||||
|
||||
+25
-21
@@ -4941,6 +4941,29 @@ gui_mch_set_shellsize(int width, int height,
|
||||
gui_mch_update();
|
||||
}
|
||||
|
||||
void
|
||||
gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3,22,0)
|
||||
GdkDisplay *dpy = gtk_widget_get_display(wid);
|
||||
GdkWindow *win = gtk_widget_get_window(wid);
|
||||
GdkMonitor *monitor = gdk_display_get_monitor_at_window(dpy, win);
|
||||
GdkRectangle geometry;
|
||||
|
||||
gdk_monitor_get_geometry(monitor, &geometry);
|
||||
*width = geometry.width;
|
||||
*height = geometry.height;
|
||||
#else
|
||||
GdkScreen* screen;
|
||||
|
||||
if (wid != NULL && gtk_widget_has_screen(wid))
|
||||
screen = gtk_widget_get_screen(wid);
|
||||
else
|
||||
screen = gdk_screen_get_default();
|
||||
*width = gdk_screen_get_width(screen);
|
||||
*height = gdk_screen_get_height(screen);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The screen size is used to make sure the initial window doesn't get bigger
|
||||
@@ -4950,30 +4973,11 @@ gui_mch_set_shellsize(int width, int height,
|
||||
void
|
||||
gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3,22,2)
|
||||
GdkRectangle rect;
|
||||
GdkMonitor * const mon = gdk_display_get_monitor_at_window(
|
||||
gtk_widget_get_display(gui.mainwin),
|
||||
gtk_widget_get_window(gui.mainwin));
|
||||
gdk_monitor_get_geometry(mon, &rect);
|
||||
gui_gtk_get_screen_size_of_win(gui.mainwin, screen_w, screen_h);
|
||||
|
||||
*screen_w = rect.width;
|
||||
/* Subtract 'guiheadroom' from the height to allow some room for the
|
||||
* window manager (task list and window title bar). */
|
||||
*screen_h = rect.height - p_ghr;
|
||||
#else
|
||||
GdkScreen* screen;
|
||||
|
||||
if (gui.mainwin != NULL && gtk_widget_has_screen(gui.mainwin))
|
||||
screen = gtk_widget_get_screen(gui.mainwin);
|
||||
else
|
||||
screen = gdk_screen_get_default();
|
||||
|
||||
*screen_w = gdk_screen_get_width(screen);
|
||||
/* Subtract 'guiheadroom' from the height to allow some room for the
|
||||
* window manager (task list and window title bar). */
|
||||
*screen_h = gdk_screen_get_height(screen) - p_ghr;
|
||||
#endif
|
||||
*screen_h -= p_ghr;
|
||||
|
||||
/*
|
||||
* FIXME: dirty trick: Because the gui_get_base_height() doesn't include
|
||||
|
||||
@@ -421,6 +421,7 @@ serverSendToVim(
|
||||
{
|
||||
LookupName(dpy, loosename ? loosename : name,
|
||||
/*DELETE=*/TRUE, NULL);
|
||||
vim_free(loosename);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -4887,8 +4887,7 @@ im_preedit_window_set_position(void)
|
||||
if (preedit_window == NULL)
|
||||
return;
|
||||
|
||||
sw = gdk_screen_get_width(gtk_widget_get_screen(preedit_window));
|
||||
sh = gdk_screen_get_height(gtk_widget_get_screen(preedit_window));
|
||||
gui_gtk_get_screen_size_of_win(preedit_window, &sw, &sh);
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y);
|
||||
#else
|
||||
|
||||
@@ -3355,9 +3355,6 @@ reset_VIsual(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FEAT_BEVAL)
|
||||
static int find_is_eval_item(char_u *ptr, int *colp, int *nbp, int dir);
|
||||
|
||||
/*
|
||||
* Check for a balloon-eval special item to include when searching for an
|
||||
* identifier. When "dir" is BACKWARD "ptr[-1]" must be valid!
|
||||
@@ -3396,7 +3393,6 @@ find_is_eval_item(
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find the identifier under or to the right of the cursor.
|
||||
@@ -3446,9 +3442,7 @@ find_ident_at_pos(
|
||||
int prev_class;
|
||||
int prevcol;
|
||||
#endif
|
||||
#if defined(FEAT_BEVAL)
|
||||
int bn = 0; /* bracket nesting */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* if i == 0: try to find an identifier
|
||||
@@ -3466,11 +3460,9 @@ find_ident_at_pos(
|
||||
{
|
||||
while (ptr[col] != NUL)
|
||||
{
|
||||
# if defined(FEAT_BEVAL)
|
||||
/* Stop at a ']' to evaluate "a[x]". */
|
||||
if ((find_type & FIND_EVAL) && ptr[col] == ']')
|
||||
break;
|
||||
# endif
|
||||
this_class = mb_get_class(ptr + col);
|
||||
if (this_class != 0 && (i == 1 || this_class != 1))
|
||||
break;
|
||||
@@ -3481,16 +3473,12 @@ find_ident_at_pos(
|
||||
#endif
|
||||
while (ptr[col] != NUL
|
||||
&& (i == 0 ? !vim_iswordc(ptr[col]) : VIM_ISWHITE(ptr[col]))
|
||||
# if defined(FEAT_BEVAL)
|
||||
&& (!(find_type & FIND_EVAL) || ptr[col] != ']')
|
||||
# endif
|
||||
)
|
||||
++col;
|
||||
|
||||
#if defined(FEAT_BEVAL)
|
||||
/* When starting on a ']' count it, so that we include the '['. */
|
||||
bn = ptr[col] == ']';
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 2. Back up to start of identifier/string.
|
||||
@@ -3499,11 +3487,9 @@ find_ident_at_pos(
|
||||
if (has_mbyte)
|
||||
{
|
||||
/* Remember class of character under cursor. */
|
||||
# if defined(FEAT_BEVAL)
|
||||
if ((find_type & FIND_EVAL) && ptr[col] == ']')
|
||||
this_class = mb_get_class((char_u *)"a");
|
||||
else
|
||||
# endif
|
||||
this_class = mb_get_class(ptr + col);
|
||||
while (col > 0 && this_class != 0)
|
||||
{
|
||||
@@ -3513,12 +3499,10 @@ find_ident_at_pos(
|
||||
&& (i == 0
|
||||
|| prev_class == 0
|
||||
|| (find_type & FIND_IDENT))
|
||||
# if defined(FEAT_BEVAL)
|
||||
&& (!(find_type & FIND_EVAL)
|
||||
|| prevcol == 0
|
||||
|| !find_is_eval_item(ptr + prevcol, &prevcol,
|
||||
&bn, BACKWARD))
|
||||
# endif
|
||||
)
|
||||
break;
|
||||
col = prevcol;
|
||||
@@ -3540,12 +3524,10 @@ find_ident_at_pos(
|
||||
: (!VIM_ISWHITE(ptr[col - 1])
|
||||
&& (!(find_type & FIND_IDENT)
|
||||
|| !vim_iswordc(ptr[col - 1]))))
|
||||
#if defined(FEAT_BEVAL)
|
||||
|| ((find_type & FIND_EVAL)
|
||||
&& col > 1
|
||||
&& find_is_eval_item(ptr + col - 1, &col,
|
||||
&bn, BACKWARD))
|
||||
#endif
|
||||
))
|
||||
--col;
|
||||
|
||||
@@ -3577,10 +3559,8 @@ find_ident_at_pos(
|
||||
/*
|
||||
* 3. Find the end if the identifier/string.
|
||||
*/
|
||||
#if defined(FEAT_BEVAL)
|
||||
bn = 0;
|
||||
startcol -= col;
|
||||
#endif
|
||||
col = 0;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
@@ -3590,11 +3570,9 @@ find_ident_at_pos(
|
||||
while (ptr[col] != NUL
|
||||
&& ((i == 0 ? mb_get_class(ptr + col) == this_class
|
||||
: mb_get_class(ptr + col) != 0)
|
||||
# if defined(FEAT_BEVAL)
|
||||
|| ((find_type & FIND_EVAL)
|
||||
&& col <= (int)startcol
|
||||
&& find_is_eval_item(ptr + col, &col, &bn, FORWARD))
|
||||
# endif
|
||||
))
|
||||
col += (*mb_ptr2len)(ptr + col);
|
||||
}
|
||||
@@ -3602,11 +3580,9 @@ find_ident_at_pos(
|
||||
#endif
|
||||
while ((i == 0 ? vim_iswordc(ptr[col])
|
||||
: (ptr[col] != NUL && !VIM_ISWHITE(ptr[col])))
|
||||
# if defined(FEAT_BEVAL)
|
||||
|| ((find_type & FIND_EVAL)
|
||||
&& col <= (int)startcol
|
||||
&& find_is_eval_item(ptr + col, &col, &bn, FORWARD))
|
||||
# endif
|
||||
)
|
||||
{
|
||||
++col;
|
||||
|
||||
@@ -25,6 +25,7 @@ int gui_mch_maximized(void);
|
||||
void gui_mch_unmaximize(void);
|
||||
void gui_mch_newfont(void);
|
||||
void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction);
|
||||
void gui_gtk_get_screen_size_of_win(GtkWidget *win, int *width, int *height);
|
||||
void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h);
|
||||
void gui_mch_settitle(char_u *title, char_u *icon);
|
||||
void gui_mch_enable_menu(int showit);
|
||||
|
||||
@@ -22,7 +22,7 @@ void ex_cnext(exarg_T *eap);
|
||||
void ex_cfile(exarg_T *eap);
|
||||
void ex_vimgrep(exarg_T *eap);
|
||||
int get_errorlist(qf_info_T *qi, win_T *wp, int qf_idx, list_T *list);
|
||||
int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict);
|
||||
int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict);
|
||||
int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what);
|
||||
int set_ref_in_quickfix(int copyID);
|
||||
void ex_cbuffer(exarg_T *eap);
|
||||
|
||||
+30
-11
@@ -4690,13 +4690,28 @@ qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the quickfix/location list number with the given identifier.
|
||||
* Returns -1 if list is not found.
|
||||
*/
|
||||
static int
|
||||
qf_id2nr(qf_info_T *qi, int_u qfid)
|
||||
{
|
||||
int qf_idx;
|
||||
|
||||
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
|
||||
if (qi->qf_lists[qf_idx].qf_id == qfid)
|
||||
return qf_idx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return quickfix/location list details (title) as a
|
||||
* dictionary. 'what' contains the details to return. If 'list_idx' is -1,
|
||||
* then current list is used. Otherwise the specified list is used.
|
||||
*/
|
||||
int
|
||||
get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
{
|
||||
qf_info_T *qi = &ql_info;
|
||||
int status = OK;
|
||||
@@ -4752,12 +4767,8 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
/* For zero, use the current list or the list specifed by 'nr' */
|
||||
if (di->di_tv.vval.v_number != 0)
|
||||
{
|
||||
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
|
||||
{
|
||||
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
|
||||
break;
|
||||
}
|
||||
if (qf_idx == qi->qf_listcount)
|
||||
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
|
||||
if (qf_idx == -1)
|
||||
return FAIL; /* List not found */
|
||||
}
|
||||
flags |= QF_GETLIST_ID;
|
||||
@@ -5024,10 +5035,8 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
|
||||
/* Use the quickfix/location list with the specified id */
|
||||
if (di->di_tv.v_type == VAR_NUMBER)
|
||||
{
|
||||
for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++)
|
||||
if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number)
|
||||
break;
|
||||
if (qf_idx == qi->qf_listcount)
|
||||
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
|
||||
if (qf_idx == -1)
|
||||
return FAIL; /* List not found */
|
||||
}
|
||||
else
|
||||
@@ -5062,6 +5071,16 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
|
||||
|
||||
retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
|
||||
title_save, action == ' ' ? 'a' : action);
|
||||
if (action == 'r')
|
||||
{
|
||||
/*
|
||||
* When replacing the quickfix list entries using
|
||||
* qf_add_entries(), the title is set with a ':' prefix.
|
||||
* Restore the title with the saved title.
|
||||
*/
|
||||
vim_free(qi->qf_lists[qf_idx].qf_title);
|
||||
qi->qf_lists[qf_idx].qf_title = vim_strsave(title_save);
|
||||
}
|
||||
vim_free(title_save);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3139,6 +3139,7 @@ win_line(
|
||||
#endif
|
||||
#ifdef FEAT_TERMINAL
|
||||
int get_term_attr = FALSE;
|
||||
int term_attr = 0; /* background for terminal window */
|
||||
#endif
|
||||
|
||||
/* draw_state: items that are drawn in sequence: */
|
||||
@@ -3256,6 +3257,7 @@ win_line(
|
||||
{
|
||||
extra_check = TRUE;
|
||||
get_term_attr = TRUE;
|
||||
term_attr = term_get_attr(wp->w_buffer, lnum, -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5056,6 +5058,9 @@ win_line(
|
||||
else if ((
|
||||
# ifdef FEAT_DIFF
|
||||
diff_hlf != (hlf_T)0 ||
|
||||
# endif
|
||||
# ifdef FEAT_TERMINAL
|
||||
term_attr != 0 ||
|
||||
# endif
|
||||
line_attr != 0
|
||||
) && (
|
||||
@@ -5090,6 +5095,15 @@ win_line(
|
||||
HL_ATTR(HLF_CUL));
|
||||
}
|
||||
}
|
||||
# endif
|
||||
# ifdef FEAT_TERMINAL
|
||||
if (term_attr != 0)
|
||||
{
|
||||
char_attr = term_attr;
|
||||
if (wp->w_p_cul && lnum == wp->w_cursor.lnum)
|
||||
char_attr = hl_combine_attr(char_attr,
|
||||
HL_ATTR(HLF_CUL));
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
+98
-89
@@ -7364,7 +7364,6 @@ do_highlight(
|
||||
int attr;
|
||||
int id;
|
||||
int idx;
|
||||
struct hl_group *item;
|
||||
struct hl_group item_before;
|
||||
int dodefault = FALSE;
|
||||
int doclear = FALSE;
|
||||
@@ -7380,6 +7379,9 @@ do_highlight(
|
||||
#else
|
||||
# define is_menu_group 0
|
||||
# define is_tooltip_group 0
|
||||
#endif
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
int did_highlight_changed = FALSE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -7461,13 +7463,12 @@ do_highlight(
|
||||
}
|
||||
|
||||
from_id = syn_check_group(from_start, (int)(from_end - from_start));
|
||||
item = &HL_TABLE()[from_id - 1];
|
||||
if (STRNCMP(to_start, "NONE", 4) == 0)
|
||||
to_id = 0;
|
||||
else
|
||||
to_id = syn_check_group(to_start, (int)(to_end - to_start));
|
||||
|
||||
if (from_id > 0 && (!init || item->sg_set == 0))
|
||||
if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0))
|
||||
{
|
||||
/*
|
||||
* Don't allow a link when there already is some highlighting
|
||||
@@ -7479,19 +7480,19 @@ do_highlight(
|
||||
if (sourcing_name == NULL && !dodefault)
|
||||
EMSG(_("E414: group has settings, highlight link ignored"));
|
||||
}
|
||||
else if (item->sg_link != to_id
|
||||
else if (HL_TABLE()[from_id - 1].sg_link != to_id
|
||||
#ifdef FEAT_EVAL
|
||||
|| item->sg_scriptID != current_SID
|
||||
|| HL_TABLE()[from_id - 1].sg_scriptID != current_SID
|
||||
#endif
|
||||
|| item->sg_cleared)
|
||||
|| HL_TABLE()[from_id - 1].sg_cleared)
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_LINK;
|
||||
item->sg_link = to_id;
|
||||
HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
|
||||
HL_TABLE()[from_id - 1].sg_link = to_id;
|
||||
#ifdef FEAT_EVAL
|
||||
item->sg_scriptID = current_SID;
|
||||
HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
|
||||
#endif
|
||||
item->sg_cleared = FALSE;
|
||||
HL_TABLE()[from_id - 1].sg_cleared = FALSE;
|
||||
redraw_all_later(SOME_VALID);
|
||||
|
||||
/* Only call highlight_changed() once after multiple changes. */
|
||||
@@ -7569,8 +7570,9 @@ do_highlight(
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
if (USE_24BIT)
|
||||
highlight_gui_started();
|
||||
else
|
||||
#endif
|
||||
highlight_changed();
|
||||
highlight_changed();
|
||||
redraw_later_clear();
|
||||
return;
|
||||
}
|
||||
@@ -7585,23 +7587,22 @@ do_highlight(
|
||||
if (id == 0) /* failed (out of memory) */
|
||||
return;
|
||||
idx = id - 1; /* index is ID minus one */
|
||||
item = &HL_TABLE()[idx];
|
||||
|
||||
/* Return if "default" was used and the group already has settings. */
|
||||
if (dodefault && hl_has_settings(idx, TRUE))
|
||||
return;
|
||||
|
||||
/* Make a copy so we can check if any attribute actually changed. */
|
||||
item_before = *item;
|
||||
item_before = HL_TABLE()[idx];
|
||||
|
||||
if (STRCMP(item->sg_name_u, "NORMAL") == 0)
|
||||
if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
|
||||
is_normal_group = TRUE;
|
||||
#ifdef FEAT_GUI_X11
|
||||
else if (STRCMP(item->sg_name_u, "MENU") == 0)
|
||||
else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0)
|
||||
is_menu_group = TRUE;
|
||||
else if (STRCMP(item->sg_name_u, "SCROLLBAR") == 0)
|
||||
else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0)
|
||||
is_scrollbar_group = TRUE;
|
||||
else if (STRCMP(item->sg_name_u, "TOOLTIP") == 0)
|
||||
else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0)
|
||||
is_tooltip_group = TRUE;
|
||||
#endif
|
||||
|
||||
@@ -7610,7 +7611,7 @@ do_highlight(
|
||||
{
|
||||
highlight_clear(idx);
|
||||
if (!doclear)
|
||||
item->sg_set = 0;
|
||||
HL_TABLE()[idx].sg_set = 0;
|
||||
}
|
||||
|
||||
if (!doclear)
|
||||
@@ -7641,10 +7642,10 @@ do_highlight(
|
||||
|
||||
if (STRCMP(key, "NONE") == 0)
|
||||
{
|
||||
if (!init || item->sg_set == 0)
|
||||
if (!init || HL_TABLE()[idx].sg_set == 0)
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_TERM+SG_CTERM+SG_GUI;
|
||||
HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
|
||||
highlight_clear(idx);
|
||||
}
|
||||
continue;
|
||||
@@ -7731,31 +7732,31 @@ do_highlight(
|
||||
break;
|
||||
if (*key == 'T')
|
||||
{
|
||||
if (!init || !(item->sg_set & SG_TERM))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_TERM;
|
||||
item->sg_term = attr;
|
||||
HL_TABLE()[idx].sg_set |= SG_TERM;
|
||||
HL_TABLE()[idx].sg_term = attr;
|
||||
}
|
||||
}
|
||||
else if (*key == 'C')
|
||||
{
|
||||
if (!init || !(item->sg_set & SG_CTERM))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_CTERM;
|
||||
item->sg_cterm = attr;
|
||||
item->sg_cterm_bold = FALSE;
|
||||
HL_TABLE()[idx].sg_set |= SG_CTERM;
|
||||
HL_TABLE()[idx].sg_cterm = attr;
|
||||
HL_TABLE()[idx].sg_cterm_bold = FALSE;
|
||||
}
|
||||
}
|
||||
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
|
||||
else
|
||||
{
|
||||
if (!init || !(item->sg_set & SG_GUI))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_GUI;
|
||||
item->sg_gui = attr;
|
||||
HL_TABLE()[idx].sg_set |= SG_GUI;
|
||||
HL_TABLE()[idx].sg_gui = attr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -7764,74 +7765,74 @@ do_highlight(
|
||||
{
|
||||
/* in non-GUI fonts are simply ignored */
|
||||
#ifdef FEAT_GUI
|
||||
if (item->sg_font_name != NULL
|
||||
&& STRCMP(item->sg_font_name, arg) == 0)
|
||||
if (HL_TABLE()[idx].sg_font_name != NULL
|
||||
&& STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0)
|
||||
{
|
||||
/* Font name didn't change, ignore. */
|
||||
}
|
||||
else if (!gui.shell_created)
|
||||
{
|
||||
/* GUI not started yet, always accept the name. */
|
||||
vim_free(item->sg_font_name);
|
||||
item->sg_font_name = vim_strsave(arg);
|
||||
vim_free(HL_TABLE()[idx].sg_font_name);
|
||||
HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiFont temp_sg_font = item->sg_font;
|
||||
GuiFont temp_sg_font = HL_TABLE()[idx].sg_font;
|
||||
# ifdef FEAT_XFONTSET
|
||||
GuiFontset temp_sg_fontset = item->sg_fontset;
|
||||
GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset;
|
||||
# endif
|
||||
/* First, save the current font/fontset.
|
||||
* Then try to allocate the font/fontset.
|
||||
* If the allocation fails, item->sg_font OR
|
||||
* If the allocation fails, HL_TABLE()[idx].sg_font OR
|
||||
* sg_fontset will be set to NOFONT or NOFONTSET respectively.
|
||||
*/
|
||||
|
||||
item->sg_font = NOFONT;
|
||||
HL_TABLE()[idx].sg_font = NOFONT;
|
||||
# ifdef FEAT_XFONTSET
|
||||
item->sg_fontset = NOFONTSET;
|
||||
HL_TABLE()[idx].sg_fontset = NOFONTSET;
|
||||
# endif
|
||||
hl_do_font(idx, arg, is_normal_group, is_menu_group,
|
||||
is_tooltip_group, FALSE);
|
||||
|
||||
# ifdef FEAT_XFONTSET
|
||||
if (item->sg_fontset != NOFONTSET)
|
||||
if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
|
||||
{
|
||||
/* New fontset was accepted. Free the old one, if there
|
||||
* was one. */
|
||||
gui_mch_free_fontset(temp_sg_fontset);
|
||||
vim_free(item->sg_font_name);
|
||||
item->sg_font_name = vim_strsave(arg);
|
||||
vim_free(HL_TABLE()[idx].sg_font_name);
|
||||
HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
|
||||
}
|
||||
else
|
||||
item->sg_fontset = temp_sg_fontset;
|
||||
HL_TABLE()[idx].sg_fontset = temp_sg_fontset;
|
||||
# endif
|
||||
if (item->sg_font != NOFONT)
|
||||
if (HL_TABLE()[idx].sg_font != NOFONT)
|
||||
{
|
||||
/* New font was accepted. Free the old one, if there was
|
||||
* one. */
|
||||
gui_mch_free_font(temp_sg_font);
|
||||
vim_free(item->sg_font_name);
|
||||
item->sg_font_name = vim_strsave(arg);
|
||||
vim_free(HL_TABLE()[idx].sg_font_name);
|
||||
HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
|
||||
}
|
||||
else
|
||||
item->sg_font = temp_sg_font;
|
||||
HL_TABLE()[idx].sg_font = temp_sg_font;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0)
|
||||
{
|
||||
if (!init || !(item->sg_set & SG_CTERM))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_CTERM;
|
||||
HL_TABLE()[idx].sg_set |= SG_CTERM;
|
||||
|
||||
/* When setting the foreground color, and previously the "bold"
|
||||
* flag was set for a light color, reset it now */
|
||||
if (key[5] == 'F' && item->sg_cterm_bold)
|
||||
if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold)
|
||||
{
|
||||
item->sg_cterm &= ~HL_BOLD;
|
||||
item->sg_cterm_bold = FALSE;
|
||||
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
|
||||
HL_TABLE()[idx].sg_cterm_bold = FALSE;
|
||||
}
|
||||
|
||||
if (VIM_ISDIGIT(*arg))
|
||||
@@ -7888,22 +7889,22 @@ do_highlight(
|
||||
* colors (on some terminals, e.g. "linux") */
|
||||
if (bold == TRUE)
|
||||
{
|
||||
item->sg_cterm |= HL_BOLD;
|
||||
item->sg_cterm_bold = TRUE;
|
||||
HL_TABLE()[idx].sg_cterm |= HL_BOLD;
|
||||
HL_TABLE()[idx].sg_cterm_bold = TRUE;
|
||||
}
|
||||
else if (bold == FALSE)
|
||||
item->sg_cterm &= ~HL_BOLD;
|
||||
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
|
||||
}
|
||||
|
||||
/* Add one to the argument, to avoid zero. Zero is used for
|
||||
* "NONE", then "color" is -1. */
|
||||
if (key[5] == 'F')
|
||||
{
|
||||
item->sg_cterm_fg = color + 1;
|
||||
HL_TABLE()[idx].sg_cterm_fg = color + 1;
|
||||
if (is_normal_group)
|
||||
{
|
||||
cterm_normal_fg_color = color + 1;
|
||||
cterm_normal_fg_bold = (item->sg_cterm & HL_BOLD);
|
||||
cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
|
||||
#ifdef FEAT_GUI
|
||||
/* Don't do this if the GUI is used. */
|
||||
if (!gui.in_use && !gui.starting)
|
||||
@@ -7917,7 +7918,7 @@ do_highlight(
|
||||
}
|
||||
else
|
||||
{
|
||||
item->sg_cterm_bg = color + 1;
|
||||
HL_TABLE()[idx].sg_cterm_bg = color + 1;
|
||||
if (is_normal_group)
|
||||
{
|
||||
cterm_normal_bg_color = color + 1;
|
||||
@@ -7957,23 +7958,23 @@ do_highlight(
|
||||
else if (STRCMP(key, "GUIFG") == 0)
|
||||
{
|
||||
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
|
||||
if (!init || !(item->sg_set & SG_GUI))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_GUI;
|
||||
HL_TABLE()[idx].sg_set |= SG_GUI;
|
||||
|
||||
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
/* In GUI guifg colors are only used when recognized */
|
||||
i = color_name2handle(arg);
|
||||
if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
|
||||
{
|
||||
item->sg_gui_fg = i;
|
||||
HL_TABLE()[idx].sg_gui_fg = i;
|
||||
# endif
|
||||
vim_free(item->sg_gui_fg_name);
|
||||
vim_free(HL_TABLE()[idx].sg_gui_fg_name);
|
||||
if (STRCMP(arg, "NONE") != 0)
|
||||
item->sg_gui_fg_name = vim_strsave(arg);
|
||||
HL_TABLE()[idx].sg_gui_fg_name = vim_strsave(arg);
|
||||
else
|
||||
item->sg_gui_fg_name = NULL;
|
||||
HL_TABLE()[idx].sg_gui_fg_name = NULL;
|
||||
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
# ifdef FEAT_GUI_X11
|
||||
if (is_menu_group)
|
||||
@@ -7994,23 +7995,23 @@ do_highlight(
|
||||
else if (STRCMP(key, "GUIBG") == 0)
|
||||
{
|
||||
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
|
||||
if (!init || !(item->sg_set & SG_GUI))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_GUI;
|
||||
HL_TABLE()[idx].sg_set |= SG_GUI;
|
||||
|
||||
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
/* In GUI guifg colors are only used when recognized */
|
||||
i = color_name2handle(arg);
|
||||
if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
|
||||
{
|
||||
item->sg_gui_bg = i;
|
||||
HL_TABLE()[idx].sg_gui_bg = i;
|
||||
# endif
|
||||
vim_free(item->sg_gui_bg_name);
|
||||
vim_free(HL_TABLE()[idx].sg_gui_bg_name);
|
||||
if (STRCMP(arg, "NONE") != 0)
|
||||
item->sg_gui_bg_name = vim_strsave(arg);
|
||||
HL_TABLE()[idx].sg_gui_bg_name = vim_strsave(arg);
|
||||
else
|
||||
item->sg_gui_bg_name = NULL;
|
||||
HL_TABLE()[idx].sg_gui_bg_name = NULL;
|
||||
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
# ifdef FEAT_GUI_X11
|
||||
if (is_menu_group)
|
||||
@@ -8031,22 +8032,22 @@ do_highlight(
|
||||
else if (STRCMP(key, "GUISP") == 0)
|
||||
{
|
||||
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
|
||||
if (!init || !(item->sg_set & SG_GUI))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
|
||||
{
|
||||
if (!init)
|
||||
item->sg_set |= SG_GUI;
|
||||
HL_TABLE()[idx].sg_set |= SG_GUI;
|
||||
|
||||
# ifdef FEAT_GUI
|
||||
i = color_name2handle(arg);
|
||||
if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use)
|
||||
{
|
||||
item->sg_gui_sp = i;
|
||||
HL_TABLE()[idx].sg_gui_sp = i;
|
||||
# endif
|
||||
vim_free(item->sg_gui_sp_name);
|
||||
vim_free(HL_TABLE()[idx].sg_gui_sp_name);
|
||||
if (STRCMP(arg, "NONE") != 0)
|
||||
item->sg_gui_sp_name = vim_strsave(arg);
|
||||
HL_TABLE()[idx].sg_gui_sp_name = vim_strsave(arg);
|
||||
else
|
||||
item->sg_gui_sp_name = NULL;
|
||||
HL_TABLE()[idx].sg_gui_sp_name = NULL;
|
||||
# ifdef FEAT_GUI
|
||||
}
|
||||
# endif
|
||||
@@ -8059,7 +8060,7 @@ do_highlight(
|
||||
char_u *tname;
|
||||
|
||||
if (!init)
|
||||
item->sg_set |= SG_TERM;
|
||||
HL_TABLE()[idx].sg_set |= SG_TERM;
|
||||
|
||||
/*
|
||||
* The "start" and "stop" arguments can be a literal escape
|
||||
@@ -8126,13 +8127,13 @@ do_highlight(
|
||||
p = vim_strsave(buf);
|
||||
if (key[2] == 'A')
|
||||
{
|
||||
vim_free(item->sg_start);
|
||||
item->sg_start = p;
|
||||
vim_free(HL_TABLE()[idx].sg_start);
|
||||
HL_TABLE()[idx].sg_start = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_free(item->sg_stop);
|
||||
item->sg_stop = p;
|
||||
vim_free(HL_TABLE()[idx].sg_stop);
|
||||
HL_TABLE()[idx].sg_stop = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -8141,13 +8142,13 @@ do_highlight(
|
||||
error = TRUE;
|
||||
break;
|
||||
}
|
||||
item->sg_cleared = FALSE;
|
||||
HL_TABLE()[idx].sg_cleared = FALSE;
|
||||
|
||||
/*
|
||||
* When highlighting has been given for a group, don't link it.
|
||||
*/
|
||||
if (!init || !(item->sg_set & SG_LINK))
|
||||
item->sg_link = 0;
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
|
||||
HL_TABLE()[idx].sg_link = 0;
|
||||
|
||||
/*
|
||||
* Continue with next argument.
|
||||
@@ -8164,10 +8165,10 @@ do_highlight(
|
||||
{
|
||||
if (is_normal_group)
|
||||
{
|
||||
item->sg_term_attr = 0;
|
||||
item->sg_cterm_attr = 0;
|
||||
HL_TABLE()[idx].sg_term_attr = 0;
|
||||
HL_TABLE()[idx].sg_cterm_attr = 0;
|
||||
#ifdef FEAT_GUI
|
||||
item->sg_gui_attr = 0;
|
||||
HL_TABLE()[idx].sg_gui_attr = 0;
|
||||
/*
|
||||
* Need to update all groups, because they might be using "bg"
|
||||
* and/or "fg", which have been changed now.
|
||||
@@ -8175,7 +8176,11 @@ do_highlight(
|
||||
#endif
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
if (USE_24BIT)
|
||||
{
|
||||
highlight_gui_started();
|
||||
did_highlight_changed = TRUE;
|
||||
redraw_all_later(NOT_VALID);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef FEAT_GUI_X11
|
||||
@@ -8202,7 +8207,7 @@ do_highlight(
|
||||
else
|
||||
set_hl_attr(idx);
|
||||
#ifdef FEAT_EVAL
|
||||
item->sg_scriptID = current_SID;
|
||||
HL_TABLE()[idx].sg_scriptID = current_SID;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -8211,7 +8216,11 @@ do_highlight(
|
||||
|
||||
/* Only call highlight_changed() once, after a sequence of highlight
|
||||
* commands, and only if an attribute actually changed. */
|
||||
if (memcmp(item, &item_before, sizeof(item_before)) != 0)
|
||||
if (memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
&& !did_highlight_changed
|
||||
#endif
|
||||
)
|
||||
{
|
||||
redraw_all_later(NOT_VALID);
|
||||
need_highlight_changed = TRUE;
|
||||
|
||||
+2
-2
@@ -4572,12 +4572,12 @@ check_termcode(
|
||||
/* Detect terminals that set $TERM to something like
|
||||
* "xterm-256colors" but are not fully xterm
|
||||
* compatible. */
|
||||
# ifdef MACOS
|
||||
|
||||
/* Mac Terminal.app sends 1;95;0 */
|
||||
if (version == 95
|
||||
&& STRNCMP(tp + extra - 2, "1;95;0c", 7) == 0)
|
||||
is_not_xterm = TRUE;
|
||||
# endif
|
||||
|
||||
/* Gnome terminal sends 1;3801;0, 1;4402;0 or 1;2501;0.
|
||||
* xfce4-terminal sends 1;2802;0.
|
||||
* screen sends 83;40500;0
|
||||
|
||||
+89
-24
@@ -39,6 +39,7 @@
|
||||
*
|
||||
* TODO:
|
||||
* - patch to use GUI or cterm colors for vterm. Yasuhiro, #2067
|
||||
* - patch to add tmap, jakalope (Jacob Askeland) #2073
|
||||
* - Redirecting output does not work on MS-Windows.
|
||||
* - implement term_setsize()
|
||||
* - add test for giving error for invalid 'termsize' value.
|
||||
@@ -84,6 +85,7 @@ typedef struct {
|
||||
typedef struct sb_line_S {
|
||||
int sb_cols; /* can differ per line */
|
||||
cellattr_T *sb_cells; /* allocated */
|
||||
cellattr_T sb_fill_attr; /* for short line */
|
||||
} sb_line_T;
|
||||
|
||||
/* typedef term_T in structs.h */
|
||||
@@ -126,6 +128,7 @@ struct terminal_S {
|
||||
|
||||
garray_T tl_scrollback;
|
||||
int tl_scrollback_scrolled;
|
||||
cellattr_T tl_default_color;
|
||||
|
||||
VTermPos tl_cursor_pos;
|
||||
int tl_cursor_visible;
|
||||
@@ -393,6 +396,7 @@ term_start(typval_T *argvar, jobopt_T *opt, int forceit)
|
||||
vim_snprintf((char *)p, len, "!%s (%d)", cmd, i);
|
||||
if (buflist_findname(p) == NULL)
|
||||
{
|
||||
vim_free(curbuf->b_ffname);
|
||||
curbuf->b_ffname = p;
|
||||
break;
|
||||
}
|
||||
@@ -552,6 +556,7 @@ ex_terminal(exarg_T *eap)
|
||||
argvar[1].v_type = VAR_UNKNOWN;
|
||||
term_start(argvar, &opt, eap->forceit);
|
||||
vim_free(tofree);
|
||||
vim_free(opt.jo_eof_chars);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -944,6 +949,28 @@ add_scrollback_line_to_buffer(term_T *term, char_u *text, int len)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cell2cellattr(const VTermScreenCell *cell, cellattr_T *attr)
|
||||
{
|
||||
attr->width = cell->width;
|
||||
attr->attrs = cell->attrs;
|
||||
attr->fg = cell->fg;
|
||||
attr->bg = cell->bg;
|
||||
}
|
||||
|
||||
static int
|
||||
equal_celattr(cellattr_T *a, cellattr_T *b)
|
||||
{
|
||||
/* Comparing the colors should be sufficient. */
|
||||
return a->fg.red == b->fg.red
|
||||
&& a->fg.green == b->fg.green
|
||||
&& a->fg.blue == b->fg.blue
|
||||
&& a->bg.red == b->bg.red
|
||||
&& a->bg.green == b->bg.green
|
||||
&& a->bg.blue == b->bg.blue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add the current lines of the terminal to scrollback and to the buffer.
|
||||
* Called after the job has ended and when switching to Terminal-Normal mode.
|
||||
@@ -956,21 +983,30 @@ move_terminal_to_buffer(term_T *term)
|
||||
int lines_skipped = 0;
|
||||
VTermPos pos;
|
||||
VTermScreenCell cell;
|
||||
cellattr_T fill_attr, new_fill_attr;
|
||||
cellattr_T *p;
|
||||
VTermScreen *screen;
|
||||
|
||||
if (term->tl_vterm == NULL)
|
||||
return;
|
||||
screen = vterm_obtain_screen(term->tl_vterm);
|
||||
fill_attr = new_fill_attr = term->tl_default_color;
|
||||
|
||||
for (pos.row = 0; pos.row < term->tl_rows; ++pos.row)
|
||||
{
|
||||
len = 0;
|
||||
for (pos.col = 0; pos.col < term->tl_cols; ++pos.col)
|
||||
if (vterm_screen_get_cell(screen, pos, &cell) != 0
|
||||
&& cell.chars[0] != NUL)
|
||||
{
|
||||
len = pos.col + 1;
|
||||
new_fill_attr = term->tl_default_color;
|
||||
}
|
||||
else
|
||||
/* Assume the last attr is the filler attr. */
|
||||
cell2cellattr(&cell, &new_fill_attr);
|
||||
|
||||
if (len == 0)
|
||||
if (len == 0 && equal_celattr(&new_fill_attr, &fill_attr))
|
||||
++lines_skipped;
|
||||
else
|
||||
{
|
||||
@@ -985,14 +1021,19 @@ move_terminal_to_buffer(term_T *term)
|
||||
|
||||
line->sb_cols = 0;
|
||||
line->sb_cells = NULL;
|
||||
line->sb_fill_attr = fill_attr;
|
||||
++term->tl_scrollback.ga_len;
|
||||
|
||||
add_scrollback_line_to_buffer(term, (char_u *)"", 0);
|
||||
}
|
||||
}
|
||||
|
||||
p = (cellattr_T *)alloc((int)sizeof(cellattr_T) * len);
|
||||
if (p != NULL && ga_grow(&term->tl_scrollback, 1) == OK)
|
||||
if (len == 0)
|
||||
p = NULL;
|
||||
else
|
||||
p = (cellattr_T *)alloc((int)sizeof(cellattr_T) * len);
|
||||
if ((p != NULL || len == 0)
|
||||
&& ga_grow(&term->tl_scrollback, 1) == OK)
|
||||
{
|
||||
garray_T ga;
|
||||
int width;
|
||||
@@ -1014,10 +1055,7 @@ move_terminal_to_buffer(term_T *term)
|
||||
{
|
||||
width = cell.width;
|
||||
|
||||
p[pos.col].width = cell.width;
|
||||
p[pos.col].attrs = cell.attrs;
|
||||
p[pos.col].fg = cell.fg;
|
||||
p[pos.col].bg = cell.bg;
|
||||
cell2cellattr(&cell, &p[pos.col]);
|
||||
|
||||
if (ga_grow(&ga, MB_MAXBYTES) == OK)
|
||||
{
|
||||
@@ -1032,6 +1070,8 @@ move_terminal_to_buffer(term_T *term)
|
||||
}
|
||||
line->sb_cols = len;
|
||||
line->sb_cells = p;
|
||||
line->sb_fill_attr = new_fill_attr;
|
||||
fill_attr = new_fill_attr;
|
||||
++term->tl_scrollback.ga_len;
|
||||
|
||||
if (ga_grow(&ga, 1) == FAIL)
|
||||
@@ -1048,6 +1088,10 @@ move_terminal_to_buffer(term_T *term)
|
||||
}
|
||||
}
|
||||
|
||||
/* Obtain the current background color. */
|
||||
vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm),
|
||||
&term->tl_default_color.fg, &term->tl_default_color.bg);
|
||||
|
||||
FOR_ALL_WINDOWS(wp)
|
||||
{
|
||||
if (wp->w_buffer == term->tl_buffer)
|
||||
@@ -2004,11 +2048,14 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
|
||||
int col;
|
||||
sb_line_T *line;
|
||||
garray_T ga;
|
||||
cellattr_T fill_attr = term->tl_default_color;
|
||||
|
||||
/* do not store empty cells at the end */
|
||||
for (i = 0; i < cols; ++i)
|
||||
if (cells[i].chars[0] != 0)
|
||||
len = i + 1;
|
||||
else
|
||||
cell2cellattr(&cells[i], &fill_attr);
|
||||
|
||||
ga_init2(&ga, 1, 100);
|
||||
if (len > 0)
|
||||
@@ -2025,10 +2072,7 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
|
||||
for (i = 0; (c = cells[col].chars[i]) > 0 || i == 0; ++i)
|
||||
ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c,
|
||||
(char_u *)ga.ga_data + ga.ga_len);
|
||||
p[col].width = cells[col].width;
|
||||
p[col].attrs = cells[col].attrs;
|
||||
p[col].fg = cells[col].fg;
|
||||
p[col].bg = cells[col].bg;
|
||||
cell2cellattr(&cells[col], &p[col]);
|
||||
}
|
||||
}
|
||||
if (ga_grow(&ga, 1) == FAIL)
|
||||
@@ -2044,6 +2088,7 @@ handle_pushline(int cols, const VTermScreenCell *cells, void *user)
|
||||
+ term->tl_scrollback.ga_len;
|
||||
line->sb_cols = len;
|
||||
line->sb_cells = p;
|
||||
line->sb_fill_attr = fill_attr;
|
||||
++term->tl_scrollback.ga_len;
|
||||
++term->tl_scrollback_scrolled;
|
||||
}
|
||||
@@ -2320,6 +2365,7 @@ term_change_in_curbuf(void)
|
||||
|
||||
/*
|
||||
* Get the screen attribute for a position in the buffer.
|
||||
* Use a negative "col" to get the filler background color.
|
||||
*/
|
||||
int
|
||||
term_get_attr(buf_T *buf, linenr_T lnum, int col)
|
||||
@@ -2329,11 +2375,15 @@ term_get_attr(buf_T *buf, linenr_T lnum, int col)
|
||||
cellattr_T *cellattr;
|
||||
|
||||
if (lnum > term->tl_scrollback.ga_len)
|
||||
return 0;
|
||||
line = (sb_line_T *)term->tl_scrollback.ga_data + lnum - 1;
|
||||
if (col >= line->sb_cols)
|
||||
return 0;
|
||||
cellattr = line->sb_cells + col;
|
||||
cellattr = &term->tl_default_color;
|
||||
else
|
||||
{
|
||||
line = (sb_line_T *)term->tl_scrollback.ga_data + lnum - 1;
|
||||
if (col < 0 || col >= line->sb_cols)
|
||||
cellattr = &line->sb_fill_attr;
|
||||
else
|
||||
cellattr = line->sb_cells + col;
|
||||
}
|
||||
return cell2attr(cellattr->attrs, cellattr->fg, cellattr->bg);
|
||||
}
|
||||
|
||||
@@ -2346,6 +2396,8 @@ create_vterm(term_T *term, int rows, int cols)
|
||||
VTerm *vterm;
|
||||
VTermScreen *screen;
|
||||
VTermValue value;
|
||||
VTermColor *fg, *bg;
|
||||
int fgval, bgval;
|
||||
|
||||
vterm = vterm_new(rows, cols);
|
||||
term->tl_vterm = vterm;
|
||||
@@ -2356,14 +2408,23 @@ create_vterm(term_T *term, int rows, int cols)
|
||||
|
||||
/* Vterm uses a default black background. Set it to white when
|
||||
* 'background' is "light". */
|
||||
vim_memset(&term->tl_default_color.attrs, 0, sizeof(VTermScreenCellAttrs));
|
||||
term->tl_default_color.width = 1;
|
||||
fg = &term->tl_default_color.fg;
|
||||
bg = &term->tl_default_color.bg;
|
||||
if (*p_bg == 'l')
|
||||
{
|
||||
VTermColor fg, bg;
|
||||
|
||||
fg.red = fg.green = fg.blue = 0;
|
||||
bg.red = bg.green = bg.blue = 255;
|
||||
vterm_state_set_default_colors(vterm_obtain_state(vterm), &fg, &bg);
|
||||
fgval = 0;
|
||||
bgval = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
fgval = 255;
|
||||
bgval = 0;
|
||||
}
|
||||
fg->red = fg->green = fg->blue = fgval;
|
||||
bg->red = bg->green = bg->blue = bgval;
|
||||
vterm_state_set_default_colors(vterm_obtain_state(vterm), fg, bg);
|
||||
|
||||
/* Required to initialize most things. */
|
||||
vterm_screen_reset(screen, 1 /* hard */);
|
||||
@@ -3101,6 +3162,7 @@ term_and_job_init(
|
||||
jobopt_T *opt)
|
||||
{
|
||||
WCHAR *cmd_wchar = NULL;
|
||||
WCHAR *cwd_wchar = NULL;
|
||||
channel_T *channel = NULL;
|
||||
job_T *job = NULL;
|
||||
DWORD error;
|
||||
@@ -3128,6 +3190,8 @@ term_and_job_init(
|
||||
cmd_wchar = enc_to_utf16(cmd, NULL);
|
||||
if (cmd_wchar == NULL)
|
||||
return FAIL;
|
||||
if (opt->jo_cwd != NULL)
|
||||
cwd_wchar = enc_to_utf16(opt->jo_cwd, NULL);
|
||||
|
||||
job = job_alloc();
|
||||
if (job == NULL)
|
||||
@@ -3154,7 +3218,7 @@ term_and_job_init(
|
||||
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
|
||||
NULL,
|
||||
cmd_wchar,
|
||||
NULL,
|
||||
cwd_wchar,
|
||||
NULL,
|
||||
&winpty_err);
|
||||
if (spawn_config == NULL)
|
||||
@@ -3205,6 +3269,7 @@ term_and_job_init(
|
||||
|
||||
winpty_spawn_config_free(spawn_config);
|
||||
vim_free(cmd_wchar);
|
||||
vim_free(cwd_wchar);
|
||||
|
||||
create_vterm(term, term->tl_rows, term->tl_cols);
|
||||
|
||||
@@ -3228,8 +3293,8 @@ term_and_job_init(
|
||||
failed:
|
||||
if (argvar->v_type == VAR_LIST)
|
||||
vim_free(ga.ga_data);
|
||||
if (cmd_wchar != NULL)
|
||||
vim_free(cmd_wchar);
|
||||
vim_free(cmd_wchar);
|
||||
vim_free(cwd_wchar);
|
||||
if (spawn_config != NULL)
|
||||
winpty_spawn_config_free(spawn_config);
|
||||
if (channel != NULL)
|
||||
|
||||
@@ -194,6 +194,7 @@ NEW_TESTS = test_arabic.res \
|
||||
test_system.res \
|
||||
test_tcl.res \
|
||||
test_terminal.res \
|
||||
test_terminal_fail.res \
|
||||
test_textobjects.res \
|
||||
test_undo.res \
|
||||
test_usercommands.res \
|
||||
|
||||
@@ -35,7 +35,8 @@ func Test_client_server()
|
||||
endif
|
||||
|
||||
" Takes a short while for the server to be active.
|
||||
call WaitFor('serverlist() =~ "' . name . '"')
|
||||
" When using valgrind it takes much longer.
|
||||
call WaitFor('serverlist() =~ "' . name . '"', 5000)
|
||||
call assert_match(name, serverlist())
|
||||
|
||||
call remote_foreground(name)
|
||||
|
||||
@@ -389,10 +389,22 @@ func! Test_normal10_expand()
|
||||
call setline(1, ['1', 'ifooar,,cbar'])
|
||||
2
|
||||
norm! $
|
||||
let a=expand('<cword>')
|
||||
let b=expand('<cWORD>')
|
||||
call assert_equal('cbar', a)
|
||||
call assert_equal('ifooar,,cbar', b)
|
||||
call assert_equal('cbar', expand('<cword>'))
|
||||
call assert_equal('ifooar,,cbar', expand('<cWORD>'))
|
||||
|
||||
call setline(1, ['prx = list[idx];'])
|
||||
1
|
||||
let expected = ['', 'prx', 'prx', 'prx',
|
||||
\ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
|
||||
\ 'idx', 'idx', 'idx', 'idx',
|
||||
\ 'list[idx]',
|
||||
\ '];',
|
||||
\ ]
|
||||
for i in range(1, 16)
|
||||
exe 'norm ' . i . '|'
|
||||
call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
|
||||
endfor
|
||||
|
||||
" clean up
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
@@ -487,6 +487,19 @@ func s:test_xhelpgrep(cchar)
|
||||
" This wipes out the buffer, make sure that doesn't cause trouble.
|
||||
Xclose
|
||||
|
||||
if a:cchar == 'l'
|
||||
" When a help window is present, running :lhelpgrep should reuse the
|
||||
" help window and not the current window
|
||||
new | only
|
||||
call g:Xsetlist([], 'f')
|
||||
help index.txt
|
||||
wincmd w
|
||||
lhelpgrep quickfix
|
||||
call assert_equal(1, winnr())
|
||||
call assert_notequal([], getloclist(1))
|
||||
call assert_equal([], getloclist(2))
|
||||
endif
|
||||
|
||||
new | only
|
||||
|
||||
" Search for non existing help string
|
||||
@@ -1684,6 +1697,10 @@ func HistoryTest(cchar)
|
||||
call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
|
||||
call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
|
||||
call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
|
||||
|
||||
call g:Xsetlist([], 'f')
|
||||
let l = split(execute(a:cchar . 'hist'), "\n")
|
||||
call assert_equal('No entries', l[0])
|
||||
endfunc
|
||||
|
||||
func Test_history()
|
||||
@@ -1862,6 +1879,11 @@ func Xproperty_tests(cchar)
|
||||
let l = g:Xgetlist({'items':1})
|
||||
call assert_equal(0, len(l.items))
|
||||
|
||||
call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
|
||||
call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
|
||||
call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
|
||||
call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
|
||||
|
||||
" The following used to crash Vim with address sanitizer
|
||||
call g:Xsetlist([], 'f')
|
||||
call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
|
||||
@@ -1904,10 +1926,10 @@ func Xproperty_tests(cchar)
|
||||
call g:Xsetlist([], 'r', l2)
|
||||
let newl1=g:Xgetlist({'nr':1,'all':1})
|
||||
let newl2=g:Xgetlist({'nr':2,'all':1})
|
||||
call assert_equal(':Fruits', newl1.title)
|
||||
call assert_equal('Fruits', newl1.title)
|
||||
call assert_equal(['Fruits'], newl1.context)
|
||||
call assert_equal('Line20', newl1.items[0].text)
|
||||
call assert_equal(':Colors', newl2.title)
|
||||
call assert_equal('Colors', newl2.title)
|
||||
call assert_equal(['Colors'], newl2.context)
|
||||
call assert_equal('Line10', newl2.items[0].text)
|
||||
call g:Xsetlist([], 'f')
|
||||
|
||||
@@ -104,6 +104,15 @@ func! s:Nasty_exit_cb(job, st)
|
||||
let g:buf = 0
|
||||
endfunc
|
||||
|
||||
func Get_cat_123_cmd()
|
||||
if has('win32')
|
||||
return 'cmd /c "cls && color 2 && echo 123"'
|
||||
else
|
||||
call writefile(["\<Esc>[32m123"], 'Xtext')
|
||||
return "cat Xtext"
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_terminal_nasty_cb()
|
||||
let cmd = Get_cat_123_cmd()
|
||||
let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')})
|
||||
@@ -143,15 +152,6 @@ func Check_123(buf)
|
||||
call assert_equal('123', l)
|
||||
endfunc
|
||||
|
||||
func Get_cat_123_cmd()
|
||||
if has('win32')
|
||||
return 'cmd /c "cls && color 2 && echo 123"'
|
||||
else
|
||||
call writefile(["\<Esc>[32m123"], 'Xtext')
|
||||
return "cat Xtext"
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_terminal_scrape_123()
|
||||
let cmd = Get_cat_123_cmd()
|
||||
let buf = term_start(cmd)
|
||||
@@ -197,7 +197,7 @@ func Test_terminal_scrape_multibyte()
|
||||
let g:line = 1
|
||||
endif
|
||||
|
||||
call WaitFor('term_scrape(g:buf, g:line)[0].chars == "l"')
|
||||
call WaitFor('len(term_scrape(g:buf, g:line)) >= 7 && term_scrape(g:buf, g:line)[0].chars == "l"')
|
||||
let l = term_scrape(g:buf, g:line)
|
||||
call assert_true(len(l) >= 7)
|
||||
call assert_equal('l', l[0].chars)
|
||||
@@ -393,18 +393,16 @@ func Test_finish_open_close()
|
||||
call assert_equal(2, winnr('$'))
|
||||
call assert_equal(4, winheight(0))
|
||||
bwipe
|
||||
|
||||
endfunc
|
||||
|
||||
func Test_terminal_cwd()
|
||||
if !has('unix')
|
||||
if !executable('pwd')
|
||||
return
|
||||
endif
|
||||
call mkdir('Xdir')
|
||||
let buf = term_start('pwd', {'cwd': 'Xdir'})
|
||||
sleep 100m
|
||||
call term_wait(buf)
|
||||
call assert_equal(getcwd() . '/Xdir', getline(1))
|
||||
call WaitFor('"Xdir" == fnamemodify(getline(1), ":t")')
|
||||
call assert_equal('Xdir', fnamemodify(getline(1), ":t"))
|
||||
|
||||
exe buf . 'bwipe'
|
||||
call delete('Xdir', 'rf')
|
||||
@@ -609,18 +607,13 @@ func Test_terminal_redir_file()
|
||||
call term_wait(buf)
|
||||
call WaitFor('len(readfile("Xfile")) > 0')
|
||||
call assert_match('123', readfile('Xfile')[0])
|
||||
let g:job = term_getjob(buf)
|
||||
call WaitFor('job_status(g:job) == "dead"')
|
||||
call delete('Xfile')
|
||||
bwipe
|
||||
endif
|
||||
|
||||
if has('unix')
|
||||
let buf = term_start('xyzabc', {'err_io': 'file', 'err_name': 'Xfile'})
|
||||
call term_wait(buf)
|
||||
call WaitFor('len(readfile("Xfile")) > 0')
|
||||
call assert_match('executing job failed', readfile('Xfile')[0])
|
||||
call delete('Xfile')
|
||||
bwipe
|
||||
|
||||
call writefile(['one line'], 'Xfile')
|
||||
let buf = term_start('cat', {'in_io': 'file', 'in_name': 'Xfile'})
|
||||
call term_wait(buf)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
" This test is in a separate file, because it usually causes reports for memory
|
||||
" leaks under valgrind. That is because when fork/exec fails memory is not
|
||||
" freed. Since the process exists right away it's not a real leak.
|
||||
|
||||
if !has('terminal')
|
||||
finish
|
||||
endif
|
||||
|
||||
source shared.vim
|
||||
|
||||
func Test_terminal_redir_fails()
|
||||
if has('unix')
|
||||
let buf = term_start('xyzabc', {'err_io': 'file', 'err_name': 'Xfile'})
|
||||
call term_wait(buf)
|
||||
call WaitFor('len(readfile("Xfile")) > 0')
|
||||
call assert_match('executing job failed', readfile('Xfile')[0])
|
||||
call WaitFor('!&modified')
|
||||
call delete('Xfile')
|
||||
bwipe
|
||||
endif
|
||||
endfunc
|
||||
@@ -784,6 +784,46 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1097,
|
||||
/**/
|
||||
1096,
|
||||
/**/
|
||||
1095,
|
||||
/**/
|
||||
1094,
|
||||
/**/
|
||||
1093,
|
||||
/**/
|
||||
1092,
|
||||
/**/
|
||||
1091,
|
||||
/**/
|
||||
1090,
|
||||
/**/
|
||||
1089,
|
||||
/**/
|
||||
1088,
|
||||
/**/
|
||||
1087,
|
||||
/**/
|
||||
1086,
|
||||
/**/
|
||||
1085,
|
||||
/**/
|
||||
1084,
|
||||
/**/
|
||||
1083,
|
||||
/**/
|
||||
1082,
|
||||
/**/
|
||||
1081,
|
||||
/**/
|
||||
1080,
|
||||
/**/
|
||||
1079,
|
||||
/**/
|
||||
1078,
|
||||
/**/
|
||||
1077,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user