Compare commits

...

21 Commits

Author SHA1 Message Date
3bfd04e672 patch 8.1.1444: not using double line characters for popup border
Problem:    Not using double line characters for popup border.
Solution:   Use double line characters if using utf-8.
2019-06-01 20:45:21 +02:00
2fd8e35e16 patch 8.1.1443: popup window padding and border not implemented yet
Problem:    Popup window padding and border not implemented yet.
Solution:   Implement padding and border.  Add core position and size to
            popup_getpos().
2019-06-01 20:16:48 +02:00
8caaf82569 patch 8.1.1442: popup windows not considered when the Vim window is resized
Problem:    Popup windows not considered when the Vim window is resized.
            (Ben Jackson)
Solution:   Reallocate the w_lines structure. (closes #4467)
2019-06-01 18:11:22 +02:00
bf0eff0b72 patch 8.1.1441: popup window filter not yet implemented
Problem:    Popup window filter not yet implemented.
Solution:   Implement the popup filter.
2019-06-01 17:13:36 +02:00
2d247849ce patch 8.1.1440: win_execute() test fails
Problem:    Win_execute() test fails.
Solution:   Adjust the expected error number.  Move to popup test.
2019-06-01 17:06:25 +02:00
c47ed44be7 patch 8.1.1439: json_encode() is very slow for large results
Problem:    Json_encode() is very slow for large results.
Solution:   In the growarray use a growth of at least 50%. (Ken Takata,
            closes #4461)
2019-06-01 14:36:26 +02:00
815b76bff6 patch 8.1.1438: some commands cause trouble in a popup window
Problem:    Some commands cause trouble in a popup window.
Solution:   Add NOT_IN_POPUP_WINDOW.
2019-06-01 14:15:52 +02:00
3a97bb3f0f patch 8.1.1437: code to handle callbacks is duplicated
Problem:    Code to handle callbacks is duplicated.
Solution:   Add callback_T and functions to deal with it.
2019-06-01 13:28:35 +02:00
7dd64a3e57 Update runtime files. 2019-05-31 21:41:05 +02:00
c28cb5b16d patch 8.1.1436: writefile test fails when run under /tmp
Problem:    Writefile test fails when run under /tmp.
Solution:   Adjust 'backupskip. (Kenta Sato, closes #4462)
2019-05-31 20:42:09 +02:00
5d508dd39e patch 8.1.1435: memory usage test is a bit too flaky
Problem:    Memory usage test is a bit too flaky.
Solution:   Adjust the tolerances a bit. (Christian Brabandt)
2019-05-31 20:23:25 +02:00
1ab74a5af3 patch 8.1.1434: test 3 is old style
Problem:    Test 3 is old style.
Solution:   Turn into a new style test. (Yegappan Lakshmanan, closes #4460)
2019-05-31 20:02:53 +02:00
eea1699836 patch 8.1.1433: win_execute() may leave popup window focused
Problem:    Win_execute() may leave popup window focused, eventually leading
            to a crash. (Bjorn Linse)
Solution:   When previous window was closed, go to the first window.
2019-05-31 17:34:48 +02:00
ccd6e3471d patch 8.1.1432: can't build with eval feature
Problem:    Can't build with eval feature.
Solution:   Add missing rename.
2019-05-30 22:35:18 +02:00
c6896e20f8 patch 8.1.1431: popup window listed as "Scratch"
Problem:    Popup window listed as "Scratch".
Solution:   List them as "Popup".
2019-05-30 22:32:34 +02:00
402502d0e4 patch 8.1.1430: popup window option "wrap" not supported
Problem:    Popup window option "wrap" not supported.
Solution:   Implement it.
2019-05-30 22:07:36 +02:00
ac1f1bc222 patch 8.1.1429: "pos" option of popup window not supported yet
Problem:    "pos" option of popup window not supported yet.
Solution:   Implement the option. Rename popup_getposition() to
            popup_getpos().
2019-05-30 21:24:26 +02:00
cc31ad9f9b patch 8.1.1428: popup_atcursor() not implemented yet
Problem:    Popup_atcursor() not implemented yet.
Solution:   Implement it. (Yasuhiro Matsumoto, closes #4456)
2019-05-30 19:25:06 +02:00
54fabd4b5e patch 8.1.1427: popup window screenshot test fails
Problem:    Popup window screenshot test fails.
Solution:   Add missing change to popup window code.
2019-05-30 19:03:22 +02:00
b42301247d patch 8.1.1426: no test for syntax highlight in popup window
Problem:    No test for syntax highlight in popup window.
Solution:   Add a screenshot test.  Update associated documentation. Avoid
            'buftype' being reset by setbufvar().
2019-05-30 18:40:53 +02:00
89adc3a137 patch 8.1.1425: win_execute() does not set window pointers properly
Problem:    Win_execute() does not set window pointers properly.
Solution:   Use switch_win_noblock().  Also execute autocommands in a popup
            window.
2019-05-30 17:29:40 +02:00
53 changed files with 7488 additions and 5491 deletions

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.1. Last change: 2019 May 25
*eval.txt* For Vim version 8.1. Last change: 2019 May 30
VIM REFERENCE MANUAL by Bram Moolenaar
@ -2087,12 +2087,12 @@ v:t_blob Value of |Blob| type. Read-only. See: |type()|
*v:termresponse* *termresponse-variable*
v:termresponse The escape sequence returned by the terminal for the |t_RV|
termcap entry. It is set when Vim receives an escape sequence
that starts with ESC [ or CSI and ends in a 'c', with only
digits, ';' and '.' in between.
that starts with ESC [ or CSI, then '>' or '?' and ends in a
'c', with only digits and ';' in between.
When this option is set, the TermResponse autocommand event is
fired, so that you can react to the response from the
terminal.
The response from a new xterm is: "<Esc>[ Pp ; Pv ; Pc c". Pp
The response from a new xterm is: "<Esc>[> Pp ; Pv ; Pc c". Pp
is the terminal type: 0 for vt100 and 1 for vt220. Pv is the
patch level (since this was introduced in patch 95, it's
always 95 or bigger). Pc is always zero.
@ -8400,6 +8400,8 @@ setreg({regname}, {value} [, {options}])
settabvar({tabnr}, {varname}, {val}) *settabvar()*
Set tab-local variable {varname} to {val} in tab page {tabnr}.
|t:var|
Note that autocommands are blocked, side effects may not be
triggered, e.g. when setting 'filetype'.
Note that the variable name without "t:" must be used.
Tabs are numbered starting with one.
This function is not available in the |sandbox|.
@ -8411,6 +8413,8 @@ settabwinvar({tabnr}, {winnr}, {varname}, {val}) *settabwinvar()*
use |setwinvar()|.
{winnr} can be the window number or the |window-ID|.
When {winnr} is zero the current window is used.
Note that autocommands are blocked, side effects may not be
triggered, e.g. when setting 'filetype' or 'syntax'.
This also works for a global or local buffer option, but it
doesn't work for a global or local buffer variable.
For a local buffer option the global value is unchanged.
@ -10318,9 +10322,13 @@ wildmenumode() *wildmenumode()*
win_execute({id}, {command} [, {silent}]) *win_execute()*
Like `execute()` but in the context of window {id}.
The window will temporarily be made the current window,
without triggering autocommands.
without triggering autocommands. When executing {command}
autocommands will be triggered, this may have unexpected side
effects. Use |:noautocmd| if needed.
Example: >
call win_execute(winid, 'syntax enable')
call win_execute(winid, 'set syntax=python')
< Doing the same with `setwinvar()` would not trigger
autocommands and not actually show syntax highlighting.
win_findbuf({bufnr}) *win_findbuf()*
Returns a list with |window-ID|s for windows that contain

View File

@ -1,4 +1,4 @@
*popup.txt* For Vim version 8.1. Last change: 2019 May 26
*popup.txt* For Vim version 8.1. Last change: 2019 Jun 01
VIM REFERENCE MANUAL by Bram Moolenaar
@ -13,9 +13,7 @@ THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
3. Examples |popup-examples|
{not available if the |+eval| feature was disabled at compile time}
{not able to use text properties if the |+textprop| feature was disabled at
compile time}
{not available if the |+textprop| feature was disabled at compile time}
==============================================================================
1. Introduction *popup-intro*
@ -60,15 +58,22 @@ WINDOW POSITION AND SIZE *popup-position*
The height of the window is normally equal to the number of, possibly
wrapping, lines in the buffer. It can be limited with the "maxheight"
property. You can use empty lines to increase the height.
property. You can use empty lines to increase the height or the "minheight"
property.
The width of the window is normally equal to the longest line in the buffer.
It can be limited with the "maxwidth" property. You can use spaces to
increase the width.
increase the width or the "minwidth" property.
By default the 'wrap' option is set, so that no text disappears. However, if
there is not enough space, some text may be invisible.
Vim tries to show the popup in the location you specify. In some cases, e.g.
when the popup would go outside of the Vim window, it will show it somewhere
else. E.g. if you use `popup_atcursor()` the popup normally shows just above
the current cursor position, but if the cursor is close to the top of the Vim
window it will be placed below the cursor position.
TODO:
@ -85,19 +90,20 @@ Probably 2. is the best choice.
IMPLEMENTATION:
- Code is in popupwin.c
- when creating the window set options to Vim default? (verify with 'number')
- Implement filter.
Check that popup_close() works in the filter.
- Implement the "pos" option.
- Handle screen resize in screenalloc().
- Why does 'nrformats' leak from the popup window buffer???
- Make redrawing more efficient and avoid flicker.
Store popup info in a mask, use the mask in screen_line()
Keep mask until next update_screen(), find differences and redraw affected
windows/lines
Fix redrawing problem with completion.
Fix redrawing problem when scrolling non-current window
Fix redrawing the statusline on top of a popup
- Disable commands, feedkeys(), CTRL-W, etc. in a popup window.
Use NOT_IN_POPUP_WINDOW for more commands.
- Invoke filter with character before mapping?
- Figure out the size and position better.
if wrapping splits a double-wide character
if wrapping has an indent
if wrapping inserts indent
- Can the buffer be re-used, to avoid using up lots of buffer numbers?
- Implement all the unimplemented options and features.
@ -114,7 +120,7 @@ popup_create({text}, {options}) *popup_create()*
- a string
- a list of strings
- a list of text lines with text properties
{not implemented yet}
{options} is a dictionary with many possible entries.
See |popup_create-usage| for details.
@ -160,10 +166,10 @@ popup_notification({text}, {options}) *popup_notification()*
popup_atcursor({text}, {options}) *popup_atcursor()*
{not implemented yet}
Show the {text} above the cursor, and close it when the cursor
moves. This works like: >
call popup_create({text}, {
\ 'pos': 'botleft',
\ 'line': 'cursor-1',
\ 'col': 'cursor',
\ 'moved': 'WORD',
@ -232,7 +238,8 @@ popup_setoptions({id}, {options}) *popup_setoptions()*
popup_getoptions({id}) *popup_getoptions()*
Return the {options} for popup {id} in a Dict.
A zero value means the option was not set.
A zero value means the option was not set. For "zindex" the
default value is returned, not zero.
The "highlight" entry is omitted, use the 'wincolor' option
for that: >
@ -240,17 +247,24 @@ popup_getoptions({id}) *popup_getoptions()*
< If popup window {id} is not found an empty Dict is returned.
popup_getposition({id}) *popup_getposition()*
popup_getpos({id}) *popup_getpos()*
Return the position and size of popup {id}. Returns a Dict
with these entries:
col screen column of the popup, one-based
line screen line of the popup, one-based
width width of the popup in screen cells
height height of the popup in screen cells
width width of the whole popup in screen cells
height height of the whole popup in screen cells
core_col screen column of the text box
core_line screen line of the text box
core_width width of the text box in screen cells
core_height height of the text box in screen cells
visible one if the popup is displayed, zero if hidden
Note that these are the actual screen positions. They differ
from the values in `popup_getoptions()` for the sizing and
positioning mechanism applied.
The "core_" values exclude the padding and border.
If popup window {id} is not found an empty Dict is returned.
@ -270,10 +284,11 @@ manipulation is restricted:
- 'bufhidden' is "hide"
- 'buflisted' is off
- 'undolevels' is -1: no undo at all
TODO: more
- all other buffer-local and window_local options are set to their Vim default
value.
It is possible to change these options, but anything might break then, so
better leave them alone.
It is possible to change the specifically mentioned options, but anything
might break then, so better leave them alone.
The window does have a cursor position, but the cursor is not displayed.
@ -285,6 +300,8 @@ Options can be set on the window with `setwinvar()`, e.g.: >
call setwinvar(winid, '&wrap', 0)
And options can be set on the buffer with `setbufvar()`, e.g.: >
call setbufvar(winbufnr(winid), '&filetype', 'java')
Note that this does not trigger autocommands. Use `win_execute()` if you do
need them.
POPUP_CREATE() ARGUMENTS *popup_create-usage*
@ -302,22 +319,22 @@ optionally text properties. It is in one of three forms:
|popup-props|.
The second argument of |popup_create()| is a dictionary with options:
line screen line where to position the popup; can use
"cursor", "cursor+1" or "cursor-1" to use the line of
the cursor and add or subtract a number of lines;
default is "cursor-1".
{only number is implemented}
col screen column where to position the popup; can use
"cursor" to use the column of the cursor, "cursor+99"
and "cursor-99" to add or subtract a number of
columns; default is "cursor"
{only number is implemented}
line screen line where to position the popup; can use a
number or "cursor", "cursor+1" or "cursor-1" to use
the line of the cursor and add or subtract a number of
lines; if omitted the popup is vertically centered,
otherwise "pos" is used.
col screen column where to position the popup; can use a
number or "cursor" to use the column of the cursor,
"cursor+99" and "cursor-99" to add or subtract a
number of columns; if omitted the popup is
horizontally centered, otherwise "pos" is used
pos "topleft", "topright", "botleft" or "botright":
defines what corner of the popup "line" and "col" are
used for. When not set "topleft" is used.
Alternatively "center" can be used to position the
popup in the center of the Vim window.
{not implemented yet}
popup in the center of the Vim window, in which case
"line" and "col" are ignored.
flip when TRUE (the default) and the position is relative
to the cursor, flip to below or above the cursor to
avoid overlap with the |popupmenu-completion| or
@ -339,13 +356,19 @@ The second argument of |popup_create()| is a dictionary with options:
popup, on top of any border
{not implemented yet}
wrap TRUE to make the lines wrap (default TRUE)
{not implemented yet}
highlight highlight group name to use for the text, stored in
the 'wincolor' option
padding list with numbers, defining the padding
above/right/below/left of the popup (similar to CSS);
an empty list uses a padding of 1 all around; the
padding goes around the text, inside any border;
padding uses the 'wincolor' highlight; Example: [1, 2,
1, 3] has 1 line of padding above, 2 columns on the
right, 1 line below and 3 columns on the left
border list with numbers, defining the border thickness
above/right/below/left of the popup; an empty list
uses a border of 1 all around
{not implemented yet}
above/right/below/left of the popup (similar to CSS);
only values of zero and non-zero are recognized;
an empty list uses a border of 1 all around
borderhighlight highlight group name to use for the border
{not implemented yet}
borderchars list with characters, defining the character to use
@ -365,7 +388,6 @@ The second argument of |popup_create()| is a dictionary with options:
{not implemented yet}
filter a callback that can filter typed characters, see
|popup-filter|
{not implemented yet}
callback a callback to be used when the popup closes, e.g. when
using |popup_filter_menu()|, see |popup-callback|.
{not implemented yet}
@ -399,14 +421,13 @@ So we get:
type name of the text property type, as added with
|prop_type_add()|
transparent do not show these characters, show the text under it;
if there is an border character to the right or below
if there is a border character to the right or below
it will be made transparent as well
{not implemented yet}
POPUP FILTER *popup-filter*
{not implemented yet}
A callback that gets any typed keys while a popup is displayed. The filter is
not invoked when the popup is hidden.
@ -417,10 +438,23 @@ filter is also called. The filter of the popup window with the highest zindex
is called first.
The filter function is called with two arguments: the ID of the popup and the
key.
key, e.g.: >
func MyFilter(winid, key)
if a:key == "\<F2>"
" do something
return 1
endif
if a:key == 'x'
call popup_close(a:winid)
return 1
endif
return 0
endfunc
Currently the key is what results after any mapping. This may change...
Some common key actions:
Esc close the popup
x close the popup (see note below)
cursor keys select another entry
Tab accept current suggestion
@ -431,6 +465,11 @@ popup is col 1, row 1 (not counting the border).
Vim provides standard filters |popup_filter_menu()| and
|popup_filter_yesno()|.
Note that "x" is the normal way to close a popup. You may want to use Esc,
but since many keys start with an Esc character, there may be a delay before
Vim recognizes the Esc key. If you do use Esc, it is reecommended to set the
'ttimeoutlen' option to 100 and set 'timeout' and/or 'ttimeout'.
POPUP CALLBACK *popup-callback*

View File

@ -1,4 +1,4 @@
*quickref.txt* For Vim version 8.1. Last change: 2019 May 24
*quickref.txt* For Vim version 8.1. Last change: 2019 May 31
VIM REFERENCE MANUAL by Bram Moolenaar
@ -982,6 +982,7 @@ Short explanation of each option: *option-list*
'wildmode' 'wim' mode for 'wildchar' command-line expansion
'wildoptions' 'wop' specifies how command line completion is done
'winaltkeys' 'wak' when the windows system handles ALT keys
'wincolor' 'wcr' window-local highlighting
'window' 'wi' nr of lines to scroll for CTRL-F and CTRL-B
'winheight' 'wh' minimum number of lines for the current window
'winfixheight' 'wfh' keep window height when opening/closing windows

View File

@ -4742,6 +4742,7 @@ E99 diff.txt /*E99*
E990 eval.txt /*E990*
E991 eval.txt /*E991*
E992 options.txt /*E992*
E993 popup.txt /*E993*
E999 repeat.txt /*E999*
EX intro.txt /*EX*
EXINIT starting.txt /*EXINIT*
@ -8207,7 +8208,7 @@ popup_dialog() popup.txt /*popup_dialog()*
popup_filter_menu() popup.txt /*popup_filter_menu()*
popup_filter_yesno() popup.txt /*popup_filter_yesno()*
popup_getoptions() popup.txt /*popup_getoptions()*
popup_getposition() popup.txt /*popup_getposition()*
popup_getpos() popup.txt /*popup_getpos()*
popup_hide() popup.txt /*popup_hide()*
popup_menu() popup.txt /*popup_menu()*
popup_move() popup.txt /*popup_move()*
@ -9853,6 +9854,7 @@ win32-vimrun gui_w32.txt /*win32-vimrun*
win32-win3.1 os_win32.txt /*win32-win3.1*
win32-win95 os_win32.txt /*win32-win95*
win32s os_win32.txt /*win32s*
win_execute() eval.txt /*win_execute()*
win_findbuf() eval.txt /*win_findbuf()*
win_getid() eval.txt /*win_getid()*
win_gotoid() eval.txt /*win_gotoid()*

View File

@ -1,4 +1,4 @@
*terminal.txt* For Vim version 8.1. Last change: 2019 May 20
*terminal.txt* For Vim version 8.1. Last change: 2019 May 29
VIM REFERENCE MANUAL by Bram Moolenaar
@ -907,7 +907,7 @@ When 'background' is "dark":
hi debugBreakpoint term=reverse ctermbg=red guibg=red
Shorcuts *termdebug_shortcuts*
Shortcuts *termdebug_shortcuts*
You can define your own shortcuts (mappings) to control gdb, that can work in
any window, using the TermDebugSendCommand() function. Example: >

View File

@ -1,4 +1,4 @@
*todo.txt* For Vim version 8.1. Last change: 2019 May 26
*todo.txt* For Vim version 8.1. Last change: 2019 May 31
VIM REFERENCE MANUAL by Bram Moolenaar
@ -42,6 +42,8 @@ Ongoing work on text properties, see src/textprop.c
Popup windows are being implemented, see |popup-window|.
Listener causes extra } to be inserted. (Paul Jolly, #4455)
Patch to beautify the output of a test run. (Christian Brabandt, #4391)
can be improved.
@ -52,6 +54,12 @@ remains equal? Then %argdel to clean it up. Do try this with 'hidden' set.
Patch for Chinese translations for nsis. (#4407) Comments handled?
Patch to add v:searchstat. (Takuya Fujiwara, #4446) Should be independent of
'shortmess', filled on demand and cached until search changes.
listener callback is invoked while another is still busy? (Paul Jolly)
Should not happen because of text lock.
'incsearch' with :s: (#3321)
- Get E20 when using command history to get "'<,'>s/a/b" and no Visual area
was set. (#3837)
@ -130,6 +138,12 @@ Should do current file first and not split it up when more results are found.
Adding "10" to 'spellsuggest' causes spell suggestions to become very slow.
(#4087)
Problem with German spell file. Hint for solution by Klaus-Peter Schreiner in
#4314, solves the Rasenmäher problem.
Visual highlight not removed when 'dipslay' is "lastline" and line doesn't
fit. (Kevin Lawler, #4457)
Does not build with MinGW out of the box:
- _stat64 is not defined, need to use "struct stat" in vim.h
- WINVER conflict, should use 0x0600 by default?
@ -177,6 +191,10 @@ register "", So that registers can be saved and fully restored.
Add a way to create an empty, hidden buffer. Like doing ":new|hide".
":let buf = bufcreate('name')
Session file contains absolute paths when "curdir" is removed form
'sessionoptions', making it impossible to have a session with a relative path.
(#4450)
When using a timer callback vgetc_busy is reset, allowing for using input().
But in a channel callback this does not happen. We need to do something
similar to check_due_timer(). Also see #3809.

View File

@ -1,4 +1,4 @@
*usr_41.txt* For Vim version 8.1. Last change: 2019 May 16
*usr_41.txt* For Vim version 8.1. Last change: 2019 May 29
VIM USER MANUAL - by Bram Moolenaar
@ -105,20 +105,21 @@ We won't explain how |:for| and |range()| work until later. Follow the links
if you are impatient.
THREE KINDS OF NUMBERS
FOUR KINDS OF NUMBERS
Numbers can be decimal, hexadecimal or octal. A hexadecimal number starts
with "0x" or "0X". For example "0x1f" is decimal 31. An octal number starts
with a zero. "017" is decimal 15. Careful: don't put a zero before a decimal
number, it will be interpreted as an octal number!
Numbers can be decimal, hexadecimal, octal or binary. A hexadecimal number
starts with "0x" or "0X". For example "0x1f" is decimal 31. An octal number
starts with a zero. "017" is decimal 15. A binary number starts with "0b" or
"0B". For example "0b101" is decimal 5. Careful: don't put a zero before a
decimal number, it will be interpreted as an octal number!
The ":echo" command always prints decimal numbers. Example: >
:echo 0x7f 036
< 127 30 ~
A number is made negative with a minus sign. This also works for hexadecimal
and octal numbers. A minus sign is also used for subtraction. Compare this
with the previous example: >
A number is made negative with a minus sign. This also works for hexadecimal,
octal and binary numbers. A minus sign is also used for subtraction. Compare
this with the previous example: >
:echo 0x7f -036
< 97 ~
@ -614,6 +615,7 @@ String manipulation: *string-functions*
repeat() repeat a string multiple times
eval() evaluate a string expression
execute() execute an Ex command and get the output
win_execute() like execute() but in a specified window
trim() trim characters from a string
List manipulation: *list-functions*

View File

@ -25914,7 +25914,7 @@ Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
Patch 8.1.0021
Problem: Clang warns for undefined behavior.
Solution: Move #ifdef outside of sprintf() call.(suggestion by Michael
Solution: Move #ifdef outside of sprintf() call. (suggestion by Michael
Jarvis, closes #2946)
Files: src/term.c
@ -25930,7 +25930,7 @@ Solution: Use mch_memmove() instead of STRNCPY().
Files: src/memline.c
Patch 8.1.0024
Problem: % command not testded on #ifdef and comment.
Problem: % command not tested on #ifdef and comment.
Solution: Add tests. (Dominique Pelle, closes #2956)
Files: src/testdir/test_goto.vim
@ -25946,7 +25946,7 @@ Files: src/testdir/test_terminal.vim
Patch 8.1.0027
Problem: Difficult to make a plugin that feeds a line to a job.
Solution: Add the nitial code for the "prompt" buftype.
Solution: Add the initial code for the "prompt" buftype.
Files: runtime/doc/channel.txt, runtime/doc/eval.txt,
runtime/doc/options.txt, runtime/doc/tags, runtime/doc/todo.txt,
src/Makefile, src/buffer.c, src/channel.c, src/diff.c, src/edit.c,
@ -25966,7 +25966,7 @@ Solution: Skip test with redirection on MS-Windows.
Files: src/testdir/test_terminal.vim
Patch 8.1.0030
Problem: Stoping Vim running in a terminal may not work.
Problem: Stopping Vim running in a terminal may not work.
Solution: Instead of sending <Esc> send CTRL-O.
Files: src/testdir/screendump.vim, src/testdir/test_prompt_buffer.vim
@ -26046,8 +26046,8 @@ Solution: Return FAIL from get_bad_opt() only when there is no valid
Files: src/ex_docmd.c, src/testdir/test_plus_arg_edit.vim
Patch 8.1.0044
Problem: If a test function exists Vim this may go unnoticed.
Solution: Check for a test funtion quitting Vim. Fix tests that did exit
Problem: If a test function exits Vim this may go unnoticed.
Solution: Check for a test function quitting Vim. Fix tests that did exit
Vim.
Files: src/testdir/runtest.vim, src/testdir/test_assert.vim
@ -26330,7 +26330,7 @@ Solution: Only use debugbreak() on MS-Windows.
Files: runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
Patch 8.1.0094
Problem: Help text "usage:" is not capatalized.
Problem: Help text "usage:" is not capitalized.
Solution: Make it "Usage:". (closes #3044)
Files: src/main.c
@ -26929,7 +26929,8 @@ Files: src/testdir/test_spell.vim
Patch 8.1.0201
Problem: Newer Python uses "importlib" instead of "imp".
Solution: Use "importlib" for newer Python versions. (closes #3163)
Solution: Use "importlib" for newer Python versions. (Ozaki Kiichi,
closes #3163)
Files: src/if_py_both.h, src/testdir/test87.in
Patch 8.1.0202
@ -27156,7 +27157,8 @@ Solution: Add a test that shows the behavior. (Christian Brabandt,
Files: src/testdir/test_tabpage.vim
Patch 8.1.0242
Problem: Insert mode completion may use an invalid buffer pointer.
Problem: Insert mode completion may use an invalid buffer pointer. (Akib
Nizam)
Solution: Check for ins_buf to be valid. (closes #3290)
Files: src/edit.c
@ -27692,7 +27694,7 @@ Solution: Allow :file without argument when curbuf_lock is set. (Jason
Files: src/ex_docmd.c, src/testdir/test_quickfix.vim
Patch 8.1.0338
Problem: MS-Windows: VTP doesn't work properly with Powershell.
Problem: MS-Windows: VTP doesn't work properly with PowerShell.
Solution: Adjust the color index. (Nobuhiro Takasaki, closes #3347)
Files: src/os_win32.c
@ -27715,7 +27717,8 @@ Files: src/ex_cmds2.c, src/testdir/test_arglist.vim,
src/testdir/test_command_count.vim
Patch 8.1.0342
Problem: Crash when a callback deletes a window that is being used.
Problem: Crash when a callback deletes a window that is being used. (Ozaki
Kiichi)
Solution: Do not unload a buffer that is being displayed while redrawing the
screen. Also avoid invoking callbacks while redrawing.
(closes #2107)
@ -27795,7 +27798,7 @@ Files: src/testdir/test_packadd.vim
Patch 8.1.0355
Problem: Incorrect adjusting the popup menu for the preview window.
Solution: Compute position and height properl. (Ronan Pigott) Also show at
Solution: Compute position and height properly. (Ronan Pigott) Also show at
least ten items. (closes #3414)
Files: src/popupmnu.c
@ -28388,7 +28391,7 @@ Files: src/os_win32.c, runtime/doc/mlang.txt
Patch 8.1.0453
Problem: MS-Windows: executable() is not reliable.
Solution: Use $PATHEXT properly. (Yasuhiro Matsumoto, closes #3412)
Solution: Use $PATHEXT properly. (Yasuhiro Matsumoto, closes #3512)
Files: src/os_win32.c, src/testdir/test_functions.vim
Patch 8.1.0454
@ -28448,7 +28451,8 @@ Files: src/memline.c
Patch 8.1.0464
Problem: MS-Windows: job_info() has cmd without backslashes. (Daniel
Hahler)
Solution: Use rem_backslash(). (closes #3517, closes #3404)
Solution: Use rem_backslash(). (closes #3517, closes #3404) Add a test.
(Yasuhiro Matsumoto)
Files: src/misc2.c, src/testdir/test_channel.vim
Patch 8.1.0465 (after 8.1.0452)
@ -28535,7 +28539,7 @@ Files: src/Make_cyg_ming.mak
Patch 8.1.0479
Problem: Failure when setting 'varsofttabstop' to end in a comma. (Ralf
Schandl)
Solution: Reject value with trailing command. Add test for invalid values
Solution: Reject value with trailing comma. Add test for invalid values
(closes #3544)
Files: src/testdir/test_vartabs.vim, src/option.c
@ -28596,7 +28600,7 @@ Solution: Return from qf_jump_edit_buffer() early. (Yegappan Lakshmanan)
Files: src/quickfix.c, src/testdir/test_quickfix.vim
Patch 8.1.0490
Problem: MS-Windows: doesn't handle missing glibwinpthread-1.dll.
Problem: MS-Windows: doesn't handle missing libwinpthread-1.dll.
Solution: Adjust Cygwin/MinGW build file. (Ken Takata, closes #2827)
Files: src/Make_cyg_ming.mak
@ -28972,7 +28976,7 @@ Files: src/popupmnu.c, src/testdir/test_popup.vim,
Patch 8.1.0555
Problem: Crash when last search pat is set but not last substitute pat.
Solution: Do not mix up last search pattern and last subtitute pattern.
Solution: Do not mix up last search pattern and last substitute pattern.
(closes #3647)
Files: src/search.c, src/testdir/test_search.vim
@ -28983,7 +28987,7 @@ Solution: Use a separate saved last_idx for saving search patterns for
Files: src/search.c
Patch 8.1.0557
Problem: Termdebug: gdb may use X.Y for breakpoint number.
Problem: Termdebug: gdb may use X.Y for breakpoint number. (Ryou Ezoe)
Solution: Handle X.Y breakpoint numbers. (Yasuhiro Matsumoto, close #3641)
Files: runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@ -29001,13 +29005,13 @@ Files: src/testdir/test_arglist.vim, src/testdir/test_filetype.vim,
src/testdir/test_syntax.vim
Patch 8.1.0560
Problem: Cannot use address type "other" with with user command.
Problem: Cannot use address type "other" with user command.
Solution: Add "other" to the list. (Daniel Hahler, closes #3655) Also
reject "%" for commands with "other". Add some more tests.
Files: src/ex_docmd.c, src/testdir/test_usercommands.vim
Patch 8.1.0561
Problem: MSCV error format has changed.
Problem: MSVC error format has changed.
Solution: Make the space between the line number and colon optional.
Files: src/option.h
@ -29069,7 +29073,7 @@ Files: src/evalfunc.c, src/testdir/test_execute_func.vim
Patch 8.1.0572
Problem: Stopping a job does not work properly on OpenBSD.
Solution: Do not use getpgid() to check the process group of the job
processs ID, always pass the negative process ID to kill().
process ID, always pass the negative process ID to kill().
(George Koehler, closes #3656)
Files: src/os_unix.c
@ -29105,7 +29109,7 @@ Files: src/gui_gtk_x11.c, src/gui_mac.c, src/gui_motif.c, src/gui.c
Patch 8.1.0578
Problem: Cannot disable arabic, rightleft and farsi in configure.
Solution: Add configur flags. (Diego Fernando Carrión, closes #1867)
Solution: Add configure flags. (Diego Fernando Carrión, closes #1867)
Files: src/configure.ac, src/auto/configure, src/config.h.in,
src/feature.h, src/Makefile
@ -29275,7 +29279,7 @@ Files: src/os_mswin.c, src/proto/buffer.pro, src/proto/ex_cmds.pro,
src/proto/userfunc.pro
Patch 8.1.0608
Problem: Coverals is not updating.
Problem: Coveralls is not updating.
Solution: Adjust path in Travis config.
Files: .travis.yml
@ -29363,7 +29367,7 @@ Files: src/eval.c, src/proto/eval.pro, src/evalfunc.c,
src/testdir/test_messages.vim, src/message.c
Patch 8.1.0620
Problem: Overuling CONF_ARGS from the environment no longer works. (Tony
Problem: Overruling CONF_ARGS from the environment no longer works. (Tony
Mechelynck)
Solution: Do not define any CONF_ARGS by default.
Files: src/Makefile
@ -29385,8 +29389,8 @@ Solution: Define FOR_ALL_FRAMES. (Yegappan Lakshmanan)
Files: src/ex_docmd.c, src/globals.h, src/screen.c, src/window.c
Patch 8.1.0624 (after 8.2.0620)
Problem: Overuling CONF_ARGS from the environment still does not work. (Tony
Mechelynck)
Problem: Overruling CONF_ARGS from the environment still does not work.
(Tony Mechelynck)
Solution: Add back CONF_ARGS next to the new numbered ones.
Files: src/Makefile
@ -29480,7 +29484,7 @@ Files: src/testdir/test_textprop.vim
Patch 8.1.0640
Problem: Get E14 while typing command :tab with 'incsearch' set.
Solution: Do not give an error when looking for the command. (Yasuhiro
Solution: Do not give an error when looking for the command. (Hirohito
Higashi)
Files: src/testdir/test_search.vim, src/ex_docmd.c
@ -29617,7 +29621,7 @@ Files: src/screen.c
Patch 8.1.0664
Problem: Configure "fail-if-missing" does not apply to the enable-gui
argument. (Rhialto)
Solution: Make configure fail if a GUI was specifified and "fail-if-missing"
Solution: Make configure fail if a GUI was specified and "fail-if-missing"
is enabled and the GUI test fails.
Files: src/configure.ac, src/auto/configure
@ -29935,7 +29939,7 @@ Files: nsis/icons.zip, nsis/icons/disabled.bmp, nsis/icons/enabled.bmp,
nsis/README.txt, Filelist, Makefile
Patch 8.1.0714
Problem: Unessesary #if lines in GTK code.
Problem: Unnecessary #if lines in GTK code.
Solution: Remove the #if. (Ken Takata, closes #3785)
Files: src/gui_beval.c, src/if_mzsch.c
@ -29970,7 +29974,7 @@ Files: src/evalfunc.c, src/version.c, src/normal.c, src/ops.c,
src/feature.h, runtime/doc/various.txt
Patch 8.1.0720
Problem: Cannot easily change the current quickfx list index.
Problem: Cannot easily change the current quickfix list index.
Solution: Add the "idx" argument to setqflist(). (Yegappan Lakshmanan,
closes #3701)
Files: runtime/doc/eval.txt, runtime/doc/quickfix.txt, src/quickfix.c,
@ -30777,7 +30781,7 @@ Files: src/ui.c
Patch 8.1.0836
Problem: User completion test can fail on MS-Windows.
Solution: Allow for other names befor "Administrator".
Solution: Allow for other names before "Administrator".
Files: src/testdir/test_cmdline.vim
Patch 8.1.0837
@ -30804,7 +30808,7 @@ Files: src/ui.c, src/testdir/test_timers.vim, src/gui_gtk_x11.c,
Patch 8.1.0841
Problem: Travis config to get Lua on MacOS is too complicated.
Solution: Use an addons entry. (Ozaki Kiichi, closes 3876)
Solution: Use an addons entry. (Ozaki Kiichi, closes #3876)
Files: .travis.yml
Patch 8.1.0842
@ -30912,7 +30916,7 @@ Solution: Make them the same, update docs. (close #3882)
Files: src/option.c, runtime/doc/options.txt, runtime/doc/indent.txt
Patch 8.1.0859
Problem: "%v" in 'errorformat' does handle multi-byte characters.
Problem: "%v" in 'errorformat' does not handle multi-byte characters.
Solution: Handle multi-byte characters. (Yegappan Lakshmanan, closes #3700)
Files: src/quickfix.c, src/testdir/test_quickfix.vim
@ -31034,7 +31038,7 @@ Files: src/testdir/test_functions.vim
Patch 8.1.0879
Problem: MS-Windows: temp name encoding can be wrong.
Solution: Convert from active code page to 'encoding'. (Ken Takata,
Solution: Convert from active code page to 'encoding'. (Yasuhiro Matsumoto,
closes #3520, closes #1698)
Files: src/fileio.c
@ -31064,7 +31068,7 @@ Files: src/fileio.c
Patch 8.1.0883
Problem: Missing some changes for Ex commands.
Solution: Add mising changes in header file.
Solution: Add missing changes in header file.
Files: src/ex_cmds.h
Patch 8.1.0884
@ -31111,7 +31115,7 @@ Solution: Correct using use_file_for_out in condition. (Ozaki Kiichi, closes
Files: src/os_unix.c, src/testdir/test_channel.vim
Patch 8.1.0891
Problem: Substitute command inssuficiently tested.
Problem: Substitute command insufficiently tested.
Solution: Add more test coverage. (Dominique Pelle)
Files: src/testdir/test_substitute.vim
@ -31165,7 +31169,7 @@ Solution: Remove check_restricted().
Files: src/eval.c
Patch 8.1.0900
Problem: ConPTY many crash with 32-bit build.
Problem: ConPTY may crash with 32-bit build.
Solution: Fix function declarations. (Ken Takata, closes #3943)
Files: src/terminal.c
@ -31219,7 +31223,7 @@ Files: runtime/doc/options.txt, src/os_win32.c, src/proto/os_win32.pro,
Patch 8.1.0910
Problem: Crash with tricky search pattern. (Kuang-che Wu)
Solution: Check for runnning out of memory. (closes #3950)
Solution: Check for running out of memory. (closes #3950)
Files: src/regexp_nfa.c, src/testdir/test_regexp_latin.vim
Patch 8.1.0911
@ -31419,7 +31423,7 @@ Files: src/ex_docmd.c, src/normal.c, src/os_win32.c,
src/proto/os_win32.pro
Patch 8.1.0941
Problem: Macros for MS-Windows are inconsistent, using "32", "3264 and
Problem: Macros for MS-Windows are inconsistent, using "32", "3264" and
others.
Solution: Use MSWIN for all MS-Windows builds. Use FEAT_GUI_MSWIN for the
GUI build. (Hirohito Higashi, closes #3932)
@ -31481,7 +31485,7 @@ Solution: Do not enable filetype detection.
Files: runtime/defaults.vim
Patch 8.1.0949
Problem: MS-windows defines GUI macros different than other systems.
Problem: MS-Windows defines GUI macros different than other systems.
Solution: Swap FEAT_GUI and FEAT_GUI_MSWIN. (Hirohito Higashi, closes #3996)
Files: src/Make_bc5.mak, src/Make_cyg_ming.mak, src/Make_ivc.mak,
src/Make_mvc.mak, src/if_ole.cpp, src/vim.h, src/vim.rc
@ -31592,7 +31596,8 @@ Files: src/regexp_nfa.c, src/testdir/test_search.vim
Patch 8.1.0969
Problem: Message written during startup is truncated.
Solution: Restore message after truncating. (closes 3969)
Solution: Restore message after truncating. (closes #3969) Add a test.
(Yasuhiro Matsumoto)
Files: src/message.c, src/testdir/test_startup.vim
Patch 8.1.0970
@ -31634,7 +31639,7 @@ Files: src/screen.c, src/textprop.c
Patch 8.1.0976
Problem: Dosinstall still has buffer overflow problems.
Solution: Adjust buffer sizes. (Yasuhiro Matsumoto, closes #4002)
Solution: Adjust buffer sizes. (Yasuhiro Matsumoto, closes #4002)
Files: src/dosinst.c, src/dosinst.h, src/uninstal.c
Patch 8.1.0977
@ -31685,7 +31690,7 @@ Solution: Check for long becoming negative int. (closes #4042)
Files: src/regexp.c, src/testdir/test_search.vim
Patch 8.1.0986
Problem: rename() is not propertly tested.
Problem: rename() is not properly tested.
Solution: Add tests. (Dominique Pelle, closes #4061)
Files: src/testdir/Make_all.mak, src/testdir/test_alot.vim,
src/testdir/test_rename.vim
@ -31742,7 +31747,7 @@ Files: src/window.c, src/evalfunc.c, runtime/doc/eval.txt,
Patch 8.1.0995
Problem: A getchar() call while executing a register resets the
reg_executing() result.
Solution: Save and restore reg_executing. (closes #406
Solution: Save and restore reg_executing. (closes #4066)
Files: src/evalfunc.c, src/testdir/test_functions.vim
Patch 8.1.0996 (after 8.1.0994)
@ -31847,7 +31852,7 @@ Files: src/os_win32.c
Patch 8.1.1014
Problem: MS-Windows: /analyze only defined for non-debug version.
Solution: Move adding of /analyze up. (Taro Muraoka, closes #4114)
Solution: Move adding of /analyze up. (Ken Takata, closes #4114)
Files: src/Make_mvc.mak
Patch 8.1.1015
@ -31859,9 +31864,9 @@ Files: runtime/doc/eval.txt, runtime/doc/quickfix.txt, src/quickfix.c,
src/testdir/test_quickfix.vim, src/window.c
Patch 8.1.1016
Problem: MS-Windows: No color in shell when using "!" in 'guioptions.
Problem: MS-Windows: No color in shell when using "!" in 'guioptions'.
Solution: Don't stop termcap when using a terminal window for the shell.
(vim-jp, closes #4117)
(Nobuhiro Takasaki, vim-jp, closes #4117)
Files: src/ex_cmds.c
Patch 8.1.1017
@ -32049,7 +32054,7 @@ Files: src/undo.c, src/proto/undo.pro, src/normal.c,
src/testdir/test_normal.vim
Patch 8.1.1050
Problem: Blank srceen when DirectWrite failed.
Problem: Blank screen when DirectWrite failed.
Solution: Call redraw_later_clear() after recreating the Direct2D render
target. (Ken Takata, closes #4172)
Files: src/gui_dwrite.cpp
@ -32411,7 +32416,7 @@ Files: src/Make_cyg.mak, src/Make_cyg_ming.mak, src/Make_mvc.mak,
Patch 8.1.1105
Problem: Long escape sequences may be split up.
Solution: Assume esccape sequences can be up to 80 bytes long. (Nobuhiro
Solution: Assume escape sequences can be up to 80 bytes long. (Nobuhiro
Takasaki, closes #4196)
Files: src/term.c
@ -32471,7 +32476,8 @@ Files: src/autocmd.c
Patch 8.1.1116
Problem: Cannot enforce a Vim script style.
Solution: Add the :scriptversion command. (closes #3857)
Solution: Add the :scriptversion command. (idea by Yasuhiro Matsumoto,
closes #3857)
Files: runtime/doc/repeat.txt, runtime/doc/eval.txt, src/eval.c,
src/ex_cmds.h, src/evalfunc.c, src/ex_cmds2.c,
src/proto/ex_cmds2.pro, src/structs.h, src/buffer.c, src/main.c,
@ -32576,7 +32582,7 @@ Files: src/globals.h
Patch 8.1.1134
Problem: Buffer for quickfix window is reused for another file.
Solution: Don't reuse the quickfx buffer. (Yegappan Lakshmanan)
Solution: Don't reuse the quickfix buffer. (Yegappan Lakshmanan)
Files: src/buffer.c, src/testdir/test_quickfix.vim
Patch 8.1.1135 (after 8.1.1134)
@ -32598,7 +32604,8 @@ Files: src/testdir/test_termcodes.vim
Patch 8.1.1138
Problem: Plugins don't get notified when the popup menu changes.
Solution: Add the CompleteChanged event. (Andy Massimino. closes #4176)
Solution: Add the CompleteChanged event. (Qiming Zhao, Andy Massimino,
closes #4176)
Files: runtime/doc/autocmd.txt, src/autocmd.c, src/dict.c,
src/insexpand.c, src/popupmnu.c, src/proto/autocmd.pro,
src/proto/dict.pro, src/proto/popupmnu.pro,
@ -32681,7 +32688,7 @@ Files: src/Makefile
Patch 8.1.1152
Problem: Compiler warning with VS2019.
Solution: Specify different offset for "AMD64". (closes #4235)
Solution: Specify different offset for "AMD64". (Ken Takata, closes #4235)
Files: src/GvimExt/Makefile
Patch 8.1.1153
@ -32691,7 +32698,7 @@ Files: src/po/Makefile
Patch 8.1.1154
Problem: Getting a newer msgfmt on Travis is too complicated.
Solution: Use a "sourcline" entry. (Ozaki Kiichi, closes #4236)
Solution: Use a "sourceline" entry. (Ozaki Kiichi, closes #4236)
Files: .travis.yml
Patch 8.1.1155
@ -32898,7 +32905,7 @@ Files: src/edit.c, src/testdir/test_bufline.vim,
Patch 8.1.1190
Problem: has('vimscript-3') does not work.
Solution: Add "vimscript-3" to the list of features.
Solution: Add "vimscript-3" to the list of features. (partly by Ken Takata)
Files: src/evalfunc.c, src/testdir/test_eval_stuff.vim
Patch 8.1.1191
@ -32947,7 +32954,7 @@ Files: src/main.c, src/testdir/test_startup.vim,
Patch 8.1.1198
Problem: Bracketed paste may remain active after Vim exists, because the
terminal emulater restores the setting.
terminal emulator restores the setting.
Solution: Set/reset bracketed paste mode before setting the terminal mode.
(closes #3579)
Files: src/term.c
@ -33331,8 +33338,8 @@ Solution: Adjust comment. Don't use different directory for DIRECTX. Do
Files: src/Make_mvc.mak
Patch 8.1.1258
Problem: The "N files to edit" message can not be surpressed.
Solution: Surpress the message with --not-a-term. (closes #4320)
Problem: The "N files to edit" message can not be suppressed.
Solution: Suppress the message with --not-a-term. (closes #4320)
Files: src/main.c
Patch 8.1.1259
@ -33741,7 +33748,7 @@ Files: src/configure.ac, src/auto/configure, src/config.h.in,
Patch 8.1.1314
Problem: MSVC makefile is not nicely indented.
Solution: Addjust spaces in preprocessor directives. (Ken Takata)
Solution: Adjust spaces in preprocessor directives. (Ken Takata)
Files: src/Make_mvc.mak
Patch 8.1.1315
@ -33757,7 +33764,8 @@ Files: src/undo.c
Patch 8.1.1317
Problem: Output from Travis can be improved.
Solution: Add section headers. Handle errors better. (closes #4098)
Solution: Add section headers. Handle errors better. (Ozaki Kiichi,
closes #4098)
Files: .travis.yml, configure
Patch 8.1.1318
@ -33790,7 +33798,7 @@ Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt,
Patch 8.1.1322
Problem: Cygwin makefile is not nicely indented.
Solution: Addjust spaces in preprocessor directives. (Ken Takata)
Solution: Adjust spaces in preprocessor directives. (Ken Takata)
Files: src/Make_cyg_ming.mak
Patch 8.1.1323
@ -34028,7 +34036,7 @@ Files: src/ex_cmds.c, src/testdir/test_textprop.vim, src/vim.h,
Patch 8.1.1360 (after Patch 8.1.1345)
Problem: Buffer left 'nomodifiable' after :substitute. (Ingo Karkat)
Solution: Save the value of 'modifiable' earlier' (Christian Brabandt,
Solution: Save the value of 'modifiable' earlier. (Christian Brabandt,
closes #4403)
Files: src/ex_cmds.c, src/testdir/test_substitute.vim
@ -34098,7 +34106,7 @@ Patch 8.1.1371
Problem: Cannot recover from a swap file.
Solution: Do not expand environment variables in the swap file name.
Do not check the extension when we already know a file is a swap
file. (Ken Takata, closes 4415, closes #4369)
file. (Ken Takata, closes #4415, closes #4369)
Files: src/buffer.c, src/ex_cmds.c, src/ex_cmds2.c, src/ex_docmd.c,
src/gui.c, src/if_cscope.c, src/main.c, src/memline.c,
src/misc1.c, src/proto/memline.pro, src/proto/misc1.pro,
@ -34109,7 +34117,7 @@ Patch 8.1.1372
Problem: When evaluating 'statusline' the current window is unknown.
(Daniel Hahler)
Solution: Set "g:actual_curwin" for %{} items. Set "g:statusline_winid"
when evaluationg %!. (closes #4406, closes #3299)
when evaluating %!. (closes #4406, closes #3299)
Files: src/buffer.c, runtime/doc/options.txt,
src/testdir/test_statusline.vim
@ -34154,13 +34162,13 @@ Files: src/fileio.c, src/testdir/test_filechanged.vim
Patch 8.1.1380
Problem: MS-Windows building VIMDLL with MSVC: SUBSYSTEM is not set.
Solution: Invert condition. (closes #4422)
Solution: Invert condition. (Ken Takata, closes #4422)
Files: src/Make_mvc.mak
Patch 8.1.1381
Problem: MS-Windows: missing build dependency.
Solution: Make gui_dwrite.cpp depend on gui_dwrite.h. (Ken Takata,
closes #4423
closes #4423)
Files: src/Make_cyg_ming.mak, src/Make_mvc.mak
Patch 8.1.1382
@ -34202,7 +34210,7 @@ Solution: Use STRLEN() instead of strlen().
Files: src/fileio.c
Patch 8.1.1386
Problem: Unessesary type casts for lalloc().
Problem: Unnecessary type casts for lalloc().
Solution: Remove type casts. Change lalloc(size, TRUE) to alloc(size).
Files: src/buffer.c, src/change.c, src/channel.c, src/diff.c, src/edit.c,
src/eval.c, src/ex_cmds.c, src/ex_getln.c, src/fileio.c,

View File

@ -1,4 +1,4 @@
*windows.txt* For Vim version 8.1. Last change: 2019 May 18
*windows.txt* For Vim version 8.1. Last change: 2019 May 30
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1030,6 +1030,13 @@ list of buffers. |unlisted-buffer|
thus you can always go to a specific buffer with ":buffer N"
or "N CTRL-^", where N is the buffer number.
For the file name these special values are used:
[Prompt] |prompt-buffer|
[Popup] buffer of a |popup-window|
[Scratch] 'buftype' is "nofile"
[No Name] no file name specified
For a |terminal-window| buffer the status is used.
Indicators (chars in the same column are mutually exclusive):
u an unlisted buffer (only displayed when [!] is used)
|unlisted-buffer|

View File

@ -3,13 +3,16 @@
[Desktop Entry]
# Translators: This is the Application Name used in the GVim desktop file
Name[de]=GVim
Name[eo]=GVim
Name=GVim
# Translators: This is the Generic Application Name used in the Vim desktop file
GenericName[de]=Texteditor
GenericName[eo]=Tekstoredaktilo
GenericName[ja]=テキストエディタ
GenericName=Text Editor
# Translators: This is the comment used in the Vim desktop file
Comment[de]=Textdateien bearbeiten
Comment[eo]=Redakti tekstajn dosierojn
Comment[ja]=テキストファイルを編集します
Comment=Edit text files
# The translations should come from the po file. Leave them here for now, they will
@ -92,10 +95,12 @@ Terminal=false
Type=Application
# Translators: Search terms to find this application. Do NOT change the semicolons! The list MUST also end with a semicolon!
Keywords[de]=Text;Editor;
Keywords[eo]=Teksto;redaktilo;
Keywords[ja]=テキスト;エディタ;
Keywords=Text;editor;
# Translators: This is the Icon file name. Do NOT translate
Icon[de]=gvim
Icon[eo]=gvim
Icon=gvim
Categories=Utility;TextEditor;
StartupNotify=true

View File

@ -6,8 +6,8 @@
" Contributor: Leonard Ehrenfried <leonard.ehrenfried@web.de>
" Contributor: Karsten Hopp <karsten@redhat.com>
" Originally: 2009-07-09
" Last Change: 2017 Oct 25
" SSH Version: 7.6p1
" Last Change: 2019-05-31
" SSH Version: 7.9p1
"
" Setup
@ -137,7 +137,8 @@ syn case ignore
" Keywords
syn keyword sshdconfigMatch Host User Group Address
" Also includes RDomain, but that is a keyword.
syn keyword sshdconfigMatch Host User Group Address LocalAddress LocalPort
syn keyword sshdconfigKeyword AcceptEnv
syn keyword sshdconfigKeyword AddressFamily
@ -150,8 +151,11 @@ syn keyword sshdconfigKeyword AuthenticationMethods
syn keyword sshdconfigKeyword AuthorizedKeysFile
syn keyword sshdconfigKeyword AuthorizedKeysCommand
syn keyword sshdconfigKeyword AuthorizedKeysCommandUser
syn keyword sshdconfigKeyword AuthorizedPrincipalsCommand
syn keyword sshdconfigKeyword AuthorizedPrincipalsCommandUser
syn keyword sshdconfigKeyword AuthorizedPrincipalsFile
syn keyword sshdconfigKeyword Banner
syn keyword sshdconfigKeyword CASignatureAlgorithms
syn keyword sshdconfigKeyword ChallengeResponseAuthentication
syn keyword sshdconfigKeyword ChrootDirectory
syn keyword sshdconfigKeyword Ciphers
@ -162,13 +166,17 @@ syn keyword sshdconfigKeyword DebianBanner
syn keyword sshdconfigKeyword DenyGroups
syn keyword sshdconfigKeyword DenyUsers
syn keyword sshdconfigKeyword DisableForwarding
syn keyword sshdconfigKeyword ExposeAuthInfo
syn keyword sshdconfigKeyword FingerprintHash
syn keyword sshdconfigKeyword ForceCommand
syn keyword sshdconfigKeyword GatewayPorts
syn keyword sshdconfigKeyword GSSAPIAuthentication
syn keyword sshdconfigKeyword GSSAPICleanupCredentials
syn keyword sshdconfigKeyword GSSAPIEnablek5users
syn keyword sshdconfigKeyword GSSAPIKeyExchange
syn keyword sshdconfigKeyword GSSAPIKexAlgorithms
syn keyword sshdconfigKeyword GSSAPIStoreCredentialsOnRekey
syn keyword sshdconfigKeyword GSSAPIStrictAcceptorCheck
syn keyword sshdconfigKeyword GatewayPorts
syn keyword sshdconfigKeyword HostCertificate
syn keyword sshdconfigKeyword HostKey
syn keyword sshdconfigKeyword HostKeyAgent
@ -184,6 +192,8 @@ syn keyword sshdconfigKeyword KerberosAuthentication
syn keyword sshdconfigKeyword KerberosGetAFSToken
syn keyword sshdconfigKeyword KerberosOrLocalPasswd
syn keyword sshdconfigKeyword KerberosTicketCleanup
syn keyword sshdconfigKeyword KerberosUniqueCCache
syn keyword sshdconfigKeyword KerberosUseKuserok
syn keyword sshdconfigKeyword KexAlgorithms
syn keyword sshdconfigKeyword KeyRegenerationInterval
syn keyword sshdconfigKeyword ListenAddress
@ -197,6 +207,7 @@ syn keyword sshdconfigKeyword MaxStartups
syn keyword sshdconfigKeyword PasswordAuthentication
syn keyword sshdconfigKeyword PermitBlacklistedKeys
syn keyword sshdconfigKeyword PermitEmptyPasswords
syn keyword sshdconfigKeyword PermitListen
syn keyword sshdconfigKeyword PermitOpen
syn keyword sshdconfigKeyword PermitRootLogin
syn keyword sshdconfigKeyword PermitTTY
@ -213,10 +224,14 @@ syn keyword sshdconfigKeyword PubkeyAuthentication
syn keyword sshdconfigKeyword RSAAuthentication
syn keyword sshdconfigKeyword RekeyLimit
syn keyword sshdconfigKeyword RevokedKeys
syn keyword sshdconfigKeyword RDomain
syn keyword sshdconfigKeyword RhostsRSAAuthentication
syn keyword sshdconfigKeyword ServerKeyBits
syn keyword sshdconfigKeyword SetEnv
syn keyword sshdconfigKeyword ShowPatchLevel
syn keyword sshdconfigKeyword StrictModes
syn keyword sshdconfigKeyword StreamLocalBindMask
syn keyword sshdconfigKeyword StreamLocalBindUnlink
syn keyword sshdconfigKeyword Subsystem
syn keyword sshdconfigKeyword SyslogFacility
syn keyword sshdconfigKeyword TCPKeepAlive
@ -227,6 +242,7 @@ syn keyword sshdconfigKeyword UsePAM
syn keyword sshdconfigKeyword VersionAddendum
syn keyword sshdconfigKeyword X11DisplayOffset
syn keyword sshdconfigKeyword X11Forwarding
syn keyword sshdconfigKeyword X11MaxDisplays
syn keyword sshdconfigKeyword X11UseLocalhost
syn keyword sshdconfigKeyword XAuthLocation

View File

@ -3,13 +3,16 @@
[Desktop Entry]
# Translators: This is the Application Name used in the Vim desktop file
Name[de]=Vim
Name[eo]=Vim
Name=Vim
# Translators: This is the Generic Application Name used in the Vim desktop file
GenericName[de]=Texteditor
GenericName[eo]=Tekstoredaktilo
GenericName[ja]=テキストエディタ
GenericName=Text Editor
# Translators: This is the comment used in the Vim desktop file
Comment[de]=Textdateien bearbeiten
Comment[eo]=Redakti tekstajn dosierojn
Comment[ja]=テキストファイルを編集します
Comment=Edit text files
# The translations should come from the po file. Leave them here for now, they will
@ -89,10 +92,12 @@ Terminal=true
Type=Application
# Translators: Search terms to find this application. Do NOT change the semicolons! The list MUST also end with a semicolon!
Keywords[de]=Text;Editor;
Keywords[eo]=Teksto;redaktilo;
Keywords[ja]=テキスト;エディタ;
Keywords=Text;editor;
# Translators: This is the Icon file name. Do NOT translate
Icon[de]=gvim
Icon[eo]=gvim
Icon=gvim
Categories=Utility;TextEditor;
StartupNotify=false

View File

@ -2181,7 +2181,6 @@ test_libvterm:
# These do not depend on the executable, compile it when needed.
test1 \
test_eval \
test3 \
test39 \
test42 test44 test48 test49 \
test52 test59 \

View File

@ -1349,7 +1349,7 @@ ex_doautoall(exarg_T *eap)
*/
FOR_ALL_BUFFERS(buf)
{
if (buf->b_ml.ml_mfp != NULL && !bt_popup(buf))
if (buf->b_ml.ml_mfp != NULL)
{
// find a window for this buffer and save some values
aucmd_prepbuf(&aco, buf);
@ -1612,8 +1612,6 @@ apply_autocmds(
int force, // when TRUE, ignore autocmd_busy
buf_T *buf) // buffer for <abuf>
{
if (bt_popup(buf))
return FALSE;
return apply_autocmds_group(event, fname, fname_io, force,
AUGROUP_ALL, buf, NULL);
}

View File

@ -862,7 +862,7 @@ free_buffer(buf_T *buf)
#endif
#ifdef FEAT_JOB_CHANNEL
vim_free(buf->b_prompt_text);
free_callback(buf->b_prompt_callback, buf->b_prompt_partial);
free_callback(&buf->b_prompt_callback);
#endif
buf_hashtab_remove(buf);
@ -5781,6 +5781,10 @@ buf_spname(buf_T *buf)
#ifdef FEAT_JOB_CHANNEL
if (bt_prompt(buf))
return (char_u *)_("[Prompt]");
#endif
#ifdef FEAT_TEXT_PROP
if (bt_popup(buf))
return (char_u *)_("[Popup]");
#endif
return (char_u *)_("[Scratch]");
}

View File

@ -270,36 +270,34 @@ may_record_change(
void
f_listener_add(typval_T *argvars, typval_T *rettv)
{
char_u *callback;
partial_T *partial;
callback_T callback;
listener_T *lnr;
buf_T *buf = curbuf;
callback = get_callback(&argvars[0], &partial);
if (callback == NULL)
callback = get_callback(&argvars[0]);
if (callback.cb_name == NULL)
return;
if (argvars[1].v_type != VAR_UNKNOWN)
{
buf = get_buf_arg(&argvars[1]);
if (buf == NULL)
{
free_callback(&callback);
return;
}
}
lnr = ALLOC_CLEAR_ONE(listener_T);
if (lnr == NULL)
{
free_callback(callback, partial);
free_callback(&callback);
return;
}
lnr->lr_next = buf->b_listener;
buf->b_listener = lnr;
if (partial == NULL)
lnr->lr_callback = vim_strsave(callback);
else
lnr->lr_callback = callback; // pointer into the partial
lnr->lr_partial = partial;
set_callback(&lnr->lr_callback, &callback);
lnr->lr_id = ++next_listener_id;
rettv->vval.v_number = lnr->lr_id;
@ -344,7 +342,7 @@ f_listener_remove(typval_T *argvars, typval_T *rettv UNUSED)
prev->lr_next = lnr->lr_next;
else
buf->b_listener = lnr->lr_next;
free_callback(lnr->lr_callback, lnr->lr_partial);
free_callback(&lnr->lr_callback);
vim_free(lnr);
}
prev = lnr;
@ -418,8 +416,8 @@ invoke_listeners(buf_T *buf)
for (lnr = buf->b_listener; lnr != NULL; lnr = lnr->lr_next)
{
call_func(lnr->lr_callback, -1, &rettv,
5, argv, NULL, 0L, 0L, &dummy, TRUE, lnr->lr_partial, NULL);
call_callback(&lnr->lr_callback, -1, &rettv,
5, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
}

View File

@ -348,7 +348,7 @@ channel_still_useful(channel_T *channel)
return FALSE;
/* If there is a close callback it may still need to be invoked. */
if (channel->ch_close_cb != NULL)
if (channel->ch_close_cb.cb_name != NULL)
return TRUE;
/* If reading from or a buffer it's still useful. */
@ -366,12 +366,12 @@ channel_still_useful(channel_T *channel)
has_err_msg = channel->ch_part[PART_ERR].ch_fd != INVALID_FD
|| channel->ch_part[PART_ERR].ch_head.rq_next != NULL
|| channel->ch_part[PART_ERR].ch_json_head.jq_next != NULL;
return (channel->ch_callback != NULL && (has_sock_msg
return (channel->ch_callback.cb_name != NULL && (has_sock_msg
|| has_out_msg || has_err_msg))
|| ((channel->ch_part[PART_OUT].ch_callback != NULL
|| ((channel->ch_part[PART_OUT].ch_callback.cb_name != NULL
|| channel->ch_part[PART_OUT].ch_bufref.br_buf != NULL)
&& has_out_msg)
|| ((channel->ch_part[PART_ERR].ch_callback != NULL
|| ((channel->ch_part[PART_ERR].ch_callback.cb_name != NULL
|| channel->ch_part[PART_ERR].ch_bufref.br_buf != NULL)
&& has_err_msg);
}
@ -1178,29 +1178,36 @@ find_buffer(char_u *name, int err, int msg)
return buf;
}
/*
* Copy callback from "src" to "dest", incrementing the refcounts.
*/
static void
set_callback(
char_u **cbp,
partial_T **pp,
char_u *callback,
partial_T *partial)
copy_callback(callback_T *dest, callback_T *src)
{
free_callback(*cbp, *pp);
if (callback != NULL && *callback != NUL)
dest->cb_partial = src->cb_partial;
if (dest->cb_partial != NULL)
{
if (partial != NULL)
*cbp = partial_name(partial);
else
{
*cbp = vim_strsave(callback);
func_ref(*cbp);
}
dest->cb_name = src->cb_name;
dest->cb_free_name = FALSE;
++dest->cb_partial->pt_refcount;
}
else
*cbp = NULL;
*pp = partial;
if (partial != NULL)
++partial->pt_refcount;
{
dest->cb_name = vim_strsave(src->cb_name);
dest->cb_free_name = TRUE;
func_ref(src->cb_name);
}
}
static void
free_set_callback(callback_T *cbp, callback_T *callback)
{
free_callback(cbp);
if (callback->cb_name != NULL && *callback->cb_name != NUL)
copy_callback(cbp, callback);
else
cbp->cb_name = NULL;
}
/*
@ -1233,19 +1240,15 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
channel->ch_part[PART_IN].ch_block_write = 1;
if (opt->jo_set & JO_CALLBACK)
set_callback(&channel->ch_callback, &channel->ch_partial,
opt->jo_callback, opt->jo_partial);
free_set_callback(&channel->ch_callback, &opt->jo_callback);
if (opt->jo_set & JO_OUT_CALLBACK)
set_callback(&channel->ch_part[PART_OUT].ch_callback,
&channel->ch_part[PART_OUT].ch_partial,
opt->jo_out_cb, opt->jo_out_partial);
free_set_callback(&channel->ch_part[PART_OUT].ch_callback,
&opt->jo_out_cb);
if (opt->jo_set & JO_ERR_CALLBACK)
set_callback(&channel->ch_part[PART_ERR].ch_callback,
&channel->ch_part[PART_ERR].ch_partial,
opt->jo_err_cb, opt->jo_err_partial);
free_set_callback(&channel->ch_part[PART_ERR].ch_callback,
&opt->jo_err_cb);
if (opt->jo_set & JO_CLOSE_CALLBACK)
set_callback(&channel->ch_close_cb, &channel->ch_close_partial,
opt->jo_close_cb, opt->jo_close_partial);
free_set_callback(&channel->ch_close_cb, &opt->jo_close_cb);
channel->ch_drop_never = opt->jo_drop_never;
if ((opt->jo_set & JO_OUT_IO) && opt->jo_io[PART_OUT] == JIO_BUFFER)
@ -1349,8 +1352,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt)
channel_set_req_callback(
channel_T *channel,
ch_part_T part,
char_u *callback,
partial_T *partial,
callback_T *callback,
int id)
{
cbq_T *head = &channel->ch_part[part].ch_cb_head;
@ -1358,17 +1360,7 @@ channel_set_req_callback(
if (item != NULL)
{
item->cq_partial = partial;
if (partial != NULL)
{
++partial->pt_refcount;
item->cq_callback = callback;
}
else
{
item->cq_callback = vim_strsave(callback);
func_ref(item->cq_callback);
}
copy_callback(&item->cq_callback, callback);
item->cq_seq_nr = id;
item->cq_prev = head->cq_prev;
head->cq_prev = item;
@ -1638,8 +1630,7 @@ channel_write_new_lines(buf_T *buf)
* This does not redraw but sets channel_need_redraw;
*/
static void
invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
typval_T *argv)
invoke_callback(channel_T *channel, callback_T *callback, typval_T *argv)
{
typval_T rettv;
int dummy;
@ -1650,8 +1641,8 @@ invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
argv[0].v_type = VAR_CHANNEL;
argv[0].vval.v_channel = channel;
call_func(callback, -1, &rettv, 2, argv, NULL,
0L, 0L, &dummy, TRUE, partial, NULL);
call_callback(callback, -1, &rettv, 2, argv, NULL,
0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
channel_need_redraw = TRUE;
}
@ -2414,12 +2405,12 @@ invoke_one_time_callback(
typval_T *argv)
{
ch_log(channel, "Invoking one-time callback %s",
(char *)item->cq_callback);
(char *)item->cq_callback.cb_name);
/* Remove the item from the list first, if the callback
* invokes ch_close() the list will be cleared. */
remove_cb_node(cbhead, item);
invoke_callback(channel, item->cq_callback, item->cq_partial, argv);
free_callback(item->cq_callback, item->cq_partial);
invoke_callback(channel, &item->cq_callback, argv);
free_callback(&item->cq_callback);
vim_free(item);
}
@ -2553,8 +2544,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
ch_mode_T ch_mode = ch_part->ch_mode;
cbq_T *cbhead = &ch_part->ch_cb_head;
cbq_T *cbitem;
char_u *callback = NULL;
partial_T *partial = NULL;
callback_T *callback = NULL;
buf_T *buffer = NULL;
char_u *p;
@ -2567,20 +2557,11 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
if (cbitem->cq_seq_nr == 0)
break;
if (cbitem != NULL)
{
callback = cbitem->cq_callback;
partial = cbitem->cq_partial;
}
else if (ch_part->ch_callback != NULL)
{
callback = ch_part->ch_callback;
partial = ch_part->ch_partial;
}
else
{
callback = channel->ch_callback;
partial = channel->ch_partial;
}
callback = &cbitem->cq_callback;
else if (ch_part->ch_callback.cb_name != NULL)
callback = &ch_part->ch_callback;
else if (channel->ch_callback.cb_name != NULL)
callback = &channel->ch_callback;
buffer = ch_part->ch_bufref.br_buf;
if (buffer != NULL && (!bufref_valid(&ch_part->ch_bufref)
@ -2642,7 +2623,7 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
{
/* If there is a close callback it may use ch_read() to get the
* messages. */
if (channel->ch_close_cb == NULL && !channel->ch_drop_never)
if (channel->ch_close_cb.cb_name == NULL && !channel->ch_drop_never)
drop_messages(channel, part);
return FALSE;
}
@ -2761,8 +2742,8 @@ may_invoke_callback(channel_T *channel, ch_part_T part)
{
/* invoke the channel callback */
ch_log(channel, "Invoking channel callback %s",
(char *)callback);
invoke_callback(channel, callback, partial, argv);
(char *)callback->cb_name);
invoke_callback(channel, callback, argv);
}
}
}
@ -2956,18 +2937,18 @@ channel_close(channel_T *channel, int invoke_close_cb)
ch_part_T part;
/* Invoke callbacks and flush buffers before the close callback. */
if (channel->ch_close_cb != NULL)
if (channel->ch_close_cb.cb_name != NULL)
ch_log(channel,
"Invoking callbacks and flushing buffers before closing");
for (part = PART_SOCK; part < PART_IN; ++part)
{
if (channel->ch_close_cb != NULL
if (channel->ch_close_cb.cb_name != NULL
|| channel->ch_part[part].ch_bufref.br_buf != NULL)
{
/* Increment the refcount to avoid the channel being freed
* halfway. */
++channel->ch_refcount;
if (channel->ch_close_cb == NULL)
if (channel->ch_close_cb.cb_name == NULL)
ch_log(channel, "flushing %s buffers before closing",
part_names[part]);
while (may_invoke_callback(channel, part))
@ -2976,7 +2957,7 @@ channel_close(channel_T *channel, int invoke_close_cb)
}
}
if (channel->ch_close_cb != NULL)
if (channel->ch_close_cb.cb_name != NULL)
{
typval_T argv[1];
typval_T rettv;
@ -2986,19 +2967,16 @@ channel_close(channel_T *channel, int invoke_close_cb)
* halfway. */
++channel->ch_refcount;
ch_log(channel, "Invoking close callback %s",
(char *)channel->ch_close_cb);
(char *)channel->ch_close_cb.cb_name);
argv[0].v_type = VAR_CHANNEL;
argv[0].vval.v_channel = channel;
call_func(channel->ch_close_cb, -1,
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
channel->ch_close_partial, NULL);
call_callback(&channel->ch_close_cb, -1,
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
channel_need_redraw = TRUE;
/* the callback is only called once */
free_callback(channel->ch_close_cb, channel->ch_close_partial);
channel->ch_close_cb = NULL;
channel->ch_close_partial = NULL;
free_callback(&channel->ch_close_cb);
if (channel_need_redraw)
{
@ -3061,7 +3039,7 @@ channel_clear_one(channel_T *channel, ch_part_T part)
cbq_T *node = cb_head->cq_next;
remove_cb_node(cb_head, node);
free_callback(node->cq_callback, node->cq_partial);
free_callback(&node->cq_callback);
vim_free(node);
}
@ -3071,9 +3049,7 @@ channel_clear_one(channel_T *channel, ch_part_T part)
remove_json_node(json_head, json_head->jq_next);
}
free_callback(ch_part->ch_callback, ch_part->ch_partial);
ch_part->ch_callback = NULL;
ch_part->ch_partial = NULL;
free_callback(&ch_part->ch_callback);
while (ch_part->ch_writeque.wq_next != NULL)
remove_from_writeque(&ch_part->ch_writeque,
@ -3092,12 +3068,8 @@ channel_clear(channel_T *channel)
channel_clear_one(channel, PART_OUT);
channel_clear_one(channel, PART_ERR);
channel_clear_one(channel, PART_IN);
free_callback(channel->ch_callback, channel->ch_partial);
channel->ch_callback = NULL;
channel->ch_partial = NULL;
free_callback(channel->ch_close_cb, channel->ch_close_partial);
channel->ch_close_cb = NULL;
channel->ch_close_partial = NULL;
free_callback(&channel->ch_callback);
free_callback(&channel->ch_close_cb);
}
#if defined(EXITFREE) || defined(PROTO)
@ -3991,19 +3963,18 @@ send_common(
/* Set the callback. An empty callback means no callback and not reading
* the response. With "ch_evalexpr()" and "ch_evalraw()" a callback is not
* allowed. */
if (opt->jo_callback != NULL && *opt->jo_callback != NUL)
if (opt->jo_callback.cb_name != NULL && *opt->jo_callback.cb_name != NUL)
{
if (eval)
{
semsg(_("E917: Cannot use a callback with %s()"), fun);
return NULL;
}
channel_set_req_callback(channel, *part_read,
opt->jo_callback, opt->jo_partial, id);
channel_set_req_callback(channel, *part_read, &opt->jo_callback, id);
}
if (channel_send(channel, part_send, text, len, fun) == OK
&& opt->jo_callback == NULL)
&& opt->jo_callback.cb_name == NULL)
return channel;
return NULL;
}
@ -4559,26 +4530,26 @@ clear_job_options(jobopt_T *opt)
void
free_job_options(jobopt_T *opt)
{
if (opt->jo_partial != NULL)
partial_unref(opt->jo_partial);
else if (opt->jo_callback != NULL)
func_unref(opt->jo_callback);
if (opt->jo_out_partial != NULL)
partial_unref(opt->jo_out_partial);
else if (opt->jo_out_cb != NULL)
func_unref(opt->jo_out_cb);
if (opt->jo_err_partial != NULL)
partial_unref(opt->jo_err_partial);
else if (opt->jo_err_cb != NULL)
func_unref(opt->jo_err_cb);
if (opt->jo_close_partial != NULL)
partial_unref(opt->jo_close_partial);
else if (opt->jo_close_cb != NULL)
func_unref(opt->jo_close_cb);
if (opt->jo_exit_partial != NULL)
partial_unref(opt->jo_exit_partial);
else if (opt->jo_exit_cb != NULL)
func_unref(opt->jo_exit_cb);
if (opt->jo_callback.cb_partial != NULL)
partial_unref(opt->jo_callback.cb_partial);
else if (opt->jo_callback.cb_name != NULL)
func_unref(opt->jo_callback.cb_name);
if (opt->jo_out_cb.cb_partial != NULL)
partial_unref(opt->jo_out_cb.cb_partial);
else if (opt->jo_out_cb.cb_name != NULL)
func_unref(opt->jo_out_cb.cb_name);
if (opt->jo_err_cb.cb_partial != NULL)
partial_unref(opt->jo_err_cb.cb_partial);
else if (opt->jo_err_cb.cb_name != NULL)
func_unref(opt->jo_err_cb.cb_name);
if (opt->jo_close_cb.cb_partial != NULL)
partial_unref(opt->jo_close_cb.cb_partial);
else if (opt->jo_close_cb.cb_name != NULL)
func_unref(opt->jo_close_cb.cb_name);
if (opt->jo_exit_cb.cb_partial != NULL)
partial_unref(opt->jo_exit_cb.cb_partial);
else if (opt->jo_exit_cb.cb_name != NULL)
func_unref(opt->jo_exit_cb.cb_name);
if (opt->jo_env != NULL)
dict_unref(opt->jo_env);
}
@ -4771,8 +4742,8 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
if (!(supported & JO_CALLBACK))
break;
opt->jo_set |= JO_CALLBACK;
opt->jo_callback = get_callback(item, &opt->jo_partial);
if (opt->jo_callback == NULL)
opt->jo_callback = get_callback(item);
if (opt->jo_callback.cb_name == NULL)
{
semsg(_(e_invargval), "callback");
return FAIL;
@ -4783,8 +4754,8 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
if (!(supported & JO_OUT_CALLBACK))
break;
opt->jo_set |= JO_OUT_CALLBACK;
opt->jo_out_cb = get_callback(item, &opt->jo_out_partial);
if (opt->jo_out_cb == NULL)
opt->jo_out_cb = get_callback(item);
if (opt->jo_out_cb.cb_name == NULL)
{
semsg(_(e_invargval), "out_cb");
return FAIL;
@ -4795,8 +4766,8 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
if (!(supported & JO_ERR_CALLBACK))
break;
opt->jo_set |= JO_ERR_CALLBACK;
opt->jo_err_cb = get_callback(item, &opt->jo_err_partial);
if (opt->jo_err_cb == NULL)
opt->jo_err_cb = get_callback(item);
if (opt->jo_err_cb.cb_name == NULL)
{
semsg(_(e_invargval), "err_cb");
return FAIL;
@ -4807,8 +4778,8 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
if (!(supported & JO_CLOSE_CALLBACK))
break;
opt->jo_set |= JO_CLOSE_CALLBACK;
opt->jo_close_cb = get_callback(item, &opt->jo_close_partial);
if (opt->jo_close_cb == NULL)
opt->jo_close_cb = get_callback(item);
if (opt->jo_close_cb.cb_name == NULL)
{
semsg(_(e_invargval), "close_cb");
return FAIL;
@ -4833,8 +4804,8 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2)
if (!(supported & JO_EXIT_CB))
break;
opt->jo_set |= JO_EXIT_CB;
opt->jo_exit_cb = get_callback(item, &opt->jo_exit_partial);
if (opt->jo_exit_cb == NULL)
opt->jo_exit_cb = get_callback(item);
if (opt->jo_exit_cb.cb_name == NULL)
{
semsg(_(e_invargval), "exit_cb");
return FAIL;
@ -5201,7 +5172,7 @@ job_free_contents(job_T *job)
#ifdef MSWIN
vim_free(job->jv_tty_type);
#endif
free_callback(job->jv_exit_cb, job->jv_exit_partial);
free_callback(&job->jv_exit_cb);
if (job->jv_argv != NULL)
{
for (i = 0; job->jv_argv[i] != NULL; i++)
@ -5289,7 +5260,7 @@ job_free_all(void)
job_need_end_check(job_T *job)
{
return job->jv_status == JOB_STARTED
&& (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
&& (job->jv_stoponexit != NULL || job->jv_exit_cb.cb_name != NULL);
}
/*
@ -5465,22 +5436,22 @@ job_cleanup(job_T *job)
if (job->jv_channel != NULL)
ch_close_part(job->jv_channel, PART_IN);
if (job->jv_exit_cb != NULL)
if (job->jv_exit_cb.cb_name != NULL)
{
typval_T argv[3];
typval_T rettv;
int dummy;
/* Invoke the exit callback. Make sure the refcount is > 0. */
ch_log(job->jv_channel, "Invoking exit callback %s", job->jv_exit_cb);
ch_log(job->jv_channel, "Invoking exit callback %s",
job->jv_exit_cb.cb_name);
++job->jv_refcount;
argv[0].v_type = VAR_JOB;
argv[0].vval.v_job = job;
argv[1].v_type = VAR_NUMBER;
argv[1].vval.v_number = job->jv_exitval;
call_func(job->jv_exit_cb, -1,
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE,
job->jv_exit_partial, NULL);
call_callback(&job->jv_exit_cb, -1,
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
--job->jv_refcount;
channel_need_redraw = TRUE;
@ -5622,26 +5593,14 @@ job_set_options(job_T *job, jobopt_T *opt)
}
if (opt->jo_set & JO_EXIT_CB)
{
free_callback(job->jv_exit_cb, job->jv_exit_partial);
if (opt->jo_exit_cb == NULL || *opt->jo_exit_cb == NUL)
free_callback(&job->jv_exit_cb);
if (opt->jo_exit_cb.cb_name == NULL || *opt->jo_exit_cb.cb_name == NUL)
{
job->jv_exit_cb = NULL;
job->jv_exit_partial = NULL;
job->jv_exit_cb.cb_name = NULL;
job->jv_exit_cb.cb_partial = NULL;
}
else
{
job->jv_exit_partial = opt->jo_exit_partial;
if (job->jv_exit_partial != NULL)
{
job->jv_exit_cb = opt->jo_exit_cb;
++job->jv_exit_partial->pt_refcount;
}
else
{
job->jv_exit_cb = vim_strsave(opt->jo_exit_cb);
func_ref(job->jv_exit_cb);
}
}
copy_callback(&job->jv_exit_cb, &opt->jo_exit_cb);
}
}
@ -5959,7 +5918,7 @@ job_info(job_T *job, dict_T *dict)
dict_add_string(dict, "tty_out", job->jv_tty_out);
dict_add_number(dict, "exitval", job->jv_exitval);
dict_add_string(dict, "exit_cb", job->jv_exit_cb);
dict_add_string(dict, "exit_cb", job->jv_exit_cb.cb_name);
dict_add_string(dict, "stoponexit", job->jv_stoponexit);
#ifdef UNIX
dict_add_string(dict, "termsig", job->jv_termsig);
@ -6059,7 +6018,8 @@ invoke_prompt_callback(void)
curwin->w_cursor.lnum = lnum + 1;
curwin->w_cursor.col = 0;
if (curbuf->b_prompt_callback == NULL || *curbuf->b_prompt_callback == NUL)
if (curbuf->b_prompt_callback.cb_name == NULL
|| *curbuf->b_prompt_callback.cb_name == NUL)
return;
text = ml_get(lnum);
prompt = prompt_text();
@ -6069,9 +6029,8 @@ invoke_prompt_callback(void)
argv[0].vval.v_string = vim_strsave(text);
argv[1].v_type = VAR_UNKNOWN;
call_func(curbuf->b_prompt_callback, -1,
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
curbuf->b_prompt_partial, NULL);
call_callback(&curbuf->b_prompt_callback, -1,
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&argv[0]);
clear_tv(&rettv);
}
@ -6086,15 +6045,14 @@ invoke_prompt_interrupt(void)
int dummy;
typval_T argv[1];
if (curbuf->b_prompt_interrupt == NULL
|| *curbuf->b_prompt_interrupt == NUL)
if (curbuf->b_prompt_interrupt.cb_name == NULL
|| *curbuf->b_prompt_interrupt.cb_name == NUL)
return FALSE;
argv[0].v_type = VAR_UNKNOWN;
got_int = FALSE; // don't skip executing commands
call_func(curbuf->b_prompt_interrupt, -1,
&rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE,
curbuf->b_prompt_int_partial, NULL);
call_callback(&curbuf->b_prompt_interrupt, -1,
&rettv, 0, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
return TRUE;
}

View File

@ -5920,10 +5920,10 @@ set_ref_in_item(
dtv.vval.v_channel = job->jv_channel;
set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
}
if (job->jv_exit_partial != NULL)
if (job->jv_exit_cb.cb_partial != NULL)
{
dtv.v_type = VAR_PARTIAL;
dtv.vval.v_partial = job->jv_exit_partial;
dtv.vval.v_partial = job->jv_exit_cb.cb_partial;
set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
}
}
@ -5946,29 +5946,30 @@ set_ref_in_item(
set_ref_in_item(jq->jq_value, copyID, ht_stack, list_stack);
for (cq = ch->ch_part[part].ch_cb_head.cq_next; cq != NULL;
cq = cq->cq_next)
if (cq->cq_partial != NULL)
if (cq->cq_callback.cb_partial != NULL)
{
dtv.v_type = VAR_PARTIAL;
dtv.vval.v_partial = cq->cq_partial;
dtv.vval.v_partial = cq->cq_callback.cb_partial;
set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
}
if (ch->ch_part[part].ch_partial != NULL)
if (ch->ch_part[part].ch_callback.cb_partial != NULL)
{
dtv.v_type = VAR_PARTIAL;
dtv.vval.v_partial = ch->ch_part[part].ch_partial;
dtv.vval.v_partial =
ch->ch_part[part].ch_callback.cb_partial;
set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
}
}
if (ch->ch_partial != NULL)
if (ch->ch_callback.cb_partial != NULL)
{
dtv.v_type = VAR_PARTIAL;
dtv.vval.v_partial = ch->ch_partial;
dtv.vval.v_partial = ch->ch_callback.cb_partial;
set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
}
if (ch->ch_close_partial != NULL)
if (ch->ch_close_cb.cb_partial != NULL)
{
dtv.v_type = VAR_PARTIAL;
dtv.vval.v_partial = ch->ch_close_partial;
dtv.vval.v_partial = ch->ch_close_cb.cb_partial;
set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
}
}

View File

@ -809,10 +809,11 @@ static struct fst
{"perleval", 1, 1, f_perleval},
#endif
#ifdef FEAT_TEXT_PROP
{"popup_atcursor", 2, 2, f_popup_atcursor},
{"popup_close", 1, 1, f_popup_close},
{"popup_create", 2, 2, f_popup_create},
{"popup_getoptions", 1, 1, f_popup_getoptions},
{"popup_getposition", 1, 1, f_popup_getposition},
{"popup_getpos", 1, 1, f_popup_getpos},
{"popup_hide", 1, 1, f_popup_hide},
{"popup_move", 2, 2, f_popup_move},
{"popup_show", 1, 1, f_popup_show},
@ -6116,19 +6117,18 @@ f_win_execute(typval_T *argvars, typval_T *rettv)
{
int id = (int)tv_get_number(argvars);
win_T *wp = win_id2wp(id);
win_T *save_curwin = curwin;
win_T *save_curwin;
tabpage_T *save_curtab;
if (wp != NULL)
{
curwin = wp;
curbuf = curwin->w_buffer;
check_cursor();
execute_common(argvars, rettv, 1);
if (win_valid(save_curwin))
if (switch_win_noblock(&save_curwin, &save_curtab, wp, curtab, TRUE)
== OK)
{
curwin = save_curwin;
curbuf = curwin->w_buffer;
check_cursor();
execute_common(argvars, rettv, 1);
}
restore_win_noblock(save_curwin, save_curtab, TRUE);
}
}
@ -9200,8 +9200,7 @@ f_printf(typval_T *argvars, typval_T *rettv)
f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
{
buf_T *buf;
char_u *callback;
partial_T *partial;
callback_T callback;
if (check_secure())
return;
@ -9209,17 +9208,12 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
if (buf == NULL)
return;
callback = get_callback(&argvars[1], &partial);
if (callback == NULL)
callback = get_callback(&argvars[1]);
if (callback.cb_name == NULL)
return;
free_callback(buf->b_prompt_callback, buf->b_prompt_partial);
if (partial == NULL)
buf->b_prompt_callback = vim_strsave(callback);
else
/* pointer into the partial */
buf->b_prompt_callback = callback;
buf->b_prompt_partial = partial;
free_callback(&buf->b_prompt_callback);
set_callback(&buf->b_prompt_callback, &callback);
}
/*
@ -9229,8 +9223,7 @@ f_prompt_setcallback(typval_T *argvars, typval_T *rettv UNUSED)
f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
{
buf_T *buf;
char_u *callback;
partial_T *partial;
callback_T callback;
if (check_secure())
return;
@ -9238,17 +9231,12 @@ f_prompt_setinterrupt(typval_T *argvars, typval_T *rettv UNUSED)
if (buf == NULL)
return;
callback = get_callback(&argvars[1], &partial);
if (callback == NULL)
callback = get_callback(&argvars[1]);
if (callback.cb_name == 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;
free_callback(&buf->b_prompt_interrupt);
set_callback(&buf->b_prompt_interrupt, &callback);
}
/*
@ -14631,42 +14619,104 @@ f_test_settime(typval_T *argvars, typval_T *rettv UNUSED)
/*
* Get a callback from "arg". It can be a Funcref or a function name.
* When "arg" is zero return an empty string.
* Return NULL for an invalid argument.
* "cb_name" is not allocated.
* "cb_name" is set to NULL for an invalid argument.
*/
char_u *
get_callback(typval_T *arg, partial_T **pp)
callback_T
get_callback(typval_T *arg)
{
callback_T res;
res.cb_free_name = FALSE;
if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
{
*pp = arg->vval.v_partial;
++(*pp)->pt_refcount;
return partial_name(*pp);
res.cb_partial = arg->vval.v_partial;
++res.cb_partial->pt_refcount;
res.cb_name = partial_name(res.cb_partial);
}
*pp = NULL;
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
else
{
func_ref(arg->vval.v_string);
return arg->vval.v_string;
res.cb_partial = NULL;
if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
{
// Note that we don't make a copy of the string.
res.cb_name = arg->vval.v_string;
func_ref(res.cb_name);
}
else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
{
res.cb_name = (char_u *)"";
}
else
{
emsg(_("E921: Invalid callback argument"));
res.cb_name = NULL;
}
}
if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
return (char_u *)"";
emsg(_("E921: Invalid callback argument"));
return NULL;
return res;
}
/*
* Unref/free "callback" and "partial" returned by get_callback().
* Copy a callback into a typval_T.
*/
void
free_callback(char_u *callback, partial_T *partial)
put_callback(callback_T *cb, typval_T *tv)
{
if (partial != NULL)
partial_unref(partial);
else if (callback != NULL)
if (cb->cb_partial != NULL)
{
func_unref(callback);
vim_free(callback);
tv->v_type = VAR_PARTIAL;
tv->vval.v_partial = cb->cb_partial;
++tv->vval.v_partial->pt_refcount;
}
else
{
tv->v_type = VAR_FUNC;
tv->vval.v_string = vim_strsave(cb->cb_name);
func_ref(cb->cb_name);
}
}
/*
* Make a copy of "src" into "dest", allocating the function name if needed,
* without incrementing the refcount.
*/
void
set_callback(callback_T *dest, callback_T *src)
{
if (src->cb_partial == NULL)
{
// just a function name, make a copy
dest->cb_name = vim_strsave(src->cb_name);
dest->cb_free_name = TRUE;
}
else
{
// cb_name is a pointer into cb_partial
dest->cb_name = src->cb_name;
dest->cb_free_name = FALSE;
}
dest->cb_partial = src->cb_partial;
}
/*
* Unref/free "callback" returned by get_callback() or set_callback().
*/
void
free_callback(callback_T *callback)
{
if (callback->cb_partial != NULL)
{
partial_unref(callback->cb_partial);
callback->cb_partial = NULL;
}
else if (callback->cb_name != NULL)
func_unref(callback->cb_name);
if (callback->cb_free_name)
{
vim_free(callback->cb_name);
callback->cb_free_name = FALSE;
}
callback->cb_name = NULL;
}
#ifdef FEAT_TIMERS
@ -14723,9 +14773,8 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
long msec = (long)tv_get_number(&argvars[0]);
timer_T *timer;
int repeat = 0;
char_u *callback;
callback_T callback;
dict_T *dict;
partial_T *partial;
rettv->vval.v_number = -1;
if (check_secure())
@ -14742,21 +14791,16 @@ f_timer_start(typval_T *argvars, typval_T *rettv)
repeat = dict_get_number(dict, (char_u *)"repeat");
}
callback = get_callback(&argvars[1], &partial);
if (callback == NULL)
callback = get_callback(&argvars[1]);
if (callback.cb_name == NULL)
return;
timer = create_timer(msec, repeat);
if (timer == NULL)
free_callback(callback, partial);
free_callback(&callback);
else
{
if (partial == NULL)
timer->tr_callback = vim_strsave(callback);
else
/* pointer into the partial */
timer->tr_callback = callback;
timer->tr_partial = partial;
set_callback(&timer->tr_callback, &callback);
rettv->vval.v_number = (varnumber_T)timer->tr_id;
}
}

View File

@ -282,7 +282,7 @@ remove_timer(timer_T *timer)
static void
free_timer(timer_T *timer)
{
free_callback(timer->tr_callback, timer->tr_partial);
free_callback(&timer->tr_callback);
vim_free(timer);
}
@ -325,9 +325,8 @@ timer_callback(timer_T *timer)
argv[0].vval.v_number = (varnumber_T)timer->tr_id;
argv[1].v_type = VAR_UNKNOWN;
call_func(timer->tr_callback, -1,
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE,
timer->tr_partial, NULL);
call_callback(&timer->tr_callback, -1,
&rettv, 1, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
clear_tv(&rettv);
}
@ -542,17 +541,8 @@ add_timer_info(typval_T *rettv, timer_T *timer)
{
if (dict_add(dict, di) == FAIL)
vim_free(di);
else if (timer->tr_partial != NULL)
{
di->di_tv.v_type = VAR_PARTIAL;
di->di_tv.vval.v_partial = timer->tr_partial;
++timer->tr_partial->pt_refcount;
}
else
{
di->di_tv.v_type = VAR_FUNC;
di->di_tv.vval.v_string = vim_strsave(timer->tr_callback);
}
put_callback(&timer->tr_callback, &di->di_tv);
}
}
@ -578,15 +568,15 @@ set_ref_in_timer(int copyID)
for (timer = first_timer; timer != NULL; timer = timer->tr_next)
{
if (timer->tr_partial != NULL)
if (timer->tr_callback.cb_partial != NULL)
{
tv.v_type = VAR_PARTIAL;
tv.vval.v_partial = timer->tr_partial;
tv.vval.v_partial = timer->tr_callback.cb_partial;
}
else
{
tv.v_type = VAR_FUNC;
tv.vval.v_string = timer->tr_callback;
tv.vval.v_string = timer->tr_callback.cb_name;
}
abort = abort || set_ref_in_item(&tv, copyID, NULL, NULL);
}
@ -1874,6 +1864,8 @@ do_argfile(exarg_T *eap, int argn)
char_u *p;
int old_arg_idx = curwin->w_arg_idx;
if (NOT_IN_POPUP_WINDOW)
return;
if (argn < 0 || argn >= ARGCOUNT)
{
if (ARGCOUNT <= 1)

View File

@ -5452,6 +5452,8 @@ ex_doautocmd(exarg_T *eap)
static void
ex_bunload(exarg_T *eap)
{
if (NOT_IN_POPUP_WINDOW)
return;
eap->errmsg = do_bufdel(
eap->cmdidx == CMD_bdelete ? DOBUF_DEL
: eap->cmdidx == CMD_bwipeout ? DOBUF_WIPE
@ -5466,6 +5468,8 @@ ex_bunload(exarg_T *eap)
static void
ex_buffer(exarg_T *eap)
{
if (NOT_IN_POPUP_WINDOW)
return;
if (*eap->arg)
eap->errmsg = e_trailing;
else
@ -6768,6 +6772,9 @@ ex_splitview(exarg_T *eap)
|| eap->cmdidx == CMD_tabfind
|| eap->cmdidx == CMD_tabnew;
if (NOT_IN_POPUP_WINDOW)
return;
#ifdef FEAT_GUI
need_mouse_correct = TRUE;
#endif
@ -6895,6 +6902,8 @@ ex_tabnext(exarg_T *eap)
{
int tab_number;
if (NOT_IN_POPUP_WINDOW)
return;
switch (eap->cmdidx)
{
case CMD_tabfirst:
@ -7146,6 +7155,8 @@ do_exedit(
int need_hide;
int exmode_was = exmode_active;
if (NOT_IN_POPUP_WINDOW)
return;
/*
* ":vi" command ends Ex mode.
*/

View File

@ -1801,6 +1801,10 @@ vgetc(void)
ui_remove_balloon();
}
#endif
#ifdef FEAT_TEXT_PROP
if (popup_do_filter(c))
c = K_IGNORE;
#endif
return c;
}

View File

@ -339,3 +339,9 @@
/* Wether a command index indicates a user command. */
#define IS_USER_CMDIDX(idx) ((int)(idx) < 0)
#ifdef FEAT_TEXT_PROP
# define NOT_IN_POPUP_WINDOW not_in_popup_window()
#else
# define NOT_IN_POPUP_WINDOW 0
#endif

View File

@ -2057,6 +2057,13 @@ ga_grow(garray_T *gap, int n)
{
if (n < gap->ga_growsize)
n = gap->ga_growsize;
// A linear growth is very inefficient when the array grows big. This
// is a compromise between allocating memory that won't be used and too
// many copy operations. A factor of 1.5 seems reasonable.
if (n < gap->ga_len / 2)
n = gap->ga_len / 2;
new_len = gap->ga_itemsize * (gap->ga_len + n);
pp = vim_realloc(gap->ga_data, new_len);
if (pp == NULL)
@ -2724,17 +2731,31 @@ get_special_key_name(int c, int modifiers)
trans_special(
char_u **srcp,
char_u *dst,
int keycode, /* prefer key code, e.g. K_DEL instead of DEL */
int in_string) /* TRUE when inside a double quoted string */
int keycode, // prefer key code, e.g. K_DEL instead of DEL
int in_string) // TRUE when inside a double quoted string
{
int modifiers = 0;
int key;
int dlen = 0;
key = find_special_key(srcp, &modifiers, keycode, FALSE, in_string);
if (key == 0)
return 0;
return special_to_buf(key, modifiers, keycode, dst);
}
/*
* Put the character sequence for "key" with "modifiers" into "dst" and return
* the resulting length.
* When "keycode" is TRUE prefer key code, e.g. K_DEL instead of DEL.
* The sequence is not NUL terminated.
* This is how characters in a string are encoded.
*/
int
special_to_buf(int key, int modifiers, int keycode, char_u *dst)
{
int dlen = 0;
/* Put the appropriate modifier in a string */
if (modifiers != 0)
{

File diff suppressed because it is too large Load Diff

View File

@ -15,23 +15,155 @@
#ifdef FEAT_TEXT_PROP
typedef struct {
char *pp_name;
poppos_T pp_val;
} poppos_entry_T;
static poppos_entry_T poppos_entries[] = {
{"botleft", POPPOS_BOTLEFT},
{"topleft", POPPOS_TOPLEFT},
{"botright", POPPOS_BOTRIGHT},
{"topright", POPPOS_TOPRIGHT},
{"center", POPPOS_CENTER}
};
/*
* Get option value for"key", which is "line" or "col".
* Handles "cursor+N" and "cursor-N".
*/
static int
popup_options_one(dict_T *dict, char_u *key)
{
dictitem_T *di;
char_u *val;
char_u *s;
char_u *endp;
int n = 0;
di = dict_find(dict, key, -1);
if (di == NULL)
return 0;
val = tv_get_string(&di->di_tv);
if (STRNCMP(val, "cursor", 6) != 0)
return dict_get_number(dict, key);
setcursor_mayforce(TRUE);
s = val + 6;
if (*s != NUL)
{
n = strtol((char *)s, (char **)&endp, 10);
if (endp != NULL && *skipwhite(endp) != NUL)
{
semsg(_(e_invexpr2), val);
return 0;
}
}
if (STRCMP(key, "line") == 0)
n = screen_screenrow() + 1 + n;
else // "col"
n = screen_screencol() + 1 + n;
if (n < 1)
n = 1;
return n;
}
static void
get_pos_options(win_T *wp, dict_T *dict)
{
char_u *str;
int nr;
nr = popup_options_one(dict, (char_u *)"line");
if (nr > 0)
wp->w_wantline = nr;
nr = popup_options_one(dict, (char_u *)"col");
if (nr > 0)
wp->w_wantcol = nr;
str = dict_get_string(dict, (char_u *)"pos", FALSE);
if (str != NULL)
{
for (nr = 0;
nr < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
++nr)
if (STRCMP(str, poppos_entries[nr].pp_name) == 0)
{
wp->w_popup_pos = poppos_entries[nr].pp_val;
nr = -1;
break;
}
if (nr != -1)
semsg(_(e_invarg2), str);
}
}
static void
get_padding_border(dict_T *dict, int *array, char *name, int max_val)
{
dictitem_T *di;
vim_memset(array, 0, sizeof(int) * 4);
di = dict_find(dict, (char_u *)name, -1);
if (di != NULL)
{
if (di->di_tv.v_type != VAR_LIST)
emsg(_(e_listreq));
else
{
list_T *list = di->di_tv.vval.v_list;
listitem_T *li;
int i;
int nr;
for (i = 0; i < 4; ++i)
array[i] = 1;
if (list != NULL)
for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
++i, li = li->li_next)
{
nr = (int)tv_get_number(&li->li_tv);
if (nr >= 0)
array[i] = nr > max_val ? max_val : nr;
}
}
}
}
/*
* Go through the options in "dict" and apply them to buffer "buf" displayed in
* popup window "wp".
* When called from f_popup_atcursor() "atcursor" is TRUE.
*/
static void
apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor)
{
int nr;
char_u *str;
int nr;
char_u *str;
dictitem_T *di;
wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth");
wp->w_minheight = dict_get_number(dict, (char_u *)"minheight");
wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth");
wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight");
wp->w_wantline = dict_get_number(dict, (char_u *)"line");
wp->w_wantcol = dict_get_number(dict, (char_u *)"col");
if (atcursor)
{
wp->w_popup_pos = POPPOS_BOTLEFT;
setcursor_mayforce(TRUE);
wp->w_wantline = screen_screenrow();
if (wp->w_wantline == 0) // cursor in first line
{
wp->w_wantline = 2;
wp->w_popup_pos = POPPOS_TOPLEFT;
}
wp->w_wantcol = screen_screencol() + 1;
}
get_pos_options(wp, dict);
wp->w_zindex = dict_get_number(dict, (char_u *)"zindex");
@ -49,18 +181,36 @@ apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict)
if (get_lambda_tv(&ptr, &tv, TRUE) == OK)
{
wp->w_popup_timer = create_timer(nr, 0);
wp->w_popup_timer->tr_callback =
vim_strsave(partial_name(tv.vval.v_partial));
func_ref(wp->w_popup_timer->tr_callback);
wp->w_popup_timer->tr_partial = tv.vval.v_partial;
wp->w_popup_timer->tr_callback = get_callback(&tv);
clear_tv(&tv);
}
}
#endif
str = dict_get_string(dict, (char_u *)"highlight", TRUE);
// Option values resulting in setting an option.
str = dict_get_string(dict, (char_u *)"highlight", FALSE);
if (str != NULL)
set_string_option_direct_in_win(wp, (char_u *)"wincolor", -1,
str, OPT_FREE|OPT_LOCAL, 0);
di = dict_find(dict, (char_u *)"wrap", -1);
if (di != NULL)
{
nr = dict_get_number(dict, (char_u *)"wrap");
wp->w_p_wrap = nr != 0;
}
di = dict_find(dict, (char_u *)"filter", -1);
if (di != NULL)
{
callback_T callback = get_callback(&di->di_tv);
if (callback.cb_name != NULL)
set_callback(&wp->w_filter_cb, &callback);
}
get_padding_border(dict, wp->w_popup_padding, "padding", 999);
get_padding_border(dict, wp->w_popup_border, "border", 1);
}
/*
@ -157,24 +307,42 @@ popup_adjust_position(win_T *wp)
linenr_T lnum;
int wrapped = 0;
int maxwidth;
int center_vert = FALSE;
int center_hor = FALSE;
// TODO: Compute the size and position properly.
if (wp->w_wantline > 0)
wp->w_winrow = wp->w_wantline - 1;
wp->w_winrow = 0;
wp->w_wincol = 0;
if (wp->w_popup_pos == POPPOS_CENTER)
{
// center after computing the size
center_vert = TRUE;
center_hor = TRUE;
}
else
// TODO: better default
wp->w_winrow = Rows > 5 ? Rows / 2 - 2 : 0;
if (wp->w_winrow >= Rows)
wp->w_winrow = Rows - 1;
{
if (wp->w_wantline == 0)
center_vert = TRUE;
else if (wp->w_popup_pos == POPPOS_TOPLEFT
|| wp->w_popup_pos == POPPOS_TOPRIGHT)
{
wp->w_winrow = wp->w_wantline - 1;
if (wp->w_winrow >= Rows)
wp->w_winrow = Rows - 1;
}
if (wp->w_wantcol > 0)
wp->w_wincol = wp->w_wantcol - 1;
else
// TODO: better default
wp->w_wincol = Columns > 20 ? Columns / 2 - 10 : 0;
if (wp->w_wincol >= Columns - 3)
wp->w_wincol = Columns - 3;
if (wp->w_wantcol == 0)
center_hor = TRUE;
else if (wp->w_popup_pos == POPPOS_TOPLEFT
|| wp->w_popup_pos == POPPOS_BOTLEFT)
{
wp->w_wincol = wp->w_wantcol - 1;
if (wp->w_wincol >= Columns - 3)
wp->w_wincol = Columns - 3;
}
}
// When centering or right aligned, use maximum width.
// When left aligned use the space available.
maxwidth = Columns - wp->w_wincol;
if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth)
maxwidth = wp->w_maxwidth;
@ -200,6 +368,16 @@ popup_adjust_position(win_T *wp)
wp->w_width = wp->w_minwidth;
if (wp->w_width > maxwidth)
wp->w_width = maxwidth;
if (center_hor)
wp->w_wincol = (Columns - wp->w_width) / 2;
else if (wp->w_popup_pos == POPPOS_BOTRIGHT
|| wp->w_popup_pos == POPPOS_TOPRIGHT)
{
// Right aligned: move to the right if needed.
// No truncation, because that would change the height.
if (wp->w_width < wp->w_wantcol)
wp->w_wincol = wp->w_wantcol - wp->w_width;
}
if (wp->w_height <= 1)
wp->w_height = wp->w_buffer->b_ml.ml_line_count + wrapped;
@ -210,14 +388,29 @@ popup_adjust_position(win_T *wp)
if (wp->w_height > Rows - wp->w_winrow)
wp->w_height = Rows - wp->w_winrow;
if (center_vert)
wp->w_winrow = (Rows - wp->w_height) / 2;
else if (wp->w_popup_pos == POPPOS_BOTRIGHT
|| wp->w_popup_pos == POPPOS_BOTLEFT)
{
if (wp->w_height <= wp->w_wantline)
// bottom aligned: may move down
wp->w_winrow = wp->w_wantline - wp->w_height;
else
// not enough space, make top aligned
wp->w_winrow = wp->w_wantline + 1;
}
wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer);
}
/*
* popup_create({text}, {options})
* popup_atcursor({text}, {options})
* When called from f_popup_atcursor() "atcursor" is TRUE.
*/
void
f_popup_create(typval_T *argvars, typval_T *rettv)
static void
popup_create(typval_T *argvars, typval_T *rettv, int atcursor)
{
win_T *wp;
buf_T *buf;
@ -247,7 +440,7 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
if (wp == NULL)
return;
rettv->vval.v_number = wp->w_id;
wp->w_p_wrap = TRUE; // 'wrap' is default on
wp->w_popup_pos = POPPOS_TOPLEFT;
buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY);
if (buf == NULL)
@ -265,6 +458,10 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
buf->b_p_swf = FALSE; // no swap file
buf->b_p_bl = FALSE; // unlisted buffer
buf->b_locked = TRUE;
wp->w_p_wrap = TRUE; // 'wrap' is default on
// Avoid that 'buftype' is reset when this buffer is entered.
buf->b_p_initialized = TRUE;
nr = (int)dict_get_number(d, (char_u *)"tab");
if (nr == 0)
@ -307,7 +504,7 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
curbuf = curwin->w_buffer;
// Deal with options.
apply_options(wp, buf, argvars[1].vval.v_dict);
apply_options(wp, buf, argvars[1].vval.v_dict, atcursor);
// set default values
if (wp->w_zindex == 0)
@ -320,6 +517,24 @@ f_popup_create(typval_T *argvars, typval_T *rettv)
redraw_all_later(NOT_VALID);
}
/*
* popup_create({text}, {options})
*/
void
f_popup_create(typval_T *argvars, typval_T *rettv)
{
popup_create(argvars, rettv, FALSE);
}
/*
* popup_atcursor({text}, {options})
*/
void
f_popup_atcursor(typval_T *argvars, typval_T *rettv)
{
popup_create(argvars, rettv, TRUE);
}
/*
* Find the popup window with window-ID "id".
* If the popup window does not exist NULL is returned.
@ -378,6 +593,7 @@ f_popup_hide(typval_T *argvars, typval_T *rettv UNUSED)
if (wp != NULL && (wp->w_popup_flags & POPF_HIDDEN) == 0)
{
wp->w_popup_flags |= POPF_HIDDEN;
--wp->w_buffer->b_nwindows;
redraw_all_later(NOT_VALID);
}
}
@ -394,6 +610,7 @@ f_popup_show(typval_T *argvars, typval_T *rettv UNUSED)
if (wp != NULL && (wp->w_popup_flags & POPF_HIDDEN) != 0)
{
wp->w_popup_flags &= ~POPF_HIDDEN;
++wp->w_buffer->b_nwindows;
redraw_all_later(NOT_VALID);
}
}
@ -501,11 +718,7 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
wp->w_maxwidth = nr;
if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0)
wp->w_maxheight = nr;
if ((nr = dict_get_number(d, (char_u *)"line")) > 0)
wp->w_wantline = nr;
if ((nr = dict_get_number(d, (char_u *)"col")) > 0)
wp->w_wantcol = nr;
// TODO: "pos"
get_pos_options(wp, d);
if (wp->w_winrow + wp->w_height >= cmdline_row)
clear_cmdline = TRUE;
@ -514,24 +727,36 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
}
/*
* popup_getposition({id})
* popup_getpos({id})
*/
void
f_popup_getposition(typval_T *argvars, typval_T *rettv)
f_popup_getpos(typval_T *argvars, typval_T *rettv)
{
dict_T *dict;
int id = (int)tv_get_number(argvars);
win_T *wp = find_popup_win(id);
int top_extra;
int left_extra;
if (rettv_dict_alloc(rettv) == OK)
{
if (wp == NULL)
return; // invalid {id}
top_extra = wp->w_popup_border[0] + wp->w_popup_padding[0];
left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
dict = rettv->vval.v_dict;
dict_add_number(dict, "line", wp->w_winrow + 1);
dict_add_number(dict, "col", wp->w_wincol + 1);
dict_add_number(dict, "width", wp->w_width);
dict_add_number(dict, "height", wp->w_height);
dict_add_number(dict, "width", wp->w_width + left_extra + wp->w_popup_border[1] + wp->w_popup_padding[1]);
dict_add_number(dict, "height", wp->w_height + top_extra + wp->w_popup_border[2] + wp->w_popup_padding[2]);
dict_add_number(dict, "core_line", wp->w_winrow + 1 + top_extra);
dict_add_number(dict, "core_col", wp->w_wincol + 1 + left_extra);
dict_add_number(dict, "core_width", wp->w_width);
dict_add_number(dict, "core_height", wp->w_height);
dict_add_number(dict, "visible",
(wp->w_popup_flags & POPF_HIDDEN) == 0);
}
@ -546,6 +771,7 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
dict_T *dict;
int id = (int)tv_get_number(argvars);
win_T *wp = find_popup_win(id);
int i;
if (rettv_dict_alloc(rettv) == OK)
{
@ -560,10 +786,137 @@ f_popup_getoptions(typval_T *argvars, typval_T *rettv)
dict_add_number(dict, "maxheight", wp->w_maxheight);
dict_add_number(dict, "maxwidth", wp->w_maxwidth);
dict_add_number(dict, "zindex", wp->w_zindex);
for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T));
++i)
if (wp->w_popup_pos == poppos_entries[i].pp_val)
{
dict_add_string(dict, "pos",
(char_u *)poppos_entries[i].pp_name);
break;
}
# if defined(FEAT_TIMERS)
dict_add_number(dict, "time", wp->w_popup_timer != NULL
? (long)wp->w_popup_timer->tr_interval : 0L);
# endif
}
}
int
not_in_popup_window()
{
if (bt_popup(curwin->w_buffer))
{
emsg(_("E994: Not allowed in a popup window"));
return TRUE;
}
return FALSE;
}
/*
* Reset all the POPF_HANDLED flags in global popup windows and popup windows
* in the current tab.
*/
void
popup_reset_handled()
{
win_T *wp;
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
wp->w_popup_flags &= ~POPF_HANDLED;
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
wp->w_popup_flags &= ~POPF_HANDLED;
}
/*
* Find the next visible popup where POPF_HANDLED is not set.
* Must have called popup_reset_handled() first.
* When "lowest" is TRUE find the popup with the lowest zindex, otherwise the
* popup with the highest zindex.
*/
win_T *
find_next_popup(int lowest)
{
win_T *wp;
win_T *found_wp;
int found_zindex;
found_zindex = lowest ? INT_MAX : 0;
found_wp = NULL;
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
if ((wp->w_popup_flags & (POPF_HANDLED|POPF_HIDDEN)) == 0
&& (lowest ? wp->w_zindex < found_zindex
: wp->w_zindex > found_zindex))
{
found_zindex = wp->w_zindex;
found_wp = wp;
}
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
if ((wp->w_popup_flags & (POPF_HANDLED|POPF_HIDDEN)) == 0
&& (lowest ? wp->w_zindex < found_zindex
: wp->w_zindex > found_zindex))
{
found_zindex = wp->w_zindex;
found_wp = wp;
}
if (found_wp != NULL)
found_wp->w_popup_flags |= POPF_HANDLED;
return found_wp;
}
/*
* Invoke the filter callback for window "wp" with typed character "c".
* Uses the global "mod_mask" for modifiers.
* Returns the return value of the filter.
* Careful: The filter may make "wp" invalid!
*/
static int
invoke_popup_filter(win_T *wp, int c)
{
int res;
typval_T rettv;
int dummy;
typval_T argv[3];
char_u buf[NUMBUFLEN];
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = (varnumber_T)wp->w_id;
// Convert the number to a string, so that the function can use:
// if a:c == "\<F2>"
buf[special_to_buf(c, mod_mask, TRUE, buf)] = NUL;
argv[1].v_type = VAR_STRING;
argv[1].vval.v_string = vim_strsave(buf);
argv[2].v_type = VAR_UNKNOWN;
call_callback(&wp->w_filter_cb, -1,
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
res = tv_get_number(&rettv);
vim_free(argv[1].vval.v_string);
clear_tv(&rettv);
return res;
}
/*
* Called when "c" was typed: invoke popup filter callbacks.
* Returns TRUE when the character was consumed,
*/
int
popup_do_filter(int c)
{
int res = FALSE;
win_T *wp;
popup_reset_handled();
while (!res && (wp = find_next_popup(FALSE)) != NULL)
if (wp->w_filter_cb.cb_name != NULL)
res = invoke_popup_filter(wp, c);
return res;
}
#endif // FEAT_TEXT_PROP

View File

@ -12,7 +12,7 @@ channel_T *channel_open_func(typval_T *argvars);
void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
void channel_set_job(channel_T *channel, job_T *job, jobopt_T *options);
void channel_set_options(channel_T *channel, jobopt_T *opt);
void channel_set_req_callback(channel_T *channel, ch_part_T part, char_u *callback, partial_T *partial, int id);
void channel_set_req_callback(channel_T *channel, ch_part_T part, callback_T *callback, int id);
void channel_buffer_free(buf_T *buf);
void channel_write_any_lines(void);
void channel_write_new_lines(buf_T *buf);

View File

@ -11,6 +11,8 @@ void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
float_T vim_round(float_T f);
long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
void f_string(typval_T *argvars, typval_T *rettv);
char_u *get_callback(typval_T *arg, partial_T **pp);
void free_callback(char_u *callback, partial_T *partial);
callback_T get_callback(typval_T *arg);
void put_callback(callback_T *cb, typval_T *tv);
void set_callback(callback_T *dest, callback_T *src);
void free_callback(callback_T *callback);
/* vim: set ft=c : */

View File

@ -69,6 +69,7 @@ int simplify_key(int key, int *modifiers);
int handle_x_keys(int key);
char_u *get_special_key_name(int c, int modifiers);
int trans_special(char_u **srcp, char_u *dst, int keycode, int in_string);
int special_to_buf(int key, int modifiers, int keycode, char_u *dst);
int find_special_key(char_u **srcp, int *modp, int keycode, int keep_x_key, int in_string);
int extract_modifiers(int key, int *modp);
int find_special_key_in_table(int c);

View File

@ -1,6 +1,7 @@
/* popupwin.c */
void popup_adjust_position(win_T *wp);
void f_popup_create(typval_T *argvars, typval_T *rettv);
void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
int popup_any_visible(void);
void f_popup_close(typval_T *argvars, typval_T *rettv);
void f_popup_hide(typval_T *argvars, typval_T *rettv);
@ -10,6 +11,10 @@ void popup_close_tabpage(tabpage_T *tp, int id);
void close_all_popups(void);
void ex_popupclear(exarg_T *eap);
void f_popup_move(typval_T *argvars, typval_T *rettv);
void f_popup_getpos(typval_T *argvars, typval_T *rettv);
void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
void f_popup_getposition(typval_T *argvars, typval_T *rettv);
int not_in_popup_window(void);
void popup_reset_handled(void);
win_T *find_next_popup(int lowest);
int popup_do_filter(int c);
/* vim: set ft=c : */

View File

@ -8,6 +8,7 @@ void save_funccal(funccal_entry_T *entry);
void restore_funccal(void);
void free_all_functions(void);
int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv);
int call_callback(callback_T *callback, int len, typval_T *rettv, int argcount, typval_T *argvars, int (*argv_func)(int, typval_T *, int), linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict);
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, int (*argv_func)(int, typval_T *, int), linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict_in);
char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fdp, partial_T **partial);
void ex_function(exarg_T *eap);

View File

@ -77,7 +77,9 @@ void reset_lnums(void);
void make_snapshot(int idx);
void restore_snapshot(int idx, int close_curwin);
int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display);
int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display);
void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display);
void restore_win_noblock(win_T *save_curwin, tabpage_T *save_curtab, int no_display);
void switch_buffer(bufref_T *save_curbuf, buf_T *buf);
void restore_buffer(bufref_T *save_curbuf);
int win_hasvertsplit(void);

View File

@ -991,57 +991,6 @@ update_debug_sign(buf_T *buf, linenr_T lnum)
}
#endif
#ifdef FEAT_TEXT_PROP
static void
update_popups(void)
{
win_T *wp;
win_T *lowest_wp;
int lowest_zindex;
// Reset all the VALID_POPUP flags.
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
wp->w_popup_flags &= ~POPF_REDRAWN;
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
wp->w_popup_flags &= ~POPF_REDRAWN;
// TODO: don't redraw every popup every time.
for (;;)
{
// Find the window with the lowest zindex that hasn't been updated yet,
// so that the window with a higher zindex is drawn later, thus goes on
// top.
lowest_zindex = INT_MAX;
lowest_wp = NULL;
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
if ((wp->w_popup_flags & (POPF_REDRAWN|POPF_HIDDEN)) == 0
&& wp->w_zindex < lowest_zindex)
{
lowest_zindex = wp->w_zindex;
lowest_wp = wp;
}
for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next)
if ((wp->w_popup_flags & (POPF_REDRAWN|POPF_HIDDEN)) == 0
&& wp->w_zindex < lowest_zindex)
{
lowest_zindex = wp->w_zindex;
lowest_wp = wp;
}
if (lowest_wp == NULL)
break;
// Recompute the position if the text changed.
if (lowest_wp->w_popup_last_changedtick
!= CHANGEDTICK(lowest_wp->w_buffer))
popup_adjust_position(lowest_wp);
win_update(lowest_wp);
lowest_wp->w_popup_flags |= POPF_REDRAWN;
}
}
#endif
/*
* Get 'wincolor' attribute for window "wp". If not set and "wp" is a popup
* window then get the "Pmenu" highlight attribute.
@ -1060,6 +1009,149 @@ get_wcr_attr(win_T *wp)
return wcr_attr;
}
#ifdef FEAT_TEXT_PROP
/*
* Return a string of "len" spaces in IObuff.
*/
static char_u *
get_spaces(int len)
{
vim_memset(IObuff, ' ', (size_t)len);
IObuff[len] = NUL;
return IObuff;
}
static void
update_popups(void)
{
win_T *wp;
int top_off;
int left_off;
int total_width;
int total_height;
int popup_attr;
int row;
int tl_corner_char = '+';
char *tr_corner_str = "+";
int bl_corner_char = '+';
char *br_corner_str = "+";
int hor_line_char = '-';
char *ver_line_str = "|";
// Find the window with the lowest zindex that hasn't been updated yet,
// so that the window with a higher zindex is drawn later, thus goes on
// top.
// TODO: don't redraw every popup every time.
popup_reset_handled();
while ((wp = find_next_popup(TRUE)) != NULL)
{
// Recompute the position if the text changed.
if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
popup_adjust_position(wp);
// adjust w_winrow and w_wincol for border and padding, since
// win_update() doesn't handle them.
top_off = wp->w_popup_padding[0] + wp->w_popup_border[0];
left_off = wp->w_popup_padding[3] + wp->w_popup_border[3];
wp->w_winrow += top_off;
wp->w_wincol += left_off;
// Draw the popup text.
win_update(wp);
wp->w_winrow -= top_off;
wp->w_wincol -= left_off;
total_width = wp->w_popup_border[3] + wp->w_popup_padding[3]
+ wp->w_width + wp->w_popup_padding[1] + wp->w_popup_border[1];
total_height = wp->w_popup_border[0] + wp->w_popup_padding[0]
+ wp->w_height + wp->w_popup_padding[2] + wp->w_popup_border[2];
popup_attr = get_wcr_attr(wp);
if (enc_utf8)
{
tl_corner_char = 0x2554;
tr_corner_str = "\xe2\x95\x97";
bl_corner_char = 0x255a;
br_corner_str = "\xe2\x95\x9d";
hor_line_char = 0x2550;
ver_line_str = "\xe2\x95\x91";
}
if (wp->w_popup_border[0] > 0)
{
// top border
screen_fill(wp->w_winrow, wp->w_winrow + 1,
wp->w_wincol,
wp->w_wincol + total_width,
wp->w_popup_border[3] != 0
? tl_corner_char : hor_line_char,
hor_line_char, popup_attr);
if (wp->w_popup_border[1] > 0)
screen_puts((char_u *)tr_corner_str, wp->w_winrow,
wp->w_wincol + total_width - 1, popup_attr);
}
if (wp->w_popup_padding[0] > 0)
{
// top padding
row = wp->w_winrow + wp->w_popup_border[0];
screen_fill(row, row + wp->w_popup_padding[0],
wp->w_wincol + wp->w_popup_border[3],
wp->w_wincol + total_width - wp->w_popup_border[1],
' ', ' ', popup_attr);
}
for (row = wp->w_winrow + wp->w_popup_border[0];
row < wp->w_winrow + total_height - wp->w_popup_border[2];
++row)
{
// left border
if (wp->w_popup_border[3] > 0)
screen_puts((char_u *)ver_line_str, row, wp->w_wincol, popup_attr);
// left padding
if (wp->w_popup_padding[3] > 0)
screen_puts(get_spaces(wp->w_popup_padding[3]), row,
wp->w_wincol + wp->w_popup_border[3], popup_attr);
// right border
if (wp->w_popup_border[1] > 0)
screen_puts((char_u *)ver_line_str, row,
wp->w_wincol + total_width - 1, popup_attr);
// right padding
if (wp->w_popup_padding[1] > 0)
screen_puts(get_spaces(wp->w_popup_padding[1]), row,
wp->w_wincol + wp->w_popup_border[3]
+ wp->w_popup_padding[3] + wp->w_width, popup_attr);
}
if (wp->w_popup_padding[2] > 0)
{
// bottom padding
row = wp->w_winrow + wp->w_popup_border[0]
+ wp->w_popup_padding[0] + wp->w_height;
screen_fill(row, row + wp->w_popup_padding[2],
wp->w_wincol + wp->w_popup_border[3],
wp->w_wincol + total_width - wp->w_popup_border[1],
' ', ' ', popup_attr);
}
if (wp->w_popup_border[2] > 0)
{
// bottom border
row = wp->w_winrow + total_height - 1;
screen_fill(row , row + 1,
wp->w_wincol,
wp->w_wincol + total_width,
wp->w_popup_border[3] != 0 ? bl_corner_char : hor_line_char,
hor_line_char, popup_attr);
if (wp->w_popup_border[1] > 0)
screen_puts((char_u *)br_corner_str, row,
wp->w_wincol + total_width - 1, popup_attr);
}
}
}
#endif
#if defined(FEAT_GUI) || defined(PROTO)
/*
* Update a single window, its status line and maybe the command line msg.
@ -8921,6 +9013,15 @@ retry:
win_free_lsize(wp);
if (aucmd_win != NULL)
win_free_lsize(aucmd_win);
#ifdef FEAT_TEXT_PROP
// global popup windows
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
win_free_lsize(wp);
// tab-local popup windows
FOR_ALL_TABPAGES(tp)
for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
win_free_lsize(wp);
#endif
new_ScreenLines = LALLOC_MULT(schar_T, (Rows + 1) * Columns);
vim_memset(new_ScreenLinesC, 0, sizeof(u8char_T *) * MAX_MCO);
@ -8949,6 +9050,24 @@ retry:
if (aucmd_win != NULL && aucmd_win->w_lines == NULL
&& win_alloc_lines(aucmd_win) == FAIL)
outofmem = TRUE;
#ifdef FEAT_TEXT_PROP
// global popup windows
for (wp = first_popupwin; wp != NULL; wp = wp->w_next)
if (win_alloc_lines(wp) == FAIL)
{
outofmem = TRUE;
goto give_up;
}
// tab-local popup windows
FOR_ALL_TABPAGES(tp)
for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next)
if (win_alloc_lines(wp) == FAIL)
{
outofmem = TRUE;
goto give_up;
}
#endif
give_up:
for (i = 0; i < p_mco; ++i)

View File

@ -1237,6 +1237,17 @@ typedef struct dictvar_S dict_T;
typedef struct partial_S partial_T;
typedef struct blobvar_S blob_T;
// Struct that holds both a normal function name and a partial_T, as used for a
// callback argument.
// When used temporarily "cb_name" is not allocated. The refcounts to either
// the function or the partial are incremented and need to be decremented
// later with free_callback().
typedef struct {
char_u *cb_name;
partial_T *cb_partial;
int cb_free_name; // cb_name was allocated
} callback_T;
typedef struct jobvar_S job_T;
typedef struct readq_S readq_T;
typedef struct writeq_S writeq_T;
@ -1566,8 +1577,7 @@ struct jobvar_S
char_u *jv_tty_type; // allocated
#endif
int jv_exitval;
char_u *jv_exit_cb; /* allocated */
partial_T *jv_exit_partial;
callback_T jv_exit_cb;
buf_T *jv_in_buf; /* buffer from "in-name" */
@ -1606,8 +1616,7 @@ struct jsonq_S
struct cbq_S
{
char_u *cq_callback;
partial_T *cq_partial;
callback_T cq_callback;
int cq_seq_nr;
cbq_T *cq_next;
cbq_T *cq_prev;
@ -1689,8 +1698,7 @@ typedef struct {
writeq_T ch_writeque; /* header for write queue */
cbq_T ch_cb_head; /* dummy node for per-request callbacks */
char_u *ch_callback; /* call when a msg is not handled */
partial_T *ch_partial;
callback_T ch_callback; /* call when a msg is not handled */
bufref_T ch_bufref; /* buffer to read from or write to */
int ch_nomodifiable; /* TRUE when buffer can be 'nomodifiable' */
@ -1731,10 +1739,8 @@ struct channel_S {
#ifdef MSWIN
int ch_named_pipe; /* using named pipe instead of pty */
#endif
char_u *ch_callback; /* call when any msg is not handled */
partial_T *ch_partial;
char_u *ch_close_cb; /* call when channel is closed */
partial_T *ch_close_partial;
callback_T ch_callback; /* call when any msg is not handled */
callback_T ch_close_cb; /* call when channel is closed */
int ch_drop_never;
int ch_keep_open; /* do not close on read error */
int ch_nonblock;
@ -1833,16 +1839,11 @@ typedef struct
linenr_T jo_in_top;
linenr_T jo_in_bot;
char_u *jo_callback; /* not allocated! */
partial_T *jo_partial; /* not referenced! */
char_u *jo_out_cb; /* not allocated! */
partial_T *jo_out_partial; /* not referenced! */
char_u *jo_err_cb; /* not allocated! */
partial_T *jo_err_partial; /* not referenced! */
char_u *jo_close_cb; /* not allocated! */
partial_T *jo_close_partial; /* not referenced! */
char_u *jo_exit_cb; /* not allocated! */
partial_T *jo_exit_partial; /* not referenced! */
callback_T jo_callback;
callback_T jo_out_cb;
callback_T jo_err_cb;
callback_T jo_close_cb;
callback_T jo_exit_cb;
int jo_drop_never;
int jo_waittime;
int jo_timeout;
@ -1886,8 +1887,7 @@ struct listener_S
{
listener_T *lr_next;
int lr_id;
char_u *lr_callback;
partial_T *lr_partial;
callback_T lr_callback;
};
#endif
@ -1950,13 +1950,12 @@ struct timer_S
#ifdef FEAT_TIMERS
timer_T *tr_next;
timer_T *tr_prev;
proftime_T tr_due; /* when the callback is to be invoked */
char tr_firing; /* when TRUE callback is being called */
char tr_paused; /* when TRUE callback is not invoked */
int tr_repeat; /* number of times to repeat, -1 forever */
long tr_interval; /* msec */
char_u *tr_callback; /* allocated */
partial_T *tr_partial;
proftime_T tr_due; // when the callback is to be invoked
char tr_firing; // when TRUE callback is being called
char tr_paused; // when TRUE callback is not invoked
int tr_repeat; // number of times to repeat, -1 forever
long tr_interval; // msec
callback_T tr_callback;
int tr_emsg_count;
#endif
};
@ -1982,6 +1981,15 @@ typedef struct {
// # define CRYPT_NOT_INPLACE 1
#endif
#ifdef FEAT_TEXT_PROP
typedef enum {
POPPOS_BOTLEFT,
POPPOS_TOPLEFT,
POPPOS_BOTRIGHT,
POPPOS_TOPRIGHT,
POPPOS_CENTER
} poppos_T;
#endif
/*
* These are items normally related to a buffer. But when using ":ownsyntax"
@ -2500,13 +2508,11 @@ struct file_buffer
int b_shortname; /* this file has an 8.3 file name */
#ifdef FEAT_JOB_CHANNEL
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.
char_u *b_prompt_text; // set by prompt_setprompt()
callback_T b_prompt_callback; // set by prompt_setcallback()
callback_T b_prompt_interrupt; // set by prompt_setinterrupt()
int b_prompt_insert; // value for restart_edit when entering
// a prompt buffer window.
#endif
#ifdef FEAT_MZSCHEME
void *b_mzscheme_ref; /* The MzScheme reference to this buffer */
@ -2873,7 +2879,8 @@ struct window_S
int w_vsep_width; /* Number of separator columns (0 or 1). */
pos_save_T w_save_cursor; /* backup of cursor pos and topline */
#ifdef FEAT_TEXT_PROP
int w_popup_flags; // PFL_ values
int w_popup_flags; // POPF_ values
poppos_T w_popup_pos;
int w_zindex;
int w_minheight; // "minheight" for popup window
int w_minwidth; // "minwidth" for popup window
@ -2881,8 +2888,11 @@ struct window_S
int w_maxwidth; // "maxwidth" for popup window
int w_wantline; // "line" for popup window
int w_wantcol; // "col" for popup window
int w_popup_padding[4]; // popup padding top/right/bot/left
int w_popup_border[4]; // popup border top/right/bot/left
varnumber_T w_popup_last_changedtick; // b:changedtick when position was
// computed
callback_T w_filter_cb; // popup filter callback
# if defined(FEAT_TIMERS)
timer_T *w_popup_timer; // timer for closing popup window
# endif

View File

@ -13,7 +13,6 @@ SCRIPTS_FIRST = \
# Tests that run on all systems.
SCRIPTS_ALL = \
test3.out \
test39.out \
test42.out \
test44.out \

View File

@ -73,7 +73,7 @@ VIMPROG = <->vim.exe
.SUFFIXES : .out .in
SCRIPT = test1.out test3.out \
SCRIPT = test1.out \
test39.out \
test42.out test44.out test48.out test49.out \
test64.out test69.out \

View File

@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @22|#+0#e000e06#5fd7ff255|i|n|c|l|u|d|e| |<+0#e000002&|s|t|d|i|o|.|h|>| +0#0000000#ffffff0@32
|4| @22|i+0#00e0003#5fd7ff255|n|t| +0#0000000&|m|a|i|n|(|v+0#00e0003&|o|i|d|)+0#0000000&| @3| +0&#ffffff0@32
|5| @22|{+0&#5fd7ff255| @16| +0&#ffffff0@32
|6| @22| +0&#5fd7ff255@3|p|r|i|n|t|f|(|1+0#e000002&|2|3|)+0#0000000&|;| @1| +0&#ffffff0@32
|7| @22|}+0&#5fd7ff255| @16| +0&#ffffff0@32
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|

View File

@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @18|#+0#e000e06#e0e0e08|i|n|c|l|u|d|e| |<+0#e000002&|s|t|d|i|o|.|h|>| +0#0000000#ffffff0@36
|4| @18|i+0#00e0003#e0e0e08|n|t| +0#0000000&|m|a|i|n|(|v+0#00e0003&|o|i|d|)+0#0000000&| @3| +0&#ffffff0@36
|5| @18|{+0&#e0e0e08| @16| +0&#ffffff0@36
|6| @18| +0&#e0e0e08@3|p|r|i|n|t|f|(|5+0#e000002&|6|7|)+0#0000000&|;| @1| +0&#ffffff0@36
|7| @18|}+0&#e0e0e08| @16| +0&#ffffff0@36
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|

View File

@ -0,0 +1,15 @@
>1+0&#ffffff0| @73
|2| |++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@18
|3| ||+0#0000001#ffd7ff255|h|e|l@1|o| |b|o|r|d|e|r||| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255|h|e|l@1|o| |p|a|d@1|i|n|g| | +0#0000000#ffffff0@4||+0#0000001#ffd7ff255| @11||| +0#0000000#ffffff0@18
|4| |++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4||+0#0000001#ffd7ff255| |h|e|l@1|o| |b|o|t|h| ||| +0#0000000#ffffff0@18
|5| @40||+0#0000001#ffd7ff255| @11||| +0#0000000#ffffff0@18
|6| |++0#0000001#ffd7ff255|-@8| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|++0#0000001#ffd7ff255|-@11|+| +0#0000000#ffffff0@18
|7| ||+0#0000001#ffd7ff255|b|o|r|d|e|r| |T|L| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@3|p|a|d@1|i|n|g|s| @2| +0#0000000#ffffff0@37
|8| @20| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@37
|9| @20| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@37
|1|0| @72
|1@1| @72
|1|2| @72
|1|3| @72
|1|4| @72
@57|1|,|1| @10|T|o|p|

View File

@ -0,0 +1,15 @@
>1+0&#ffffff0| @73
|2| |╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|╔+0#0000001#ffd7ff255|═@11|╗| +0#0000000#ffffff0@18
|3| |║+0#0000001#ffd7ff255|h|e|l@1|o| |b|o|r|d|e|r|║| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255|h|e|l@1|o| |p|a|d@1|i|n|g| | +0#0000000#ffffff0@4|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0@18
|4| |╚+0#0000001#ffd7ff255|═@11|╝| +0#0000000#ffffff0@5| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|║+0#0000001#ffd7ff255| |h|e|l@1|o| |b|o|t|h| |║| +0#0000000#ffffff0@18
|5| @40|║+0#0000001#ffd7ff255| @11|║| +0#0000000#ffffff0@18
|6| |╔+0#0000001#ffd7ff255|═@8| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@4|╚+0#0000001#ffd7ff255|═@11|╝| +0#0000000#ffffff0@18
|7| |║+0#0000001#ffd7ff255|b|o|r|d|e|r| |T|L| +0#0000000#ffffff0@9| +0#0000001#ffd7ff255@3|p|a|d@1|i|n|g|s| @2| +0#0000000#ffffff0@37
|8| @20| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@37
|9| @20| +0#0000001#ffd7ff255@14| +0#0000000#ffffff0@37
|1|0| @72
|1@1| @72
|1|2| @72
|1|3| @72
|1|4| @72
@57|1|,|1| @10|T|o|p|

View File

@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @17|a+0#0000001#ffd7ff255| |l|o|n|g| |l|i|n| +0#0000000#ffffff0@45
|4| @73
|5| @73
|6| @73
|7| @73
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|

View File

@ -0,0 +1,10 @@
>1+0&#ffffff0| @73
|2| @73
|3| @17|a+0#0000001#ffd7ff255| |l|o|n|g| |l|i|n| +0#0000000#ffffff0@45
|4| @17|e+0#0000001#ffd7ff255| |t|h|a|t| |w|o|n| +0#0000000#ffffff0@45
|5| @17|t+0#0000001#ffd7ff255| |f|i|t| @4| +0#0000000#ffffff0@45
|6| @73
|7| @73
|8| @73
|9| @73
@57|1|,|1| @10|T|o|p|

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -94,8 +94,6 @@ func Test_win_execute()
let line = win_execute(popupwin, 'echo getline(1)')
call assert_match('the popup win', line)
call assert_fails('call win_execute(popupwin, "bwipe!")', 'E937:')
call popup_close(popupwin)
endif

View File

@ -97,13 +97,14 @@ func Test_memory_func_capture_vargs()
let after = s:monitor_memory_usage(vim.pid)
" Estimate the limit of max usage as 2x initial usage.
" The lower limit can fluctuate a bit, use 98%.
call assert_inrange(before * 98 / 100, 2 * before, after.max)
" The lower limit can fluctuate a bit, use 97%.
call assert_inrange(before * 97 / 100, 2 * before, after.max)
" In this case, garbage collecting is not needed.
" The value might fluctuate a bit, allow for 3% tolerance.
" The value might fluctuate a bit, allow for 3% tolerance below and 5% above.
" Based on various test runs.
let lower = after.last * 97 / 100
let upper = after.last * 103 / 100
let upper = after.last * 105 / 100
call assert_inrange(lower, upper, after.max)
call vim.stop()

View File

@ -56,6 +56,171 @@ func Test_simple_popup()
call delete('XtestPopup')
endfunc
func Test_popup_with_border_and_padding()
if !CanRunVimInTerminal()
return
endif
for iter in range(0, 1)
call writefile([iter == 1 ? '' : 'set enc=latin1',
\ "call setline(1, range(1, 100))",
\ "call popup_create('hello border', {'line': 2, 'col': 3, 'border': []})",
\ "call popup_create('hello padding', {'line': 2, 'col': 23, 'padding': []})",
\ "call popup_create('hello both', {'line': 2, 'col': 43, 'border': [], 'padding': []})",
\ "call popup_create('border TL', {'line': 6, 'col': 3, 'border': [1, 0, 0, 4]})",
\ "call popup_create('paddings', {'line': 6, 'col': 23, 'padding': [1, 3, 2, 4]})",
\], 'XtestPopupBorder')
let buf = RunVimInTerminal('-S XtestPopupBorder', {'rows': 15})
call VerifyScreenDump(buf, 'Test_popupwin_2' .. iter, {})
call StopVimInTerminal(buf)
call delete('XtestPopupBorder')
endfor
let with_border_or_padding = {
\ 'line': 2,
\ 'core_line': 3,
\ 'col': 3,
\ 'core_col': 4,
\ 'width': 14,
\ 'core_width': 12,
\ 'height': 3,
\ 'core_height': 1,
\ 'visible': 1}
let winid = popup_create('hello border', {'line': 2, 'col': 3, 'border': []})",
call assert_equal(with_border_or_padding, popup_getpos(winid))
let winid = popup_create('hello paddng', {'line': 2, 'col': 3, 'padding': []})
call assert_equal(with_border_or_padding, popup_getpos(winid))
let winid = popup_create('hello both', {'line': 3, 'col': 8, 'border': [], 'padding': []})
call assert_equal({
\ 'line': 3,
\ 'core_line': 5,
\ 'col': 8,
\ 'core_col': 10,
\ 'width': 14,
\ 'core_width': 10,
\ 'height': 5,
\ 'core_height': 1,
\ 'visible': 1}, popup_getpos(winid))
endfunc
func Test_popup_with_syntax_win_execute()
if !CanRunVimInTerminal()
return
endif
call writefile([
\ "call setline(1, range(1, 100))",
\ "hi PopupColor ctermbg=lightblue",
\ "let winid = popup_create([",
\ "\\ '#include <stdio.h>',",
\ "\\ 'int main(void)',",
\ "\\ '{',",
\ "\\ ' printf(123);',",
\ "\\ '}',",
\ "\\], {'line': 3, 'col': 25, 'highlight': 'PopupColor'})",
\ "call win_execute(winid, 'set syntax=cpp')",
\], 'XtestPopup')
let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10})
call VerifyScreenDump(buf, 'Test_popupwin_10', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopup')
endfunc
func Test_popup_with_syntax_setbufvar()
if !CanRunVimInTerminal()
return
endif
let lines =<< trim END
call setline(1, range(1, 100))
hi PopupColor ctermbg=lightgrey
let winid = popup_create([
\ '#include <stdio.h>',
\ 'int main(void)',
\ '{',
\ ' printf(567);',
\ '}',
\], {'line': 3, 'col': 21, 'highlight': 'PopupColor'})
call setbufvar(winbufnr(winid), '&syntax', 'cpp')
END
call writefile(lines, 'XtestPopup')
let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10})
call VerifyScreenDump(buf, 'Test_popupwin_11', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopup')
endfunc
func Test_win_execute_closing_curwin()
split
let winid = popup_create('some text', {})
call assert_fails('call win_execute(winid, winnr() .. "close")', 'E994')
popupclear
endfunc
func Test_win_execute_not_allowed()
let winid = popup_create('some text', {})
call assert_fails('call win_execute(winid, "split")', 'E994:')
call assert_fails('call win_execute(winid, "vsplit")', 'E994:')
call assert_fails('call win_execute(winid, "close")', 'E994:')
call assert_fails('call win_execute(winid, "bdelete")', 'E994:')
call assert_fails('call win_execute(winid, "bwipe!")', 'E994:')
call assert_fails('call win_execute(winid, "tabnew")', 'E994:')
call assert_fails('call win_execute(winid, "tabnext")', 'E994:')
call assert_fails('call win_execute(winid, "next")', 'E994:')
call assert_fails('call win_execute(winid, "rewind")', 'E994:')
call assert_fails('call win_execute(winid, "buf")', 'E994:')
call assert_fails('call win_execute(winid, "edit")', 'E994:')
call assert_fails('call win_execute(winid, "enew")', 'E994:')
call assert_fails('call win_execute(winid, "wincmd x")', 'E994:')
call assert_fails('call win_execute(winid, "wincmd w")', 'E994:')
call assert_fails('call win_execute(winid, "wincmd t")', 'E994:')
call assert_fails('call win_execute(winid, "wincmd b")', 'E994:')
popupclear
endfunc
func Test_popup_with_wrap()
if !CanRunVimInTerminal()
return
endif
let lines =<< trim END
call setline(1, range(1, 100))
let winid = popup_create(
\ 'a long line that wont fit',
\ {'line': 3, 'col': 20, 'maxwidth': 10, 'wrap': 1})
END
call writefile(lines, 'XtestPopup')
let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10})
call VerifyScreenDump(buf, 'Test_popupwin_wrap', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopup')
endfunc
func Test_popup_without_wrap()
if !CanRunVimInTerminal()
return
endif
let lines =<< trim END
call setline(1, range(1, 100))
let winid = popup_create(
\ 'a long line that wont fit',
\ {'line': 3, 'col': 20, 'maxwidth': 10, 'wrap': 0})
END
call writefile(lines, 'XtestPopup')
let buf = RunVimInTerminal('-S XtestPopup', {'rows': 10})
call VerifyScreenDump(buf, 'Test_popupwin_nowrap', {})
" clean up
call StopVimInTerminal(buf)
call delete('XtestPopup')
endfunc
func Test_popup_time()
if !has('timers')
return
@ -108,19 +273,23 @@ func Test_popup_hide()
redraw
let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
call assert_equal('world', line)
call assert_equal(1, popup_getposition(winid).visible)
call assert_equal(1, popup_getpos(winid).visible)
" buffer is still listed and active
call assert_match(winbufnr(winid) .. 'u a.*\[Popup\]', execute('ls u'))
call popup_hide(winid)
redraw
let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
call assert_equal('hello', line)
call assert_equal(0, popup_getposition(winid).visible)
call assert_equal(0, popup_getpos(winid).visible)
" buffer is still listed but hidden
call assert_match(winbufnr(winid) .. 'u h.*\[Popup\]', execute('ls u'))
call popup_show(winid)
redraw
let line = join(map(range(1, 5), 'screenstring(1, v:val)'), '')
call assert_equal('world', line)
call assert_equal(1, popup_getposition(winid).visible)
call assert_equal(1, popup_getpos(winid).visible)
call popup_close(winid)
@ -168,7 +337,7 @@ func Test_popup_move()
bwipe!
endfunc
func Test_popup_getposition()
func Test_popup_getpos()
let winid = popup_create('hello', {
\ 'line': 2,
\ 'col': 3,
@ -176,7 +345,7 @@ func Test_popup_getposition()
\ 'minheight': 11,
\})
redraw
let res = popup_getposition(winid)
let res = popup_getpos(winid)
call assert_equal(2, res.line)
call assert_equal(3, res.col)
call assert_equal(10, res.width)
@ -198,7 +367,7 @@ func Test_popup_width_longest()
for test in tests
let winid = popup_create(test[0], {'line': 2, 'col': 3})
redraw
let position = popup_getposition(winid)
let position = popup_getpos(winid)
call assert_equal(test[1], position.width)
call popup_close(winid)
endfor
@ -214,12 +383,12 @@ func Test_popup_wraps()
let winid = popup_create(test[0],
\ {'line': 2, 'col': 3, 'maxwidth': 12})
redraw
let position = popup_getposition(winid)
let position = popup_getpos(winid)
call assert_equal(test[1], position.width)
call assert_equal(test[2], position.height)
call popup_close(winid)
call assert_equal({}, popup_getposition(winid))
call assert_equal({}, popup_getpos(winid))
endfor
endfunc
@ -287,3 +456,113 @@ func Test_popup_option_values()
call popup_close(winid)
bwipe
endfunc
func Test_popup_atcursor()
topleft vnew
call setline(1, [
\ 'xxxxxxxxxxxxxxxxx',
\ 'xxxxxxxxxxxxxxxxx',
\ 'xxxxxxxxxxxxxxxxx',
\])
call cursor(2, 2)
redraw
let winid = popup_atcursor('vim', {})
redraw
let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '')
call assert_equal('xvimxxxxxxxxxxxxx', line)
call popup_close(winid)
call cursor(3, 4)
redraw
let winid = popup_atcursor('vim', {})
redraw
let line = join(map(range(1, 17), 'screenstring(2, v:val)'), '')
call assert_equal('xxxvimxxxxxxxxxxx', line)
call popup_close(winid)
call cursor(1, 1)
redraw
let winid = popup_create('vim', {
\ 'line': 'cursor+2',
\ 'col': 'cursor+1',
\})
redraw
let line = join(map(range(1, 17), 'screenstring(3, v:val)'), '')
call assert_equal('xvimxxxxxxxxxxxxx', line)
call popup_close(winid)
call cursor(3, 3)
redraw
let winid = popup_create('vim', {
\ 'line': 'cursor-2',
\ 'col': 'cursor-1',
\})
redraw
let line = join(map(range(1, 17), 'screenstring(1, v:val)'), '')
call assert_equal('xvimxxxxxxxxxxxxx', line)
call popup_close(winid)
" just enough room above
call cursor(3, 3)
redraw
let winid = popup_atcursor(['vim', 'is great'], {})
redraw
let pos = popup_getpos(winid)
call assert_equal(1, pos.line)
call popup_close(winid)
" not enough room above, popup goes below the cursor
call cursor(3, 3)
redraw
let winid = popup_atcursor(['vim', 'is', 'great'], {})
redraw
let pos = popup_getpos(winid)
call assert_equal(4, pos.line)
call popup_close(winid)
bwipe!
endfunc
func Test_popup_filter()
new
call setline(1, 'some text')
func MyPopupFilter(winid, c)
if a:c == 'e'
let g:eaten = 'e'
return 1
endif
if a:c == '0'
let g:ignored = '0'
return 0
endif
if a:c == 'x'
call popup_close(a:winid)
return 1
endif
return 0
endfunc
let winid = popup_create('something', {'filter': 'MyPopupFilter'})
redraw
" e is consumed by the filter
call feedkeys('e', 'xt')
call assert_equal('e', g:eaten)
" 0 is ignored by the filter
normal $
call assert_equal(9, getcurpos()[2])
call feedkeys('0', 'xt')
call assert_equal('0', g:ignored)
call assert_equal(1, getcurpos()[2])
" x closes the popup
call feedkeys('x', 'xt')
call assert_equal('e', g:eaten)
call assert_equal(-1, winbufnr(winid))
delfunc MyPopupFilter
popupclear
endfunc

View File

@ -38,7 +38,7 @@ func Test_writefile_fails_conversion()
endif
" Without a backup file the write won't happen if there is a conversion
" error.
set nobackup nowritebackup
set nobackup nowritebackup backupdir=. backupskip=
new
let contents = ["line one", "line two"]
call writefile(contents, 'Xfile')
@ -49,7 +49,7 @@ func Test_writefile_fails_conversion()
call delete('Xfile')
bwipe!
set backup& writebackup&
set backup& writebackup& backupdir&vim backupskip&vim
endfunc
func Test_writefile_fails_conversion2()
@ -58,7 +58,7 @@ func Test_writefile_fails_conversion2()
endif
" With a backup file the write happens even if there is a conversion error,
" but then the backup file must remain
set nobackup writebackup
set nobackup writebackup backupdir=. backupskip=
let contents = ["line one", "line two"]
call writefile(contents, 'Xfile_conversion_err')
edit Xfile_conversion_err
@ -71,6 +71,7 @@ func Test_writefile_fails_conversion2()
call delete('Xfile_conversion_err')
call delete('Xfile_conversion_err~')
bwipe!
set backup& writebackup& backupdir&vim backupskip&vim
endfunc
func SetFlag(timer)

View File

@ -1446,6 +1446,30 @@ func_call(
return r;
}
/*
* Invoke call_func() with a callback.
*/
int
call_callback(
callback_T *callback,
int len, // length of "name" or -1 to use strlen()
typval_T *rettv, // return value goes here
int argcount, // number of "argvars"
typval_T *argvars, // vars for arguments, must have "argcount"
// PLUS ONE elements!
int (* argv_func)(int, typval_T *, int),
// function to fill in argvars
linenr_T firstline, // first line of range
linenr_T lastline, // last line of range
int *doesrange, // return: function handled range
int evaluate,
dict_T *selfdict) // Dictionary for "self"
{
return call_func(callback->cb_name, len, rettv, argcount, argvars,
argv_func, firstline, lastline, doesrange, evaluate,
callback->cb_partial, selfdict);
}
/*
* Call a function with its resolved parameters
*

View File

@ -767,6 +767,46 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1444,
/**/
1443,
/**/
1442,
/**/
1441,
/**/
1440,
/**/
1439,
/**/
1438,
/**/
1437,
/**/
1436,
/**/
1435,
/**/
1434,
/**/
1433,
/**/
1432,
/**/
1431,
/**/
1430,
/**/
1429,
/**/
1428,
/**/
1427,
/**/
1426,
/**/
1425,
/**/
1424,
/**/

View File

@ -615,7 +615,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
// Values for w_popup_flags.
#define POPF_HIDDEN 1 // popup is not displayed
#define POPF_REDRAWN 2 // popup was just redrawn
#define POPF_HANDLED 2 // popup was just redrawn or filtered
/*
* Terminal highlighting attribute bits.

View File

@ -87,7 +87,8 @@ do_window(
#endif
char_u cbuf[40];
Prenum1 = Prenum == 0 ? 1 : Prenum;
if (NOT_IN_POPUP_WINDOW)
return;
#ifdef FEAT_CMDWIN
# define CHECK_CMDWIN \
@ -102,6 +103,8 @@ do_window(
# define CHECK_CMDWIN do { /**/ } while (0)
#endif
Prenum1 = Prenum == 0 ? 1 : Prenum;
switch (nchar)
{
/* split current window in two parts, horizontally */
@ -732,6 +735,9 @@ cmd_with_count(
int
win_split(int size, int flags)
{
if (NOT_IN_POPUP_WINDOW)
return FAIL;
/* When the ":tab" modifier was used open a new tab page instead. */
if (may_open_tabpage() == OK)
return OK;
@ -1509,7 +1515,9 @@ win_exchange(long Prenum)
win_T *wp2;
int temp;
if (ONE_WINDOW) /* just one window */
if (NOT_IN_POPUP_WINDOW)
return;
if (ONE_WINDOW) // just one window
{
beep_flush();
return;
@ -2363,6 +2371,9 @@ win_close(win_T *win, int free_buf)
tabpage_T *prev_curtab = curtab;
frame_T *win_frame = win->w_frame->fr_parent;
if (NOT_IN_POPUP_WINDOW)
return FAIL;
if (last_window())
{
emsg(_("E444: Cannot close last window"));
@ -4221,6 +4232,8 @@ win_goto(win_T *wp)
win_T *owp = curwin;
#endif
if (NOT_IN_POPUP_WINDOW)
return;
if (text_locked())
{
beep_flush();
@ -4831,6 +4844,9 @@ win_free(
#ifdef FEAT_MENU
remove_winbar(wp);
#endif
#ifdef FEAT_TEXT_PROP
free_callback(&wp->w_filter_cb);
#endif
#ifdef FEAT_SYN_HL
vim_free(wp->w_p_cc_cols);
@ -6495,6 +6511,20 @@ switch_win(
int no_display)
{
block_autocmds();
return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display);
}
/*
* As switch_win() but without blocking autocommands.
*/
int
switch_win_noblock(
win_T **save_curwin,
tabpage_T **save_curtab,
win_T *win,
tabpage_T *tp,
int no_display)
{
*save_curwin = curwin;
if (tp != NULL)
{
@ -6524,9 +6554,22 @@ switch_win(
*/
void
restore_win(
win_T *save_curwin UNUSED,
tabpage_T *save_curtab UNUSED,
int no_display UNUSED)
win_T *save_curwin,
tabpage_T *save_curtab,
int no_display)
{
restore_win_noblock(save_curwin, save_curtab, no_display);
unblock_autocmds();
}
/*
* As restore_win() but without unblocking autocommands.
*/
void
restore_win_noblock(
win_T *save_curwin,
tabpage_T *save_curtab,
int no_display)
{
if (save_curtab != NULL && valid_tabpage(save_curtab))
{
@ -6546,7 +6589,12 @@ restore_win(
curwin = save_curwin;
curbuf = curwin->w_buffer;
}
unblock_autocmds();
#ifdef FEAT_TEXT_PROP
else if (bt_popup(curwin->w_buffer))
// original window was closed and now we're in a popup window: Go
// to the first valid window.
win_goto(firstwin);
#endif
}
/*