Compare commits

...

36 Commits

Author SHA1 Message Date
Kazuki Sakamoto ed3fd67cfc MacVim Snapshot 149
Binary targets macOS 10.8+

- Vim patch 8.1.0072

Script interfaces have compatibility with these versions

- Lua 5.3
- Perl 5.18
- Python2 2.7
- Python3 3.6
- Ruby 2.5
2018-06-17 15:52:28 -07:00
Kazuki Sakamoto 678963c2b8 Merge remote-tracking branch 'vim/master' 2018-06-17 15:38:13 -07:00
Bram Moolenaar dcdeaaf150 patch 8.1.0072: use of 'termwinkey' is inconsistent
Problem:    Use of 'termwinkey' is inconsistent.
Solution:   Change the documentation and the behavior. (Ken Takata)
2018-06-17 22:19:12 +02:00
Bram Moolenaar b3307b5e7e patch 8.1.0071: terminal debugger only works with the terminal feature
Problem:    Terminal debugger only works with the terminal feature.
Solution:   Make it also work with a prompt buffer.  Makes it possible to use
            on MS-Windows. Various other improvements. (closes #3012)
2018-06-17 21:34:11 +02:00
Bram Moolenaar 222cd20e26 patch 8.1.0070: missing part of the changes for prompt_setinterrupt()
Problem:    Missing part of the changes for prompt_setinterrupt().
Solution:   Add the missing changes.
2018-06-17 20:10:39 +02:00
Bram Moolenaar 0e5979a6d4 patch 8.1.0069: cannot handle pressing CTRL-C in a prompt buffer
Problem:    Cannot handle pressing CTRL-C in a prompt buffer.
Solution:   Add prompt_setinterrupt().
2018-06-17 19:36:33 +02:00
Bram Moolenaar 2f82ca7d79 patch 8.1.0068: nasty autocommands can still cause using freed memory
Problem:    Nasty autocommands can still cause using freed memory.
Solution:   Disallow using setloclist() and setqflist() recursively.
2018-06-17 19:22:52 +02:00
Bram Moolenaar a5616b0136 patch 8.1.0067: syntax highlighting not working when re-entering a buffer
Problem:    Syntax highlighting not working when re-entering a buffer.
Solution:   Do force executing autocommands when not called recursively.
2018-06-17 19:08:30 +02:00
Bram Moolenaar c3ffc9b8d3 patch 8.1.0066: nasty autocommand causes using freed memory
Problem:    Nasty autocommand causes using freed memory. (Dominique Pelle)
Solution:   Do not force executing autocommands if the value of 'syntax' or
            'filetype' did not change.
2018-06-17 17:32:58 +02:00
Bram Moolenaar 0e6e179f55 patch 8.1.0065: balloon displayed at the wrong position
Problem:    Balloon displayed at the wrong position.
Solution:   Do not reposition the popup menu at the cursor position.
2018-06-17 17:10:59 +02:00
Bram Moolenaar 942b4541a2 patch 8.1.0064: typing CTRL-W in a prompt buffer shows mode "-- --"
Problem:    Typing CTRL-W in a prompt buffer shows mode "-- --".
Solution:   Set restart_edit to 'A' and check for it.
2018-06-17 16:23:34 +02:00
Bram Moolenaar d595a1910c patch 8.1.0063: Mac: NSStringPboardType is deprecated
Problem:    Mac: NSStringPboardType is deprecated.
Solution:   Use NSPasteboardTypeString. (Akshay Hegde, closes #3022)
2018-06-17 15:01:04 +02:00
Bram Moolenaar 491ac28d5f patch 8.1.0062: popup menu broken if a callback changes the window layout
Problem:    Popup menu broken if a callback changes the window layout. (Qiming
            Zhao)
Solution:   Recompute the popup menu position if needed.  Redraw the ruler
            even when the popup menu is displayed.
2018-06-17 14:47:55 +02:00
Bram Moolenaar 84a9308511 patch 8.1.0061: window title is wrong after resetting and setting 'title'
Problem:    Window title is wrong after resetting and setting 'title'.
Solution:   Move resetting the title into maketitle(). (Jason Franklin)
2018-06-16 22:58:15 +02:00
Bram Moolenaar 600323b4ef patch 8.1.0060: crash when autocommands delete the current buffer
Problem:    Crash when autocommands delete the current buffer. (Dominique
            Pelle)
Solution:   Check that autocommands don't change the buffer.
2018-06-16 22:16:47 +02:00
Bram Moolenaar bc5020aa4d patch 8.1.0059: displayed digraph for "ga" wrong with 'encoding' "cp1251"
Problem:    Displayed digraph for "ga" wrong with 'encoding' "cp1251".
Solution:   Convert from 'encoding' to "utf-8" if needed. (closes #3015)
2018-06-16 17:25:22 +02:00
Bram Moolenaar bfa4246768 patch 8.1.0058: display problem with margins and scrolling
Problem:    Display problem with margins and scrolling.
Solution:   Place the cursor in the right column. (Kouichi Iwamoto,
            closes #3016)
2018-06-16 16:20:52 +02:00
Bram Moolenaar 6ba3ec1bac patch 8.1.0057: popup menu displayed wrong when using autocmd
Problem:    Popup menu displayed wrong when using autocmd.
Solution:   Use aucmd_prepbuf().  Force updating status line if the popup menu
            is going to be redrawn anyway. (Christian Brabandt, closes #3009)
2018-06-16 15:32:38 +02:00
Bram Moolenaar 43dee181f5 patch 8.1.0056: crash when using :hardcopy with illegal byte
Problem:    Crash when using :hardcopy with illegal byte.
Solution:   Check for string_convert() returning NULL. (Dominique Pelle)
2018-06-16 14:44:11 +02:00
Bram Moolenaar 52d3aaeea4 patch 8.1.0055: complete test has wrong order of arguments
Problem:    Complete test has wrong order of arguments. Wrong type for
            sentinel variable.
Solution:   Swap arguments, use VAR_UNKNOWN. (Ozaki Kiichi)
2018-06-13 21:27:24 +02:00
Bram Moolenaar 5ecdf96422 patch 8.1.0054: compiler warning for using %ld for "long long"
Problem:    Compiler warning for using %ld for "long long".
Solution:   Add a type cast. (closes #3002)
2018-06-13 20:49:50 +02:00
Kazuki Sakamoto cf915c85f7 Merge remote-tracking branch 'vim/master' 2018-06-12 20:28:23 -07:00
Bram Moolenaar ffa9684150 patch 8.1.0053: first argument of 'completefunc' has inconsistent type
Problem:    The first argument given to 'completefunc' can be Number or
            String, depending on the value.
Solution:   Avoid guessing the type of an argument, use typval_T in the
            callers of call_vim_function(). (Ozaki Kiichi, closes #2993)
2018-06-12 22:05:14 +02:00
Bram Moolenaar 83f4cbd973 patch 8.1.0052: when mapping to <Nop> times out the next mapping is skipped
Problem:    When a mapping to <Nop> times out the next mapping is skipped.
Solution:   Reset "timedout" when waiting for a character. (Christian
            Brabandt, closes #2921)
2018-06-12 21:35:40 +02:00
Bram Moolenaar 79c6b51e40 patch 8.1.0051: MS-Windows: missing #endif
Problem:    MS-Windows: missing #endif.
Solution:   Add the #endif.
2018-06-12 21:11:12 +02:00
Bram Moolenaar 493359eb3b patch 8.1.0050: $VIM_TERMINAL is also set when not in a terminal window
Problem:    $VIM_TERMINAL is also set when not in a terminal window.
Solution:   Pass a flag to indicate whether the job runs in a terminal.
2018-06-12 20:25:52 +02:00
Bram Moolenaar d7a137fb0d patch 8.1.0049: shell cannot tell running in a terminal window
Problem:    Shell cannot tell running in a terminal window.
Solution:   Add the VIM_TERMINAL environment variable. (Christian Brabandt)
2018-06-12 18:05:24 +02:00
Bram Moolenaar 07ccf7ce7f patch 8.1.0048: vim_str2nr() does not handle numbers close to the maximum
Problem:    vim_str2nr() does not handle numbers close to the maximum.
Solution:   Check for overflow more precisely. (Ken Takata, closes #2746)
2018-06-12 17:25:36 +02:00
Bram Moolenaar 1983401088 patch 8.1.0047: no completion for :unlet $VAR
Problem:    No completion for :unlet $VAR.
Solution:   Add completion. (Jason Franklin)
2018-06-12 17:03:39 +02:00
Bram Moolenaar 1c3c10492a patch 8.1.0046: loading a session file fails if 'winheight' is big
Problem:    Loading a session file fails if 'winheight' is a big number.
Solution:   Set 'minwinheight' to zero at first.  Don't give an error when
            setting 'minwinheight' while 'winheight' is a big number.
            Fix using vertical splits. Fix setting 'minwinwidth'.
            (closes #2970)
2018-06-12 16:49:30 +02:00
Bram Moolenaar ae0f30b761 patch 8.1.0045: popup test isn't run completely
Problem:    Popup test isn't run completely.
Solution:   Remove "finish".  Clean up function definitions.
2018-06-12 15:22:43 +02:00
Bram Moolenaar 8903676d3d patch 8.1.0044: if a test function exists Vim this may go unnoticed
Problem:    If a test function exists Vim this may go unnoticed.
Solution:   Check for a test funtion quitting Vim.  Fix tests that did exit
            Vim.
2018-06-12 14:58:39 +02:00
Bram Moolenaar 7580849df9 patch 8.1.0043: ++bad argument of :edit does not work properly
Problem:    ++bad argument of :edit does not work properly.
Solution:   Return FAIL from get_bad_opt() only when there is no valid
            argument. (Dominique Pelle, Christian Brabandt, closes #2966,
            closes #2947)
2018-06-12 12:39:41 +02:00
Bram Moolenaar f98b845dd1 patch 8.1.0042: if omni completion opens a window Insert mode is stopped
Problem:    If omni completion opens a window Insert mode is stopped.
            (Hirohito Higashi)
Solution:   Only set stop_insert_mode in a prompt buffer window.
2018-06-10 14:39:52 +02:00
Bram Moolenaar e950f9992b patch 8.1.0041: attribute "width" missing from python window attribute list
Problem:    Attribute "width" missing from python window attribute list.
Solution:   Add the item. (Ken Takata) Order the list like the items are used
            in the WindowAttr() function.
2018-06-10 13:55:55 +02:00
Bram Moolenaar e31e256ba1 patch 8.1.0040: warnings from 64-bit compiler
Problem:    Warnings from 64-bit compiler.
Solution:   Add type casts. (Mike Williams)
2018-06-10 13:12:55 +02:00
48 changed files with 1184 additions and 356 deletions
+26 -12
View File
@@ -2297,8 +2297,9 @@ pow({x}, {y}) Float {x} to the power of {y}
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
printf({fmt}, {expr1}...) String format text
prompt_addtext({buf}, {expr}) none add text to a prompt buffer
prompt_setprompt({buf}, {text}) none set prompt text
prompt_setcallback({buf}, {expr}) none set prompt callback function
prompt_setinterrupt({buf}, {text}) none set prompt interrupt function
prompt_setprompt({buf}, {text}) none set prompt text
pumvisible() Number whether popup menu is visible
pyeval({expr}) any evaluate |Python| expression
py3eval({expr}) any evaluate |python3| expression
@@ -6506,17 +6507,11 @@ printf({fmt}, {expr1} ...) *printf()*
arguments an error is given. Up to 18 arguments can be used.
prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Set prompt for buffer {buf} to {text}. You most likely want
{text} to end in a space.
The result is only visible if {buf} has 'buftype' set to
"prompt". Example: >
call prompt_setprompt(bufnr(''), 'command: ')
prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
Set prompt callback for buffer {buf} to {expr}. This has only
Set prompt callback for buffer {buf} to {expr}. When {expr}
is an empty string the callback is removed. This has only
effect if {buf} has 'buftype' set to "prompt".
The callback is invoked when pressing Enter. The current
buffer will always be the prompt buffer. A new line for a
prompt is added before invoking the callback, thus the prompt
@@ -6541,6 +6536,22 @@ prompt_setcallback({buf}, {expr}) *prompt_setcallback()*
endif
endfunc
prompt_setinterrupt({buf}, {expr}) *prompt_setinterrupt()*
Set a callback for buffer {buf} to {expr}. When {expr} is an
empty string the callback is removed. This has only effect if
{buf} has 'buftype' set to "prompt".
This callback will be invoked when pressing CTRL-C in Insert
mode. Without setting a callback Vim will exit Insert mode,
as in any buffer.
prompt_setprompt({buf}, {text}) *prompt_setprompt()*
Set prompt for buffer {buf} to {text}. You most likely want
{text} to end in a space.
The result is only visible if {buf} has 'buftype' set to
"prompt". Example: >
call prompt_setprompt(bufnr(''), 'command: ')
pumvisible() *pumvisible()*
Returns non-zero when the popup menu is visible, zero
@@ -8563,7 +8574,9 @@ term_start({cmd}, {options}) *term_start()*
instead of using 'termwinsize'
"term_cols" horizontal size to use for the terminal,
instead of using 'termwinsize'
"vertical" split the window vertically
"vertical" split the window vertically; note that
other window position can be defined with
command modifiers, such as |:belowright|.
"curwin" use the current window, do not split the
window; fails if the current buffer
cannot be |abandon|ed
@@ -9396,11 +9409,12 @@ vtp Compiled for vcon support |+vtp| (check vcon to find
out if it works in the current console).
wildignore Compiled with 'wildignore' option.
wildmenu Compiled with 'wildmenu' option.
win16 old version for MS-Windows 3.1 (always False)
win32 Win32 version of Vim (MS-Windows 95 and later, 32 or
64 bits)
win32unix Win32 version of Vim, using Unix files (Cygwin)
win64 Win64 version of Vim (MS-Windows 64 bit).
win95 Win32 version for MS-Windows 95/98/ME.
win95 Win32 version for MS-Windows 95/98/ME (always False)
winaltkeys Compiled with 'winaltkeys' option.
windows Compiled with support for more than one window.
writebackup Compiled with 'writebackup' default on.
+33 -1
View File
@@ -38,6 +38,7 @@ If the result is "1" you have it.
Stepping through code |termdebug-stepping|
Inspecting variables |termdebug-variables|
Other commands |termdebug-commands|
Prompt mode |termdebug-prompt|
Communication |termdebug-communication|
Customizing |termdebug-customizing|
@@ -86,7 +87,8 @@ to the job. For example:
'termwinkey' CTRL-W move focus to the next window
'termwinkey' : enter an Ex command
'termwinkey' 'termwinkey' send 'termwinkey' to the job in the terminal
'termwinkey' . send a CTRL-W to the job in the terminal
'termwinkey' . send 'termwinkey' to the job in the terminal
'termwinkey' CTRL-\ send a CTRL-\ to the job in the terminal
'termwinkey' N go to terminal Normal mode, see below
'termwinkey' CTRL-N same as CTRL-W N
'termwinkey' CTRL-C same as |t_CTRL-W_CTRL-C|
@@ -376,6 +378,7 @@ Environment variables are used to pass information to the running job:
COLUMNS number of columns in the terminal initially
COLORS number of colors, 't_Co' (256*256*256 in the GUI)
VIM_SERVERNAME v:servername
VIM_TERMINAL v:version
MS-Windows ~
@@ -619,6 +622,10 @@ The Terminal debugging plugin can be used to debug a program with gdb and view
the source code in a Vim window. Since this is completely contained inside
Vim this also works remotely over an ssh connection.
When the |+terminal| feature is missing, the plugin will use the "prompt"
buffer type, if possible. The running program will then use a newly opened
terminal window. See |termdebug-prompt| below for details.
Starting ~
*termdebug-starting*
@@ -798,6 +805,23 @@ Other commands ~
isn't one
Prompt mode ~
*termdebug-prompt*
When the |+terminal| feature is not supported and on MS-Windows, gdb will run
in a buffer with 'buftype' set to "prompt". This works slightly differently:
- The gdb window will be in Insert mode while typing commands. Go to Normal
mode with <Esc>, then you can move around in the buffer, copy/paste, etc.
Go back to editing the gdb command with any command that starts Insert mode,
such as `a` or `i`.
- The program being debugged will run in a separate window. On MS-Windows
this is a new console window. On Unix, if the |+terminal| feature is
available a Terminal window will be opened to run the debugged program in.
*termdebug_use_prompt*
Prompt mode can be used even when the |+terminal| feature is present with: >
let g:termdebug_use_prompt = 1
Communication ~
*termdebug-communication*
There is another, hidden, buffer, which is used for Vim to communicate with
@@ -835,6 +859,14 @@ When 'background' is "dark":
hi debugBreakpoint term=reverse ctermbg=red guibg=red
Shorcuts *termdebug_shortcuts*
You can define your own shortcuts (mappings) to control gdb, that can work in
any window, using the TermDebugSendCommand() function. Example: >
map ,w :call TermDebugSendCommand('where')<CR>
The argument is the gdb command.
Popup menu *termdebug_popup*
By default the Termdebug plugin sets 'mousemodel' to "popup_setpos" and adds
+326 -47
View File
@@ -1,27 +1,60 @@
" Debugger plugin using gdb.
"
" WORK IN PROGRESS - much doesn't work yet
"
" Open two visible terminal windows:
" 1. run a pty, as with ":term NONE"
" 2. run gdb, passing the pty
" The current window is used to view source code and follows gdb.
"
" A third terminal window is hidden, it is used for communication with gdb.
"
" The communication with gdb uses GDB/MI. See:
" https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html
"
" Author: Bram Moolenaar
" Copyright: Vim license applies, see ":help license"
" Last Update: 2018 Jun 3
"
" WORK IN PROGRESS - Only the basics work
" Note: On MS-Windows you need a recent version of gdb. The one included with
" MingW is too old (7.6.1).
" I used version 7.12 from http://www.equation.com/servlet/equation.cmd?fa=gdb
"
" There are two ways to run gdb:
" - In a terminal window; used if possible, does not work on MS-Windows
" Not used when g:termdebug_use_prompt is set to 1.
" - Using a "prompt" buffer; may use a terminal window for the program
"
" For both the current window is used to view source code and shows the
" current statement from gdb.
"
" USING A TERMINAL WINDOW
"
" Opens two visible terminal windows:
" 1. runs a pty for the debugged program, as with ":term NONE"
" 2. runs gdb, passing the pty of the debugged program
" A third terminal window is hidden, it is used for communication with gdb.
"
" USING A PROMPT BUFFER
"
" Opens a window with a prompt buffer to communicate with gdb.
" Gdb is run as a job with callbacks for I/O.
" On Unix another terminal window is opened to run the debugged program
" On MS-Windows a separate console is opened to run the debugged program
"
" The communication with gdb uses GDB/MI. See:
" https://sourceware.org/gdb/current/onlinedocs/gdb/GDB_002fMI.html
" In case this gets loaded twice.
" In case this gets sourced twice.
if exists(':Termdebug')
finish
endif
" Uncomment this line to write logging in "debuglog".
" call ch_logfile('debuglog', 'w')
" Need either the +terminal feature or +channel and the prompt buffer.
" The terminal feature does not work with gdb on win32.
if has('terminal') && !has('win32')
let s:way = 'terminal'
elseif has('channel') && exists('*prompt_setprompt')
let s:way = 'prompt'
else
if has('terminal')
let s:err = 'Cannot debug, missing prompt buffer support'
else
let s:err = 'Cannot debug, +channel feature is not supported'
endif
command -nargs=* -complete=file -bang Termdebug echoerr s:err
command -nargs=+ -complete=file -bang TermdebugCommand echoerr s:err
finish
endif
" The command that starts debugging, e.g. ":Termdebug vim".
" To end type "quit" in the gdb window.
@@ -59,8 +92,12 @@ func s:StartDebug_internal(dict)
echoerr 'Terminal debugger already running'
return
endif
let s:ptywin = 0
let s:startwin = win_getid(winnr())
" Uncomment this line to write logging in "debuglog".
" call ch_logfile('debuglog', 'w')
let s:sourcewin = win_getid(winnr())
let s:startsigncolumn = &signcolumn
let s:save_columns = 0
@@ -69,15 +106,31 @@ func s:StartDebug_internal(dict)
let s:save_columns = &columns
let &columns = g:termdebug_wide
endif
let vertical = 1
let s:vertical = 1
else
let vertical = 0
let s:vertical = 0
endif
" Open a terminal window without a job, to run the debugged program
" Override using a terminal window by setting g:termdebug_use_prompt to 1.
let use_prompt = exists('g:termdebug_use_prompt') && g:termdebug_use_prompt
if has('terminal') && !has('win32') && !use_prompt
let s:way = 'terminal'
else
let s:way = 'prompt'
endif
if s:way == 'prompt'
call s:StartDebug_prompt(a:dict)
else
call s:StartDebug_term(a:dict)
endif
endfunc
func s:StartDebug_term(dict)
" Open a terminal window without a job, to run the debugged program in.
let s:ptybuf = term_start('NONE', {
\ 'term_name': 'gdb program',
\ 'vertical': vertical,
\ 'term_name': 'debugged program',
\ 'vertical': s:vertical,
\ })
if s:ptybuf == 0
echoerr 'Failed to open the program terminal window'
@@ -85,7 +138,7 @@ func s:StartDebug_internal(dict)
endif
let pty = job_info(term_getjob(s:ptybuf))['tty_out']
let s:ptywin = win_getid(winnr())
if vertical
if s:vertical
" Assuming the source code window will get a signcolumn, use two more
" columns for that, thus one less for the terminal window.
exe (&columns / 2 - 1) . "wincmd |"
@@ -110,9 +163,9 @@ func s:StartDebug_internal(dict)
let proc_args = get(a:dict, 'proc_args', [])
let cmd = [g:termdebugger, '-quiet', '-tty', pty] + gdb_args
echomsg 'executing "' . join(cmd) . '"'
call ch_log('executing "' . join(cmd) . '"')
let s:gdbbuf = term_start(cmd, {
\ 'exit_cb': function('s:EndDebug'),
\ 'exit_cb': function('s:EndTermDebug'),
\ 'term_finish': 'close',
\ })
if s:gdbbuf == 0
@@ -166,11 +219,108 @@ func s:StartDebug_internal(dict)
" exec-interrupt, since many commands don't work properly while the target is
" running.
call s:SendCommand('-gdb-set mi-async on')
" Older gdb uses a different command.
call s:SendCommand('-gdb-set target-async on')
" Disable pagination, it causes everything to stop at the gdb
" "Type <return> to continue" prompt.
call s:SendCommand('-gdb-set pagination off')
call s:SendCommand('set pagination off')
call s:StartDebugCommon(a:dict)
endfunc
func s:StartDebug_prompt(dict)
" Open a window with a prompt buffer to run gdb in.
if s:vertical
vertical new
else
new
endif
let s:gdbwin = win_getid(winnr())
let s:promptbuf = bufnr('')
call prompt_setprompt(s:promptbuf, 'gdb> ')
set buftype=prompt
file gdb
call prompt_setcallback(s:promptbuf, function('s:PromptCallback'))
call prompt_setinterrupt(s:promptbuf, function('s:PromptInterrupt'))
if s:vertical
" Assuming the source code window will get a signcolumn, use two more
" columns for that, thus one less for the terminal window.
exe (&columns / 2 - 1) . "wincmd |"
endif
" Add -quiet to avoid the intro message causing a hit-enter prompt.
let gdb_args = get(a:dict, 'gdb_args', [])
let proc_args = get(a:dict, 'proc_args', [])
let cmd = [g:termdebugger, '-quiet', '--interpreter=mi2'] + gdb_args
call ch_log('executing "' . join(cmd) . '"')
let s:gdbjob = job_start(cmd, {
\ 'exit_cb': function('s:EndPromptDebug'),
\ 'out_cb': function('s:GdbOutCallback'),
\ })
if job_status(s:gdbjob) != "run"
echoerr 'Failed to start gdb'
exe 'bwipe! ' . s:promptbuf
return
endif
let s:gdb_channel = job_getchannel(s:gdbjob)
" Interpret commands while the target is running. This should usualy only
" be exec-interrupt, since many commands don't work properly while the
" target is running.
call s:SendCommand('-gdb-set mi-async on')
" Older gdb uses a different command.
call s:SendCommand('-gdb-set target-async on')
let s:ptybuf = 0
if has('win32')
" MS-Windows: run in a new console window for maximum compatibility
call s:SendCommand('set new-console on')
elseif has('terminal')
" Unix: Run the debugged program in a terminal window. Open it below the
" gdb window.
belowright let s:ptybuf = term_start('NONE', {
\ 'term_name': 'debugged program',
\ })
if s:ptybuf == 0
echoerr 'Failed to open the program terminal window'
call job_stop(s:gdbjob)
return
endif
let s:ptywin = win_getid(winnr())
let pty = job_info(term_getjob(s:ptybuf))['tty_out']
call s:SendCommand('tty ' . pty)
" Since GDB runs in a prompt window, the environment has not been set to
" match a terminal window, need to do that now.
call s:SendCommand('set env TERM = xterm-color')
call s:SendCommand('set env ROWS = ' . winheight(s:ptywin))
call s:SendCommand('set env LINES = ' . winheight(s:ptywin))
call s:SendCommand('set env COLUMNS = ' . winwidth(s:ptywin))
call s:SendCommand('set env COLORS = ' . &t_Co)
call s:SendCommand('set env VIM_TERMINAL = ' . v:version)
else
" TODO: open a new terminal get get the tty name, pass on to gdb
call s:SendCommand('show inferior-tty')
endif
call s:SendCommand('set print pretty on')
call s:SendCommand('set breakpoint pending on')
" Disable pagination, it causes everything to stop at the gdb
call s:SendCommand('set pagination off')
" Set arguments to be run
if len(proc_args)
call s:SendCommand('set args ' . join(proc_args))
endif
call s:StartDebugCommon(a:dict)
startinsert
endfunc
func s:StartDebugCommon(dict)
" Sign used to highlight the line where the program has stopped.
" There can be only one.
sign define debugPC linehl=debugPC
@@ -180,7 +330,7 @@ func s:StartDebug_internal(dict)
sign define debugBreakpoint text=>> texthl=debugBreakpoint
" Install debugger commands in the text window.
call win_gotoid(s:startwin)
call win_gotoid(s:sourcewin)
call s:InstallCommands()
call win_gotoid(s:gdbwin)
@@ -202,27 +352,130 @@ func s:StartDebug_internal(dict)
au BufUnload * call s:BufUnloaded()
augroup END
" Run the command if the bang attribute was given
" and got to the window
" Run the command if the bang attribute was given and got to the debug
" window.
if get(a:dict, 'bang', 0)
call s:SendCommand('-exec-run')
call win_gotoid(s:ptywin)
endif
endfunc
func s:EndDebug(job, status)
exe 'bwipe! ' . s:ptybuf
" Send a command to gdb. "cmd" is the string without line terminator.
func s:SendCommand(cmd)
call ch_log('sending to gdb: ' . a:cmd)
if s:way == 'prompt'
call ch_sendraw(s:gdb_channel, a:cmd . "\n")
else
call term_sendkeys(s:commbuf, a:cmd . "\r")
endif
endfunc
" This is global so that a user can create their mappings with this.
func TermDebugSendCommand(cmd)
if s:way == 'prompt'
call ch_sendraw(s:gdb_channel, a:cmd . "\n")
else
let do_continue = 0
if !s:stopped
let do_continue = 1
call s:SendCommand('-exec-interrupt')
sleep 10m
endif
call term_sendkeys(s:gdbbuf, a:cmd . "\r")
if do_continue
Continue
endif
endif
endfunc
" Function called when entering a line in the prompt buffer.
func s:PromptCallback(text)
call s:SendCommand(a:text)
endfunc
" Function called when pressing CTRL-C in the prompt buffer.
func s:PromptInterrupt()
call ch_log('Interrupting gdb')
call job_stop(s:gdbjob, 'int')
endfunc
" Function called when gdb outputs text.
func s:GdbOutCallback(channel, text)
call ch_log('received from gdb: ' . a:text)
" Drop the gdb prompt, we have our own.
" Drop status and echo'd commands.
if a:text == '(gdb) ' || a:text == '^done' || a:text[0] == '&' || a:text[0] == '='
return
endif
if a:text =~ '^^error,msg='
let text = s:DecodeMessage(a:text[11:])
if exists('s:evalexpr') && text =~ 'A syntax error in expression, near\|No symbol .* in current context'
" Silently drop evaluation errors.
unlet s:evalexpr
return
endif
elseif a:text[0] == '~'
let text = s:DecodeMessage(a:text[1:])
else
call s:CommOutput(a:channel, a:text)
return
endif
let curwinid = win_getid(winnr())
call win_gotoid(s:gdbwin)
" Add the output above the current prompt.
call append(line('$') - 1, text)
set nomodified
call win_gotoid(curwinid)
endfunc
" Decode a message from gdb. quotedText starts with a ", return the text up
" to the next ", unescaping characters.
func s:DecodeMessage(quotedText)
if a:quotedText[0] != '"'
echoerr 'DecodeMessage(): missing quote'
return
endif
let result = ''
let i = 1
while a:quotedText[i] != '"' && i < len(a:quotedText)
if a:quotedText[i] == '\'
let i += 1
if a:quotedText[i] == 'n'
" drop \n
let i += 1
continue
endif
endif
let result .= a:quotedText[i]
let i += 1
endwhile
return result
endfunc
func s:EndTermDebug(job, status)
exe 'bwipe! ' . s:commbuf
unlet s:gdbwin
call s:EndDebugCommon()
endfunc
func s:EndDebugCommon()
let curwinid = win_getid(winnr())
call win_gotoid(s:startwin)
if exists('s:ptybuf') && s:ptybuf
exe 'bwipe! ' . s:ptybuf
endif
call win_gotoid(s:sourcewin)
let &signcolumn = s:startsigncolumn
call s:DeleteCommands()
call win_gotoid(curwinid)
if s:save_columns > 0
let &columns = s:save_columns
endif
@@ -240,6 +493,19 @@ func s:EndDebug(job, status)
au! TermDebug
endfunc
func s:EndPromptDebug(job, status)
let curwinid = win_getid(winnr())
call win_gotoid(s:gdbwin)
close
if curwinid != s:gdbwin
call win_gotoid(curwinid)
endif
call s:EndDebugCommon()
unlet s:gdbwin
call ch_log("Returning from EndPromptDebug()")
endfunc
" Handle a message received from gdb on the GDB/MI interface.
func s:CommOutput(chan, msg)
let msgs = split(a:msg, "\r")
@@ -275,11 +541,18 @@ func s:InstallCommands()
command -nargs=* Run call s:Run(<q-args>)
command -nargs=* Arguments call s:SendCommand('-exec-arguments ' . <q-args>)
command Stop call s:SendCommand('-exec-interrupt')
command Continue call s:SendCommand('-exec-continue')
" using -exec-continue results in CTRL-C in gdb window not working
if s:way == 'prompt'
command Continue call s:SendCommand('continue')
else
command Continue call term_sendkeys(s:gdbbuf, "continue\r")
endif
command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
command Gdb call win_gotoid(s:gdbwin)
command Program call win_gotoid(s:ptywin)
command Source call s:GotoStartwinOrCreateIt()
command Source call s:GotoSourcewinOrCreateIt()
command Winbar call s:InstallWinbar()
" TODO: can the K mapping be restored?
@@ -375,7 +648,13 @@ func s:SetBreakpoint()
let do_continue = 0
if !s:stopped
let do_continue = 1
call s:SendCommand('-exec-interrupt')
if s:way == 'prompt'
" Need to send a signal to get the UI to listen. Strangely this is only
" needed once.
call job_stop(s:gdbjob, 'int')
else
call s:SendCommand('-exec-interrupt')
endif
sleep 10m
endif
call s:SendCommand('-break-insert --source '
@@ -391,7 +670,7 @@ func s:ClearBreakpoint()
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")
call s:SendCommand('-break-delete ' . key)
" Assume this always wors, the reply is simply "^done".
exe 'sign unplace ' . (s:break_id + key)
unlet s:breakpoints[key]
@@ -400,11 +679,6 @@ func s:ClearBreakpoint()
endfor
endfunc
" :Next, :Continue, etc - send a command to gdb
func s:SendCommand(cmd)
call term_sendkeys(s:commbuf, a:cmd . "\r")
endfunc
func s:Run(args)
if a:args != ''
call s:SendCommand('-exec-arguments ' . a:args)
@@ -466,7 +740,12 @@ endfunc
" Show a balloon with information of the variable under the mouse pointer,
" if there is any.
func TermDebugBalloonExpr()
if v:beval_winid != s:startwin
if v:beval_winid != s:sourcewin
return
endif
if !s:stopped
" Only evaluate when stopped, otherwise setting a breakpoint using the
" mouse triggers a balloon.
return
endif
let s:evalFromBalloonExpr = 1
@@ -487,10 +766,10 @@ func s:HandleError(msg)
echoerr substitute(a:msg, '.*msg="\(.*\)"', '\1', '')
endfunc
func s:GotoStartwinOrCreateIt()
if !win_gotoid(s:startwin)
func s:GotoSourcewinOrCreateIt()
if !win_gotoid(s:sourcewin)
new
let s:startwin = win_getid(winnr())
let s:sourcewin = win_getid(winnr())
call s:InstallWinbar()
endif
endfunc
@@ -506,7 +785,7 @@ func s:HandleCursor(msg)
let s:stopped = 0
endif
call s:GotoStartwinOrCreateIt()
call s:GotoSourcewinOrCreateIt()
let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '')
if a:msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname)
@@ -516,7 +795,7 @@ func s:HandleCursor(msg)
if &modified
" TODO: find existing window
exe 'split ' . fnameescape(fname)
let s:startwin = win_getid(winnr())
let s:sourcewin = win_getid(winnr())
call s:InstallWinbar()
else
exe 'edit ' . fnameescape(fname)
+1 -1
View File
@@ -1255,7 +1255,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>148</string>
<string>149</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
+31 -28
View File
@@ -38,7 +38,7 @@ static int buf_same_ino(buf_T *buf, stat_T *stp);
static int otherfile_buf(buf_T *buf, char_u *ffname);
#endif
#ifdef FEAT_TITLE
static int ti_change(char_u *str, char_u **last);
static int value_changed(char_u *str, char_u **last);
#endif
static int append_arg_number(win_T *wp, char_u *buf, int buflen, int add_file);
static void free_buffer(buf_T *);
@@ -3549,20 +3549,18 @@ col_print(
}
#if defined(FEAT_TITLE) || defined(PROTO)
/*
* put file name in title bar of window and in icon title
*/
static char_u *lasttitle = NULL;
static char_u *lasticon = NULL;
/*
* Put the file name in the title bar and icon of the window.
*/
void
maketitle(void)
{
char_u *p;
char_u *t_str = NULL;
char_u *i_name;
char_u *i_str = NULL;
char_u *title_str = NULL;
char_u *icon_str = NULL;
int maxlen = 0;
int len;
int mustset;
@@ -3582,7 +3580,7 @@ maketitle(void)
need_maketitle = FALSE;
if (!p_title && !p_icon && lasttitle == NULL && lasticon == NULL)
return;
return; // nothing to do
if (p_title)
{
@@ -3593,7 +3591,7 @@ maketitle(void)
maxlen = 10;
}
t_str = buf;
title_str = buf;
if (*p_titlestring != NUL)
{
#ifdef FEAT_STL_OPT
@@ -3606,7 +3604,7 @@ maketitle(void)
use_sandbox = was_set_insecurely((char_u *)"titlestring", 0);
# endif
called_emsg = FALSE;
build_stl_str_hl(curwin, t_str, sizeof(buf),
build_stl_str_hl(curwin, title_str, sizeof(buf),
p_titlestring, use_sandbox,
0, maxlen, NULL, NULL);
if (called_emsg)
@@ -3616,7 +3614,7 @@ maketitle(void)
}
else
#endif
t_str = p_titlestring;
title_str = p_titlestring;
}
else
{
@@ -3724,11 +3722,11 @@ maketitle(void)
}
}
}
mustset = ti_change(t_str, &lasttitle);
mustset = value_changed(title_str, &lasttitle);
if (p_icon)
{
i_str = buf;
icon_str = buf;
if (*p_iconstring != NUL)
{
#ifdef FEAT_STL_OPT
@@ -3741,7 +3739,7 @@ maketitle(void)
use_sandbox = was_set_insecurely((char_u *)"iconstring", 0);
# endif
called_emsg = FALSE;
build_stl_str_hl(curwin, i_str, sizeof(buf),
build_stl_str_hl(curwin, icon_str, sizeof(buf),
p_iconstring, use_sandbox,
0, 0, NULL, NULL);
if (called_emsg)
@@ -3751,32 +3749,32 @@ maketitle(void)
}
else
#endif
i_str = p_iconstring;
icon_str = p_iconstring;
}
else
{
if (buf_spname(curbuf) != NULL)
i_name = buf_spname(curbuf);
p = buf_spname(curbuf);
else /* use file name only in icon */
i_name = gettail(curbuf->b_ffname);
*i_str = NUL;
p = gettail(curbuf->b_ffname);
*icon_str = NUL;
/* Truncate name at 100 bytes. */
len = (int)STRLEN(i_name);
len = (int)STRLEN(p);
if (len > 100)
{
len -= 100;
#ifdef FEAT_MBYTE
if (has_mbyte)
len += (*mb_tail_off)(i_name, i_name + len) + 1;
len += (*mb_tail_off)(p, p + len) + 1;
#endif
i_name += len;
p += len;
}
STRCPY(i_str, i_name);
trans_characters(i_str, IOSIZE);
STRCPY(icon_str, p);
trans_characters(icon_str, IOSIZE);
}
}
mustset |= ti_change(i_str, &lasticon);
mustset |= value_changed(icon_str, &lasticon);
if (mustset)
resettitle();
@@ -3785,20 +3783,25 @@ maketitle(void)
/*
* Used for title and icon: Check if "str" differs from "*last". Set "*last"
* from "str" if it does.
* Return TRUE when "*last" changed.
* Return TRUE if resettitle() is to be called.
*/
static int
ti_change(char_u *str, char_u **last)
value_changed(char_u *str, char_u **last)
{
if ((str == NULL) != (*last == NULL)
|| (str != NULL && *last != NULL && STRCMP(str, *last) != 0))
{
vim_free(*last);
if (str == NULL)
{
*last = NULL;
mch_restore_title(last == &lasttitle ? 1 : 2);
}
else
{
*last = vim_strsave(str);
return TRUE;
return TRUE;
}
}
return FALSE;
}
+31 -3
View File
@@ -5567,7 +5567,11 @@ job_check_ended(void)
* Returns NULL when out of memory.
*/
job_T *
job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
job_start(
typval_T *argvars,
char **argv_arg,
jobopt_T *opt_arg,
int is_terminal UNUSED)
{
job_T *job;
char_u *cmd = NULL;
@@ -5721,7 +5725,7 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
ch_log(NULL, "Starting job: %s", (char *)ga.ga_data);
ga_clear(&ga);
}
mch_job_start(argv, job, &opt);
mch_job_start(argv, job, &opt, is_terminal);
#else
ch_log(NULL, "Starting job: %s", (char *)cmd);
mch_job_start((char *)cmd, job, &opt);
@@ -5894,7 +5898,7 @@ invoke_prompt_callback(void)
curwin->w_cursor.lnum = lnum + 1;
curwin->w_cursor.col = 0;
if (curbuf->b_prompt_callback == NULL)
if (curbuf->b_prompt_callback == NULL || *curbuf->b_prompt_callback == NUL)
return;
text = ml_get(lnum);
prompt = prompt_text();
@@ -5912,6 +5916,30 @@ invoke_prompt_callback(void)
clear_tv(&rettv);
}
/*
* Return TRUE when the interrupt callback was invoked.
*/
int
invoke_prompt_interrupt(void)
{
typval_T rettv;
int dummy;
typval_T argv[1];
if (curbuf->b_prompt_interrupt == NULL
|| *curbuf->b_prompt_interrupt == NUL)
return FALSE;
argv[0].v_type = VAR_UNKNOWN;
got_int = FALSE; // don't skip executing commands
call_func(curbuf->b_prompt_interrupt,
(int)STRLEN(curbuf->b_prompt_interrupt),
&rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE,
curbuf->b_prompt_int_partial, NULL);
clear_tv(&rettv);
return TRUE;
}
# ifdef FEAT_GUI_MACVIM
void
job_cleanup_all(void)
+9 -6
View File
@@ -1928,8 +1928,8 @@ vim_str2nr(
while ('0' <= *ptr && *ptr <= '1')
{
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 2)
un = 2 * un + (unsigned long)(*ptr - '0');
if (un <= UVARNUM_MAX / 2)
un = 2 * un + (uvarnumber_T)(*ptr - '0');
else
un = UVARNUM_MAX;
++ptr;
@@ -1943,7 +1943,7 @@ vim_str2nr(
while ('0' <= *ptr && *ptr <= '7')
{
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 8)
if (un <= UVARNUM_MAX / 8)
un = 8 * un + (uvarnumber_T)(*ptr - '0');
else
un = UVARNUM_MAX;
@@ -1960,7 +1960,7 @@ vim_str2nr(
while (vim_isxdigit(*ptr))
{
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 16)
if (un <= UVARNUM_MAX / 16)
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
else
un = UVARNUM_MAX;
@@ -1974,9 +1974,12 @@ vim_str2nr(
/* decimal */
while (VIM_ISDIGIT(*ptr))
{
uvarnumber_T digit = (uvarnumber_T)(*ptr - '0');
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 10)
un = 10 * un + (uvarnumber_T)(*ptr - '0');
if (un < UVARNUM_MAX / 10
|| (un == UVARNUM_MAX / 10 && digit <= UVARNUM_MAX % 10))
un = 10 * un + digit;
else
un = UVARNUM_MAX;
++ptr;
+25 -2
View File
@@ -1979,14 +1979,37 @@ do_digraph(int c)
* If not found return NULL.
*/
char_u *
get_digraph_for_char(val)
int val;
get_digraph_for_char(int val_arg)
{
int val = val_arg;
int i;
int use_defaults;
digr_T *dp;
static char_u r[3];
#if defined(FEAT_MBYTE) && defined(USE_UNICODE_DIGRAPHS)
if (!enc_utf8)
{
char_u buf[6], *to;
vimconv_T vc;
// convert the character from 'encoding' to Unicode
i = mb_char2bytes(val, buf);
vc.vc_type = CONV_NONE;
if (convert_setup(&vc, p_enc, (char_u *)"utf-8") == OK)
{
vc.vc_fail = TRUE;
to = string_convert(&vc, buf, &i);
if (to != NULL)
{
val = utf_ptr2char(to);
vim_free(to);
}
(void)convert_setup(&vc, NULL, NULL);
}
}
#endif
for (use_defaults = 0; use_defaults <= 1; use_defaults++)
{
if (use_defaults == 0)
+39 -10
View File
@@ -1016,6 +1016,19 @@ edit(
goto doESCkey;
}
#endif
#ifdef FEAT_JOB_CHANNEL
if (c == Ctrl_C && bt_prompt(curbuf))
{
if (invoke_prompt_interrupt())
{
if (!bt_prompt(curbuf))
// buffer changed to a non-prompt buffer, get out of
// Insert mode
goto doESCkey;
break;
}
}
#endif
#ifdef UNIX
do_intr:
@@ -1179,7 +1192,7 @@ doESCkey:
// In a prompt window CTRL-W is used for window commands.
// Use Shift-CTRL-W to delete a word.
stuffcharReadbuff(Ctrl_W);
restart_edit = 'i';
restart_edit = 'A';
nomove = TRUE;
count = 0;
goto doESCkey;
@@ -1713,7 +1726,12 @@ ins_redraw(
#endif
)
{
aco_save_T aco;
// save and restore curwin and curbuf, in case the autocmd changes them
aucmd_prepbuf(&aco, curbuf);
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
aucmd_restbuf(&aco);
curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
}
@@ -1725,7 +1743,12 @@ ins_redraw(
&& curbuf->b_last_changedtick_pum != CHANGEDTICK(curbuf)
&& pum_visible())
{
aco_save_T aco;
// save and restore curwin and curbuf, in case the autocmd changes them
aucmd_prepbuf(&aco, curbuf);
apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
aucmd_restbuf(&aco);
curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf);
}
#endif
@@ -1903,7 +1926,7 @@ init_prompt(int cmdchar_todo)
|| Insstart_orig.col != (int)STRLEN(prompt))
{
Insstart.lnum = curwin->w_cursor.lnum;
Insstart.col = STRLEN(prompt);
Insstart.col = (int)STRLEN(prompt);
Insstart_orig = Insstart;
Insstart_textlen = Insstart.col;
Insstart_blank_vcol = MAXCOL;
@@ -1913,7 +1936,7 @@ init_prompt(int cmdchar_todo)
if (cmdchar_todo == 'A')
coladvance((colnr_T)MAXCOL);
if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt))
curwin->w_cursor.col = STRLEN(prompt);
curwin->w_cursor.col = (int)STRLEN(prompt);
/* Make sure the cursor is in a valid position. */
check_cursor();
}
@@ -4215,7 +4238,7 @@ expand_by_function(
{
list_T *matchlist = NULL;
dict_T *matchdict = NULL;
char_u *args[2];
typval_T args[3];
char_u *funcname;
pos_T pos;
win_T *curwin_save;
@@ -4227,15 +4250,18 @@ expand_by_function(
return;
/* Call 'completefunc' to obtain the list of matches. */
args[0] = (char_u *)"0";
args[1] = base;
args[0].v_type = VAR_NUMBER;
args[0].vval.v_number = 0;
args[1].v_type = VAR_STRING;
args[1].vval.v_string = base != NULL ? base : (char_u *)"";
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
/* Call a function, which returns a list or dict. */
if (call_vim_function(funcname, 2, args, FALSE, FALSE, &rettv) == OK)
if (call_vim_function(funcname, 2, args, &rettv, FALSE) == OK)
{
switch (rettv.v_type)
{
@@ -5542,7 +5568,7 @@ ins_complete(int c, int enable_pum)
* Call user defined function 'completefunc' with "a:findstart"
* set to 1 to obtain the length of text to use for completion.
*/
char_u *args[2];
typval_T args[3];
int col;
char_u *funcname;
pos_T pos;
@@ -5562,8 +5588,11 @@ ins_complete(int c, int enable_pum)
return FAIL;
}
args[0] = (char_u *)"1";
args[1] = NULL;
args[0].v_type = VAR_NUMBER;
args[0].vval.v_number = 1;
args[1].v_type = VAR_STRING;
args[1].vval.v_string = (char_u *)"";
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
+18 -60
View File
@@ -1011,63 +1011,22 @@ eval_expr(char_u *arg, char_u **nextcmd)
/*
* Call some Vim script function and return the result in "*rettv".
* Uses argv[argc] for the function arguments. Only Number and String
* arguments are currently supported.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc]
* should have type VAR_UNKNOWN.
* Returns OK or FAIL.
*/
int
call_vim_function(
char_u *func,
int argc,
char_u **argv,
int safe, /* use the sandbox */
int str_arg_only, /* all arguments are strings */
typval_T *rettv)
typval_T *argv,
typval_T *rettv,
int safe) /* use the sandbox */
{
typval_T *argvars;
varnumber_T n;
int len;
int i;
int doesrange;
void *save_funccalp = NULL;
int ret;
argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T)));
if (argvars == NULL)
return FAIL;
for (i = 0; i < argc; i++)
{
/* Pass a NULL or empty argument as an empty string */
if (argv[i] == NULL || *argv[i] == NUL)
{
argvars[i].v_type = VAR_STRING;
argvars[i].vval.v_string = (char_u *)"";
continue;
}
if (str_arg_only)
len = 0;
else
{
/* Recognize a number argument, the others must be strings. A dash
* is a string too. */
vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
if (len == 1 && *argv[i] == '-')
len = 0;
}
if (len != 0 && len == (int)STRLEN(argv[i]))
{
argvars[i].v_type = VAR_NUMBER;
argvars[i].vval.v_number = n;
}
else
{
argvars[i].v_type = VAR_STRING;
argvars[i].vval.v_string = argv[i];
}
}
if (safe)
{
save_funccalp = save_funccal();
@@ -1075,7 +1034,7 @@ call_vim_function(
}
rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, NULL,
ret = call_func(func, (int)STRLEN(func), rettv, argc, argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, TRUE, NULL, NULL);
if (safe)
@@ -1083,7 +1042,6 @@ call_vim_function(
--sandbox;
restore_funccal(save_funccalp);
}
vim_free(argvars);
if (ret == FAIL)
clear_tv(rettv);
@@ -1094,20 +1052,20 @@ call_vim_function(
/*
* Call Vim script function "func" and return the result as a number.
* Returns -1 when calling the function fails.
* Uses argv[argc] for the function arguments.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
* have type VAR_UNKNOWN.
*/
varnumber_T
call_func_retnr(
char_u *func,
int argc,
char_u **argv,
typval_T *argv,
int safe) /* use the sandbox */
{
typval_T rettv;
varnumber_T retval;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
return -1;
retval = get_tv_number_chk(&rettv, NULL);
@@ -1122,20 +1080,20 @@ call_func_retnr(
/*
* Call Vim script function "func" and return the result as a string.
* Returns NULL when calling the function fails.
* Uses argv[argc] for the function arguments.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
* have type VAR_UNKNOWN.
*/
void *
call_func_retstr(
char_u *func,
int argc,
char_u **argv,
typval_T *argv,
int safe) /* use the sandbox */
{
typval_T rettv;
char_u *retval;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
return NULL;
retval = vim_strsave(get_tv_string(&rettv));
@@ -1146,20 +1104,20 @@ call_func_retstr(
/*
* Call Vim script function "func" and return the result as a List.
* Uses argv[argc] for the function arguments.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
* have type VAR_UNKNOWN.
* Returns NULL when there is something wrong.
*/
void *
call_func_retlist(
char_u *func,
int argc,
char_u **argv,
typval_T *argv,
int safe) /* use the sandbox */
{
typval_T rettv;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
return NULL;
if (rettv.v_type != VAR_LIST)
+39 -2
View File
@@ -298,6 +298,7 @@ static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
static void f_printf(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_JOB_CHANNEL
static void f_prompt_setcallback(typval_T *argvars, typval_T *rettv);
static void f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv);
static void f_prompt_setprompt(typval_T *argvars, typval_T *rettv);
#endif
static void f_pumvisible(typval_T *argvars, typval_T *rettv);
@@ -754,6 +755,7 @@ static struct fst
{"printf", 1, 19, f_printf},
#ifdef FEAT_JOB_CHANNEL
{"prompt_setcallback", 2, 2, f_prompt_setcallback},
{"prompt_setinterrupt", 2, 2, f_prompt_setinterrupt},
{"prompt_setprompt", 2, 2, f_prompt_setprompt},
#endif
{"pumvisible", 0, 0, f_pumvisible},
@@ -7273,7 +7275,7 @@ f_job_start(typval_T *argvars, typval_T *rettv)
rettv->v_type = VAR_JOB;
if (check_restricted() || check_secure())
return;
rettv->vval.v_job = job_start(argvars, NULL, NULL);
rettv->vval.v_job = job_start(argvars, NULL, NULL, FALSE);
}
/*
@@ -8640,6 +8642,35 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
buf->b_prompt_partial = partial;
}
/*
* "prompt_setinterrupt({buffer}, {callback})" function
*/
static void
f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
{
buf_T *buf;
char_u *callback;
partial_T *partial;
if (check_secure())
return;
buf = get_buf_tv(&argvars[0], FALSE);
if (buf == NULL)
return;
callback = get_callback(&argvars[1], &partial);
if (callback == NULL)
return;
free_callback(buf->b_prompt_interrupt, buf->b_prompt_int_partial);
if (partial == NULL)
buf->b_prompt_interrupt = vim_strsave(callback);
else
/* pointer into the partial */
buf->b_prompt_interrupt = callback;
buf->b_prompt_int_partial = partial;
}
/*
* "prompt_setprompt({buffer}, {text})" function
*/
@@ -10648,6 +10679,7 @@ set_qf_ll_list(
static char *e_invact = N_("E927: Invalid action: '%s'");
char_u *act;
int action = 0;
static int recursive = 0;
#endif
rettv->vval.v_number = -1;
@@ -10655,6 +10687,8 @@ set_qf_ll_list(
#ifdef FEAT_QUICKFIX
if (list_arg->v_type != VAR_LIST)
EMSG(_(e_listreq));
else if (recursive != 0)
EMSG(_(e_au_recursive));
else
{
list_T *l = list_arg->vval.v_list;
@@ -10689,9 +10723,12 @@ set_qf_ll_list(
}
}
++recursive;
if (l != NULL && action && valid_dict && set_errorlist(wp, l, action,
(char_u *)(wp == NULL ? ":setqflist()" : ":setloclist()"), d) == OK)
(char_u *)(wp == NULL ? ":setqflist()" : ":setloclist()"),
d) == OK)
rettv->vval.v_number = 0;
--recursive;
}
#endif
}
+15 -2
View File
@@ -4063,8 +4063,16 @@ set_one_cmd_context(
case CMD_unlet:
while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
arg = xp->xp_pattern + 1;
xp->xp_context = EXPAND_USER_VARS;
xp->xp_pattern = arg;
if (*xp->xp_pattern == '$')
{
xp->xp_context = EXPAND_ENV_VARS;
++xp->xp_pattern;
}
break;
case CMD_function:
@@ -5334,7 +5342,9 @@ get_bad_opt(char_u *p, exarg_T *eap)
eap->bad_char = BAD_DROP;
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
eap->bad_char = *p;
return FAIL;
else
return FAIL;
return OK;
}
#endif
@@ -11310,7 +11320,10 @@ makeopens(
* winminheight and winminwidth need to be set to avoid an error if the
* user has set winheight or winwidth.
*/
if (put_line(fd, "set winminheight=1 winheight=1 winminwidth=1 winwidth=1") == FAIL)
if (put_line(fd, "set winminheight=0") == FAIL
|| put_line(fd, "set winheight=1") == FAIL
|| put_line(fd, "set winminwidth=0") == FAIL
|| put_line(fd, "set winwidth=1") == FAIL)
return FAIL;
if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
return FAIL;
+14 -9
View File
@@ -5280,7 +5280,7 @@ expand_shellcmd(
# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, char_u **, int), expand_T *xp, int *num_file, char_u ***file);
static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, typval_T *, int), expand_T *xp, int *num_file, char_u ***file);
/*
* Call "user_expand_func()" to invoke a user defined Vim script function and
@@ -5288,15 +5288,15 @@ static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, cha
*/
static void *
call_user_expand_func(
void *(*user_expand_func)(char_u *, int, char_u **, int),
void *(*user_expand_func)(char_u *, int, typval_T *, int),
expand_T *xp,
int *num_file,
char_u ***file)
{
int keep = 0;
char_u num[50];
char_u *args[3];
typval_T args[4];
int save_current_SID = current_SID;
char_u *pat = NULL;
void *ret;
struct cmdline_info save_ccline;
@@ -5311,10 +5311,15 @@ call_user_expand_func(
ccline.cmdbuff[ccline.cmdlen] = 0;
}
args[0] = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
args[1] = xp->xp_line;
sprintf((char *)num, "%d", xp->xp_col);
args[2] = num;
pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
args[0].v_type = VAR_STRING;
args[0].vval.v_string = pat;
args[1].v_type = VAR_STRING;
args[1].vval.v_string = xp->xp_line;
args[2].v_type = VAR_NUMBER;
args[2].vval.v_number = xp->xp_col;
args[3].v_type = VAR_UNKNOWN;
/* Save the cmdline, we don't know what the function may do. */
save_ccline = ccline;
@@ -5329,7 +5334,7 @@ call_user_expand_func(
if (ccline.cmdbuff != NULL)
ccline.cmdbuff[ccline.cmdlen] = keep;
vim_free(args[0]);
vim_free(pat);
return ret;
}
+5
View File
@@ -2856,6 +2856,11 @@ vgetorpeek(int advance)
/*
* get a character: 3. from the user - get it
*/
if (typebuf.tb_len == 0)
// timedout may have been set while waiting for a mapping
// that has a <Nop> RHS.
timedout = FALSE;
wait_tb_len = typebuf.tb_len;
c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
+9 -1
View File
@@ -3372,8 +3372,9 @@ mch_print_start_line(int margin, int page_line)
}
int
mch_print_text_out(char_u *p, int len UNUSED)
mch_print_text_out(char_u *textp, int len UNUSED)
{
char_u *p = textp;
int need_break;
char_u ch;
char_u ch_buff[8];
@@ -3508,8 +3509,15 @@ mch_print_text_out(char_u *p, int len UNUSED)
#ifdef FEAT_MBYTE
if (prt_do_conv)
{
/* Convert from multi-byte to 8-bit encoding */
tofree = p = string_convert(&prt_conv, p, &len);
if (p == NULL)
{
p = (char_u *)"";
len = 0;
}
}
if (prt_out_mbyte)
{
+13 -2
View File
@@ -3836,9 +3836,20 @@ get_firstwin(TabPageObject *tabObject)
else
return firstwin;
}
// Use the same order as in the WindowAttr() function.
static char *WindowAttrs[] = {
"buffer", "cursor", "height", "vars", "options", "number", "row", "col",
"tabpage", "valid",
"buffer",
"cursor",
"height",
"row",
"width",
"col",
"vars",
"options",
"number",
"tabpage",
"valid",
NULL
};
+4 -5
View File
@@ -4799,12 +4799,11 @@ iconv_end(void)
# endif
call_imactivatefunc(int active)
{
char_u *argv[1];
typval_T argv[2];
if (active)
argv[0] = (char_u *)"1";
else
argv[0] = (char_u *)"0";
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = active ? 1 : 0;
argv[1].v_type = VAR_UNKNOWN;
(void)call_func_retnr(p_imaf, 1, argv, FALSE);
}
+6 -4
View File
@@ -2219,7 +2219,7 @@ op_colon(oparg_T *oap)
op_function(oparg_T *oap UNUSED)
{
#ifdef FEAT_EVAL
char_u *(argv[1]);
typval_T argv[2];
# ifdef FEAT_VIRTUALEDIT
int save_virtual_op = virtual_op;
# endif
@@ -2235,12 +2235,14 @@ op_function(oparg_T *oap UNUSED)
/* Exclude the end position. */
decl(&curbuf->b_op_end);
argv[0].v_type = VAR_STRING;
if (oap->block_mode)
argv[0] = (char_u *)"block";
argv[0].vval.v_string = (char_u *)"block";
else if (oap->motion_type == MLINE)
argv[0] = (char_u *)"line";
argv[0].vval.v_string = (char_u *)"line";
else
argv[0] = (char_u *)"char";
argv[0].vval.v_string = (char_u *)"char";
argv[1].v_type = VAR_UNKNOWN;
# ifdef FEAT_VIRTUALEDIT
/* Reset virtual_op so that 'virtualedit' can be changed in the
+30 -38
View File
@@ -3339,9 +3339,6 @@ static char_u *illegal_char(char_u *, int);
#ifdef FEAT_CMDWIN
static char_u *check_cedit(void);
#endif
#ifdef FEAT_TITLE
static void did_set_title(int icon);
#endif
static char_u *option_expand(int opt_idx, char_u *val);
static void didset_options(void);
static void didset_options2(void);
@@ -5478,27 +5475,14 @@ check_cedit(void)
* the old value back.
*/
static void
did_set_title(
int icon) /* Did set icon instead of title */
did_set_title(void)
{
if (starting != NO_SCREEN
#ifdef FEAT_GUI
&& !gui.starting
#endif
)
{
maketitle();
if (icon)
{
if (!p_icon)
mch_restore_title(2);
}
else
{
if (!p_title)
mch_restore_title(1);
}
}
}
#endif
@@ -6153,7 +6137,7 @@ did_set_string_option(
/* set when changing an option that only requires a redraw in the GUI */
int redraw_gui_only = FALSE;
#endif
int ft_changed = FALSE;
int value_changed = FALSE;
#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
int did_swaptcap = FALSE;
#endif
@@ -7062,8 +7046,7 @@ did_set_string_option(
else
stl_syntax &= ~flagval;
# endif
did_set_title(varp == &p_iconstring);
did_set_title();
}
#endif
@@ -7577,7 +7560,7 @@ did_set_string_option(
if (!valid_filetype(*varp))
errmsg = e_invarg;
else
ft_changed = STRCMP(oldval, *varp) != 0;
value_changed = STRCMP(oldval, *varp) != 0;
}
#ifdef FEAT_SYN_HL
@@ -7585,6 +7568,8 @@ did_set_string_option(
{
if (!valid_filetype(*varp))
errmsg = e_invarg;
else
value_changed = STRCMP(oldval, *varp) != 0;
}
#endif
@@ -7705,8 +7690,14 @@ did_set_string_option(
/* When 'syntax' is set, load the syntax of that name */
if (varp == &(curbuf->b_p_syn))
{
apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
curbuf->b_fname, TRUE, curbuf);
static int syn_recursive = 0;
++syn_recursive;
// Only pass TRUE for "force" when the value changed or not used
// recursively, to avoid endless recurrence.
apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, curbuf->b_fname,
value_changed || syn_recursive == 1, curbuf);
--syn_recursive;
}
#endif
else if (varp == &(curbuf->b_p_ft))
@@ -7714,11 +7705,17 @@ did_set_string_option(
/* 'filetype' is set, trigger the FileType autocommand.
* Skip this when called from a modeline and the filetype was
* already set to this value. */
if (!(opt_flags & OPT_MODELINE) || ft_changed)
if (!(opt_flags & OPT_MODELINE) || value_changed)
{
static int ft_recursive = 0;
++ft_recursive;
did_filetype = TRUE;
apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft,
curbuf->b_fname, TRUE, curbuf);
// Only pass TRUE for "force" when the value changed or not
// used recursively, to avoid endless recurrence.
apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname,
value_changed || ft_recursive == 1, curbuf);
--ft_recursive;
/* Just in case the old "curbuf" is now invalid. */
if (varp != &(curbuf->b_p_ft))
varp = NULL;
@@ -8569,14 +8566,9 @@ set_bool_option(
#ifdef FEAT_TITLE
/* when 'title' changed, may need to change the title; same for 'icon' */
else if ((int *)varp == &p_title)
else if ((int *)varp == &p_title || (int *)varp == &p_icon)
{
did_set_title(FALSE);
}
else if ((int *)varp == &p_icon)
{
did_set_title(TRUE);
did_set_title();
}
#endif
@@ -8967,6 +8959,7 @@ set_num_option(
*/
if (pp == &p_wh || pp == &p_hh)
{
// 'winheight' and 'helpheight'
if (p_wh < 1)
{
errmsg = e_positive;
@@ -8992,10 +8985,9 @@ set_num_option(
win_setheight((int)p_hh);
}
}
/* 'winminheight' */
else if (pp == &p_wmh)
{
// 'winminheight'
if (p_wmh < 0)
{
errmsg = e_positive;
@@ -9010,6 +9002,7 @@ set_num_option(
}
else if (pp == &p_wiw)
{
// 'winwidth'
if (p_wiw < 1)
{
errmsg = e_positive;
@@ -9025,10 +9018,9 @@ set_num_option(
if (!ONE_WINDOW && curwin->w_width < p_wiw)
win_setwidth((int)p_wiw);
}
/* 'winminwidth' */
else if (pp == &p_wmw)
{
// 'winminwidth'
if (p_wmw < 0)
{
errmsg = e_positive;
@@ -9039,7 +9031,7 @@ set_num_option(
errmsg = e_winwidth;
p_wmw = p_wiw;
}
win_setminheight();
win_setminwidth();
}
/* (re)set last window status line */
+21 -2
View File
@@ -63,8 +63,13 @@ clip_mch_request_selection(VimClipboard *cbd)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSPasteboard *pb = [NSPasteboard generalPasteboard];
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
NSPasteboardTypeString, nil];
#else
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
NSStringPboardType, nil];
#endif
NSString *bestType = [pb availableTypeFromArray:supportedTypes];
if (!bestType) goto releasepool;
@@ -76,7 +81,7 @@ clip_mch_request_selection(VimClipboard *cbd)
/* This type should consist of an array with two objects:
* 1. motion type (NSNumber)
* 2. text (NSString)
* If this is not the case we fall back on using NSStringPboardType.
* If this is not the case we fall back on using NSPasteboardTypeString.
*/
id plist = [pb propertyListForType:VimPboardType];
if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2)
@@ -92,10 +97,15 @@ clip_mch_request_selection(VimClipboard *cbd)
if (!string)
{
/* Use NSStringPboardType. The motion type is detected automatically.
/* Use NSPasteboardTypeString. The motion type is detected automatically.
*/
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
NSMutableString *mstring =
[[pb stringForType:NSPasteboardTypeString] mutableCopy];
#else
NSMutableString *mstring =
[[pb stringForType:NSStringPboardType] mutableCopy];
#endif
if (!mstring) goto releasepool;
/* Replace unrecognized end-of-line sequences with \x0a (line feed). */
@@ -178,15 +188,24 @@ clip_mch_set_selection(VimClipboard *cbd)
/* See clip_mch_request_selection() for info on pasteboard types. */
NSPasteboard *pb = [NSPasteboard generalPasteboard];
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
NSPasteboardTypeString, nil];
#else
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPboardType,
NSStringPboardType, nil];
#endif
[pb declareTypes:supportedTypes owner:nil];
NSNumber *motion = [NSNumber numberWithInt:motion_type];
NSArray *plist = [NSArray arrayWithObjects:motion, string, nil];
[pb setPropertyList:plist forType:VimPboardType];
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
[pb setString:string forType:NSPasteboardTypeString];
#else
[pb setString:string forType:NSStringPboardType];
#endif
[string release];
}
+30 -7
View File
@@ -4165,7 +4165,11 @@ wait4pid(pid_t child, waitstatus *status)
* Set the environment for a child process.
*/
static void
set_child_environment(long rows, long columns, char *term)
set_child_environment(
long rows,
long columns,
char *term,
int is_terminal UNUSED)
{
# ifdef HAVE_SETENV
char envbuf[50];
@@ -4175,6 +4179,9 @@ set_child_environment(long rows, long columns, char *term)
static char envbuf_Lines[20];
static char envbuf_Columns[20];
static char envbuf_Colors[20];
# ifdef FEAT_TERMINAL
static char envbuf_Version[20];
# endif
# ifdef FEAT_CLIENTSERVER
static char envbuf_Servername[60];
# endif
@@ -4195,6 +4202,13 @@ set_child_environment(long rows, long columns, char *term)
setenv("COLUMNS", (char *)envbuf, 1);
sprintf((char *)envbuf, "%ld", colors);
setenv("COLORS", (char *)envbuf, 1);
# ifdef FEAT_TERMINAL
if (is_terminal)
{
sprintf((char *)envbuf, "%ld", (long)get_vim_var_nr(VV_VERSION));
setenv("VIM_TERMINAL", (char *)envbuf, 1);
}
# endif
# ifdef FEAT_CLIENTSERVER
setenv("VIM_SERVERNAME", serverName == NULL ? "" : (char *)serverName, 1);
# endif
@@ -4215,6 +4229,14 @@ set_child_environment(long rows, long columns, char *term)
putenv(envbuf_Columns);
vim_snprintf(envbuf_Colors, sizeof(envbuf_Colors), "COLORS=%ld", colors);
putenv(envbuf_Colors);
# ifdef FEAT_TERMINAL
if (is_terminal)
{
vim_snprintf(envbuf_Version, sizeof(envbuf_Version),
"VIM_TERMINAL=%ld", (long)get_vim_var_nr(VV_VERSION));
putenv(envbuf_Version);
}
# endif
# ifdef FEAT_CLIENTSERVER
vim_snprintf(envbuf_Servername, sizeof(envbuf_Servername),
"VIM_SERVERNAME=%s", serverName == NULL ? "" : (char *)serverName);
@@ -4224,9 +4246,9 @@ set_child_environment(long rows, long columns, char *term)
}
static void
set_default_child_environment(void)
set_default_child_environment(int is_terminal)
{
set_child_environment(Rows, Columns, "dumb");
set_child_environment(Rows, Columns, "dumb", is_terminal);
}
#endif
@@ -4701,7 +4723,7 @@ mch_call_shell_fork(
# endif
}
# endif
set_default_child_environment();
set_default_child_environment(FALSE);
/*
* stderr is only redirected when using the GUI, so that a
@@ -5383,7 +5405,7 @@ mch_call_shell(
#if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
void
mch_job_start(char **argv, job_T *job, jobopt_T *options)
mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal)
{
pid_t pid;
int fd_in[2] = {-1, -1}; /* for stdin */
@@ -5531,11 +5553,12 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
set_child_environment(
(long)options->jo_term_rows,
(long)options->jo_term_cols,
term);
term,
is_terminal);
}
else
# endif
set_default_child_environment();
set_default_child_environment(is_terminal);
if (options->jo_env != NULL)
{
+35 -6
View File
@@ -5275,22 +5275,51 @@ win32_build_env(dict_T *env, garray_T *gap, int is_terminal)
}
}
# ifdef FEAT_CLIENTSERVER
if (is_terminal)
# if defined(FEAT_CLIENTSERVER) || defined(FEAT_TERMINAL)
{
# ifdef FEAT_CLIENTSERVER
char_u *servername = get_vim_var_str(VV_SEND_SERVER);
size_t lval = STRLEN(servername);
size_t n;
size_t servername_len = STRLEN(servername);
# endif
# ifdef FEAT_TERMINAL
char_u *version = get_vim_var_str(VV_VERSION);
size_t version_len = STRLEN(version);
# endif
// size of "VIM_SERVERNAME=" and value,
// plus "VIM_TERMINAL=" and value,
// plus two terminating NULs
size_t n = 0
# ifdef FEAT_CLIENTSERVER
+ 15 + servername_len
# endif
# ifdef FEAT_TERMINAL
+ 13 + version_len + 2
# endif
;
if (ga_grow(gap, (int)(14 + lval + 2)) == OK)
if (ga_grow(gap, (int)n) == OK)
{
# ifdef FEAT_CLIENTSERVER
for (n = 0; n < 15; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)"VIM_SERVERNAME="[n];
for (n = 0; n < lval; n++)
for (n = 0; n < servername_len; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)servername[n];
*((WCHAR*)gap->ga_data + gap->ga_len++) = L'\0';
# endif
# ifdef FEAT_TERMINAL
if (is_terminal)
{
for (n = 0; n < 13; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)"VIM_TERMINAL="[n];
for (n = 0; n < version_len; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)version[n];
*((WCHAR*)gap->ga_data + gap->ga_len++) = L'\0';
}
# endif
}
}
# endif
+64 -11
View File
@@ -29,6 +29,13 @@ static int pum_scrollbar; /* TRUE when scrollbar present */
static int pum_row; /* top row of pum */
static int pum_col; /* left column of pum */
static win_T *pum_window = NULL;
static int pum_win_row;
static int pum_win_height;
static int pum_win_col;
static int pum_win_wcol;
static int pum_win_width;
static int pum_do_redraw = FALSE; /* do redraw anyway */
static int pum_set_selected(int n, int repeat);
@@ -81,7 +88,6 @@ pum_display(
{
int def_width;
int max_width;
int row;
int context_lines;
int cursor_col;
int above_row;
@@ -103,7 +109,14 @@ pum_display(
validate_cursor_col();
pum_array = NULL;
row = curwin->w_wrow + W_WINROW(curwin);
// Remember the essential parts of the window position and size, so we
// can decide when to reposition the popup menu.
pum_window = curwin;
pum_win_row = curwin->w_wrow + W_WINROW(curwin);
pum_win_height = curwin->w_height;
pum_win_col = curwin->w_wincol;
pum_win_wcol = curwin->w_wcol;
pum_win_width = curwin->w_width;
#if defined(FEAT_QUICKFIX)
FOR_ALL_WINDOWS(pvwin)
@@ -128,12 +141,12 @@ pum_display(
if (p_ph > 0 && pum_height > p_ph)
pum_height = p_ph;
/* Put the pum below "row" if possible. If there are few lines decide
/* Put the pum below "pum_win_row" if possible. If there are few lines decide
* on where there is more room. */
if (row + 2 >= below_row - pum_height
&& row - above_row > (below_row - above_row) / 2)
if (pum_win_row + 2 >= below_row - pum_height
&& pum_win_row - above_row > (below_row - above_row) / 2)
{
/* pum above "row" */
/* pum above "pum_win_row" */
/* Leave two lines of context if possible */
if (curwin->w_wrow - curwin->w_cline_row >= 2)
@@ -141,15 +154,15 @@ pum_display(
else
context_lines = curwin->w_wrow - curwin->w_cline_row;
if (row >= size + context_lines)
if (pum_win_row >= size + context_lines)
{
pum_row = row - size - context_lines;
pum_row = pum_win_row - size - context_lines;
pum_height = size;
}
else
{
pum_row = 0;
pum_height = row - context_lines;
pum_height = pum_win_row - context_lines;
}
if (p_ph > 0 && pum_height > p_ph)
{
@@ -159,7 +172,7 @@ pum_display(
}
else
{
/* pum below "row" */
/* pum below "pum_win_row" */
/* Leave two lines of context if possible */
if (curwin->w_cline_row
@@ -169,7 +182,7 @@ pum_display(
context_lines = curwin->w_cline_row
+ curwin->w_cline_height - curwin->w_wrow;
pum_row = row + context_lines;
pum_row = pum_win_row + context_lines;
if (size > below_row - pum_row)
pum_height = below_row - pum_row;
else
@@ -822,6 +835,43 @@ pum_visible(void)
return !pum_do_redraw && pum_array != NULL;
}
/*
* Reposition the popup menu to adjust for window layout changes.
*/
void
pum_may_redraw(void)
{
pumitem_T *array = pum_array;
int len = pum_size;
int selected = pum_selected;
if (!pum_visible())
return; // nothing to do
if (pum_window != curwin
|| (pum_win_row == curwin->w_wrow + W_WINROW(curwin)
&& pum_win_height == curwin->w_height
&& pum_win_col == curwin->w_wincol
&& pum_win_width == curwin->w_width))
{
// window position didn't change, redraw in the same position
pum_redraw();
}
else
{
int wcol = curwin->w_wcol;
// Window layout changed, recompute the position.
// Use the remembered w_wcol value, the cursor may have moved when a
// completion was inserted, but we want the menu in the same position.
pum_undisplay();
curwin->w_wcol = pum_win_wcol;
curwin->w_valid |= VALID_WCOL;
pum_display(array, len, selected);
curwin->w_wcol = wcol;
}
}
/*
* Return the height of the popup menu, the number of entries visible.
* Only valid when pum_visible() returns TRUE!
@@ -865,6 +915,9 @@ pum_position_at_mouse(int min_width)
pum_width = Columns - pum_col;
if (pum_width > pum_base_width + 1)
pum_width = pum_base_width + 1;
// Do not redraw at cursor position.
pum_window = NULL;
}
# endif
+2 -1
View File
@@ -67,11 +67,12 @@ void job_set_options(job_T *job, jobopt_T *opt);
void job_stop_on_exit(void);
int has_pending_job(void);
void job_check_ended(void);
job_T *job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg);
job_T *job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg, int is_terminal);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
void job_info_all(list_T *l);
int job_stop(job_T *job, typval_T *argvars, char *type);
void invoke_prompt_callback(void);
int invoke_prompt_interrupt(void);
void job_cleanup_all(void);
/* vim: set ft=c : */
+4 -4
View File
@@ -19,10 +19,10 @@ varnumber_T eval_to_number(char_u *expr);
list_T *eval_spell_expr(char_u *badword, char_u *expr);
int get_spellword(list_T *list, char_u **pp);
typval_T *eval_expr(char_u *arg, char_u **nextcmd);
int call_vim_function(char_u *func, int argc, char_u **argv, int safe, int str_arg_only, typval_T *rettv);
varnumber_T call_func_retnr(char_u *func, int argc, char_u **argv, int safe);
void *call_func_retstr(char_u *func, int argc, char_u **argv, int safe);
void *call_func_retlist(char_u *func, int argc, char_u **argv, int safe);
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv, int safe);
varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv, int safe);
void *call_func_retstr(char_u *func, int argc, typval_T *argv, int safe);
void *call_func_retlist(char_u *func, int argc, typval_T *argv, int safe);
int eval_foldexpr(char_u *arg, int *cp);
void ex_let(exarg_T *eap);
void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
+1 -1
View File
@@ -62,7 +62,7 @@ void mch_set_shellsize(void);
void mch_new_shellsize(void);
void may_send_sigint(int c, pid_t pid, pid_t wpid);
int mch_call_shell(char_u *cmd, int options);
void mch_job_start(char **argv, job_T *job, jobopt_T *options);
void mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal);
char *mch_job_status(job_T *job);
job_T *mch_detect_ended_job(job_T *job_list);
int mch_signal_job(job_T *job, char_u *how);
+1
View File
@@ -4,6 +4,7 @@ void pum_redraw(void);
void pum_undisplay(void);
void pum_clear(void);
int pum_visible(void);
void pum_may_redraw(void);
int pum_get_height(void);
int split_message(char_u *mesg, pumitem_T **array);
void ui_remove_balloon(void);
-1
View File
@@ -25,7 +25,6 @@ void status_redraw_curbuf(void);
void redraw_statuslines(void);
void win_redraw_last_status(frame_T *frp);
void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, int match, int showtail);
void win_redr_status(win_T *wp);
int stl_connected(win_T *wp);
int get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len);
void screen_putchar(int c, int row, int col, int attr);
+1
View File
@@ -54,6 +54,7 @@ void win_setheight_win(int height, win_T *win);
void win_setwidth(int width);
void win_setwidth_win(int width, win_T *wp);
void win_setminheight(void);
void win_setminwidth(void);
void win_drag_status_line(win_T *dragwin, int offset);
void win_drag_vsep_line(win_T *dragwin, int offset);
void set_fraction(win_T *wp);
+8
View File
@@ -6272,8 +6272,16 @@ ex_cbuffer(exarg_T *eap)
if (res >= 0)
qf_list_changed(qi, qi->qf_curlist);
if (au_name != NULL)
{
buf_T *curbuf_old = curbuf;
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf);
if (curbuf != curbuf_old)
// Autocommands changed buffer, don't jump now, "qi" may
// be invalid.
res = 0;
}
if (res > 0 && (eap->cmdidx == CMD_cbuffer ||
eap->cmdidx == CMD_lbuffer))
qf_jump(qi, 0, 0, eap->forceit); /* display first error */
+41 -29
View File
@@ -125,6 +125,7 @@ static int redrawing_for_callback = 0;
static schar_T *current_ScreenLine;
static void win_update(win_T *wp);
static void win_redr_status(win_T *wp, int ignore_pum);
static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T hl);
#ifdef FEAT_FOLDING
static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row);
@@ -170,7 +171,7 @@ static void redraw_win_toolbar(win_T *wp);
static void win_redr_custom(win_T *wp, int draw_ruler);
#endif
#ifdef FEAT_CMDL_INFO
static void win_redr_ruler(win_T *wp, int always);
static void win_redr_ruler(win_T *wp, int always, int ignore_pum);
#endif
/* Ugly global: overrule attribute used by screen_char() */
@@ -778,7 +779,7 @@ update_screen(int type_arg)
if (wp->w_redr_status)
{
cursor_off();
win_redr_status(wp);
win_redr_status(wp, TRUE); // any popup menu will be redrawn below
}
}
#if defined(FEAT_SEARCH_EXTRA)
@@ -786,8 +787,7 @@ update_screen(int type_arg)
#endif
#ifdef FEAT_INS_EXPAND
/* May need to redraw the popup menu. */
if (pum_visible())
pum_redraw();
pum_may_redraw();
#endif
/* Reset b_mod_set flags. Going through all windows is probably faster
@@ -1034,7 +1034,7 @@ update_debug_sign(buf_T *buf, linenr_T lnum)
if (wp->w_redr_type != 0)
win_update(wp);
if (wp->w_redr_status)
win_redr_status(wp);
win_redr_status(wp, FALSE);
}
update_finish();
@@ -1078,7 +1078,7 @@ updateWindow(win_T *wp)
|| *p_stl != NUL || *wp->w_p_stl != NUL
# endif
)
win_redr_status(wp);
win_redr_status(wp, FALSE);
update_finish();
}
@@ -6555,7 +6555,7 @@ redraw_statuslines(void)
FOR_ALL_WINDOWS(wp)
if (wp->w_redr_status)
win_redr_status(wp);
win_redr_status(wp, FALSE);
if (redraw_tabline)
draw_tabline();
}
@@ -6884,9 +6884,11 @@ win_redr_status_matches(
* Redraw the status line of window wp.
*
* If inversion is possible we use it. Else '=' characters are used.
* If "ignore_pum" is TRUE, also redraw statusline when the popup menu is
* displayed.
*/
void
win_redr_status(win_T *wp)
static void
win_redr_status(win_T *wp, int ignore_pum)
{
int row;
char_u *p;
@@ -6910,9 +6912,9 @@ win_redr_status(win_T *wp)
}
else if (!redrawing()
#ifdef FEAT_INS_EXPAND
/* don't update status line when popup menu is visible and may be
* drawn over it */
|| pum_visible()
// don't update status line when popup menu is visible and may be
// drawn over it, unless it will be redrawn later
|| (!ignore_pum && pum_visible())
#endif
)
{
@@ -7019,7 +7021,7 @@ win_redr_status(win_T *wp)
- 1 + wp->w_wincol), attr);
#ifdef FEAT_CMDL_INFO
win_redr_ruler(wp, TRUE);
win_redr_ruler(wp, TRUE, ignore_pum);
#endif
}
@@ -9843,6 +9845,7 @@ screen_ins_lines(
int j;
unsigned temp;
int cursor_row;
int cursor_col = 0;
int type;
int result_empty;
int can_ce = can_clear(T_CE);
@@ -9939,6 +9942,9 @@ screen_ins_lines(
gui_dont_update_cursor(row + off <= gui.cursor_row);
#endif
if (wp != NULL && wp->w_wincol != 0 && *T_CSV != NUL && *T_CCS == NUL)
cursor_col = wp->w_wincol;
if (*T_CCS != NUL) /* cursor relative to region */
cursor_row = row;
else
@@ -9985,7 +9991,7 @@ screen_ins_lines(
}
screen_stop_highlight();
windgoto(cursor_row, 0);
windgoto(cursor_row, cursor_col);
if (clear_attr != 0)
screen_start_highlight(clear_attr);
@@ -10004,7 +10010,7 @@ screen_ins_lines(
if (type == USE_T_AL)
{
if (i && cursor_row != 0)
windgoto(cursor_row, 0);
windgoto(cursor_row, cursor_col);
out_str(T_AL);
}
else /* type == USE_T_SR */
@@ -10021,7 +10027,7 @@ screen_ins_lines(
{
for (i = 0; i < line_count; ++i)
{
windgoto(off + i, 0);
windgoto(off + i, cursor_col);
out_str(T_CE);
screen_start(); /* don't know where cursor is now */
}
@@ -10057,6 +10063,7 @@ screen_del_lines(
int i;
unsigned temp;
int cursor_row;
int cursor_col = 0;
int cursor_end;
int result_empty; /* result is empty until end of region */
int can_delete; /* deleting line codes can be used */
@@ -10156,6 +10163,9 @@ screen_del_lines(
&& gui.cursor_row < end + off);
#endif
if (wp != NULL && wp->w_wincol != 0 && *T_CSV != NUL && *T_CCS == NUL)
cursor_col = wp->w_wincol;
if (*T_CCS != NUL) /* cursor relative to region */
{
cursor_row = row;
@@ -10218,13 +10228,13 @@ screen_del_lines(
redraw_block(row, end, wp);
else if (type == USE_T_CD) /* delete the lines */
{
windgoto(cursor_row, 0);
windgoto(cursor_row, cursor_col);
out_str(T_CD);
screen_start(); /* don't know where cursor is now */
}
else if (type == USE_T_CDL)
{
windgoto(cursor_row, 0);
windgoto(cursor_row, cursor_col);
term_delete_lines(line_count);
screen_start(); /* don't know where cursor is now */
}
@@ -10235,7 +10245,7 @@ screen_del_lines(
*/
else if (type == USE_NL)
{
windgoto(cursor_end - 1, 0);
windgoto(cursor_end - 1, cursor_col);
for (i = line_count; --i >= 0; )
out_char('\n'); /* cursor will remain on same line */
}
@@ -10245,12 +10255,12 @@ screen_del_lines(
{
if (type == USE_T_DL)
{
windgoto(cursor_row, 0);
windgoto(cursor_row, cursor_col);
out_str(T_DL); /* delete a line */
}
else /* type == USE_T_CE */
{
windgoto(cursor_row + i, 0);
windgoto(cursor_row + i, cursor_col);
out_str(T_CE); /* erase a line */
}
screen_start(); /* don't know where cursor is now */
@@ -10265,7 +10275,7 @@ screen_del_lines(
{
for (i = line_count; i > 0; --i)
{
windgoto(cursor_end - i, 0);
windgoto(cursor_end - i, cursor_col);
out_str(T_CE); /* erase a line */
screen_start(); /* don't know where cursor is now */
}
@@ -10302,7 +10312,7 @@ showmode(void)
do_mode = ((p_smd && msg_silent == 0)
&& ((State & INSERT)
|| restart_edit
|| restart_edit != NUL
|| VIsual_active));
if (do_mode || reg_recording != 0)
{
@@ -10410,7 +10420,7 @@ showmode(void)
#endif
MSG_PUTS_ATTR(_(" INSERT"), attr);
}
else if (restart_edit == 'I')
else if (restart_edit == 'I' || restart_edit == 'A')
MSG_PUTS_ATTR(_(" (insert)"), attr);
else if (restart_edit == 'R')
MSG_PUTS_ATTR(_(" (replace)"), attr);
@@ -10494,7 +10504,7 @@ showmode(void)
/* If the last window has no status line, the ruler is after the mode
* message and must be redrawn */
if (redrawing() && lastwin->w_status_height == 0)
win_redr_ruler(lastwin, TRUE);
win_redr_ruler(lastwin, TRUE, FALSE);
#endif
redraw_cmdline = FALSE;
clear_cmdline = FALSE;
@@ -10913,6 +10923,7 @@ redraw_win_toolbar(win_T *wp)
(int)wp->w_width, FALSE);
}
#endif
/*
* Show current status info in ruler and various other places
* If always is FALSE, only show ruler if position has changed.
@@ -10938,7 +10949,7 @@ showruler(int always)
else
#endif
#ifdef FEAT_CMDL_INFO
win_redr_ruler(curwin, always);
win_redr_ruler(curwin, always, FALSE);
#endif
#ifdef FEAT_TITLE
@@ -10957,7 +10968,7 @@ showruler(int always)
#ifdef FEAT_CMDL_INFO
static void
win_redr_ruler(win_T *wp, int always)
win_redr_ruler(win_T *wp, int always, int ignore_pum)
{
#define RULER_BUF_LEN 70
char_u buffer[RULER_BUF_LEN];
@@ -10990,8 +11001,9 @@ win_redr_ruler(win_T *wp, int always)
if (wp == lastwin && lastwin->w_status_height == 0)
if (edit_submode != NULL)
return;
/* Don't draw the ruler when the popup menu is visible, it may overlap. */
if (pum_visible())
// Don't draw the ruler when the popup menu is visible, it may overlap.
// Except when the popup menu will be redrawn anyway.
if (!ignore_pum && pum_visible())
return;
#endif
+2
View File
@@ -2366,6 +2366,8 @@ struct file_buffer
char_u *b_prompt_text; // set by prompt_setprompt()
char_u *b_prompt_callback; // set by prompt_setcallback()
partial_T *b_prompt_partial; // set by prompt_setcallback()
char_u *b_prompt_interrupt; // set by prompt_setinterrupt()
partial_T *b_prompt_int_partial; // set by prompt_setinterrupt()
int b_prompt_insert; // value for restart_edit when entering
// a prompt buffer window.
#endif
+9 -4
View File
@@ -2112,7 +2112,11 @@ terminal_loop(int blocking)
in_terminal_loop = curbuf->b_term;
if (*curwin->w_p_twk != NUL)
{
termwinkey = string_to_key(curwin->w_p_twk, TRUE);
if (termwinkey == Ctrl_W)
termwinkey = 0;
}
position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
may_set_cursor_props(curbuf->b_term);
@@ -2208,12 +2212,13 @@ terminal_loop(int blocking)
/* "CTRL-W CTRL-C" or 'termwinkey' CTRL-C: end the job */
mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill");
}
else if (termwinkey == 0 && c == '.')
else if (c == '.')
{
/* "CTRL-W .": send CTRL-W to the job */
c = Ctrl_W;
/* "'termwinkey' .": send 'termwinkey' to the job */
c = termwinkey == 0 ? Ctrl_W : termwinkey;
}
else if (termwinkey == 0 && c == Ctrl_BSL)
else if (c == Ctrl_BSL)
{
/* "CTRL-W CTRL-\": send CTRL-\ to the job */
c = Ctrl_BSL;
@@ -5774,7 +5779,7 @@ term_and_job_init(
#endif
/* This may change a string in "argvar". */
term->tl_job = job_start(argvar, argv, opt);
term->tl_job = job_start(argvar, argv, opt, TRUE);
if (term->tl_job != NULL)
++term->tl_job->jv_refcount;
+12
View File
@@ -124,7 +124,10 @@ func RunTheTest(test)
exe 'call ' . a:test
else
try
let s:test = a:test
au VimLeavePre * call EarlyExit(s:test)
exe 'call ' . a:test
au! VimLeavePre
catch /^\cskipped/
call add(s:messages, ' Skipped')
call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
@@ -174,6 +177,15 @@ func AfterTheTest()
endif
endfunc
func EarlyExit(test)
" It's OK for the test we use to test the quit detection.
if a:test != 'Test_zz_quit_detected()'
call add(v:errors, 'Test caused Vim to exit: ' . a:test)
endif
call FinishTesting()
endfunc
" This function can be called by a test if it wants to abort testing.
func FinishTesting()
call AfterTheTest()
+1 -1
View File
@@ -443,7 +443,7 @@ vim.current.window:Window:True
vim.current.tabpage:TabPage:True
current:__dir__,__members__,buffer,line,range,tabpage,window
buffer:__dir__,__members__,append,mark,name,number,options,range,valid,vars
window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
tabpage:__dir__,__members__,number,valid,vars,window,windows
range:__dir__,__members__,append,end,start
dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
+1 -1
View File
@@ -443,7 +443,7 @@ vim.current.window:Window:True
vim.current.tabpage:TabPage:True
current:__dir__,buffer,line,range,tabpage,window
buffer:__dir__,append,mark,name,number,options,range,valid,vars
window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
tabpage:__dir__,number,valid,vars,window,windows
range:__dir__,append,end,start
dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
+6
View File
@@ -198,3 +198,9 @@ func Test_user_is_happy()
smile
sleep 300m
endfunc
" Must be last.
func Test_zz_quit_detected()
" Verify that if a test function ends Vim the test script detects this.
quit
endfunc
+12
View File
@@ -465,4 +465,16 @@ func Test_show_digraph()
bwipe!
endfunc
func Test_show_digraph_cp1251()
if !has('multi_byte')
return
endif
new
set encoding=cp1251
call Put_Dig("='")
call assert_equal("\n<\xfa> <|z> <M-z> 250, Hex fa, Oct 372, Digr ='", execute('ascii'))
set encoding=utf-8
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+22 -7
View File
@@ -63,12 +63,27 @@ func Test_with_syntax()
endfunc
func Test_fname_with_spaces()
if has('postscript')
split t\ e\ s\ t.txt
call setline(1, ['just', 'some', 'text'])
hardcopy > %.ps
call assert_true(filereadable('t e s t.txt.ps'))
call delete('t e s t.txt.ps')
bwipe!
if !has('postscript')
return
endif
split t\ e\ s\ t.txt
call setline(1, ['just', 'some', 'text'])
hardcopy > %.ps
call assert_true(filereadable('t e s t.txt.ps'))
call delete('t e s t.txt.ps')
bwipe!
endfunc
func Test_illegal_byte()
if !has('postscript') || &enc != 'utf-8'
return
endif
new
" conversion of 0xff will fail, this used to cause a crash
call setline(1, "\xff")
hardcopy >Xpstest
bwipe!
call delete('Xpstest')
endfunc
+25
View File
@@ -117,6 +117,31 @@ func Test_omni_dash()
set omnifunc=
endfunc
func Test_completefunc_args()
let s:args = []
func! CompleteFunc(findstart, base)
let s:args += [[a:findstart, empty(a:base)]]
endfunc
new
set completefunc=CompleteFunc
call feedkeys("i\<C-X>\<C-U>\<Esc>", 'x')
call assert_equal([1, 1], s:args[0])
call assert_equal(0, s:args[1][0])
set completefunc=
let s:args = []
set omnifunc=CompleteFunc
call feedkeys("i\<C-X>\<C-O>\<Esc>", 'x')
call assert_equal([1, 1], s:args[0])
call assert_equal(0, s:args[1][0])
set omnifunc=
bwipe!
unlet s:args
delfunc CompleteFunc
endfunc
function! s:CompleteDone_CompleteFuncDict( findstart, base )
if a:findstart
return 0
+10 -1
View File
@@ -106,13 +106,22 @@ endfunc
func Test_mksession_winheight()
new
set winheight=10 winminheight=2
set winheight=10
set winminheight=2
mksession! Xtest_mks.out
source Xtest_mks.out
call delete('Xtest_mks.out')
endfunc
func Test_mksession_large_winheight()
set winheight=999
mksession! Xtest_mks_winheight.out
set winheight&
source Xtest_mks_winheight.out
call delete('Xtest_mks_winheight.out')
endfunc
func Test_mksession_arglist()
argdel *
next file1 file2 file3 file4
+30 -2
View File
@@ -1,10 +1,38 @@
" Tests for complicated + argument to :edit command
function Test_edit()
call writefile(["foo|bar"], "Xfile1")
call writefile(["foo/bar"], "Xfile2")
call writefile(["foo|bar"], "Xfile1")
call writefile(["foo/bar"], "Xfile2")
edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w
call assert_equal(["fooPIPEbar"], readfile("Xfile1"))
call assert_equal(["fooSLASHbar"], readfile("Xfile2"))
call delete('Xfile1')
call delete('Xfile2')
endfunction
func Test_edit_bad()
if !has('multi_byte')
finish
endif
" Test loading a utf8 file with bad utf8 sequences.
call writefile(["[\xff][\xc0][\xe2\x89\xf0][\xc2\xc2]"], "Xfile")
new
" Without ++bad=..., the default behavior is like ++bad=?
e! ++enc=utf8 Xfile
call assert_equal('[?][?][???][??]', getline(1))
e! ++enc=utf8 ++bad=_ Xfile
call assert_equal('[_][_][___][__]', getline(1))
e! ++enc=utf8 ++bad=drop Xfile
call assert_equal('[][][][]', getline(1))
e! ++enc=utf8 ++bad=keep Xfile
call assert_equal("[\xff][\xc0][\xe2\x89\xf0][\xc2\xc2]", getline(1))
call assert_fails('e! ++enc=utf8 ++bad=foo Xfile', 'E474:')
bw!
call delete('Xfile')
endfunc
+25 -29
View File
@@ -6,7 +6,7 @@ source screendump.vim
let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
let g:setting = ''
func! ListMonths()
func ListMonths()
if g:setting != ''
exe ":set" g:setting
endif
@@ -19,7 +19,7 @@ func! ListMonths()
return ''
endfunc
func! Test_popup_complete2()
func Test_popup_complete2()
" Although the popupmenu is not visible, this does not mean completion mode
" has ended. After pressing <f5> to complete the currently typed char, Vim
" still stays in the first state of the completion (:h ins-completion-menu),
@@ -34,9 +34,9 @@ func! Test_popup_complete2()
call assert_equal(["Dece", "", "December2015"], getline(1,3))
%d
bw!
endfu
endfunc
func! Test_popup_complete()
func Test_popup_complete()
new
inoremap <f5> <c-r>=ListMonths()<cr>
@@ -215,10 +215,10 @@ func! Test_popup_complete()
call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
call assert_equal(["March", "M", "March"], getline(1,4))
%d
endfu
endfunc
func! Test_popup_completion_insertmode()
func Test_popup_completion_insertmode()
new
inoremap <F5> <C-R>=ListMonths()<CR>
@@ -247,20 +247,16 @@ func! Test_popup_completion_insertmode()
iunmap <F5>
endfunc
" TODO: Fix what breaks after this line.
" - Do not use "q!", it may exit Vim if there is an error
finish
func Test_noinsert_complete()
function! s:complTest1() abort
func! s:complTest1() abort
call complete(1, ['source', 'soundfold'])
return ''
endfunction
endfunc
function! s:complTest2() abort
func! s:complTest2() abort
call complete(1, ['source', 'soundfold'])
return ''
endfunction
endfunc
new
set completeopt+=noinsert
@@ -281,9 +277,9 @@ func Test_noinsert_complete()
endfunc
func Test_compl_vim_cmds_after_register_expr()
function! s:test_func()
func! s:test_func()
return 'autocmd '
endfunction
endfunc
augroup AAAAA_Group
au!
augroup END
@@ -330,7 +326,7 @@ func DummyCompleteTwo(findstart, base)
else
return ['twodef', 'twoDEF']
endif
endfunction
endfunc
" Test that nothing happens if the 'completefunc' opens
" a new window (no completion, no crash)
@@ -407,7 +403,7 @@ func Test_omnifunc_with_check()
q!
endfunc
function UndoComplete()
func UndoComplete()
call complete(1, ['January', 'February', 'March',
\ 'April', 'May', 'June', 'July', 'August', 'September',
\ 'October', 'November', 'December'])
@@ -444,7 +440,7 @@ func Test_complete_no_undo()
q!
endfunc
function! DummyCompleteFive(findstart, base)
func DummyCompleteFive(findstart, base)
if a:findstart
return 0
else
@@ -489,7 +485,7 @@ func Test_completion_ctrl_e_without_autowrap()
q!
endfunc
function! DummyCompleteSix()
func DummyCompleteSix()
call complete(1, ['Hello', 'World'])
return ''
endfunction
@@ -577,7 +573,7 @@ func Test_completion_comment_formatting()
bwipe!
endfunc
fun MessCompleteMonths()
func MessCompleteMonths()
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
call complete_add(m)
if complete_check()
@@ -585,14 +581,14 @@ fun MessCompleteMonths()
endif
endfor
return []
endfun
endfunc
fun MessCompleteMore()
func MessCompleteMore()
call complete(1, split("Oct Nov Dec"))
return []
endfun
endfunc
fun MessComplete(findstart, base)
func MessComplete(findstart, base)
if a:findstart
let line = getline('.')
let start = col('.') - 1
@@ -605,7 +601,7 @@ fun MessComplete(findstart, base)
call MessCompleteMore()
return []
endif
endf
endfunc
func Test_complete_func_mess()
" Calling complete() after complete_add() in 'completefunc' is wrong, but it
@@ -835,7 +831,7 @@ func Test_popup_complete_backwards_ctrl_p()
bwipe!
endfunc
fun! Test_complete_o_tab()
func Test_complete_o_tab()
let s:o_char_pressed = 0
fun! s:act_on_text_changed()
@@ -843,7 +839,7 @@ fun! Test_complete_o_tab()
let s:o_char_pressed = 0
call feedkeys("\<c-x>\<c-n>", 'i')
endif
endf
endfunc
set completeopt=menu,noselect
new
@@ -862,7 +858,7 @@ fun! Test_complete_o_tab()
bwipe!
set completeopt&
delfunc s:act_on_text_changed
endf
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+12
View File
@@ -3350,3 +3350,15 @@ func Test_qftitle()
call assert_equal('Errors', w:quickfix_title)
cclose
endfunc
func Test_lbuffer_with_bwipe()
new
new
augroup nasty
au * * bwipe
augroup END
lbuffer
augroup nasty
au!
augroup END
endfunc
+11 -4
View File
@@ -482,18 +482,25 @@ func Test_terminal_servername()
if !has('clientserver')
return
endif
call s:test_environment("VIM_SERVERNAME", v:servername)
endfunc
func Test_terminal_version()
call s:test_environment("VIM_TERMINAL", string(v:version))
endfunc
func s:test_environment(name, value)
let buf = Run_shell_in_terminal({})
" Wait for the shell to display a prompt
call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
if has('win32')
call term_sendkeys(buf, "echo %VIM_SERVERNAME%\r")
call term_sendkeys(buf, "echo %" . a:name . "%\r")
else
call term_sendkeys(buf, "echo $VIM_SERVERNAME\r")
call term_sendkeys(buf, "echo $" . a:name . "\r")
endif
call term_wait(buf)
call Stop_shell_in_terminal(buf)
call WaitFor('getline(2) == v:servername')
call assert_equal(v:servername, getline(2))
call WaitForAssert({-> assert_equal(a:value, getline(2))})
exe buf . 'bwipe'
unlet buf
+10
View File
@@ -45,3 +45,13 @@ func Test_unlet_env()
unlet $MUST_NOT_BE_AN_ERROR
endfunc
func Test_unlet_complete()
let g:FOOBAR = 1
call feedkeys(":unlet g:FOO\t\n", 'tx')
call assert_true(!exists('g:FOOBAR'))
let $FOOBAR = 1
call feedkeys(":unlet $FOO\t\n", 'tx')
call assert_true(!exists('$FOOBAR') || empty($FOOBAR))
endfunc
+66
View File
@@ -776,6 +776,72 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
72,
/**/
71,
/**/
70,
/**/
69,
/**/
68,
/**/
67,
/**/
66,
/**/
65,
/**/
64,
/**/
63,
/**/
62,
/**/
61,
/**/
60,
/**/
59,
/**/
58,
/**/
57,
/**/
56,
/**/
55,
/**/
54,
/**/
53,
/**/
52,
/**/
51,
/**/
50,
/**/
49,
/**/
48,
/**/
47,
/**/
46,
/**/
45,
/**/
44,
/**/
43,
/**/
42,
/**/
41,
/**/
40,
/**/
39,
/**/
+48 -12
View File
@@ -2112,17 +2112,24 @@ win_equal_rec(
static void
leaving_window(win_T *win)
{
// Only matters for a prompt window.
if (!bt_prompt(win->w_buffer))
return;
// When leaving a prompt window stop Insert mode and perhaps restart
// it when entering that window again.
win->w_buffer->b_prompt_insert = restart_edit;
if (restart_edit != 0 && mode_displayed)
clear_cmdline = TRUE; /* unshow mode later */
restart_edit = NUL;
// When leaving the window (or closing the window) was done from a
// callback we need to break out of the Insert mode loop.
// callback we need to break out of the Insert mode loop and restart Insert
// mode when entering the window again.
if (State & INSERT)
{
stop_insert_mode = TRUE;
if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert == NUL)
if (win->w_buffer->b_prompt_insert == NUL)
win->w_buffer->b_prompt_insert = 'A';
}
}
@@ -2130,12 +2137,17 @@ leaving_window(win_T *win)
static void
entering_window(win_T *win)
{
// Only matters for a prompt window.
if (!bt_prompt(win->w_buffer))
return;
// When switching to a prompt buffer that was in Insert mode, don't stop
// Insert mode, it may have been set in leaving_window().
if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert != NUL)
if (win->w_buffer->b_prompt_insert != NUL)
stop_insert_mode = FALSE;
// When entering the prompt window may restart Insert mode.
// When entering the prompt window restart Insert mode if we were in Insert
// mode when we left it.
restart_edit = win->w_buffer->b_prompt_insert;
}
#endif
@@ -5425,23 +5437,21 @@ frame_setwidth(frame_T *curfrp, int width)
}
/*
* Check 'winminheight' for a valid value.
* Check 'winminheight' for a valid value and reduce it if needed.
*/
void
win_setminheight(void)
{
int room;
int needed;
int first = TRUE;
win_T *wp;
/* loop until there is a 'winminheight' that is possible */
// loop until there is a 'winminheight' that is possible
while (p_wmh > 0)
{
/* TODO: handle vertical splits */
room = -p_wh;
FOR_ALL_WINDOWS(wp)
room += VISIBLE_HEIGHT(wp) - p_wmh;
if (room >= 0)
room = Rows - p_ch;
needed = frame_minheight(topframe, NULL);
if (room >= needed)
break;
--p_wmh;
if (first)
@@ -5452,6 +5462,32 @@ win_setminheight(void)
}
}
/*
* Check 'winminwidth' for a valid value and reduce it if needed.
*/
void
win_setminwidth(void)
{
int room;
int needed;
int first = TRUE;
// loop until there is a 'winminheight' that is possible
while (p_wmw > 0)
{
room = Columns;
needed = frame_minwidth(topframe, NULL);
if (room >= needed)
break;
--p_wmw;
if (first)
{
EMSG(_(e_noroom));
first = FALSE;
}
}
}
#if defined(FEAT_MOUSE) || defined(PROTO)
/*