summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2018-09-11 22:12:18 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2018-09-11 22:12:30 +0000
commit609295bc5793e51026e1745577ebf7c27796a792 (patch)
treed491916f4b48a8e8da0b5e2f92a0696fd6766879
parentReleasing progress-linux version 2:8.1.0229-1~dschinn1. (diff)
downloadvim-609295bc5793e51026e1745577ebf7c27796a792.zip
vim-609295bc5793e51026e1745577ebf7c27796a792.tar.xz
Merging upstream version 2:8.1.0320.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--README.md1
-rw-r--r--runtime/doc/autocmd.txt2
-rw-r--r--runtime/doc/change.txt4
-rw-r--r--runtime/doc/diff.txt4
-rw-r--r--runtime/doc/eval.txt64
-rw-r--r--runtime/doc/ft_rust.txt2
-rw-r--r--runtime/doc/if_perl.txt5
-rw-r--r--runtime/doc/intro.txt6
-rw-r--r--runtime/doc/options.txt38
-rw-r--r--runtime/doc/os_qnx.txt2
-rw-r--r--runtime/doc/print.txt2
-rw-r--r--runtime/doc/quickfix.txt24
-rw-r--r--runtime/doc/starting.txt5
-rw-r--r--runtime/doc/tabpage.txt6
-rw-r--r--runtime/doc/tags8
-rw-r--r--runtime/doc/term.txt4
-rw-r--r--runtime/doc/terminal.txt2
-rw-r--r--runtime/doc/todo.txt151
-rw-r--r--runtime/doc/uganda.txt2
-rw-r--r--runtime/doc/undo.txt2
-rw-r--r--runtime/doc/usr_01.txt2
-rw-r--r--runtime/doc/usr_02.txt2
-rw-r--r--runtime/doc/usr_03.txt2
-rw-r--r--runtime/doc/usr_04.txt2
-rw-r--r--runtime/doc/usr_05.txt2
-rw-r--r--runtime/doc/usr_06.txt2
-rw-r--r--runtime/doc/usr_07.txt2
-rw-r--r--runtime/doc/usr_08.txt2
-rw-r--r--runtime/doc/usr_09.txt2
-rw-r--r--runtime/doc/usr_10.txt2
-rw-r--r--runtime/doc/usr_11.txt2
-rw-r--r--runtime/doc/usr_12.txt2
-rw-r--r--runtime/doc/usr_20.txt2
-rw-r--r--runtime/doc/usr_21.txt2
-rw-r--r--runtime/doc/usr_22.txt2
-rw-r--r--runtime/doc/usr_23.txt2
-rw-r--r--runtime/doc/usr_24.txt2
-rw-r--r--runtime/doc/usr_25.txt2
-rw-r--r--runtime/doc/usr_26.txt2
-rw-r--r--runtime/doc/usr_27.txt2
-rw-r--r--runtime/doc/usr_28.txt2
-rw-r--r--runtime/doc/usr_29.txt2
-rw-r--r--runtime/doc/usr_30.txt2
-rw-r--r--runtime/doc/usr_31.txt2
-rw-r--r--runtime/doc/usr_32.txt2
-rw-r--r--runtime/doc/usr_40.txt2
-rw-r--r--runtime/doc/usr_41.txt2
-rw-r--r--runtime/doc/usr_42.txt2
-rw-r--r--runtime/doc/usr_43.txt2
-rw-r--r--runtime/doc/usr_44.txt2
-rw-r--r--runtime/doc/usr_45.txt2
-rw-r--r--runtime/doc/usr_90.txt2
-rw-r--r--runtime/doc/usr_toc.txt2
-rw-r--r--runtime/doc/various.txt2
-rw-r--r--runtime/doc/version4.txt2
-rw-r--r--runtime/doc/version5.txt2
-rw-r--r--runtime/doc/version6.txt2
-rw-r--r--runtime/doc/version7.txt2
-rw-r--r--runtime/doc/version8.txt2
-rw-r--r--runtime/doc/vi_diff.txt2
-rw-r--r--runtime/doc/visual.txt2
-rw-r--r--runtime/doc/windows.txt2
-rw-r--r--runtime/doc/workshop.txt2
-rw-r--r--runtime/filetype.vim8
-rw-r--r--runtime/ftplugin/logtalk.dict362
-rw-r--r--runtime/ftplugin/logtalk.vim5
-rw-r--r--runtime/ftplugin/vim.vim28
-rw-r--r--runtime/ftplugin/wast.vim17
-rw-r--r--runtime/indent/logtalk.vim5
-rw-r--r--runtime/indent/wast.vim17
-rw-r--r--runtime/pack/dist/opt/cfilter/plugin/cfilter.vim43
-rw-r--r--runtime/syntax/debcontrol.vim4
-rw-r--r--runtime/syntax/debsources.vim6
-rw-r--r--runtime/syntax/logtalk.vim39
-rw-r--r--runtime/syntax/sh.vim77
-rw-r--r--runtime/syntax/vim.vim88
-rw-r--r--runtime/syntax/wast.vim84
-rw-r--r--runtime/tutor/tutor.it6
-rw-r--r--runtime/tutor/tutor.it.utf-88
-rw-r--r--src/Make_all.mak1
-rwxr-xr-xsrc/auto/configure3
-rw-r--r--src/buffer.c65
-rw-r--r--src/channel.c18
-rw-r--r--src/configure.ac3
-rw-r--r--src/dosinst.c7
-rw-r--r--src/edit.c56
-rw-r--r--src/eval.c31
-rw-r--r--src/evalfunc.c80
-rw-r--r--src/ex_cmds.c79
-rw-r--r--src/ex_cmds.h6
-rw-r--r--src/ex_docmd.c993
-rw-r--r--src/ex_getln.c816
-rw-r--r--src/feature.h4
-rw-r--r--src/fileio.c85
-rw-r--r--src/globals.h23
-rw-r--r--src/gui_beval.c16
-rw-r--r--src/gui_gtk_x11.c58
-rw-r--r--src/if_cscope.c7
-rw-r--r--src/if_lua.c14
-rw-r--r--src/if_perl.xs15
-rw-r--r--src/if_py_both.h87
-rw-r--r--src/if_ruby.c70
-rw-r--r--src/main.c4
-rw-r--r--src/mbyte.c20
-rw-r--r--src/memline.c69
-rw-r--r--src/misc1.c22
-rw-r--r--src/normal.c2
-rw-r--r--src/ops.c73
-rw-r--r--src/option.c10
-rw-r--r--src/os_amiga.c10
-rw-r--r--src/os_mswin.c6
-rw-r--r--src/os_unix.c130
-rw-r--r--src/os_unix.h19
-rw-r--r--src/os_win32.c106
-rw-r--r--src/os_win32.h1
-rw-r--r--src/osdef1.h.in4
-rw-r--r--src/proto/buffer.pro1
-rw-r--r--src/proto/eval.pro8
-rw-r--r--src/proto/ex_docmd.pro3
-rw-r--r--src/proto/gui_gtk_x11.pro2
-rw-r--r--src/proto/memline.pro2
-rw-r--r--src/proto/term.pro3
-rw-r--r--src/proto/window.pro1
-rw-r--r--src/quickfix.c1053
-rw-r--r--src/screen.c7
-rw-r--r--src/search.c7
-rw-r--r--src/term.c62
-rw-r--r--src/term.h12
-rw-r--r--src/terminal.c10
-rw-r--r--src/testdir/dumps/Test_incsearch_sort_01.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_01.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_02.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_03.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_04.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_05.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_06.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_07.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_08.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_substitute_09.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_vimgrep_01.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_vimgrep_02.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_vimgrep_03.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_vimgrep_04.dump9
-rw-r--r--src/testdir/dumps/Test_incsearch_vimgrep_05.dump9
-rw-r--r--src/testdir/runtest.vim1
-rw-r--r--src/testdir/test86.ok2
-rw-r--r--src/testdir/test87.ok2
-rw-r--r--src/testdir/test_alot.vim1
-rw-r--r--src/testdir/test_autocmd.vim25
-rw-r--r--src/testdir/test_backup.vim58
-rw-r--r--src/testdir/test_cscope.vim7
-rw-r--r--src/testdir/test_functions.vim27
-rw-r--r--src/testdir/test_help_tagjump.vim28
-rw-r--r--src/testdir/test_ins_complete.vim13
-rw-r--r--src/testdir/test_options.vim23
-rw-r--r--src/testdir/test_perl.vim17
-rw-r--r--src/testdir/test_profile.vim225
-rw-r--r--src/testdir/test_quickfix.vim47
-rw-r--r--src/testdir/test_ruby.vim13
-rw-r--r--src/testdir/test_search.vim278
-rw-r--r--src/testdir/test_stat.vim47
-rw-r--r--src/testdir/test_swap.vim39
-rw-r--r--src/testdir/test_tabpage.vim13
-rw-r--r--src/testdir/test_terminal.vim28
-rw-r--r--src/testdir/test_textobjects.vim17
-rw-r--r--src/testdir/test_window_id.vim20
-rw-r--r--src/undo.c9
-rw-r--r--src/version.c182
-rw-r--r--src/vim.h71
-rw-r--r--src/window.c49
170 files changed, 4710 insertions, 2068 deletions
diff --git a/README.md b/README.md
index bc59214..0ea8e4c 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
[![Coverage Status](https://coveralls.io/repos/vim/vim/badge.svg?branch=master&service=github)](https://coveralls.io/github/vim/vim?branch=master)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/o2qht2kjm02sgghk?svg=true)](https://ci.appveyor.com/project/chrisbra/vim)
[![Coverity Scan](https://scan.coverity.com/projects/241/badge.svg)](https://scan.coverity.com/projects/vim)
+[![Language Grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/vim/vim.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/vim/vim/context:cpp)
[![Debian CI](https://badges.debian.net/badges/debian/testing/vim/version.svg)](https://buildd.debian.org/vim)
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 8d1dca2..7b59130 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -661,7 +661,7 @@ DirChanged The working directory has changed in response
to the |:cd| or |:lcd| commands, or as a
result of the 'autochdir' option.
The pattern can be:
- "window" to trigger on `:lcd
+ "window" to trigger on `:lcd`
"global" to trigger on `:cd`
"auto" to trigger on 'autochdir'.
"drop" to trigger on editing a file
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 1ad2930..1670db6 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1447,7 +1447,7 @@ to the name of an external program for Vim to use for text formatting. The
program.
*format-formatexpr*
-The 'formatexpr' option can be set to a Vim Script function that performs
+The 'formatexpr' option can be set to a Vim script function that performs
reformatting of the buffer. This should usually happen in an |ftplugin|,
since formatting is highly dependent on the type of file. It makes
sense to use an |autoload| script, so the corresponding script is only loaded
@@ -1481,7 +1481,7 @@ text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim: >
You can then enable the formatting by executing: >
setlocal formatexpr=format#Format()
->
+
Note: this function explicitly returns non-zero when called from insert mode
(which basically means, text is inserted beyond the 'textwidth' limit). This
causes Vim to fall back to reformat the text by using the internal formatter.
diff --git a/runtime/doc/diff.txt b/runtime/doc/diff.txt
index 502fb49..d56aea7 100644
--- a/runtime/doc/diff.txt
+++ b/runtime/doc/diff.txt
@@ -384,12 +384,16 @@ Example (this does almost the same as 'diffexpr' being empty): >
endif
silent execute "!diff -a --binary " . opt . v:fname_in . " " . v:fname_new .
\ " > " . v:fname_out
+ redraw!
endfunction
The "-a" argument is used to force comparing the files as text, comparing as
binaries isn't useful. The "--binary" argument makes the files read in binary
mode, so that a CTRL-Z doesn't end the text on DOS.
+The `redraw!` command may not be needed, depending on whether executing a
+shell command shows something on the display or not.
+
*E810* *E97*
Vim will do a test if the diff output looks alright. If it doesn't, you will
get an error message. Possible causes:
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 2c9c114..2e5bf7f 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2111,7 +2111,7 @@ cursor({list}) Number move cursor to position in {list}
debugbreak({pid}) Number interrupt process being debugged
deepcopy({expr} [, {noref}]) any make a full copy of {expr}
delete({fname} [, {flags}]) Number delete the file or directory {fname}
-deletebufline({expr}, {first}[, {last}])
+deletebufline({expr}, {first} [, {last}])
Number delete lines from buffer {expr}
did_filetype() Number |TRUE| if FileType autocmd event used
diff_filler({lnum}) Number diff filler lines about {lnum}
@@ -2409,6 +2409,7 @@ submatch({nr} [, {list}]) String or List
specific match in ":s" or substitute()
substitute({expr}, {pat}, {sub}, {flags})
String all {pat} in {expr} replaced with {sub}
+swapinfo({fname}) Dict information about swap file {fname}
synID({lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
synIDattr({synID}, {what} [, {mode}])
String attribute {what} of syntax ID {synID}
@@ -2477,7 +2478,7 @@ tolower({expr}) String the String {expr} switched to lowercase
toupper({expr}) String the String {expr} switched to uppercase
tr({src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
to chars in {tostr}
-trim({text}[, {mask}]) String trim characters in {mask} from {text}
+trim({text} [, {mask}]) String trim characters in {mask} from {text}
trunc({expr}) Float truncate Float {expr}
type({name}) Number type of variable {name}
undofile({name}) String undo file name for {name}
@@ -2497,6 +2498,7 @@ win_screenpos({nr}) List get screen position of window {nr}
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr}
+winlayout([{tabnr}]) List layout of windows in tab {tabnr}
winline() Number window line of the cursor
winnr([{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes
@@ -3529,7 +3531,7 @@ delete({fname} [, {flags}]) *delete()*
To delete a line from the buffer use |:delete| or
|deletebufline()|.
-deletebufline({expr}, {first}[, {last}]) *deletebufline()*
+deletebufline({expr}, {first} [, {last}]) *deletebufline()*
Delete lines {first} to {last} (inclusive) from buffer {expr}.
If {last} is omitted then delete line {first} only.
On success 0 is returned, on failure 1 is returned.
@@ -4307,7 +4309,7 @@ getbufinfo([{dict}])
endfor
<
To get buffer-local options use: >
- getbufvar({bufnr}, '&')
+ getbufvar({bufnr}, '&option_name')
<
*getbufline()*
@@ -8000,6 +8002,24 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
|submatch()| returns. Example: >
:echo substitute(s, '%\(\x\x\)', {m -> '0x' . m[1]}, 'g')
+swapinfo({fname}) swapinfo()
+ The result is a dictionary, which holds information about the
+ swapfile {fname}. The available fields are:
+ version VIM version
+ user user name
+ host host name
+ fname original file name
+ pid PID of the VIM process that created the swap
+ file
+ mtime last modification time in seconds
+ inode Optional: INODE number of the file
+ dirty 1 if file was modified, 0 if not
+ In case of failure an "error" item is added with the reason:
+ Cannot open file: file not found or in accessible
+ Cannot read file: cannot read first block
+ Not a swap file: does not contain correct block ID
+ Magic number mismatch: Info in first block is invalid
+
synID({lnum}, {col}, {trans}) *synID()*
The result is a Number, which is the syntax ID at the position
{lnum} and {col} in the current window.
@@ -8591,9 +8611,8 @@ term_start({cmd}, {options}) *term_start()*
|job-options|. However, not all options can be used. These
are supported:
all timeout options
- "stoponexit"
- "callback", "out_cb", "err_cb"
- "exit_cb", "close_cb"
+ "stoponexit", "cwd", "env"
+ "callback", "out_cb", "err_cb", "exit_cb", "close_cb"
"in_io", "in_top", "in_bot", "in_name", "in_buf"
"out_io", "out_name", "out_buf", "out_modifiable", "out_msg"
"err_io", "err_name", "err_buf", "err_modifiable", "err_msg"
@@ -8837,7 +8856,7 @@ tr({src}, {fromstr}, {tostr}) *tr()*
echo tr("<blob>", "<>", "{}")
< returns "{blob}"
-trim({text}[, {mask}]) *trim()*
+trim({text} [, {mask}]) *trim()*
Return {text} as a String where any character in {mask} is
removed from the beginning and end of {text}.
If {mask} is not given, {mask} is all characters up to 0x20,
@@ -9089,6 +9108,35 @@ winheight({nr}) *winheight()*
Examples: >
:echo "The current window has " . winheight(0) . " lines."
<
+winlayout([{tabnr}]) *winlayout()*
+ The result is a nested List containing the layout of windows
+ in a tabpage.
+
+ Without {tabnr} use the current tabpage, otherwise the tabpage
+ with number {tabnr}. If the tabpage {tabnr} is not found,
+ returns an empty list.
+
+ For a leaf window, it returns:
+ ['leaf', {winid}]
+ For horizontally split windows, which form a column, it
+ returns:
+ ['col', [{nested list of windows}]]
+ For vertically split windows, which form a row, it returns:
+ ['row', [{nested list of windows}]]
+
+ Example: >
+ " Only one window in the tab page
+ :echo winlayout()
+ ['leaf', 1000]
+ " Two horizontally split windows
+ :echo winlayout()
+ ['col', [['leaf', 1000], ['leaf', 1001]]]
+ " Three horizontally split windows, with two
+ " vertically split windows in the middle window
+ :echo winlayout(2)
+ ['col', [['leaf', 1002], ['row', ['leaf', 1003],
+ ['leaf', 1001]]], ['leaf', 1000]]
+<
*winline()*
winline() The result is a Number, which is the screen line of the cursor
in the window. This is counting screen lines from the top of
diff --git a/runtime/doc/ft_rust.txt b/runtime/doc/ft_rust.txt
index b94e1f8..ff2e0ca 100644
--- a/runtime/doc/ft_rust.txt
+++ b/runtime/doc/ft_rust.txt
@@ -236,4 +236,4 @@ It also has a few other mappings:
Note: This binding is only available in MacVim.
==============================================================================
- vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
+ vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/if_perl.txt b/runtime/doc/if_perl.txt
index b82ee83..a4df06a 100644
--- a/runtime/doc/if_perl.txt
+++ b/runtime/doc/if_perl.txt
@@ -44,8 +44,9 @@ The Perl patches for Vim were made by:
Sven Verdoolaege <skimo@breughel.ufsia.ac.be>
Matt Gerassimof
-Perl for MS-Windows can be found at: http://www.perl.com/
-The ActiveState one should work.
+Perl for MS-Windows (and other platforms) can be found at:
+http://www.perl.org/ The ActiveState one should work, Strawberry Perl is a
+good alternative.
==============================================================================
3. Using the Perl interface *perl-using*
diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt
index a000482..13542de 100644
--- a/runtime/doc/intro.txt
+++ b/runtime/doc/intro.txt
@@ -595,9 +595,9 @@ Virtual Replace mode Virtual Replace mode is similar to Replace mode, but
If the 'showmode' option is on "-- VREPLACE --" is
shown at the bottom of the window.
-Insert Normal mode Entered when CTRL-O given in Insert mode. This is
- like Normal mode, but after executing one command Vim
- returns to Insert mode.
+Insert Normal mode Entered when CTRL-O is typed in Insert mode (see
+ |i_CTRL-O|). This is like Normal mode, but after
+ executing one command Vim returns to Insert mode.
If the 'showmode' option is on "-- (insert) --" is
shown at the bottom of the window.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 8645c47..2343d63 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1054,6 +1054,14 @@ A jump table for the options with a short description can be found at |Q_op|.
name, precede it with a backslash.
- To include a comma in a directory name precede it with a backslash.
- A directory name may end in an '/'.
+ - For Unix and Win32, if a directory ends in two path separators "//",
+ the swap file name will be built from the complete path to the file
+ with all path separators changed to percent '%' signs. This will
+ ensure file name uniqueness in the backup directory.
+ On Win32, it is also possible to end with "\\". However, When a
+ separating comma is following, you must use "//", since "\\" will
+ include the comma in the file name. Therefore it is recommended to
+ use '//', instead of '\\'.
- Environment variables are expanded |:set_env|.
- Careful with '\' characters, type one before a space, type two to
get one in the option (see |option-backslash|), for example: >
@@ -2680,12 +2688,14 @@ A jump table for the options with a short description can be found at |Q_op|.
- A directory starting with "./" (or ".\" for MS-DOS et al.) means to
put the swap file relative to where the edited file is. The leading
"." is replaced with the path name of the edited file.
- - For Unix and Win32, if a directory ends in two path separators "//"
- or "\\", the swap file name will be built from the complete path to
- the file with all path separators substituted to percent '%' signs.
- This will ensure file name uniqueness in the preserve directory.
- On Win32, when a separating comma is following, you must use "//",
- since "\\" will include the comma in the file name.
+ - For Unix and Win32, if a directory ends in two path separators "//",
+ the swap file name will be built from the complete path to the file
+ with all path separators substituted to percent '%' signs. This will
+ ensure file name uniqueness in the preserve directory.
+ On Win32, it is also possible to end with "\\". However, When a
+ separating comma is following, you must use "//", since "\\" will
+ include the comma in the file name. Therefore it is recommended to
+ use '//', instead of '\\'.
- Spaces after the comma are ignored, other spaces are considered part
of the directory name. To have a space at the start of a directory
name, precede it with a backslash.
@@ -4363,7 +4373,7 @@ A jump table for the options with a short description can be found at |Q_op|.
methods. Use 'imdisable' to disable XIM then.
You can set 'imactivatefunc' and 'imstatusfunc' to handle IME/XIM
- via external command if vim is not compiled with the |+xim|,
+ via external command if Vim is not compiled with the |+xim|,
|+multi_byte_ime| or |global-ime|.
*'imsearch'* *'ims'*
@@ -4470,6 +4480,7 @@ A jump table for the options with a short description can be found at |Q_op|.
so far, matches. The matched string is highlighted. If the pattern
is invalid or not found, nothing is shown. The screen will be updated
often, this is only useful on fast terminals.
+ Also applies to the `:s`, `:g` and `:v` commands.
Note that the match will be shown, but the cursor will return to its
original position when no match is found and when pressing <Esc>. You
still need to finish the search command with <Enter> to move the
@@ -4483,9 +4494,9 @@ A jump table for the options with a short description can be found at |Q_op|.
The highlighting can be set with the 'i' flag in 'highlight'.
When 'hlsearch' is on, all matched strings are highlighted too while
typing a search command. See also: 'hlsearch'.
- If you don't want turn 'hlsearch' on, but want to highlight all matches
- while searching, you can turn on and off 'hlsearch' with autocmd.
- Example: >
+ If you don't want to turn 'hlsearch' on, but want to highlight all
+ matches while searching, you can turn on and off 'hlsearch' with
+ autocmd. Example: >
augroup vimrc-incsearch-highlight
autocmd!
autocmd CmdlineEnter /,\? :set hlsearch
@@ -6640,7 +6651,8 @@ A jump table for the options with a short description can be found at |Q_op|.
tabpages all tab pages; without this only the current tab page
is restored, so that you can make a session for each
tab page separately
- terminal include terminal windows where the command can be restored
+ terminal include terminal windows where the command can be
+ restored
unix with Unix end-of-line format (single <NL>), even when
on Windows or DOS
winpos position of the whole Vim window
@@ -6676,7 +6688,7 @@ A jump table for the options with a short description can be found at |Q_op|.
Example with escaped space (Vim will do this when initializing the
option from $SHELL): >
:set shell=/bin/with\\\ space/sh
-< The resulting value of 'shell' is "/bin/with\ space/sh", two
+< The resulting value of 'shell' is "/bin/with\ space/sh", two
backslashes are consumed by `:set`.
Under MS-Windows, when the executable ends in ".com" it must be
@@ -7502,7 +7514,7 @@ A jump table for the options with a short description can be found at |Q_op|.
line is displayed. The current buffer and current window will be set
temporarily to that of the window (and buffer) whose statusline is
currently being drawn. The expression will evaluate in this context.
- The variable "actual_curbuf" is set to the 'bufnr()' number of the
+ The variable "g:actual_curbuf" is set to the `bufnr()` number of the
real current buffer.
The 'statusline' option will be evaluated in the |sandbox| if set from
diff --git a/runtime/doc/os_qnx.txt b/runtime/doc/os_qnx.txt
index 4cbc7ea..a252b34 100644
--- a/runtime/doc/os_qnx.txt
+++ b/runtime/doc/os_qnx.txt
@@ -135,4 +135,4 @@ Todo:
- Replace usage of fork() with spawn() when launching external
programs.
- vim:tw=78:sw=4:ts=8:noet:ts=8:ft=help:norl:
+ vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/print.txt b/runtime/doc/print.txt
index 07a9503..2f5a1a9 100644
--- a/runtime/doc/print.txt
+++ b/runtime/doc/print.txt
@@ -46,6 +46,8 @@ Note: If you have problems printing with |:hardcopy|, an alternative is to use
'printexpr' through |v:cmdarg|. Otherwise [arguments]
is ignored. 'printoptions' can be used to specify
paper size, duplex, etc.
+ Note: If you want PDF, there are tools such as
+ "ps2pdf" that can convert the PostScript to PDF.
:[range]ha[rdcopy][!] >{filename}
As above, but write the resulting PostScript in file
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 95bcfa0..211fe96 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -46,7 +46,7 @@ compiler (see |errorformat| below).
*quickfix-ID*
Each quickfix list has a unique identifier called the quickfix ID and this
-number will not change within a Vim session. The getqflist() function can be
+number will not change within a Vim session. The |getqflist()| function can be
used to get the identifier assigned to a list. There is also a quickfix list
number which may change whenever more than ten lists are added to a quickfix
stack.
@@ -68,7 +68,7 @@ the location list is destroyed.
Every quickfix and location list has a read-only changedtick variable that
tracks the total number of changes made to the list. Every time the quickfix
list is modified, this count is incremented. This can be used to perform an
-action only when the list has changed. The getqflist() and getloclist()
+action only when the list has changed. The |getqflist()| and |getloclist()|
functions can be used to query the current value of changedtick. You cannot
change the changedtick variable.
@@ -602,7 +602,7 @@ present). Examples: >
echo getloclist(2, {'winid' : 1}).winid
<
*getqflist-examples*
-The getqflist() and getloclist() functions can be used to get the various
+The |getqflist()| and |getloclist()| functions can be used to get the various
attributes of a quickfix and location list respectively. Some examples for
using these functions are below:
>
@@ -659,7 +659,7 @@ using these functions are below:
:echo getloclist(3, {'winid' : 0}).winid
<
*setqflist-examples*
-The setqflist() and setloclist() functions can be used to set the various
+The |setqflist()| and |setloclist()| functions can be used to set the various
attributes of a quickfix and location list respectively. Some examples for
using these functions are below:
>
@@ -1551,6 +1551,22 @@ The backslashes before the pipe character are required to avoid it to be
recognized as a command separator. The backslash before each space is
required for the set command.
+ *cfilter-plugin*
+If you have too many matching messages, you can use the cfilter plugin to
+reduce the number of entries. Load the plugin with: >
+ packadd cfilter
+
+Then you can use these command: >
+ :Cfilter[!] {pat}
+ :Lfilter[!] {pat}
+
+:Cfilter creates a new quickfix list from entries matching {pat} in the
+current quickfix list. Both the file name and the text of the entries are
+matched against {pat}. If ! is supplied, then entries not matching {pat} are
+used.
+
+:Lfilter does the same as :Cfilter but operates on the current location list.
+
=============================================================================
8. The directory stack *quickfix-directory-stack*
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 3c2d868..b060c45 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -487,7 +487,8 @@ a slash. Thus "-R" means recovery and "-/R" readonly.
When {vimrc} is equal to "DEFAULTS" (all uppercase), this has
the same effect as "NONE", but the |defaults.vim| script is
- loaded, which will also set 'nocompatible'.
+ loaded, which will also set 'nocompatible'. Also see
+ |--clean|.
Using the "-u" argument with another argument than DEFAULTS
has the side effect that the 'compatible' option will be on by
@@ -520,7 +521,7 @@ a slash. Thus "-R" means recovery and "-/R" readonly.
'nocompatible': use Vim defaults
- no |gvimrc| script is loaded
- no viminfo file is read or written
- - the home directory is excluded from 'runtimepath'
+
*-x*
-x Use encryption to read/write files. Will prompt for a key,
which is then stored in the 'key' option. All writes will
diff --git a/runtime/doc/tabpage.txt b/runtime/doc/tabpage.txt
index a80d7c3..1d3365c 100644
--- a/runtime/doc/tabpage.txt
+++ b/runtime/doc/tabpage.txt
@@ -241,8 +241,10 @@ REORDERING TAB PAGES:
:tabm[ove] [N] *:tabm* *:tabmove*
:[N]tabm[ove]
Move the current tab page to after tab page N. Use zero to
- make the current tab page the first one. Without N the tab
- page is made the last one. >
+ make the current tab page the first one. N is counted before
+ the move, thus if the second tab is the current one,
+ `:tabmove 1`` and `:tabmove 2` have no effect.
+ Without N the tab page is made the last one. >
:.tabmove " do nothing
:-tabmove " move the tab page to the left
:+tabmove " move the tab page to the right
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 135c390..ed262d4 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -991,13 +991,17 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
't_RF' term.txt /*'t_RF'*
't_RI' term.txt /*'t_RI'*
't_RS' term.txt /*'t_RS'*
+'t_RT' term.txt /*'t_RT'*
't_RV' term.txt /*'t_RV'*
+'t_Ri' term.txt /*'t_Ri'*
't_SC' term.txt /*'t_SC'*
't_SH' term.txt /*'t_SH'*
't_SI' term.txt /*'t_SI'*
't_SR' term.txt /*'t_SR'*
+'t_ST' term.txt /*'t_ST'*
't_Sb' term.txt /*'t_Sb'*
't_Sf' term.txt /*'t_Sf'*
+'t_Si' term.txt /*'t_Si'*
't_Te' term.txt /*'t_Te'*
't_Ts' term.txt /*'t_Ts'*
't_VS' term.txt /*'t_VS'*
@@ -8744,13 +8748,17 @@ t_RC term.txt /*t_RC*
t_RF term.txt /*t_RF*
t_RI term.txt /*t_RI*
t_RS term.txt /*t_RS*
+t_RT term.txt /*t_RT*
t_RV term.txt /*t_RV*
+t_Ri term.txt /*t_Ri*
t_SC term.txt /*t_SC*
t_SH term.txt /*t_SH*
t_SI term.txt /*t_SI*
t_SR term.txt /*t_SR*
+t_ST term.txt /*t_ST*
t_Sb term.txt /*t_Sb*
t_Sf term.txt /*t_Sf*
+t_Si term.txt /*t_Si*
t_Te term.txt /*t_Te*
t_Ts term.txt /*t_Ts*
t_VS term.txt /*t_VS*
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt
index 77cd933..4ade4a1 100644
--- a/runtime/doc/term.txt
+++ b/runtime/doc/term.txt
@@ -352,6 +352,10 @@ Added by Vim (there are no standard codes for these):
t_SH set cursor shape *t_SH* *'t_SH'*
t_RC request terminal cursor blinking *t_RC* *'t_RC'*
t_RS request terminal cursor style *t_RS* *'t_RS'*
+ t_ST save window title to stack *t_ST* *'t_ST'*
+ t_RT restore window title from stack *t_RT* *'t_RT'*
+ t_Si save icon text to stack *t_Si* *'t_Si'*
+ t_Ri restore icon text from stack *t_Ri* *'t_Ri'*
Some codes have a start, middle and end part. The start and end are defined
by the termcap option, the middle part is text.
diff --git a/runtime/doc/terminal.txt b/runtime/doc/terminal.txt
index f9fc0ee..7bdef48 100644
--- a/runtime/doc/terminal.txt
+++ b/runtime/doc/terminal.txt
@@ -635,7 +635,7 @@ Starting ~
Load the plugin with this command: >
packadd termdebug
< *:Termdebug*
-To start debugging use `:Termdebug` or `:TermdebugCommand`` followed by the
+To start debugging use `:Termdebug` or `:TermdebugCommand` followed by the
command name, for example: >
:Termdebug vim
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 6929417..4b1739b 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -34,7 +34,7 @@ entered there will not be repeated below, unless there is extra information.
The #1234 numbers refer to an issue or pull request on github. To see it in a
browser use: https://github.com/vim/vim/issues/1234
-
+(replace 1234 with the issue/pull number)
*known-bugs*
-------------------- Known bugs and current work -----------------------
@@ -74,13 +74,40 @@ Terminal emulator window:
- When 'encoding' is not utf-8, or the job is using another encoding, setup
conversions.
+Patch to support ":tag <tagkind> <tagname". (emmrk, 2018 May 7, #2871)
+
+Patch to parse ":line" in tags file and use it for search. (Daniel Hahler,
+#2546) Fixes #1057. Missing a test.
+
+Problem with quickfix giving E42 when filtering the error list.
+(Nobuhiro Takasaki, 2018 Aug 1, #3270)
+Patch with test from Yegappan, Aug 2.
+
+Patch to add variable name after "scope add". (Eddie Lebow, 2018 Feb 7, #2620)
+Maybe not needed?
+
+Patch in issue 3268, fix suggestion window appearing on wrong screen.
+Also from Ken Takata, 2018 Aug 2.
+
+Patch for Lua support. (Kazunobu Kuriyama, 2018 May 26)
+
+Patch to use NGETTEXT() in many more places. (Sergey Alyoshin, 2018 May 25)
+Updated patch May 27.
+
+Patch to add winlayout() function. (Yegappan Lakshmanan, 2018 Jan 4)
+
+Patch to fix profiling condition lines. (Ozaki Kiichi,, 2017 Dec 26, #2499)
+
+Issue #686: apply 'F' in 'shortmess' to more messages. Also #3221.
+Patch on #3221 from Christian. Does it work now?
+
+Patch to include a cfilter plugin to filter quickfix/location lists.
+(Yegappan Lakshmanan, 2018 May 12)
+
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?
-Patches for Python: #3162, #3263 (Ozaki Kiichi)
- Needs update.
-
Crash when mixing matchadd and substitute()? (Max Christian Pohle, 2018 May
13, #2910) Can't reproduce?
@@ -96,16 +123,18 @@ Include part of #3242?
Inlcude Chinese-Taiwan translations. (bystar, #3261)
+Completion mixes results from the current buffer with tags and other files.
+Happens when typing CTRL-N while still search for results. E.g., type "b_" in
+terminal.c and then CTRL-N twice.
+Should do current file first and not split it up when more results are found.
+(Also #1890)
+
Using mouse for inputlist() doesn't work after patch 8.0.1756. (Dominique
Pelle, 2018 Jul 22, #3239) Also see 8.0.0722. Check both console and GUI.
More warnings from static analysis:
https://lgtm.com/projects/g/vim/vim/alerts/?mode=list
-When handle_drop() is called while the updating_screen is true, it fails
-completely. Should store the file list and use it when updating_screen is set
-to false in reset_updating_screen().
-
Pasting foo} causes Vim to behave weird. (John Little, 2018 Jun 17)
Related to bracketed paste. I cannot reproduce it.
@@ -152,11 +181,17 @@ Memory leak in test_terminal:
gethostbyname() is old, use getaddrinfo() if available. (#3227)
+Delete the src/main.aap file?
+
matchaddpos() gets slow with many matches. Proposal by Rick Howe, 2018 Jul
19.
-Patch to make mode() return something different for Normal mode when coming
-from Insert mode with CTRL-O. (#3000) Useful for positioning the cursor.
+home_replace() uses $HOME instead of "homedir". (Cesar Martins, 2018 Aug 9)
+
+Adjust windows installer explanation of behavior. (scootergrisen, #3310)
+
+Set g:actual_curbuf when evaluating 'statusline', not just with an expression.
+(Daniel Hahler, 2018 Aug 8, #3299)
Script generated by :mksession does not work well if there are windows with
modified buffers
@@ -165,13 +200,6 @@ modified buffers
skip "badd fname" if "fname" is already in the buffer list
remove remark about unloading buffers from documentation
-Patch to make :help work for tags with a ?. (Hirohito Higashi, 2018 May 28)
-
-Patch to adjust to DPI setting for GTK. (Roel van de Kraats, 2017 Nov 20,
-#2357)
-
-Patch to fix window size when using VTP. (Nobuhiro Takasaki, #3164)
-
Compiler warnings (geeknik, 2017 Oct 26):
- signed integer overflow in do_sub() (#2249)
- signed integer overflow in get_address() (#2248)
@@ -181,8 +209,6 @@ Compiler warnings (geeknik, 2017 Oct 26):
Win32 console: <F11> and <F12> typed in Insert mode don't result in normal
characters. (#3246)
-Patch for more quickfix refactoring. (Yegappan Lakshmanan, #2950)
-
Tests failing for "make testgui" with GTK:
- Test_setbufvar_options()
- Test_exit_callback_interval()
@@ -192,17 +218,6 @@ is cleared, to avoid going back to the list of errors buffer (would have two
windows with it). Can we just remove the jump list entries for the quickfix
buffer?
-Patch to stack and pop the window title and icon. (IWAMOTO Kouichi, 2018 Jun
-22, #3059)
-8 For xterm need to open a connection to the X server to get the window
- title, which can be slow. Can also get the title with "<Esc>[21t", no
- need to use X11 calls. This returns "<Esc>]l{title}<Esc>\".
-Using title stack probably works better.
-
-When a function is defined in the sandbox (with :function or as a lambda)
-always execute it in the sandbox. (#3182)
-Remove "safe" argument from call_vim_function(), it's always FALSE.
-
Make balloon_show() work outside of 'balloonexpr'? Users expect it to work:
#2948. (related to #1512?)
On Win32 it stops showing, because showState is already ShS_SHOWING.
@@ -224,8 +239,6 @@ used for git temp files.
Cursor in wrong position when line wraps. (#2540)
-Patch for Lua support. (Kazunobu Kuriyama, 2018 May 26)
-
Make {skip} argument of searchpair() consistent with other places where we
pass an expression to evaluate. Allow passing zero for "never skip".
@@ -235,8 +248,6 @@ script or function.
Universal solution to detect if t_RS is working, using cursor position.
Koichi Iwamoto, #2126
-Patch to fix profiling condition lines. (Ozaki Kiichi,, 2017 Dec 26, #2499)
-
When using a menu item while the "more" prompt is displayed doesn't work well.
E.g. after using help->version. Have a key that ends the "more" prompt and
does nothing otherwise?
@@ -270,9 +281,6 @@ How to test that it works well for all Vim users?
Alternative manpager.vim. (Enno, 2018 Jan 5, #2529)
-Patch to use NGETTEXT() in many more places. (Sergey Alyoshin, 2018 May 25)
-Updated ptach May 27.
-
Does setting 'cursorline' cause syntax highlighting to slow down? Perhaps is
mess up the cache? (Mike Lee Williams, 2018 Jan 27, #2539)
Also: 'foldtext' is evaluated too often. (Daniel Hahler, #2773)
@@ -306,18 +314,14 @@ confusing error message. (Wang Shidong, 2018 Jan 2, #2519)
Add the debug command line history to viminfo.
-Issue #686: apply 'F' in 'shortmess' to more messages. Also #3221.
-
Avoid that "sign unplace id" does a redraw right away, esp. when there is a
sequence of these commands. (Andy Stewart, 2018 Mar 16)
ch_sendraw() with long string does not try to read in between, which may cause
a deadlock if the reading side is waiting for the write to finish. (Nate
Bosch, 2018 Jan 13, #2548)
-Perhaps just make chunks of 1024 bytes?
-
-Patch to include a cfilter plugin to filter quickfix/location lists.
-(Yegappan Lakshmanan, 2018 May 12)
+Perhaps just make chunks of 1024 bytes? Make the write non-blocking?
+Also a problem on MS-Windows: #2828.
Add Makefiles to the runtime/spell directory tree, since nobody uses Aap.
Will have to explain the manual steps (downloading the .aff and .dic files,
@@ -337,8 +341,6 @@ With foldmethod=syntax and nofoldenable comment highlighting isn't removed.
Using 'wildignore' also applies to literally entered file name. Also with
:drop (remote commands).
-Patch to support ":tag <tagkind> <tagname". (emmrk, 2018 May 7, #2871)
-
Inserting a line in a CompleteDone autocommand may confuse undo. (micbou,
2018 Jun 18, #3027)
@@ -379,23 +381,21 @@ crash when removing an element while inside map(). (Nikolai Pavlov, 2018 Feb
When 'virtualedit' is "all" and 'cursorcolumn' is set, the wrong column may be
highlighted. (van-de-bugger, 2018 Jan 23, #2576)
-Patch to parse ":line" in tags file and use it for search. (Daniel Hahler,
-#2546) Fixes #1057. Missing a test.
-
":file" does not show anything when 'shortmess' contains 'F'. (#3070)
-Patch to add winlayout() function. (Yegappan Lakshmanan, 2018 Jan 4)
-
No profile information for function that executes ":quit". (Daniel Hahler,
2017 Dec 26, #2501)
+A function on a dictionary is not profiled. (ZyX, 2010 Dec 25)
+
+A function defined locally and lambda's are not easily recognized.
+Mention where they were defined somewhere.
+
Get a "No Name" buffer when 'hidden' is set and opening a new window from the
quickfix list. (bfrg, 2018 Jan 22, #2574)
CTRL-X on zero gets stuck on 0xfffffffffffffffe. (Hengyang Zhao, #2746)
-A function on a dictionary is not profiled. (ZyX, 2010 Dec 25)
-
Invalid range error when using BufWinLeave for closing terminal.
(Gabriel Barta, 2017 Nov 15, #2339)
@@ -406,8 +406,8 @@ Olaf Dabrunz is working on this. (10 Jan 2016)
9 Instead invoking an external diff program, use builtin code. One can be
found here: http://www.ioplex.com/~miallen/libmba/dl/src/diff.c
It's complicated and badly documented.
-Alternative: use the xdiff library. Patch from Christian Brabandt, 2018 Mar
-20, #2732)
+Alternative: use the xdiff library. Unfinished Patch from Christian Brabandt,
+2018 Mar 20, #2732)
ml_get errors with buggy script. (Dominique, 2017 Apr 30)
@@ -452,9 +452,6 @@ always nested.
matchit hasn't been maintained for a long time. #955.
-Patch to add variable name after "scope add". (Eddie Lebow, 2018 Feb 7, #2620)
-Maybe not needed?
-
Problem with 'delcombine'. (agguser, 2017 Nov 10, #2313)
MS-Windows: buffer completion doesn't work when using backslash (or slash)
@@ -556,12 +553,6 @@ that optiona? (Bjorn Linse, 2017 Aug 5)
Cindent: returning a structure has more indent for the second item.
(Sam Pagenkopf, 2017 Sep 14, #2090)
-Completion mixes results from the current buffer with tags and other files.
-Happens when typing CTRL-N while still search for results. E.g., type "b_" in
-terminal.c and then CTRL-N twice.
-Should do current file first and not split it up when more results are found.
-(Also #1890)
-
Patch from Christian Brabandt to preserve upper case marks when wiping out a
buffer. (2013 Dec 9)
Also fixes #2166?
@@ -1279,12 +1270,6 @@ Syntax highlighting slow (hangs) in SASS file. (Niek Bosch, 2013 Aug 21)
Adding "~" to 'cdpath' doesn't work for completion? (Davido, 2013 Aug 19)
-Should be easy to highlight all matches with 'incsearch'. Idea by Itchyny,
-2015 Feb 6.
-
-Wrong scrolling when using incsearch. Patch by Christian Brabandt, 2014 Dec 4.
-Is this a good solution?
-
Patch: Let rare word highlighting overrule good word highlighting.
(Jakson A. Aquino, 2010 Jul 30, again 2011 Jul 2)
@@ -1302,8 +1287,6 @@ Remark from Roland Eggner: does it cause crashes? (2014 Dec 12)
Updated patch by Roland Eggner, Dec 16
Updated patch from Charles, 2016 Jul 2
-Patch to open folds for 'incsearch'. (Christian Brabandt, 2015 Jan 6)
-
Patch for building a 32bit Vim with 64bit MingW compiler.
(Michael Soyka, 2014 Oct 15)
@@ -1874,13 +1857,6 @@ Ruby: ":ruby print $buffer.number" returns zero.
setpos() does not restore cursor position after :normal. (Tyru, 2010 Aug 11)
-7 The 'directory' option supports changing path separators to "%" to make
- file names unique, also support this for 'backupdir'. (Mikolaj Machowski)
- Patch by Christian Brabandt, 2010 Oct 21.
- Is this an update: related to: #179
- https://github.com/chrisbra/vim-mq-patches/blob/master/backupdir
- Fixed patch 2017 Jul 1.
-
With "tw=55 fo+=a" typing space before ) doesn't work well. (Scott Mcdermott,
2010 Oct 24)
@@ -1976,9 +1952,6 @@ Patch to support :undo absolute jump to file save number. (Christian Brabandt,
Patch to use 'foldnestmax' also for "marker" foldmethod. (Arnaud Lacombe, 2011
Jan 7)
-Bug with 'incsearch' going to wrong line. (Wolfram Kresse, 2009 Aug 17)
-Only with "vim -u NONE".
-
Problem with editing file in binary mode. (Ingo Krabbe, 2009 Oct 8)
With 'wildmode' set to "longest:full,full" and pressing Tab once the first
@@ -3454,8 +3427,6 @@ Macintosh:
'magic' in history. (Margo)
9 optwin.vim: Restoring a mapping for <Space> or <CR> is not correct for
":noremap". Add "mapcmd({string}, {mode})? Use code from ":mkexrc".
-9 incsearch is incorrect for "/that/<Return>/this/;//" (last search pattern
- isn't updated).
9 term_console is used before it is set (msdos, Amiga).
9 Get out-of-memory for ":g/^/,$s//@/" on 1000 lines, this is not handled
correctly. Get many error messages while redrawing the screen, which
@@ -5231,16 +5202,22 @@ Mappings and Abbreviations:
Incsearch:
-- Add a limit to the number of lines that are searched for 'incsearch'?
+- Wrong scrolling when using incsearch. Patch by Christian Brabandt, 2014
+ Dec 4. Is this a good solution?
+- Temporarily open folds to show where the search ends up. Restore the
+ folds when going to another line.
+ Patch to open folds for 'incsearch'. (Christian Brabandt, 2015 Jan 6)
+- Bug with 'incsearch' going to wrong line. (Wolfram Kresse, 2009 Aug 17)
+ Only with "vim -u NONE".
- When no match is found and the user types more, the screen is redrawn
anyway. Could skip that. Esp. if the line wraps and the text is scrolled
up every time.
-- Temporarily open folds to show where the search ends up. Restore the
- folds when going to another line.
- When incsearch used and hitting return, no need to search again in many
cases, saves a lot of time in big files. (Slootman wants to work on this?)
When not using special characters, can continue search from the last match
(or not at all, when there was no match). See oldmail/webb/in.872.
+9 incsearch is incorrect for "/that/<Return>/this/;//" (last search pattern
+ isn't updated).
Searching:
@@ -6154,5 +6131,5 @@ Far future and "big" extensions:
are reflected in each Vim immediately. Could work with local files but
also over the internet. See http://www.codingmonkeys.de/subethaedit/.
-vim:tw=78:sw=4:sts=4:ts=8:ft=help:norl:
+vim:tw=78:sw=4:sts=4:ts=8:noet:ft=help:norl:
vim: set fo+=n :
diff --git a/runtime/doc/uganda.txt b/runtime/doc/uganda.txt
index befb9f3..47ba3b0 100644
--- a/runtime/doc/uganda.txt
+++ b/runtime/doc/uganda.txt
@@ -285,4 +285,4 @@ Address to send checks to:
This address is expected to be valid for a long time.
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/undo.txt b/runtime/doc/undo.txt
index d271222..2ada2a6 100644
--- a/runtime/doc/undo.txt
+++ b/runtime/doc/undo.txt
@@ -403,4 +403,4 @@ if it is not what you want do 'u.'. This will remove the contents of the
first put, and repeat the put command for the second register. Repeat the
'u.' until you got what you want.
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_01.txt b/runtime/doc/usr_01.txt
index 040bcd9..f7abd9c 100644
--- a/runtime/doc/usr_01.txt
+++ b/runtime/doc/usr_01.txt
@@ -189,4 +189,4 @@ donate part of the profit to help AIDS victims in Uganda. See |iccf|.
Next chapter: |usr_02.txt| The first steps in Vim
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_02.txt b/runtime/doc/usr_02.txt
index 2f976ba..b9e968e 100644
--- a/runtime/doc/usr_02.txt
+++ b/runtime/doc/usr_02.txt
@@ -698,4 +698,4 @@ Summary: *help-summary* >
Next chapter: |usr_03.txt| Moving around
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_03.txt b/runtime/doc/usr_03.txt
index ba51aa2..5c204f0 100644
--- a/runtime/doc/usr_03.txt
+++ b/runtime/doc/usr_03.txt
@@ -654,4 +654,4 @@ You will notice a few special marks. These include:
Next chapter: |usr_04.txt| Making small changes
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_04.txt b/runtime/doc/usr_04.txt
index 1b4f579..236f190 100644
--- a/runtime/doc/usr_04.txt
+++ b/runtime/doc/usr_04.txt
@@ -511,4 +511,4 @@ else:
Next chapter: |usr_05.txt| Set your settings
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_05.txt b/runtime/doc/usr_05.txt
index e2424d6..a77f90b 100644
--- a/runtime/doc/usr_05.txt
+++ b/runtime/doc/usr_05.txt
@@ -664,4 +664,4 @@ This does mean there is less room to edit text, thus it's a compromise.
Next chapter: |usr_06.txt| Using syntax highlighting
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_06.txt b/runtime/doc/usr_06.txt
index e2750ae..e52d110 100644
--- a/runtime/doc/usr_06.txt
+++ b/runtime/doc/usr_06.txt
@@ -277,4 +277,4 @@ others look at the colored text.
Next chapter: |usr_07.txt| Editing more than one file
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_07.txt b/runtime/doc/usr_07.txt
index a163006..7c30a92 100644
--- a/runtime/doc/usr_07.txt
+++ b/runtime/doc/usr_07.txt
@@ -476,4 +476,4 @@ This protects you from accidentally overwriting another file.
Next chapter: |usr_08.txt| Splitting windows
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_08.txt b/runtime/doc/usr_08.txt
index 5253856..1f8776a 100644
--- a/runtime/doc/usr_08.txt
+++ b/runtime/doc/usr_08.txt
@@ -598,4 +598,4 @@ For more information about tab pages see |tab-page|.
Next chapter: |usr_09.txt| Using the GUI
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_09.txt b/runtime/doc/usr_09.txt
index 1bc7aff..a6f068d 100644
--- a/runtime/doc/usr_09.txt
+++ b/runtime/doc/usr_09.txt
@@ -287,4 +287,4 @@ You can tune the way Select mode works with the 'selectmode' option.
Next chapter: |usr_10.txt| Making big changes
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_10.txt b/runtime/doc/usr_10.txt
index 46f7677..d551d11 100644
--- a/runtime/doc/usr_10.txt
+++ b/runtime/doc/usr_10.txt
@@ -821,4 +821,4 @@ has written. To tell Vim to redraw the screen: >
Next chapter: |usr_11.txt| Recovering from a crash
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_11.txt b/runtime/doc/usr_11.txt
index 13c08f9..727228c 100644
--- a/runtime/doc/usr_11.txt
+++ b/runtime/doc/usr_11.txt
@@ -304,4 +304,4 @@ For remarks about encryption and the swap file, see |:recover-crypt|.
Next chapter: |usr_12.txt| Clever tricks
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_12.txt b/runtime/doc/usr_12.txt
index 13401b1..6da0830 100644
--- a/runtime/doc/usr_12.txt
+++ b/runtime/doc/usr_12.txt
@@ -355,4 +355,4 @@ matches and where they are.
Next chapter: |usr_20.txt| Typing command-line commands quickly
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_20.txt b/runtime/doc/usr_20.txt
index afeb713..53c4b08 100644
--- a/runtime/doc/usr_20.txt
+++ b/runtime/doc/usr_20.txt
@@ -381,4 +381,4 @@ there can be only one.
Next chapter: |usr_21.txt| Go away and come back
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_21.txt b/runtime/doc/usr_21.txt
index 40388ee..513dad0 100644
--- a/runtime/doc/usr_21.txt
+++ b/runtime/doc/usr_21.txt
@@ -496,4 +496,4 @@ For more details see |modeline|.
Next chapter: |usr_22.txt| Finding the file to edit
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_22.txt b/runtime/doc/usr_22.txt
index 1720997..06ab022 100644
--- a/runtime/doc/usr_22.txt
+++ b/runtime/doc/usr_22.txt
@@ -397,4 +397,4 @@ can't be editing nothing!
Next chapter: |usr_23.txt| Editing other files
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_23.txt b/runtime/doc/usr_23.txt
index 049ca20..c09e5b9 100644
--- a/runtime/doc/usr_23.txt
+++ b/runtime/doc/usr_23.txt
@@ -340,4 +340,4 @@ decompression. You might need to install the programs first.
Next chapter: |usr_24.txt| Inserting quickly
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_24.txt b/runtime/doc/usr_24.txt
index a5e3344..625e9cb 100644
--- a/runtime/doc/usr_24.txt
+++ b/runtime/doc/usr_24.txt
@@ -603,4 +603,4 @@ This deletes up to the third word into register g.
Next chapter: |usr_25.txt| Editing formatted text
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_25.txt b/runtime/doc/usr_25.txt
index f5be3e0..7f65a85 100644
--- a/runtime/doc/usr_25.txt
+++ b/runtime/doc/usr_25.txt
@@ -579,4 +579,4 @@ The "gR" command uses Virtual Replace mode. This preserves the layout:
Next chapter: |usr_26.txt| Repeating
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_26.txt b/runtime/doc/usr_26.txt
index f3afe9b..8cf5aeb 100644
--- a/runtime/doc/usr_26.txt
+++ b/runtime/doc/usr_26.txt
@@ -218,4 +218,4 @@ start all over, use the "-W" argument. It overwrites any existing file.
Next chapter: |usr_27.txt| Search commands and patterns
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_27.txt b/runtime/doc/usr_27.txt
index 7098c07..2e6ae72 100644
--- a/runtime/doc/usr_27.txt
+++ b/runtime/doc/usr_27.txt
@@ -560,4 +560,4 @@ and "\w" for "[0-9A-Za-z_]".
Next chapter: |usr_28.txt| Folding
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_28.txt b/runtime/doc/usr_28.txt
index e2565b0..9e18c5c 100644
--- a/runtime/doc/usr_28.txt
+++ b/runtime/doc/usr_28.txt
@@ -423,4 +423,4 @@ the defined folds. Then you can delete or add folds manually.
Next chapter: |usr_29.txt| Moving through programs
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_29.txt b/runtime/doc/usr_29.txt
index 996046e..a8ad295 100644
--- a/runtime/doc/usr_29.txt
+++ b/runtime/doc/usr_29.txt
@@ -608,4 +608,4 @@ for the identifier. Example (cursor on "idx"):
Next chapter: |usr_30.txt| Editing programs
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_30.txt b/runtime/doc/usr_30.txt
index fa39dbf..79fcf7b 100644
--- a/runtime/doc/usr_30.txt
+++ b/runtime/doc/usr_30.txt
@@ -640,4 +640,4 @@ For more details see |format-comments|.
Next chapter: |usr_31.txt| Exploiting the GUI
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_31.txt b/runtime/doc/usr_31.txt
index 13de489..ac561a0 100644
--- a/runtime/doc/usr_31.txt
+++ b/runtime/doc/usr_31.txt
@@ -269,4 +269,4 @@ another font size, for example.
Next chapter: |usr_32.txt| The undo tree
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_32.txt b/runtime/doc/usr_32.txt
index 9e48d53..7c043a1 100644
--- a/runtime/doc/usr_32.txt
+++ b/runtime/doc/usr_32.txt
@@ -177,4 +177,4 @@ use the |undotree()| function. To see what it returns: >
Next chapter: |usr_40.txt| Make new commands
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_40.txt b/runtime/doc/usr_40.txt
index 151c4e6..572f684 100644
--- a/runtime/doc/usr_40.txt
+++ b/runtime/doc/usr_40.txt
@@ -654,4 +654,4 @@ To set it back to the normal behavior, make 'eventignore' empty: >
Next chapter: |usr_41.txt| Write a Vim script
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index f891f44..cf34363 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -2592,4 +2592,4 @@ It's good if you add a line to allow automatic updating. See |glvs-plugins|.
Next chapter: |usr_42.txt| Add new menus
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_42.txt b/runtime/doc/usr_42.txt
index 1e187e9..4648361 100644
--- a/runtime/doc/usr_42.txt
+++ b/runtime/doc/usr_42.txt
@@ -362,4 +362,4 @@ is...
Next chapter: |usr_43.txt| Using filetypes
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_43.txt b/runtime/doc/usr_43.txt
index 331f5b8..11647f6 100644
--- a/runtime/doc/usr_43.txt
+++ b/runtime/doc/usr_43.txt
@@ -176,4 +176,4 @@ and sources a script or executes a function to check the contents of the file.
Next chapter: |usr_44.txt| Your own syntax highlighted
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_44.txt b/runtime/doc/usr_44.txt
index b6f37e2..e557ca2 100644
--- a/runtime/doc/usr_44.txt
+++ b/runtime/doc/usr_44.txt
@@ -716,4 +716,4 @@ up scrolling backwards and CTRL-L.
Next chapter: |usr_45.txt| Select your language
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_45.txt b/runtime/doc/usr_45.txt
index e7844a8..3830eab 100644
--- a/runtime/doc/usr_45.txt
+++ b/runtime/doc/usr_45.txt
@@ -416,4 +416,4 @@ Don't type the spaces. See |i_CTRL-V_digit| for the details.
Next chapter: |usr_90.txt| Installing Vim
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_90.txt b/runtime/doc/usr_90.txt
index 5ecba60..a5b4292 100644
--- a/runtime/doc/usr_90.txt
+++ b/runtime/doc/usr_90.txt
@@ -495,4 +495,4 @@ files that you created. You might want to keep that.
Table of contents: |usr_toc.txt|
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/usr_toc.txt b/runtime/doc/usr_toc.txt
index 6a6543d..9247ba0 100644
--- a/runtime/doc/usr_toc.txt
+++ b/runtime/doc/usr_toc.txt
@@ -352,4 +352,4 @@ Before you can use Vim.
==============================================================================
-Copyright: see |manual-copyright| vim:tw=78:ts=8:ft=help:norl:
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 48d63cd..fce8ba1 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -729,4 +729,4 @@ LessInitFunc in your vimrc, for example: >
endfunc
<
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/version4.txt b/runtime/doc/version4.txt
index 3990a4b..6758b7a 100644
--- a/runtime/doc/version4.txt
+++ b/runtime/doc/version4.txt
@@ -352,4 +352,4 @@ this and accidentally hit CTRL-B, it is very difficult to find out how to undo
it. Since hardly anybody uses this feature, it is disabled by default. If
you want to use it, define RIGHTLEFT in feature.h before compiling. |'revins'|
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/version5.txt b/runtime/doc/version5.txt
index 075e583..ee23a22 100644
--- a/runtime/doc/version5.txt
+++ b/runtime/doc/version5.txt
@@ -7810,4 +7810,4 @@ Solution: Allocate the buffer for the shell command.
Files: src/ex_docmd.c
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/version6.txt b/runtime/doc/version6.txt
index a4dd5e6..a2e5474 100644
--- a/runtime/doc/version6.txt
+++ b/runtime/doc/version6.txt
@@ -14527,4 +14527,4 @@ Solution: Don't advance the cursor to include a line break when it's already
Files: src/search.c
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt
index 8155176..ff1a42c 100644
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -18309,4 +18309,4 @@ Files: src/os_win32.c
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/version8.txt b/runtime/doc/version8.txt
index 90784a0..50ebf33 100644
--- a/runtime/doc/version8.txt
+++ b/runtime/doc/version8.txt
@@ -25792,4 +25792,4 @@ Solution: Move the todo items to the help file.
Files: src/terminal.c
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/vi_diff.txt b/runtime/doc/vi_diff.txt
index a395c88..ddcb09d 100644
--- a/runtime/doc/vi_diff.txt
+++ b/runtime/doc/vi_diff.txt
@@ -1021,4 +1021,4 @@ These are remarks about running the POSIX test suite:
- ex test 534 fails because .exrc isn't read in silent mode.
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/visual.txt b/runtime/doc/visual.txt
index 5e15b3b..c48c1b5 100644
--- a/runtime/doc/visual.txt
+++ b/runtime/doc/visual.txt
@@ -538,4 +538,4 @@ g CTRL-H Start Select mode, blockwise. This is like CTRL-V,
but starts Select mode instead of Visual mode.
Mnemonic: "get Highlighted".
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index f7045b8..dea6a18 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -1311,4 +1311,4 @@ unlisted The buffer is not in the buffer list. It is not used for
:setlocal nobuflisted
<
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/doc/workshop.txt b/runtime/doc/workshop.txt
index 8a699a4..bcdfcf4 100644
--- a/runtime/doc/workshop.txt
+++ b/runtime/doc/workshop.txt
@@ -95,4 +95,4 @@ the directory /usr/local/xpm and untar the file there you can use the
uncommented lines in the Makefile without changing them. If you use another
xpm directory you will need to change the XPM_DIR in src/Makefile.
- vim:tw=78:ts=8:ft=help:norl:
+ vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index 46bf567..98b5c71 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -586,7 +586,7 @@ au BufNewFile,BufRead auto.master setf conf
au BufNewFile,BufRead *.mas,*.master setf master
" Forth
-au BufNewFile,BufRead *.fs,*.ft setf forth
+au BufNewFile,BufRead *.fs,*.ft,*.fth setf forth
" Reva Forth
au BufNewFile,BufRead *.frt setf reva
@@ -1766,6 +1766,9 @@ au BufNewFile,BufRead *.vroom setf vroom
" Webmacro
au BufNewFile,BufRead *.wm setf webmacro
+" WebAssembly
+au BufNewFile,BufRead *.wast,*.wat setf wast
+
" Wget config
au BufNewFile,BufRead .wgetrc,wgetrc setf wget
@@ -1862,6 +1865,9 @@ au BufNewFile,BufRead */etc/xdg/menus/*.menu setf xml
" ATI graphics driver configuration
au BufNewFile,BufRead fglrxrc setf xml
+" Web Services Description Language (WSDL)
+au BufNewFile,BufRead *.wsdl setf xml
+
" XLIFF (XML Localisation Interchange File Format) is also XML
au BufNewFile,BufRead *.xlf setf xml
au BufNewFile,BufRead *.xliff setf xml
diff --git a/runtime/ftplugin/logtalk.dict b/runtime/ftplugin/logtalk.dict
index e3b9e6f..3fcdfc6 100644
--- a/runtime/ftplugin/logtalk.dict
+++ b/runtime/ftplugin/logtalk.dict
@@ -1,164 +1,262 @@
-encoding
+abolish
+abolish_category
+abolish_events
+abolish_object
+abolish_protocol
+abs
+acos
+acyclic_term
+after
+alias
+always_true_or_false_goals
+arg
+asin
+asserta
+assertz
+atan
+atan2
+atom
+atomic
+atom_chars
+atom_chars
+atom_codes
+atom_codes
+atom_concat
+atom_concat
+atom_length
+at_end_of_stream
+bagof
+before
+built_in
+call
+callable
calls
+catch
category
+category_property
+ceiling
+char_code
+char_conversion
+clause
+clean
+close
+code_prefix
+coinduction
+coinductive
+compare
+complements
+complements
+complements_object
+compound
+conforms_to_protocol
+context
+context_switching_calls
+copy_term
+cos
+create_category
+create_logtalk_flag
+create_object
+create_protocol
+current_category
+current_char_conversion
+current_event
+current_input
+current_logtalk_flag
+current_object
+current_op
+current_output
+current_predicate
+current_prolog_flag
+current_protocol
+debug
+define_events
+deprecated
+discontiguous
+div
+domain_error
+duplicated_directives
dynamic
+dynamic_declarations
+elif
+else
+encoding
+encoding_directive
+endif
end_category
end_object
end_protocol
-info
-initialization
-object
-protocol
-synchronized
-threaded
-uses
-alias
-discontiguous
-meta_predicate
-mode
-op
-private
-protected
-public
-current_object
-current_protocol
-current_category
-object_property
-protocol_property
-category_property
-create_object
-create_protocol
-create_category
-abolish_object
-abolish_protocol
-abolish_category
-complements
-complements_object
+engines
+ensure_loaded
+evaluation_error
+events
+existence_error
+exp
+expand_goal
+expand_term
+export
extends
+extends_category
extends_object
extends_protocol
-extends_category
+fail
+false
+findall
+float
+float_fractional_part
+float_integer_part
+floor
+flush_output
+forall
+forward
+functor
+get_byte
+get_char
+get_code
+goal_expansion
+ground
+halt
+hook
+if
+ignore
implements
implements_protocol
imports
imports_category
+include
+info
+initialization
instantiates
instantiates_class
-specializes
-specializes_class
-abolish_events
-current_event
-define_events
-logtalk_load
+instantiation_error
+integer
+keysort
+lambda_variables
+log
logtalk_compile
logtalk_library_path
-current_logtalk_flag
-set_logtalk_flag
-threaded_call
-threaded_once
-threaded_ignore
-threaded_exit
-threaded_peek
-threaded_wait
-threaded_notify
-self
-this
-sender
-parameter
-before
-after
-phrase
-expand_term
-goal_expansion
-term_expansion
-true
-fail
-call
-catch
-throw
-unify_with_occurs_check
-var
-atom
-integer
-float
-atomic
-compound
+logtalk_load
+logtalk_load_context
+logtalk_make
+logtalk_make_target_action
+max
+meta_non_terminal
+meta_predicate
+min
+missing_directives
+mod
+mode
+modules
+multifile
+nl
nonvar
number
-arg
-copy_term
-functor
-current_predicate
-predicate_property
-abolish
-assertz
-asserta
-clause
-retract
-retractall
-bagof
-findall
-forall
-setof
-current_input
-current_output
-set_input
-set_output
+numbervars
+number_chars
+number_chars
+number_codes
+number_codes
+object
+object_property
+once
+op
open
-close
-flush_output
-stream_property
-at_end_of_stream
-set_stream_position
-get_char
-get_code
+optimize
+parameter
+peek_byte
peek_char
peek_code
+permission_error
+phrase
+portability
+predicate_property
+private
+prolog_compatible_version
+prolog_compiler
+prolog_dialect
+prolog_loader
+prolog_version
+protected
+protocol
+protocol_property
+public
+put_byte
put_char
put_code
-nl
-get_byte
-peek_byte
-put_byte
read
read_term
-write
-writeq
-write_canonical
-atom_chars
-atom_codes
-atom_concat
-number_chars
-number_codes
-current_op
-char_conversion
-current_char_conversion
-once
-repeat
-atom_length
-atom_concat
-sub_atom
-atom_chars
-atom_codes
-char_code
-number_chars
-number_codes
-set_prolog_flag
-current_prolog_flag
-halt
-abs
-atan
-ceiling
-cos
-exp
-float_fractional_part
-float_integer_part
-floor
-log
-mod
+redefined_built_ins
+reexport
+reload
rem
+repeat
+report
+representation_error
+resource_error
+retract
+retractall
round
+scratch_directory
+self
+sender
+setof
+set_input
+set_logtalk_flag
+set_output
+set_prolog_flag
+set_stream_position
sign
sin
+singleton_variables
+sort
+source_data
+specializes
+specializes_class
sqrt
+stream_property
+subsumes_term
+sub_atom
+suspicious_calls
+synchronized
+syntax_error
+system_error
+tabling
+tan
+term_expansion
+term_variables
+this
+threaded
+threaded_call
+threaded_engine
+threaded_engine_create
+threaded_engine_destroy
+threaded_engine_fetch
+threaded_engine_next
+threaded_engine_next_reified
+threaded_engine_post
+threaded_engine_self
+threaded_engine_yield
+threaded_exit
+threaded_ignore
+threaded_notify
+threaded_once
+threaded_peek
+threaded_wait
+threads
+throw
+trivial_goal_fails
+true
truncate
+type_error
+undefined_predicates
+underscore_variables
+unify_with_occurs_check
+unknown_entities
+unknown_predicates
+uses
+use_module
+var
+version
+write
+writeq
+write_canonical
+xor
diff --git a/runtime/ftplugin/logtalk.vim b/runtime/ftplugin/logtalk.vim
index e71307a..667907c 100644
--- a/runtime/ftplugin/logtalk.vim
+++ b/runtime/ftplugin/logtalk.vim
@@ -1,7 +1,7 @@
" Logtalk filetype plugin file
" Language: Logtalk
" Maintainer: Paulo Moura <pmoura@logtalk.org>
-" Latest Revision: 2007-07-06
+" Latest Revision: 2018-08-03
if exists("b:did_ftplugin")
finish
@@ -10,9 +10,10 @@ let b:did_ftplugin = 1
let b:undo_ftplugin = "setl ts< sw< fdm< fdc< ai< dict<"
-"setlocal ts=4
+setlocal ts=4
setlocal sw=4
setlocal fdm=syntax
+setlocal fdn=10
setlocal fdc=2
setlocal autoindent
setlocal dict=$VIMRUNTIME/ftplugin/logtalk.dict
diff --git a/runtime/ftplugin/vim.vim b/runtime/ftplugin/vim.vim
index 03a7789..a0f0f3a 100644
--- a/runtime/ftplugin/vim.vim
+++ b/runtime/ftplugin/vim.vim
@@ -1,7 +1,7 @@
" Vim filetype plugin
" Language: Vim
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2017 Dec 05
+" Last Change: 2018 Aug 07
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -17,19 +17,19 @@ set cpo-=C
if !exists('*VimFtpluginUndo')
func VimFtpluginUndo()
setl fo< isk< com< tw< commentstring<
- if exists(b:did_add_maps)
- silent! nunmap <buffer> [['
- silent! vunmap <buffer> [['
- silent! nunmap <buffer> ]]'
- silent! vunmap <buffer> ]]'
- silent! nunmap <buffer> []'
- silent! vunmap <buffer> []'
- silent! nunmap <buffer> ]['
- silent! vunmap <buffer> ]['
- silent! nunmap <buffer> ]"'
- silent! vunmap <buffer> ]"'
- silent! nunmap <buffer> ["'
- silent! vunmap <buffer> ["'
+ if exists('b:did_add_maps')
+ silent! nunmap <buffer> [[
+ silent! vunmap <buffer> [[
+ silent! nunmap <buffer> ]]
+ silent! vunmap <buffer> ]]
+ silent! nunmap <buffer> []
+ silent! vunmap <buffer> []
+ silent! nunmap <buffer> ][
+ silent! vunmap <buffer> ][
+ silent! nunmap <buffer> ]"
+ silent! vunmap <buffer> ]"
+ silent! nunmap <buffer> ["
+ silent! vunmap <buffer> ["
endif
unlet! b:match_ignorecase b:match_words b:match_skip b:did_add_maps
endfunc
diff --git a/runtime/ftplugin/wast.vim b/runtime/ftplugin/wast.vim
new file mode 100644
index 0000000..0d9e98d
--- /dev/null
+++ b/runtime/ftplugin/wast.vim
@@ -0,0 +1,17 @@
+" Vim filetype plugin file
+" Language: WebAssembly
+" Maintainer: rhysd <lin90162@yahoo.co.jp>
+" Last Change: Jul 29, 2018
+" For bugs, patches and license go to https://github.com/rhysd/vim-wasm
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+setlocal comments=s:(;,e:;),:;;
+setlocal commentstring=(;%s;)
+setlocal formatoptions-=t
+setlocal iskeyword+=$,.,/
+
+let b:undo_ftplugin = "setlocal comments< commentstring< formatoptions< iskeyword<"
diff --git a/runtime/indent/logtalk.vim b/runtime/indent/logtalk.vim
index 5b69663..8e36f86 100644
--- a/runtime/indent/logtalk.vim
+++ b/runtime/indent/logtalk.vim
@@ -1,5 +1,5 @@
" Maintainer: Paulo Moura <pmoura@logtalk.org>
-" Revised on: 2008.06.02
+" Revised on: 2018.08.04
" Language: Logtalk
" This Logtalk indent file is a modified version of the Prolog
@@ -42,6 +42,9 @@ function! GetLogtalkIndent()
" Check for clause head on previous line
elseif pline =~ ':-\s*\(%.*\)\?$'
let ind = ind + shiftwidth()
+ " Check for grammar rule head on previous line
+ elseif pline =~ '-->\s*\(%.*\)\?$'
+ let ind = ind + shiftwidth()
" Check for entity closing directive on previous line
elseif pline =~ '^\s*:-\send_\(object\|protocol\|category\)\.\(%.*\)\?$'
let ind = ind - shiftwidth()
diff --git a/runtime/indent/wast.vim b/runtime/indent/wast.vim
new file mode 100644
index 0000000..1be234b
--- /dev/null
+++ b/runtime/indent/wast.vim
@@ -0,0 +1,17 @@
+" Vim indent file
+" Language: WebAssembly
+" Maintainer: rhysd <lin90162@yahoo.co.jp>
+" Last Change: Jul 29, 2018
+" For bugs, patches and license go to https://github.com/rhysd/vim-wasm
+
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+
+" WebAssembly text format is S-expression. We can reuse LISP indentation
+" logic.
+setlocal indentexpr=lispindent('.')
+setlocal noautoindent nosmartindent
+
+let b:undo_indent = "setl lisp< indentexpr<"
diff --git a/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim b/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim
new file mode 100644
index 0000000..7a6464f
--- /dev/null
+++ b/runtime/pack/dist/opt/cfilter/plugin/cfilter.vim
@@ -0,0 +1,43 @@
+" cfilter.vim: Plugin to filter entries from a quickfix/location list
+" Last Change: May 12, 2018
+" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
+" Version: 1.0
+"
+" Commands to filter the quickfix list:
+" :Cfilter[!] {pat}
+" Create a new quickfix list from entries matching {pat} in the current
+" quickfix list. Both the file name and the text of the entries are
+" matched against {pat}. If ! is supplied, then entries not matching
+" {pat} are used.
+" :Lfilter[!] {pat}
+" Same as :Cfilter but operates on the current location list.
+"
+if exists("loaded_cfilter")
+ finish
+endif
+let loaded_cfilter = 1
+
+func s:Qf_filter(qf, pat, bang)
+ if a:qf
+ let Xgetlist = function('getqflist')
+ let Xsetlist = function('setqflist')
+ let cmd = ':Cfilter' . a:bang
+ else
+ let Xgetlist = function('getloclist', [0])
+ let Xsetlist = function('setloclist', [0])
+ let cmd = ':Lfilter' . a:bang
+ endif
+
+ if a:bang == '!'
+ let cond = 'v:val.text !~# a:pat && bufname(v:val.bufnr) !~# a:pat'
+ else
+ let cond = 'v:val.text =~# a:pat || bufname(v:val.bufnr) =~# a:pat'
+ endif
+
+ let items = filter(Xgetlist(), cond)
+ let title = cmd . ' ' . a:pat
+ call Xsetlist([], ' ', {'title' : title, 'items' : items})
+endfunc
+
+com! -nargs=+ -bang Cfilter call s:Qf_filter(1, <q-args>, <q-bang>)
+com! -nargs=+ -bang Lfilter call s:Qf_filter(0, <q-args>, <q-bang>)
diff --git a/runtime/syntax/debcontrol.vim b/runtime/syntax/debcontrol.vim
index e630373..9085cd0 100644
--- a/runtime/syntax/debcontrol.vim
+++ b/runtime/syntax/debcontrol.vim
@@ -3,7 +3,7 @@
" Maintainer: Debian Vim Maintainers
" Former Maintainers: Gerfried Fuchs <alfie@ist.org>
" Wichert Akkerman <wakkerma@debian.org>
-" Last Change: 2018 May 31
+" Last Change: 2018 Aug 11
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debcontrol.vim
" Standard syntax initialization
@@ -30,7 +30,7 @@ let s:kernels = ['linux', 'hurd', 'kfreebsd', 'knetbsd', 'kopensolaris', 'netbsd
let s:archs = [
\ 'alpha', 'amd64', 'armeb', 'armel', 'armhf', 'arm64', 'avr32', 'hppa'
\, 'i386', 'ia64', 'lpia', 'm32r', 'm68k', 'mipsel', 'mips64el', 'mips'
- \, 'powerpcspe', 'powerpc', 'ppc64el', 'ppc64', 's390x', 's390', 'sh3eb'
+ \, 'powerpcspe', 'powerpc', 'ppc64el', 'ppc64', 'riscv64', 's390x', 's390', 'sh3eb'
\, 'sh3', 'sh4eb', 'sh4', 'sh', 'sparc64', 'sparc', 'x32'
\ ]
let s:pairs = [
diff --git a/runtime/syntax/debsources.vim b/runtime/syntax/debsources.vim
index c7960c1..74e8d42 100644
--- a/runtime/syntax/debsources.vim
+++ b/runtime/syntax/debsources.vim
@@ -2,7 +2,7 @@
" Language: Debian sources.list
" Maintainer: Debian Vim Maintainers
" Former Maintainer: Matthijs Mohlmann <matthijs@cacholong.nl>
-" Last Change: 2018 May 03
+" Last Change: 2018 Aug 11
" URL: https://salsa.debian.org/vim-team/vim-debian/blob/master/syntax/debsources.vim
" Standard syntax initialization
@@ -25,7 +25,7 @@ let s:supported = [
\ 'oldstable', 'stable', 'testing', 'unstable', 'experimental',
\ 'wheezy', 'jessie', 'stretch', 'sid', 'rc-buggy',
\
- \ 'trusty', 'xenial', 'artful', 'bionic', 'cosmic', 'devel'
+ \ 'trusty', 'xenial', 'bionic', 'cosmic', 'devel'
\ ]
let s:unsupported = [
\ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato',
@@ -34,7 +34,7 @@ let s:unsupported = [
\ 'warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty',
\ 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid',
\ 'maverick', 'natty', 'oneiric', 'precise', 'quantal', 'raring', 'saucy',
- \ 'utopic', 'vivid', 'wily', 'yakkety', 'zesty'
+ \ 'utopic', 'vivid', 'wily', 'yakkety', 'zesty', 'artful'
\ ]
let &cpo=s:cpo
diff --git a/runtime/syntax/logtalk.vim b/runtime/syntax/logtalk.vim
index 532f83d..a7fe9ce 100644
--- a/runtime/syntax/logtalk.vim
+++ b/runtime/syntax/logtalk.vim
@@ -2,7 +2,7 @@
"
" Language: Logtalk
" Maintainer: Paulo Moura <pmoura@logtalk.org>
-" Last Change: February 4, 2012
+" Last Change: August 3, 2018
" quit when a syntax file was already loaded
@@ -79,13 +79,13 @@ syn region logtalkDir matchgroup=logtalkDirTag start=":- elif(" matchgroup=log
syn match logtalkDirTag ":- else\."
syn match logtalkDirTag ":- endif\."
syn region logtalkDir matchgroup=logtalkDirTag start=":- alias(" matchgroup=logtalkDirTag end=")\." contains=ALL
-syn region logtalkDir matchgroup=logtalkDirTag start=":- calls(" matchgroup=logtalkDirTag end=")\." contains=ALL
syn region logtalkDir matchgroup=logtalkDirTag start=":- coinductive(" matchgroup=logtalkDirTag end=")\." contains=ALL
syn region logtalkDir matchgroup=logtalkDirTag start=":- encoding(" matchgroup=logtalkDirTag end=")\." contains=ALL
syn region logtalkDir matchgroup=logtalkDirTag start=":- initialization(" matchgroup=logtalkDirTag end=")\." contains=ALL
syn region logtalkDir matchgroup=logtalkDirTag start=":- info(" matchgroup=logtalkDirTag end=")\." contains=ALL
syn region logtalkDir matchgroup=logtalkDirTag start=":- mode(" matchgroup=logtalkDirTag end=")\." contains=logtalkOperator, logtalkAtom
syn region logtalkDir matchgroup=logtalkDirTag start=":- dynamic(" matchgroup=logtalkDirTag end=")\." contains=ALL
+syn match logtalkDirTag ":- built_in\."
syn match logtalkDirTag ":- dynamic\."
syn region logtalkDir matchgroup=logtalkDirTag start=":- discontiguous(" matchgroup=logtalkDirTag end=")\." contains=ALL
syn region logtalkDir matchgroup=logtalkDirTag start=":- multifile(" matchgroup=logtalkDirTag end=")\." contains=ALL
@@ -131,17 +131,20 @@ syn match logtalkBuiltIn "\<\(instantiat\|specializ\)es_class\ze("
syn match logtalkBuiltIn "\<\(abolish\|define\)_events\ze("
syn match logtalkBuiltIn "\<current_event\ze("
-syn match logtalkBuiltIn "\<\(curren\|se\)t_logtalk_flag\ze("
+syn match logtalkBuiltIn "\<\(create\|current\|set\)_logtalk_flag\ze("
-syn match logtalkBuiltIn "\<logtalk_\(compile\|l\(ibrary_path\|oad\|oad_context\)\)\ze("
+syn match logtalkBuiltIn "\<logtalk_\(compile\|l\(ibrary_path\|oad\|oad_context\)\|make\(_target_action\)\?\)\ze("
+syn match logtalkBuiltIn "\<logtalk_make\>"
syn match logtalkBuiltIn "\<\(for\|retract\)all\ze("
syn match logtalkBuiltIn "\<threaded\(_\(call\|once\|ignore\|exit\|peek\|wait\|notify\)\)\?\ze("
+syn match logtalkBuiltIn "\<threaded_engine\(_\(create\|destroy\|self\|next\|next_reified\|yield\|post\|fetch\)\)\?\ze("
" Logtalk built-in methods
+syn match logtalkBuiltInMethod "\<context\ze("
syn match logtalkBuiltInMethod "\<parameter\ze("
syn match logtalkBuiltInMethod "\<se\(lf\|nder\)\ze("
syn match logtalkBuiltInMethod "\<this\ze("
@@ -159,6 +162,8 @@ syn match logtalkBuiltInMethod "\<f\(ind\|or\)all\ze("
syn match logtalkBuiltInMethod "\<before\ze("
syn match logtalkBuiltInMethod "\<after\ze("
+syn match logtalkBuiltInMethod "\<forward\ze("
+
syn match logtalkBuiltInMethod "\<expand_\(goal\|term\)\ze("
syn match logtalkBuiltInMethod "\<\(goal\|term\)_expansion\ze("
syn match logtalkBuiltInMethod "\<phrase\ze("
@@ -174,6 +179,7 @@ syn match logtalkOperator "@"
syn match logtalkKeyword "\<true\>"
syn match logtalkKeyword "\<fail\>"
+syn match logtalkKeyword "\<false\>"
syn match logtalkKeyword "\<ca\(ll\|tch\)\ze("
syn match logtalkOperator "!"
" syn match logtalkOperator ","
@@ -181,11 +187,14 @@ syn match logtalkOperator ";"
syn match logtalkOperator "-->"
syn match logtalkOperator "->"
syn match logtalkKeyword "\<throw\ze("
+syn match logtalkKeyword "\<\(instantiation\|system\)_error\>"
+syn match logtalkKeyword "\<\(type\|domain\|existence\|permission\|representation\|evaluation\|resource\|syntax\)_error\ze("
" Term unification
syn match logtalkOperator "="
+syn match logtalkKeyword "\<subsumes_term\ze("
syn match logtalkKeyword "\<unify_with_occurs_check\ze("
syn match logtalkOperator "\\="
@@ -199,6 +208,7 @@ syn match logtalkKeyword "\<float\ze("
syn match logtalkKeyword "\<c\(allable\|ompound\)\ze("
syn match logtalkKeyword "\<n\(onvar\|umber\)\ze("
syn match logtalkKeyword "\<ground\ze("
+syn match logtalkKeyword "\<acyclic_term\ze("
" Term comparison
@@ -219,14 +229,20 @@ syn match logtalkKeyword "\<arg\ze("
syn match logtalkOperator "=\.\."
syn match logtalkKeyword "\<copy_term\ze("
syn match logtalkKeyword "\<numbervars\ze("
+syn match logtalkKeyword "\<term_variables\ze("
+
+
+" Predicate aliases
+
+syn match logtalkOperator "\<as\>"
-" Arithemtic evaluation
+" Arithmetic evaluation
syn match logtalkOperator "\<is\>"
-" Arithemtic comparison
+" Arithmetic comparison
syn match logtalkOperator "=:="
syn match logtalkOperator "=\\="
@@ -299,16 +315,18 @@ syn match logtalkOperator "-"
syn match logtalkOperator "\*"
syn match logtalkOperator "//"
syn match logtalkOperator "/"
+syn match logtalkKeyword "\<div\ze("
syn match logtalkKeyword "\<r\(ound\|em\)\ze("
syn match logtalkKeyword "\<e\>"
syn match logtalkKeyword "\<pi\>"
+syn match logtalkKeyword "\<div\>"
syn match logtalkKeyword "\<rem\>"
-syn match logtalkKeyword "\<mod\ze("
+syn match logtalkKeyword "\<m\(ax\|in\|od\)\ze("
syn match logtalkKeyword "\<mod\>"
syn match logtalkKeyword "\<abs\ze("
syn match logtalkKeyword "\<sign\ze("
syn match logtalkKeyword "\<flo\(or\|at\(_\(integer\|fractional\)_part\)\?\)\ze("
-syn match logtalkKeyword "\<truncate\ze("
+syn match logtalkKeyword "\<t\(an\|runcate\)\ze("
syn match logtalkKeyword "\<ceiling\ze("
@@ -317,7 +335,7 @@ syn match logtalkKeyword "\<ceiling\ze("
syn match logtalkOperator "\*\*"
syn match logtalkKeyword "\<s\(in\|qrt\)\ze("
syn match logtalkKeyword "\<cos\ze("
-syn match logtalkKeyword "\<atan\ze("
+syn match logtalkKeyword "\<a\(cos\|sin\|tan\|tan2\)\ze("
syn match logtalkKeyword "\<exp\ze("
syn match logtalkKeyword "\<log\ze("
@@ -329,6 +347,7 @@ syn match logtalkOperator "<<"
syn match logtalkOperator "/\\"
syn match logtalkOperator "\\/"
syn match logtalkOperator "\\"
+syn match logtalkKeyword "\<xor\ze("
" Logtalk list operator
@@ -347,7 +366,7 @@ syn match logtalkNumber "\<\d\+\>"
syn match logtalkNumber "\<\d\+\.\d\+\>"
syn match logtalkNumber "\<\d\+[eE][-+]\=\d\+\>"
syn match logtalkNumber "\<\d\+\.\d\+[eE][-+]\=\d\+\>"
-syn match logtalkNumber "\<0'.\|0''\|0'\"\>"
+syn match logtalkNumber "\<0'[\\]\?.\|0''\|0'\"\>"
syn match logtalkNumber "\<0b[0-1]\+\>"
syn match logtalkNumber "\<0o\o\+\>"
syn match logtalkNumber "\<0x\x\+\>"
diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index a8258d7..167300c 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -2,8 +2,8 @@
" Language: shell (sh) Korn shell (ksh) bash (sh)
" Maintainer: Charles E. Campbell <NdrOchipS@PcampbellAfamily.Mbiz>
" Previous Maintainer: Lennart Schultz <Lennart.Schultz@ecmwf.int>
-" Last Change: Mar 19, 2018
-" Version: 174
+" Last Change: Jul 31, 2018
+" Version: 179
" URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_SH
" For options and settings, please use: :help ft-sh-syntax
" This file includes many ideas from Eric Brunet (eric.brunet@ens.fr)
@@ -126,17 +126,17 @@ if exists("b:is_kornshell") || exists("b:is_bash")
endif
syn cluster shArithParenList contains=shArithmetic,shCaseEsac,shComment,shDeref,shDo,shDerefSimple,shEcho,shEscape,shNumber,shOperator,shPosnParm,shExSingleQuote,shExDoubleQuote,shHereString,shRedir,shSingleQuote,shDoubleQuote,shStatement,shVariable,shAlias,shTest,shCtrlSeq,shSpecial,shParen,bashSpecialVariables,bashStatement,shIf,shFor
syn cluster shArithList contains=@shArithParenList,shParenError
-syn cluster shCaseEsacList contains=shCaseStart,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
-syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
-syn cluster shCommandSubList contains=shAlias,shArithmetic,shCmdParenRegion,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
+syn cluster shCaseEsacList contains=shCaseStart,shCaseLabel,shCase,shCaseBar,shCaseIn,shComment,shDeref,shDerefSimple,shCaseCommandSub,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote,shCtrlSeq,@shErrorList,shStringSpecial,shCaseRange
+syn cluster shCaseList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shCommandSubBQ,shComment,shDo,shEcho,shExpr,shFor,shForPP,shHereDoc,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq
+syn cluster shCommandSubList contains=shAlias,shArithmetic,shCmdParenRegion,shCommandSub,shComment,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shEcho,shEscape,shExDoubleQuote,shExpr,shExSingleQuote,shHereDoc,shNumber,shOperator,shOption,shPosnParm,shHereString,shRedir,shSingleQuote,shSpecial,shStatement,shSubSh,shTest,shVariable
syn cluster shCurlyList contains=shNumber,shComma,shDeref,shDerefSimple,shDerefSpecial
-syn cluster shDblQuoteList contains=shCommandSub,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial
+syn cluster shDblQuoteList contains=shArithmetic,shCommandSub,shCommandSubBQ,shDeref,shDerefSimple,shEscape,shPosnParm,shCtrlSeq,shSpecial,shSpecialDQ
syn cluster shDerefList contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial,shDerefWordError,shDerefPSR,shDerefPPS
syn cluster shDerefVarList contains=shDerefOff,shDerefOp,shDerefVarArray,shDerefOpError
-syn cluster shEchoList contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shEscape,shExpr,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
+syn cluster shEchoList contains=shArithmetic,shCommandSub,shCommandSubBQ,shDeref,shDerefSimple,shEscape,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
syn cluster shExprList2 contains=@shExprList1,@shCaseList,shTest
-syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
+syn cluster shFunctionList contains=@shCommandSubList,shCaseEsac,shColon,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
if exists("b:is_kornshell") || exists("b:is_bash")
syn cluster shFunctionList add=shRepeat
syn cluster shFunctionList add=shDblBrace,shDblParen
@@ -144,12 +144,12 @@ endif
syn cluster shHereBeginList contains=@shCommandSubList
syn cluster shHereList contains=shBeginHere,shHerePayload
syn cluster shHereListDQ contains=shBeginHere,@shDblQuoteList,shHerePayload
-syn cluster shIdList contains=shCommandSub,shWrapLineOperator,shSetOption,shDeref,shDerefSimple,shHereString,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
+syn cluster shIdList contains=shCommandSub,shCommandSubBQ,shWrapLineOperator,shSetOption,shComment,shDeref,shDerefSimple,shHereString,shRedir,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shCtrlSeq,shStringSpecial,shAtExpr
syn cluster shIfList contains=@shLoopList,shDblBrace,shDblParen,shFunctionKey,shFunctionOne,shFunctionTwo
syn cluster shLoopList contains=@shCaseList,@shErrorList,shCaseEsac,shConditional,shDblBrace,shExpr,shFor,shForPP,shIf,shOption,shSet,shTest,shTestOpr,shTouch
syn cluster shPPSRightList contains=shComment,shDeref,shDerefSimple,shEscape,shPosnParm
-syn cluster shSubShList contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
-syn cluster shTestList contains=shCharClass,shCommandSub,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
+syn cluster shSubShList contains=@shCommandSubList,shCommandSubBQ,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shIf,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shCtrlSeq,shOperator
+syn cluster shTestList contains=shCharClass,shCommandSub,shCommandSubBQ,shCtrlSeq,shDeref,shDerefSimple,shDoubleQuote,shSpecialDQ,shExDoubleQuote,shExpr,shExSingleQuote,shNumber,shOperator,shSingleQuote,shTest,shTestOpr
syn cluster shNoZSList contains=shSpecialNoZS
" Echo: {{{1
@@ -262,14 +262,15 @@ syn match shComma contained ","
" Case: case...esac {{{1
" ====
-syn match shCaseBar contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|" nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
-syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
+syn match shCaseBar contained skipwhite "\(^\|[^\\]\)\(\\\\\)*\zs|" nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
+syn match shCaseStart contained skipwhite skipnl "(" nextgroup=shCase,shCaseBar
+syn match shCaseLabel contained skipwhite "\%(\\.\|[-a-zA-Z0-9_*.]\)\+" contains=shCharClass
if exists("b:is_bash")
- ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end=";&" end=";;&" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
-else
- ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
+ ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end=";&" end=";;&" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
+else
+ ShFoldIfDoFor syn region shCase contained skipwhite skipnl matchgroup=shSnglCase start="\%(\\.\|[^#$()'" \t]\)\{-}\zs)" end=";;" end="esac"me=s-1 contains=@shCaseList nextgroup=shCaseStart,shCase,shComment
endif
-ShFoldIfDoFor syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
+ShFoldIfDoFor syn region shCaseEsac matchgroup=shConditional start="\<case\>" end="\<esac\>" contains=@shCaseEsacList
syn keyword shCaseIn contained skipwhite skipnl in nextgroup=shCase,shCaseStart,shCaseBar,shComment,shCaseExSingleQuote,shCaseSingleQuote,shCaseDoubleQuote
if exists("b:is_bash")
@@ -289,8 +290,8 @@ endif
" Misc: {{{1
"======
syn match shWrapLineOperator "\\$"
-syn region shCommandSub start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
-syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.'
+syn region shCommandSubBQ start="`" skip="\\\\\|\\." end="`" contains=@shCommandSubList
+syn match shEscape contained '\%(^\)\@!\%(\\\\\)*\\.' nextgroup=shSingleQuote,shDoubleQuote,shComment
" $() and $(()): {{{1
" $(..) is not supported by sh (Bourne shell). However, apparently
@@ -347,17 +348,19 @@ elseif !exists("g:sh_no_error")
syn region shExSingleQuote matchGroup=Error start=+\$'+ skip=+\\\\\|\\.+ end=+'+ contains=shStringSpecial
syn region shExDoubleQuote matchGroup=Error start=+\$"+ skip=+\\\\\|\\.+ end=+"+ contains=shStringSpecial
endif
-syn region shSingleQuote matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart
+syn region shSingleQuote matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart,shSpecialSQ
syn region shDoubleQuote matchgroup=shQuote start=+\%(\%(\\\\\)*\\\)\@<!"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
+syn region shDoubleQuote matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+ contained contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
syn match shStringSpecial "[^[:print:] \t]" contained
-syn match shStringSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]"
-syn match shSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]" nextgroup=shBkslshSnglQuote,shBkslshDblQuote,@shNoZSList
+syn match shStringSpecial "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]" nextgroup=shComment
+syn match shSpecialSQ "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]" contained nextgroup=shBkslshSnglQuote,@shNoZSList
+syn match shSpecialDQ "[^\\]\zs\%(\\\\\)*\\[\\"'`$()#]" contained nextgroup=shBkslshDblQuote,@shNoZSList
syn match shSpecialStart "\%(\\\\\)*\\[\\"'`$()#]" contained nextgroup=shBkslshSnglQuote,shBkslshDblQuote,@shNoZSList
syn match shSpecial "^\%(\\\\\)*\\[\\"'`$()#]"
syn match shSpecialNoZS contained "\%(\\\\\)*\\[\\"'`$()#]"
syn match shSpecialNxt contained "\\[\\"'`$()#]"
-syn region shBkslshSnglQuote contained matchgroup=shQuote start=+'+ end=+'+ contains=@Spell
-syn region shBkslshDblQuote contained matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell
+syn region shBkslshSnglQuote contained matchgroup=shQuote start=+'+ end=+'+ contains=@Spell nextgroup=shSpecialStart
+syn region shBkslshDblQuote contained matchgroup=shQuote start=+"+ skip=+\\"+ end=+"+ contains=@shDblQuoteList,shStringSpecial,@Spell nextgroup=shSpecialStart
" Comments: {{{1
"==========
@@ -375,20 +378,21 @@ syn match shQuickComment contained "#.*$"
" Here Documents: {{{1
" =========================================
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc01 start="<<\s*\\\=\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc01 end="^\z1\s*$" contains=@shDblQuoteList
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc02 start="<<\s*\"\z([^ \t0-9|>]\+\)\"" matchgroup=shHereDoc02 end="^\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc02 start="<<\s*\"\z([^ \t|>]\+\)\"" matchgroup=shHereDoc02 end="^\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc03 start="<<-\s*\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc03 end="^\s*\z1\s*$" contains=@shDblQuoteList
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc04 start="<<-\s*'\z([^'0-9]\+\)'" matchgroup=shHereDoc04 end="^\s*\z1\s*$"
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc05 start="<<\s*'\z([^'0-9]\+\)'" matchgroup=shHereDoc05 end="^\z1\s*$"
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*\"\z([^ \t0-9|>]\+\)\"" matchgroup=shHereDoc06 end="^\s*\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc04 start="<<-\s*'\z([^']\+\)'" matchgroup=shHereDoc04 end="^\s*\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc05 start="<<\s*'\z([^']\+\)'" matchgroup=shHereDoc05 end="^\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc06 start="<<-\s*\"\z([^ \t|>]\+\)\"" matchgroup=shHereDoc06 end="^\s*\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc07 start="<<\s*\\\_$\_s*\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc07 end="^\z1\s*$" contains=@shDblQuoteList
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc08 start="<<\s*\\\_$\_s*'\z([^ \t0-9|>]\+\)'" matchgroup=shHereDoc08 end="^\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc09 start="<<\s*\\\_$\_s*\"\z([^ \t0-9|>]\+\)\"" matchgroup=shHereDoc09 end="^\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc10 start="<<-\s*\\\_$\_s*\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc10 end="^\s*\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc11 start="<<-\s*\\\_$\_s*\\\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc11 end="^\s*\z1\s*$"
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*'\z([^ \t0-9|>]\+\)'" matchgroup=shHereDoc12 end="^\s*\z1\s*$"
-ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<-\s*\\\_$\_s*\"\z([^ \t0-9|>]\+\)\"" matchgroup=shHereDoc13 end="^\s*\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc12 start="<<-\s*\\\_$\_s*'\z([^ \t|>]\+\)'" matchgroup=shHereDoc12 end="^\s*\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc13 start="<<-\s*\\\_$\_s*\"\z([^ \t|>]\+\)\"" matchgroup=shHereDoc13 end="^\s*\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc14 start="<<\\\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc14 end="^\z1\s*$"
ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc15 start="<<-\s*\\\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc15 end="^\s*\z1\s*$"
+ShFoldHereDoc syn region shHereDoc matchgroup=shHereDoc16 start="<<-\s*\\\z([^ \t0-9|>]\+\)" matchgroup=shHereDoc15 end="^\s*\z1\s*$"
" Here Strings: {{{1
" =============
@@ -404,9 +408,11 @@ syn match shVariable "\<\([bwglsav]:\)\=[a-zA-Z0-9.!@_%+,]*\ze=" nextgroup=shVa
syn match shVarAssign "=" contained nextgroup=shCmdParenRegion,shPattern,shDeref,shDerefSimple,shDoubleQuote,shExDoubleQuote,shSingleQuote,shExSingleQuote
syn region shAtExpr contained start="@(" end=")" contains=@shIdList
if exists("b:is_bash")
+ syn match shSet "^\s*set\ze\s*$"
syn region shSetList oneline matchgroup=shSet start="\<\(declare\|typeset\|local\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+#\|=" contains=@shIdList
- syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="\ze[;|)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+=" contains=@shIdList
+ syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="\ze[;|#)]\|$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+=" contains=@shIdList nextgroup=shComment
elseif exists("b:is_kornshell") || exists("b:is_posix")
+ syn match shSet "^\s*set\ze\s*$"
syn region shSetList oneline matchgroup=shSet start="\<\(typeset\|export\|unset\)\>\ze[^/]" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
syn region shSetList oneline matchgroup=shSet start="\<set\>\ze[^/]" end="$" matchgroup=shSetListDelim end="\ze[}|);&]" matchgroup=NONE end="\ze\s\+[#=]" contains=@shIdList
else
@@ -508,9 +514,9 @@ syn match shDerefString contained "\\["']" nextgroup=shDerefPattern
if exists("b:is_bash")
" bash : ${parameter:offset}
" bash : ${parameter:offset:length}
- syn region shDerefOff contained start=':' end='\ze:' end='\ze}' contains=shDeref,shDerefSimple,shDerefEscape nextgroup=shDerefLen,shDeref,shDerefSimple
+ syn region shDerefOff contained start=':[^-=?+]' end='\ze:' end='\ze}' contains=shDeref,shDerefSimple,shDerefEscape nextgroup=shDerefLen,shDeref,shDerefSimple
syn region shDerefOff contained start=':\s-' end='\ze:' end='\ze}' contains=shDeref,shDerefSimple,shDerefEscape nextgroup=shDerefLen,shDeref,shDerefSimple
- syn match shDerefLen contained ":[^}]\+" contains=shDeref,shDerefSimple
+ syn match shDerefLen contained ":[^}]\+" contains=shDeref,shDerefSimple,shArithmetic
" bash : ${parameter//pattern/string}
" bash : ${parameter//pattern}
@@ -588,6 +594,8 @@ if !exists("skip_sh_syntax_inits")
hi def link shArithRegion shShellVariables
hi def link shAstQuote shDoubleQuote
hi def link shAtExpr shSetList
+ hi def link shBkslshSnglQuote shSingleQuote
+ hi def link shBkslshDblQuote shDOubleQuote
hi def link shBeginHere shRedir
hi def link shCaseBar shConditional
hi def link shCaseCommandSub shCommandSub
@@ -680,6 +688,7 @@ if !exists("skip_sh_syntax_inits")
hi def link shCharClass Identifier
hi def link shSnglCase Statement
hi def link shCommandSub Special
+ hi def link shCommandSubBQ shCommandSub
hi def link shComment Comment
hi def link shConditional Conditional
hi def link shCtrlSeq Special
@@ -693,6 +702,8 @@ if !exists("skip_sh_syntax_inits")
hi def link shSetList Identifier
hi def link shShellVariables PreProc
hi def link shSpecial Special
+ hi def link shSpecialDQ Special
+ hi def link shSpecialSQ Special
hi def link shSpecialNoZS shSpecial
hi def link shStatement Statement
hi def link shString String
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index c3e1344..30c3f2f 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -1,8 +1,8 @@
" Vim syntax file
" Language: Vim 8.0 script
" Maintainer: Charles E. Campbell <NdrOchipS@PcampbellAfamily.Mbiz>
-" Last Change: April 30, 2018
-" Version: 8.0-14
+" Last Change: July 31, 2018
+" Version: 8.0-19
" URL: http://www.drchip.org/astronaut/vim/index.html#SYNTAX_VIM
" Automatically generated keyword lists: {{{1
@@ -19,26 +19,24 @@ syn keyword vimTodo contained COMBAK FIXME TODO XXX
syn cluster vimCommentGroup contains=vimTodo,@Spell
" regular vim commands {{{2
-syn keyword vimCommand contained a arga[dd] argu[ment] bad[d] bn[ext] breakd[el] bw[ipeout] cadde[xpr] cc cf[ile] changes cla[st] cnf[ile] comp[iler] cq[uit] cw[indow] delep dell diffg[et] dig[raphs] doau ea el[se] endt[ry] f[ile] fina[lly] foldd[oopen] go[to] ha[rdcopy] hid[e] ij[ump] isp[lit] keepa l[ist] lat lcl[ose] lex[pr] lgete[xpr] lla[st] lnf[ile] lol[der] lt[ag] lw[indow] menut[ranslate] mkv[imrc] n[ext] nmapc[lear] nore omapc[lear] pa[ckadd] perld[o] prev[ious] promptr[epl] ptj[ump] pts[elect] py[thon] pyx quita[ll] redr[aw] retu[rn] rub[y] sI sIn sal[l] sba[ll] sbp[revious] scg scripte[ncoding] setg[lobal] sgI sgn sic sim[alt] sla[st] smile so[urce] spelli[nfo] sr sri sta[g] stopi[nsert] sus[pend] sync ta[g] tabe[dit] tabn[ext] tabs te[aroff] tm[enu] to[pleft] tu[nmenu] undol[ist] up[date] vi[sual] vmapc[lear] wa[ll] winp[os] ws[verb] xmapc[lear] xprop
-syn keyword vimCommand contained ab argd[elete] as[cii] bd[elete] bo[tright] breakl[ist] cN[ext] caddf[ile] ccl[ose] cfdo chd[ir] cle[arjumps] co[py] con[tinue] cr[ewind] d[elete] deletel delm[arks] diffo[ff] dir dp earlier elsei[f] endw[hile] files fini[sh] folddoc[losed] gr[ep] helpc[lose] his[tory] il[ist] iuna[bbrev] keepalt la[st] later lcs lf[ile] lgr[ep] lli[st] lo[adview] lop[en] lua m[ove] mes mkvie[w] nb[key] noa nos[wapfile] on[ly] packl[oadall] po[p] pro ps[earch] ptl[ast] pu[t] pydo pyxdo r[ead] redraws[tatus] rew[ind] rubyd[o] sIc sIp san[dbox] sbf[irst] sbr[ewind] sci scs setl[ocal] sgc sgp sie sin sm[agic] sn[ext] sor[t] spellr[epall] srI srl star[tinsert] sts[elect] sv[iew] syncbind tab tabf[ind] tabnew tags tf[irst] tma[p] tp[revious] tunma[p] unh[ide] v vie[w] vne[w] wh[ile] wn[ext] wundo xme xunme
-syn keyword vimCommand contained abc[lear] argdo au bel[owright] bp[revious] bro[wse] cNf[ile] cal[l] cd cfir[st] che[ckpath] clo[se] col[der] conf[irm] cs debug deletep delp diffp[atch] dj[ump] dr[op] ec em[enu] ene[w] filet fir[st] foldo[pen] grepa[dd] helpf[ind] i imapc[lear] j[oin] keepj[umps] lad[dexpr] lb[uffer] lcscope lfdo lgrepa[dd] lmak[e] loadk lp[revious] luado ma[rk] messages mod[e] nbc[lose] noautocmd nu[mber] opt[ions] pc[lose] popu[p] prof[ile] ptN[ext] ptn[ext] pw[d] pyf[ile] pyxfile rec[over] reg[isters] ri[ght] rubyf[ile] sIe sIr sav[eas] sbl[ast] sc scl scscope sf[ind] sge sgr sig sip sm[ap] sno[magic] sp[lit] spellu[ndo] src srn startg[replace] sun[hide] sw[apname] syntime tabN[ext] tabfir[st] tabo[nly] tc[l] th[row] tmapc[lear] tr[ewind] u[ndo] unl ve[rsion] vim[grep] vs[plit] win[size] wp[revious] wv[iminfo] xmenu xunmenu
-syn keyword vimCommand contained abo[veleft] arge[dit] bN[ext] bf[irst] br[ewind] bufdo c[hange] cat[ch] cdo cg[etfile] checkt[ime] cmapc[lear] colo[rscheme] cope[n] cscope debugg[reedy] deletl dep diffpu[t] dl ds[earch] echoe[rr] en[dif] ex filetype fix[del] for gui helpg[rep] ia in ju[mps] keepp[atterns] laddb[uffer] lbo[ttom] ld[o] lfir[st] lh[elpgrep] lmapc[lear] loadkeymap lpf[ile] luafile mak[e] mk[exrc] mz[scheme] nbs[tart] noh[lsearch] o[pen] ownsyntax pe[rl] pp[op] profd[el] pta[g] ptp[revious] py3 python3 q[uit] red[o] res[ize] rightb[elow] rundo sIg sN[ext] sbN[ext] sbm[odified] scI scp se[t] sfir[st] sgi sh[ell] sign sir sme snoreme spe[llgood] spellw[rong] sre[wind] srp startr[eplace] sunme sy t tabc[lose] tabl[ast] tabp[revious] tcld[o] tj[ump] tn[ext] try una[bbreviate] unlo[ckvar] verb[ose] vimgrepa[dd] wN[ext] winc[md] wq x[it] xnoreme xwininfo
-syn keyword vimCommand contained al[l] argg[lobal] b[uffer] bl[ast] brea[k] buffers cabc[lear] cb[uffer] ce[nter] cgetb[uffer] chi[story] cn[ext] com cp[revious] cstag delc[ommand] deletp di[splay] diffs[plit] dli[st] dsp[lit] echom[sg] endf[unction] exi[t] filt[er] fo[ld] fu[nction] gvim helpt[ags] iabc[lear] intro k lN[ext] laddf[ile] lc[d] le[ft] lg[etfile] lhi[story] lne[xt] loc[kmarks] lr[ewind] lv[imgrep] marks mks[ession] mzf[ile] new nor ol[dfiles] p[rint] ped[it] pre[serve] promptf[ind] ptf[irst] ptr[ewind] py3do pythonx qa[ll] redi[r] ret[ab] ru[ntime] rv[iminfo] sIl sa[rgument] sb[uffer] sbn[ext] sce scr[iptnames] setf[iletype] sg sgl si sil[ent] sl[eep] smenu snoremenu spelld[ump] spr[evious] srg st[op] stj[ump] sunmenu syn tN[ext] tabd[o] tabm[ove] tabr[ewind] tclf[ile] tl[ast] tno[remap] ts[elect] undoj[oin] uns[ilent] vert[ical] viu[sage] w[rite] windo wqa[ll] xa[ll] xnoremenu y[ank]
-syn keyword vimCommand contained ar[gs] argl[ocal] ba[ll] bm[odified] breaka[dd] bun[load] cad[dbuffer] cbo[ttom] cex[pr] cgete[xpr] cl[ist] cnew[er] comc[lear] cpf[ile] cuna[bbrev] delel delf[unction] dif[fupdate] difft[his] do e[dit] echon endfo[r] exu[sage] fin[d] foldc[lose] g h[elp] hi if is[earch] kee[pmarks] lNf[ile] lan[guage] lch[dir] lefta[bove] lgetb[uffer] ll lnew[er] lockv[ar] ls lvimgrepa[dd] mat[ch] mksp[ell]
-syn keyword vimCommand contained ter[minal]
-
+syn keyword vimCommand contained a arga[dd] argu[ment] bad[d] bn[ext] breakd[el] bw[ipeout] cadde[xpr] cc cf[ile] changes cla[st] cnf[ile] comp[iler] cq[uit] cw[indow] delep dell diffg[et] dig[raphs] doau ea el[se] endt[ry] f[ile] fina[lly] foldd[oopen] go[to] ha[rdcopy] hid[e] ij[ump] isp[lit] keepa l[ist] lat lcl[ose] lex[pr] lgete[xpr] lla[st] lnf[ile] lol[der] lt[ag] lw[indow] menut[ranslate] mkv[imrc] nb[key] noa nos[wapfile] on[ly] packl[oadall] po[p] pro ps[earch] ptl[ast] pu[t] pydo pyxdo r[ead] redraws[tatus] rew[ind] rubyd[o] sIc sIp san[dbox] sbf[irst] sbr[ewind] sci scs setl[ocal] sgc sgp sie sin sm[agic] sn[ext] sor[t] spellr[epall] srI srl star[tinsert] sts[elect] sv[iew] syncbind tab tabf[ind] tabnew tags ter[minal] tm[enu] to[pleft] tu[nmenu] undol[ist] up[date] vi[sual] vmapc[lear] wa[ll] winp[os] ws[verb] xmapc[lear] xprop
+syn keyword vimCommand contained ab argd[elete] as[cii] bd[elete] bo[tright] breakl[ist] cN[ext] caddf[ile] ccl[ose] cfdo chd[ir] cle[arjumps] co[py] con[tinue] cr[ewind] d[elete] deletel delm[arks] diffo[ff] dir dp earlier elsei[f] endw[hile] files fini[sh] folddoc[losed] gr[ep] helpc[lose] his[tory] il[ist] iuna[bbrev] keepalt la[st] later lcs lf[ile] lgr[ep] lli[st] lo[adview] lop[en] lua m[ove] mes mkvie[w] nbc[lose] noautocmd nu[mber] opt[ions] pc[lose] popu[p] prof[ile] ptN[ext] ptn[ext] pw[d] pyf[ile] pyxfile rec[over] reg[isters] ri[ght] rubyf[ile] sIe sIr sav[eas] sbl[ast] sc scl scscope sf[ind] sge sgr sig sip sm[ap] sno[magic] sp[lit] spellu[ndo] src srn startg[replace] sun[hide] sw[apname] syntime tabN[ext] tabfir[st] tabo[nly] tc[l] tf[irst] tma[p] tp[revious] tunma[p] unh[ide] v vie[w] vne[w] wh[ile] wn[ext] wundo xme xunme
+syn keyword vimCommand contained abc[lear] argdo au bel[owright] bp[revious] bro[wse] cNf[ile] cal[l] cd cfir[st] che[ckpath] clo[se] col[der] conf[irm] cs debug deletep delp diffp[atch] dj[ump] dr[op] ec em[enu] ene[w] filet fir[st] foldo[pen] grepa[dd] helpf[ind] i imapc[lear] j[oin] keepj[umps] lad[dexpr] lb[uffer] lcscope lfdo lgrepa[dd] lmak[e] loadk lp[revious] luado ma[rk] messages mod[e] nbs[tart] noh[lsearch] o[pen] ownsyntax pe[rl] pp[op] profd[el] pta[g] ptp[revious] py3 python3 q[uit] red[o] res[ize] rightb[elow] rundo sIg sN[ext] sbN[ext] sbm[odified] scI scp se[t] sfir[st] sgi sh[ell] sign sir sme snoreme spe[llgood] spellw[rong] sre[wind] srp startr[eplace] sunme sy t tabc[lose] tabl[ast] tabp[revious] tcld[o] th[row] tmapc[lear] tr[ewind] u[ndo] unl ve[rsion] vim[grep] vs[plit] win[size] wp[revious] wv[iminfo] xmenu xunmenu
+syn keyword vimCommand contained abo[veleft] arge[dit] bN[ext] bf[irst] br[ewind] bufdo c[hange] cat[ch] cdo cg[etfile] checkt[ime] cmapc[lear] colo[rscheme] cope[n] cscope debugg[reedy] deletl dep diffpu[t] dl ds[earch] echoe[rr] en[dif] ex filetype fix[del] for gui helpg[rep] ia in ju[mps] keepp[atterns] laddb[uffer] lbo[ttom] ld[o] lfir[st] lh[elpgrep] lmapc[lear] loadkeymap lpf[ile] luafile mak[e] mk[exrc] mz[scheme] new nor ol[dfiles] p[rint] ped[it] pre[serve] promptf[ind] ptf[irst] ptr[ewind] py3do pythonx qa[ll] redi[r] ret[ab] ru[ntime] rv[iminfo] sIl sa[rgument] sb[uffer] sbn[ext] sce scr[iptnames] setf[iletype] sg sgl si sil[ent] sl[eep] smenu snoremenu spelld[ump] spr[evious] srg st[op] stj[ump] sunmenu syn tN[ext] tabd[o] tabm[ove] tabr[ewind] tclf[ile] tj[ump] tn[ext] try una[bbreviate] unlo[ckvar] verb[ose] vimgrepa[dd] wN[ext] winc[md] wq x[it] xnoreme xwininfo
+syn keyword vimCommand contained al[l] argg[lobal] b[uffer] bl[ast] brea[k] buffers cabc[lear] cb[uffer] ce[nter] cgetb[uffer] chi[story] cn[ext] com cp[revious] cstag delc[ommand] deletp di[splay] diffs[plit] dli[st] dsp[lit] echom[sg] endf[unction] exi[t] filt[er] fo[ld] fu[nction] gvim helpt[ags] iabc[lear] intro k lN[ext] laddf[ile] lc[d] le[ft] lg[etfile] lhi[story] lne[xt] loc[kmarks] lr[ewind] lv[imgrep] marks mks[ession] mzf[ile] nmapc[lear] nore omapc[lear] pa[ckadd] perld[o] prev[ious] promptr[epl] ptj[ump] pts[elect] py[thon] pyx quita[ll] redr[aw] retu[rn] rub[y] sI sIn sal[l] sba[ll] sbp[revious] scg scripte[ncoding] setg[lobal] sgI sgn sic sim[alt] sla[st] smile so[urce] spelli[nfo] sr sri sta[g] stopi[nsert] sus[pend] sync ta[g] tabe[dit] tabn[ext] tabs te[aroff] tl[ast] tno[remap] ts[elect] undoj[oin] uns[ilent] vert[ical] viu[sage] w[rite] windo wqa[ll] xa[ll] xnoremenu y[ank]
+syn keyword vimCommand contained ar[gs] argl[ocal] ba[ll] bm[odified] breaka[dd] bun[load] cad[dbuffer] cbo[ttom] cex[pr] cgete[xpr] cl[ist] cnew[er] comc[lear] cpf[ile] cuna[bbrev] delel delf[unction] dif[fupdate] difft[his] do e[dit] echon endfo[r] exu[sage] fin[d] foldc[lose] g h[elp] hi if is[earch] kee[pmarks] lNf[ile] lan[guage] lch[dir] lefta[bove] lgetb[uffer] ll lnew[er] lockv[ar] ls lvimgrepa[dd] mat[ch] mksp[ell] n[ext]
syn match vimCommand contained "\<z[-+^.=]\=\>"
-syn keyword vimStdPlugin contained DiffOrig Man N[ext] P[rint] S TOhtml XMLent XMLns
+syn keyword vimStdPlugin contained Arguments Break Clear Continue DiffOrig Evaluate Finish Gdb Man N[ext] Over P[rint] Program Run S Source Step Stop Termdebug TermdebugCommand TOhtml Winbar XMLent XMLns
" vimOptions are caught only when contained in a vimSet {{{2
-syn keyword vimOption contained acd ambw arshape background ballooneval bex bl brk buftype cf cinkeys cmdwinheight com conceallevel crb cscopeverbose cuc def diffexpr ea ei ep eventignore fdi fenc fileformat fkmap foldexpr foldopen fsync gfw guicursor guitabtooltip hidden hlg imactivatefunc imi inc inex isident keymap langnoremap linespace lnr lw makeprg maxmem mfd mmd modified mousemodel msm nu omnifunc para pdev pheader preserveindent printheader pumwidth pythonthreehome readonly restorescreen rnu ruf sc scrolloff selection shellcmdflag shellxescape showbreak si sm so spellfile spr st sts swapsync syn tag tal tcldll termwinscroll tgc titlelen toolbariconsize ttimeout ttymouse tx undolevels vbs viewdir vop wd wic wildmode winheight wm wrapscan
-syn keyword vimOption contained ai anti autochdir backspace balloonevalterm bexpr bo browsedir casemap cfu cino cmp comments confirm cryptmethod cspc cul define diffopt ead ek equalalways ex fdl fencs fileformats flp foldignore foldtext ft ghr guifont helpfile highlight hls imactivatekey iminsert include inf isk keymodel langremap lisp loadplugins lz mat maxmempattern mh mmp more mouses mzq number opendevice paragraphs penc pi previewheight printmbcharset pvh pyx redrawtime revins ro ruler scb scrollopt selectmode shellpipe shellxquote showcmd sidescroll smartcase softtabstop spelllang sps sta su swb synmaxcol tagbsearch tb tenc termwinsize tgst titleold top ttimeoutlen ttyscroll uc undoreload vdir viewoptions wa weirdinvert wig wildoptions winminheight wmh write
-syn keyword vimOption contained akm antialias autoindent backup balloonexpr bg bomb bs cb ch cinoptions cms commentstring copyindent cscopepathcomp csprg cursorbind delcombine digraph eadirection emo equalprg expandtab fdls fex fileignorecase fml foldlevel formatexpr gcr go guifontset helpheight history hlsearch imaf ims includeexpr infercase iskeyword keywordprg laststatus lispwords lpl ma matchpairs maxmemtot mis mmt mouse mouseshape mzquantum numberwidth operatorfunc paste perldll pm previewwindow printmbfont pvw pyxversion regexpengine ri rop rulerformat scl scs sessionoptions shellquote shiftround showfulltag sidescrolloff smartindent sol spellsuggest sr stal sua swf syntax tagcase tbi term terse thesaurus titlestring tpm ttm ttytype udf updatecount ve vif wak wfh wildchar wim winminwidth wmnu writeany
-syn keyword vimOption contained al ar autoread backupcopy bdir bh breakat bsdir cc charconvert cinw co compatible cot cscopeprg csqf cursorcolumn dex dip eb emoji errorbells exrc fdm ff filetype fmr foldlevelstart formatlistpat gd gp guifontwide helplang hk ic imak imsearch incsearch insertmode isp km lazyredraw list lrm macatsui matchtime mco mkspellmem mod mousef mouset mzschemedll nuw opfunc pastetoggle pex pmbcs printdevice printoptions pw qe relativenumber rightleft rs runtimepath scr sect sft shellredir shiftwidth showmatch signcolumn smarttab sp spf srr startofline suffixes switchbuf ta taglength tbidi termbidi textauto tildeop tl tr tty tw udir updatetime verbose viminfo warn wfw wildcharm winaltkeys winptydll wmw writebackup
-syn keyword vimOption contained aleph arab autowrite backupdir bdlay bin breakindent bsk ccv ci cinwords cocu complete cp cscopequickfix csre cursorline dg dir ed enc errorfile fcl fdn ffs fillchars fo foldmarker formatoptions gdefault grepformat guiheadroom hf hkmap icon imc imsf inde is isprint kmp lbr listchars ls magic maxcombine mef ml modeline mousefocus mousetime mzschemegcdll odev osfiletype patchexpr pexpr pmbfn printencoding prompt pythondll quoteescape remap rightleftcmd rtp sb scroll sections sh shellslash shm showmode siso smc spc spl ss statusline suffixesadd sws tabline tagrelative tbis termencoding textmode timeout tm ts ttybuiltin twk ul ur verbosefile viminfofile wb wh wildignore window winwidth wop writedelay
-syn keyword vimOption contained allowrevins arabic autowriteall backupext belloff binary breakindentopt bt cd cin clipboard cole completefunc cpo cscoperelative cst cwh dict directory edcompatible encoding errorformat fcs fdo fic fixendofline foldclose foldmethod formatprg gfm grepprg guioptions hh hkmapp iconstring imcmdline imst indentexpr isf joinspaces kp lcs lm lsp makeef maxfuncdepth menc mls modelines mousehide mp nf oft pa patchmode pfn popt printexpr pt pythonhome rdt renderoptions rl ru sbo scrollbind secure shcf shelltemp shortmess showtabline sj smd spell splitbelow ssl stl sw sxe tabpagemax tags tbs termguicolors textwidth timeoutlen to tsl ttyfast tws undodir ut vfile virtualedit wc whichwrap wildignorecase winfixheight wiv wrap ws
-syn keyword vimOption contained altkeymap arabicshape aw backupskip beval bk bri bufhidden cdpath cindent cm colorcolumn completeopt cpoptions cscopetag csto debug dictionary display ef endofline esckeys fdc fdt fileencoding fixeol foldcolumn foldminlines fp gfn gtl guipty hi hkp ignorecase imd imstatusfunc indentkeys isfname js langmap linebreak lmap luadll makeencoding maxmapdepth menuitems mm modifiable mousem mps nrformats ofu packpath path ph pp printfont pumheight pythonthreedll re report rlc rubydll sbr scrolljump sel shell shelltype shortname shq slm sn spellcapcheck splitright ssop stmp swapfile sxq tabstop tagstack tc termwinkey tf title toolbar tsr ttym twsl undofile vb vi visualbell wcm wi wildmenu winfixwidth wiw wrapmargin ww
-syn keyword vimOption contained ambiwidth ari awa balloondelay bevalterm bkc briopt buflisted cedit cink cmdheight columns concealcursor cpt cscopetagorder csverb deco diff dy efm eol et fde fen fileencodings fk foldenable foldnestmax fs gfs gtt guitablabel hid hl im imdisable imstyle indk isi key langmenu lines
+syn keyword vimOption contained acd ambw arshape background ballooneval bex bl brk buftype cf cinkeys cmdwinheight com conceallevel crb cscopeverbose cuc def diffexpr ea ei ep eventignore fdi fenc fileformat fkmap foldexpr foldopen fsync gfw guicursor guitabtooltip hidden hlg imactivatefunc imi inc inex isident keymap langnoremap linespace loadplugins ma matchtime mef ml modeline mousefocus mousetime mzschemegcdll odev osfiletype patchexpr pexpr pmbfn printencoding prompt pythondll quoteescape remap rightleftcmd rtp sb scroll sections sh shellslash shm showmode siso smc spc spl ss statusline suffixesadd sws tabline tagrelative tbis termencoding textmode timeout tm ts ttybuiltin twk ul ur ve vif vts wd wic wildmode winheight wm wrapscan
+syn keyword vimOption contained ai anti autochdir backspace balloonevalterm bexpr bo browsedir casemap cfu cino cmp comments confirm cryptmethod cspc cul define diffopt ead ek equalalways ex fdl fencs fileformats flp foldignore foldtext ft ghr guifont helpfile highlight hls imactivatekey iminsert include inf isk keymodel langremap lisp lpl macatsui maxcombine menc mls modelines mousehide mp nf oft pa patchmode pfn popt printexpr pt pythonhome rdt renderoptions rl ru sbo scrollbind secure shcf shelltemp shortmess showtabline sj smd spell splitbelow ssl stl sw sxe tabpagemax tags tbs termguicolors textwidth timeoutlen to tsl ttyfast tws undodir ut verbose viminfo wa weirdinvert wig wildoptions winminheight wmh write
+syn keyword vimOption contained akm antialias autoindent backup balloonexpr bg bomb bs cb ch cinoptions cms commentstring copyindent cscopepathcomp csprg cursorbind delcombine digraph eadirection emo equalprg expandtab fdls fex fileignorecase fml foldlevel formatexpr gcr go guifontset helpheight history hlsearch imaf ims includeexpr infercase iskeyword keywordprg laststatus lispwords lrm magic maxfuncdepth menuitems mm modifiable mousem mps nrformats ofu packpath path ph pp printfont pumheight pythonthreedll re report rlc rubydll sbr scrolljump sel shell shelltype shortname shq slm sn spellcapcheck splitright ssop stmp swapfile sxq tabstop tagstack tc termwinkey tf title toolbar tsr ttym twsl undofile varsofttabstop verbosefile viminfofile wak wfh wildchar wim winminwidth wmnu writeany
+syn keyword vimOption contained al ar autoread backupcopy bdir bh breakat bsdir cc charconvert cinw co compatible cot cscopeprg csqf cursorcolumn dex dip eb emoji errorbells exrc fdm ff filetype fmr foldlevelstart formatlistpat gd gp guifontwide helplang hk ic imak imsearch incsearch insertmode isp km lazyredraw list ls makeef maxmapdepth mfd mmd modified mousemodel msm nu omnifunc para pdev pheader preserveindent printheader pumwidth pythonthreehome readonly restorescreen rnu ruf sc scrolloff selection shellcmdflag shellxescape showbreak si sm so spellfile spr st sts swapsync syn tag tal tcldll termwinscroll tgc titlelen toolbariconsize ttimeout ttymouse tx undolevels vartabstop vfile virtualedit warn wfw wildcharm winaltkeys winptydll wmw writebackup
+syn keyword vimOption contained aleph arab autowrite backupdir bdlay bin breakindent bsk ccv ci cinwords cocu complete cp cscopequickfix csre cursorline dg dir ed enc errorfile fcl fdn ffs fillchars fo foldmarker formatoptions gdefault grepformat guiheadroom hf hkmap icon imc imsf inde is isprint kmp lbr listchars lsp makeencoding maxmem mh mmp more mouses mzq number opendevice paragraphs penc pi previewheight printmbcharset pvh pyx redrawtime revins ro ruler scb scrollopt selectmode shellpipe shellxquote showcmd sidescroll smartcase softtabstop spelllang sps sta su swb synmaxcol tagbsearch tb tenc termwinsize tgst titleold top ttimeoutlen ttyscroll uc undoreload vb vi visualbell wb wh wildignore window winwidth wop writedelay
+syn keyword vimOption contained allowrevins arabic autowriteall backupext belloff binary breakindentopt bt cd cin clipboard cole completefunc cpo cscoperelative cst cwh dict directory edcompatible encoding errorformat fcs fdo fic fixendofline foldclose foldmethod formatprg gfm grepprg guioptions hh hkmapp iconstring imcmdline imst indentexpr isf joinspaces kp lcs lm luadll makeprg maxmempattern mis mmt mouse mouseshape mzquantum numberwidth operatorfunc paste perldll pm previewwindow printmbfont pvw pyxversion regexpengine ri rop rulerformat scl scs sessionoptions shellquote shiftround showfulltag sidescrolloff smartindent sol spellsuggest sr stal sua swf syntax tagcase tbi term terse thesaurus titlestring tpm ttm ttytype udf updatecount vbs viewdir vop wc whichwrap wildignorecase winfixheight wiv wrap ws
+syn keyword vimOption contained altkeymap arabicshape aw backupskip beval bk bri bufhidden cdpath cindent cm colorcolumn completeopt cpoptions cscopetag csto debug dictionary display ef endofline esckeys fdc fdt fileencoding fixeol foldcolumn foldminlines fp gfn gtl guipty hi hkp ignorecase imd imstatusfunc indentkeys isfname js langmap linebreak lmap lw mat maxmemtot mkspellmem mod mousef mouset mzschemedll nuw opfunc pastetoggle pex pmbcs printdevice printoptions pw qe relativenumber rightleft rs runtimepath scr sect sft shellredir shiftwidth showmatch signcolumn smarttab sp spf srr startofline suffixes switchbuf ta taglength tbidi termbidi textauto tildeop tl tr tty tw udir updatetime vdir viewoptions vsts wcm wi wildmenu winfixwidth wiw wrapmargin ww
+syn keyword vimOption contained ambiwidth ari awa balloondelay bevalterm bkc briopt buflisted cedit cink cmdheight columns concealcursor cpt cscopetagorder csverb deco diff dy efm eol et fde fen fileencodings fk foldenable foldnestmax fs gfs gtt guitablabel hid hl im imdisable imstyle indk isi key langmenu lines lnr lz matchpairs mco
" vimOptions: These are the turn-off setting variants {{{2
syn keyword vimOption contained noacd noallowrevins noantialias noarabic noarshape noautoread noaw noballooneval nobevalterm nobk nobreakindent nocf nocindent nocopyindent nocscoperelative nocsre nocuc nocursorcolumn nodelcombine nodigraph noed noemo noeol noesckeys noexpandtab nofic nofixeol nofoldenable nogd nohid nohkmap nohls noicon noimc noimdisable noinfercase nojoinspaces nolangremap nolinebreak nolist noloadplugins nolrm noma nomagic noml nomodeline nomodified nomousef nomousehide nonumber noopendevice nopi nopreviewwindow nopvw norelativenumber norestorescreen nori norl noro noru nosb noscb noscs nosft noshelltemp noshortname noshowfulltag noshowmode nosm nosmartindent nosmd nosol nosplitbelow nospr nossl nostartofline noswapfile nota notagrelative notbi notbs noterse notextmode notgst notimeout noto notr nottybuiltin notx noundofile novisualbell nowarn noweirdinvert nowfw nowildignorecase nowinfixheight nowiv nowrap nowrite nowritebackup
@@ -68,7 +66,7 @@ syn keyword vimErrSetting contained bioskey biosk conskey consk autoprint beauti
" AutoCmd Events {{{2
syn case ignore
-syn keyword vimAutoEvent contained BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineChanged CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme CompleteDone CursorHold CursorHoldI CursorMoved CursorMovedI DirChanged EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave MenuPopup OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TermResponse TextChanged TextChangedI TextChangedP TextYankPost User VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave WinNew
+syn keyword vimAutoEvent contained BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineChanged CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme ColorSchemePre CompleteDone CursorHold CursorHoldI CursorMoved CursorMovedI DirChanged EncodingChanged ExitPre FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave MenuPopup OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TerminalOpen TermResponse TextChanged TextChangedI TextChangedP TextYankPost User VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave WinNew
" Highlight commonly used Groupnames {{{2
syn keyword vimGroup contained Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo
@@ -79,10 +77,10 @@ syn match vimHLGroup contained "Conceal"
syn case match
" Function Names {{{2
-syn keyword vimFuncName contained abs append argv assert_equalfile assert_inrange assert_report balloon_show bufexists bufnr byteidx changenr ch_close_in ch_getjob ch_open ch_sendraw clearmatches complete_check cosh deepcopy diff_hlID eventhandler exists feedkeys finddir fmod foldclosedend foreground get getchangelist getcmdline getcompletion getfperm getjumplist getpid getregtype getwininfo getwinvar has histadd hlexists indent inputlist insert isnan job_setoptions join json_encode libcallnr localtime map matchadd matchend max mzeval option_save pow py3eval readfile remote_expr remote_send repeat screenattr search searchpos setbufvar setline setqflist setwinvar simplify soundfold sqrt strchars stridx strridx substitute synIDtrans tabpagebuflist taglist term_dumpdiff term_getansicolors term_getline term_gettitle term_sendkeys term_setsize test_autochdir test_ignore_error test_null_job test_null_string timer_info timer_stop toupper trunc undotree virtcol winbufnr win_getid win_id2tabwin winnr winsaveview wordcount
-syn keyword vimFuncName contained acos argc asin assert_exception assert_match assert_true balloon_split buflisted bufwinid byteidxcomp char2nr ch_evalexpr ch_info ch_read ch_setoptions col confirm count delete empty executable exp filereadable findfile fnameescape foldlevel funcref getbufinfo getchar getcmdpos getcurpos getfsize getline getpos gettabinfo getwinpos glob has_key histdel hlID index inputrestore invert items job_start js_decode keys line log maparg matchaddpos matchlist min nextnonblank or prevnonblank pyeval reltime remote_foreground remote_startserver resolve screenchar searchdecl server2client setcharsearch setloclist setreg sha256 sin spellbadword str2float strdisplaywidth string strtrans synconcealed synstack tabpagenr tan term_dumpload term_getattr term_getscrolled term_gettty term_setansicolors term_start test_feedinput test_null_channel test_null_list test_override timer_pause timer_stopall tr type uniq visualmode wincol win_gotoid win_id2win winrestcmd win_screenpos writefile
-syn keyword vimFuncName contained add argidx assert_beeps assert_fails assert_notequal atan browse bufloaded bufwinnr call ch_canread ch_evalraw ch_log ch_readraw ch_status complete copy cscope_connection did_filetype escape execute expand filewritable float2nr fnamemodify foldtext function getbufline getcharmod getcmdtype getcwd getftime getloclist getqflist gettabvar getwinposx glob2regpat haslocaldir histget hostname input inputsave isdirectory job_getchannel job_status js_encode len line2byte log10 mapcheck matcharg matchstr mkdir nr2char pathshorten printf pyxeval reltimefloat remote_peek remove reverse screencol searchpair serverlist setcmdpos setmatches settabvar shellescape sinh spellsuggest str2nr strftime strlen strwidth synID system tabpagewinnr tanh term_dumpwrite term_getcursor term_getsize term_list term_setkill term_wait test_garbagecollect_now test_null_dict test_null_partial test_settime timer_start tolower trim undofile values wildmenumode win_findbuf winheight winline winrestview winwidth xor
-syn keyword vimFuncName contained and arglistid assert_equal assert_false assert_notmatch atan2 browsedir bufname byte2line ceil ch_close ch_getbufnr ch_logfile ch_sendexpr cindent complete_add cos cursor diff_filler eval exepath extend filter floor foldclosed foldtextresult garbagecollect getbufvar getcharsearch getcmdwintype getfontname getftype getmatches getreg gettabwinvar getwinposy globpath hasmapto histnr iconv inputdialog inputsecret islocked job_info job_stop json_decode libcall lispindent luaeval match matchdelete matchstrpos mode option_restore perleval pumvisible range reltimestr remote_read rename round screenrow searchpairpos setbufline setfperm setpos settabwinvar shiftwidth sort split strcharpart strgetchar strpart submatch synIDattr systemlist tagfiles tempname term_getaltscreen term_getjob term_getstatus term_scrape term_setrestore test_alloc_fail
+syn keyword vimFuncName contained abs append arglistid assert_equal assert_false assert_notmatch atan2 browsedir bufname byte2line ceil ch_close ch_getbufnr ch_logfile ch_sendexpr cindent complete_add cos cursor deletebufline empty executable exp filereadable findfile fnameescape foldlevel funcref getbufinfo getchar getcmdpos getcurpos getfsize getline getpos gettabinfo getwinpos glob has_key histdel hlID index inputrestore invert items job_start js_decode keys line log maparg matchaddpos matchlist min nextnonblank perleval prompt_addtext pumvisible range reltime remote_foreground remote_startserver resolve screenchar searchdecl server2client setcharsearch setloclist setreg sha256 sin spellbadword str2float strdisplaywidth string strtrans synconcealed synstack tabpagenr tan term_dumpload term_getattr term_getscrolled term_gettty term_setansicolors term_start test_feedinput test_null_dict test_null_string timer_pause tolower trunc undotree virtcol winbufnr win_getid win_id2tabwin winnr winsaveview wordcount
+syn keyword vimFuncName contained acos appendbufline argv assert_equalfile assert_inrange assert_report balloon_show bufexists bufnr byteidx changenr ch_close_in ch_getjob ch_open ch_sendraw clearmatches complete_check cosh debugbreak did_filetype escape execute expand filewritable float2nr fnamemodify foldtext function getbufline getcharmod getcmdtype getcwd getftime getloclist getqflist gettabvar getwinposx glob2regpat haslocaldir histget hostname input inputsave isdirectory job_getchannel job_status js_encode len line2byte log10 mapcheck matcharg matchstr mkdir nr2char pow prompt_setcallback py3eval readfile reltimefloat remote_peek remove reverse screencol searchpair serverlist setcmdpos setmatches settabvar shellescape sinh spellsuggest str2nr strftime strlen strwidth synID system tabpagewinnr tanh term_dumpwrite term_getcursor term_getsize term_list term_setkill term_wait test_garbagecollect_now test_null_job test_override timer_start toupper type uniq visualmode wincol win_gotoid win_id2win winrestcmd win_screenpos writefile
+syn keyword vimFuncName contained add argc asin assert_exception assert_match assert_true balloon_split buflisted bufwinid byteidxcomp char2nr ch_evalexpr ch_info ch_read ch_setoptions col confirm count deepcopy diff_filler eval exepath extend filter floor foldclosed foldtextresult garbagecollect getbufvar getcharsearch getcmdwintype getfontname getftype getmatches getreg gettabwinvar getwinposy globpath hasmapto histnr iconv inputdialog inputsecret islocked job_info job_stop json_decode libcall lispindent luaeval match matchdelete matchstrpos mode or prevnonblank prompt_setinterrupt pyeval reg_executing reltimestr remote_read rename round screenrow searchpairpos setbufline setfperm setpos settabwinvar shiftwidth sort split strcharpart strgetchar strpart submatch synIDattr systemlist tagfiles tempname term_getaltscreen term_getjob term_getstatus term_scrape term_setrestore test_alloc_fail test_ignore_error test_null_list test_settime timer_stop tr undofile values wildmenumode win_findbuf winheight winline winrestview winwidth xor
+syn keyword vimFuncName contained and argidx assert_beeps assert_fails assert_notequal atan browse bufloaded bufwinnr call ch_canread ch_evalraw ch_log ch_readraw ch_status complete copy cscope_connection delete diff_hlID eventhandler exists feedkeys finddir fmod foldclosedend foreground get getchangelist getcmdline getcompletion getfperm getjumplist getpid getregtype getwininfo getwinvar has histadd hlexists indent inputlist insert isnan job_setoptions join json_encode libcallnr localtime map matchadd matchend max mzeval pathshorten printf prompt_setprompt pyxeval reg_recording remote_expr remote_send repeat screenattr search searchpos setbufvar setline setqflist setwinvar simplify soundfold sqrt strchars stridx strridx substitute synIDtrans tabpagebuflist taglist term_dumpdiff term_getansicolors term_getline term_gettitle term_sendkeys term_setsize test_autochdir test_null_channel test_null_partial timer_info timer_stopall trim
"--- syntax here and above generated by mkvimvim ---
" Special Vim Highlighting (not automatic) {{{1
@@ -163,24 +161,26 @@ endif
" Numbers {{{2
" =======
-syn match vimNumber "\<\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\=" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand
-syn match vimNumber "-\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\=" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand
-syn match vimNumber "\<0[xX]\x\+"
-syn match vimNumber "\%(^\|\A\)\zs#\x\{6}"
+syn match vimNumber "\<\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\=" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment
+syn match vimNumber "-\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\=" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment
+syn match vimNumber "\<0[xX]\x\+" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment
+syn match vimNumber "\%(^\|\A\)\zs#\x\{6}" skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment
" All vimCommands are contained by vimIsCommands. {{{2
-syn match vimCmdSep "[:|]\+" skipwhite nextgroup=vimAddress,vimAutoCmd,vimIsCommand,vimExtCmd,vimFilter,vimLet,vimMap,vimMark,vimSet,vimSyntax,vimUserCmd
+syn match vimCmdSep "[:|]\+" skipwhite nextgroup=vimAddress,vimAutoCmd,vimEcho,vimIsCommand,vimExtCmd,vimFilter,vimLet,vimMap,vimMark,vimSet,vimSyntax,vimUserCmd
syn match vimIsCommand "\<\h\w*\>" contains=vimCommand
-syn match vimVar contained "\<\h[a-zA-Z0-9#_]*\>"
+syn match vimVar contained "\<\h[a-zA-Z0-9#_]*\>"
syn match vimVar "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>"
+syn match vimVar "\s\zs&\a\+\>"
syn match vimFBVar contained "\<[bwglstav]:\h[a-zA-Z0-9#_]*\>"
syn keyword vimCommand contained in
" Insertions And Appends: insert append {{{2
" =======================
-syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=a\%[ppend]$" matchgroup=vimCommand end="^\.$""
-syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=c\%[hange]$" matchgroup=vimCommand end="^\.$""
-syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=i\%[nsert]$" matchgroup=vimCommand end="^\.$""
+syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=a\%[ppend]$" matchgroup=vimCommand end="^\.$""
+syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=c\%[hange]$" matchgroup=vimCommand end="^\.$""
+syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=i\%[nsert]$" matchgroup=vimCommand end="^\.$""
+syn region vimInsert matchgroup=vimCommand start="^[: \t]*\(\d\+\(,\d\+\)\=\)\=starti\%[nsert]$" matchgroup=vimCommand end="^\.$""
" Behave! {{{2
" =======
@@ -228,7 +228,7 @@ endif
" Functions : Tag is provided for those who wish to highlight tagged functions {{{2
" =========
syn cluster vimFuncList contains=vimCommand,vimFunctionError,vimFuncKey,Tag,vimFuncSID
-syn cluster vimFuncBodyList contains=vimAbb,vimAddress,vimAugroupKey,vimAutoCmd,vimCmplxRepeat,vimComment,vimContinue,vimCtrlChar,vimEcho,vimEchoHL,vimExecute,vimIf,vimIsCommand,vimFBVar,vimFunc,vimFunction,vimFuncVar,vimGlobal,vimHighlight,vimIsCommand,vimLet,vimLineComment,vimMap,vimMark,vimNorm,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegion,vimRegister,vimSet,vimSpecFile,vimString,vimSubst,vimSynLine,vimUnmap,vimUserCommand
+syn cluster vimFuncBodyList contains=vimAbb,vimAddress,vimAugroupKey,vimAutoCmd,vimCmplxRepeat,vimComment,vimContinue,vimCtrlChar,vimEcho,vimEchoHL,vimExecute,vimIsCommand,vimFBVar,vimFunc,vimFunction,vimFuncVar,vimGlobal,vimHighlight,vimIsCommand,vimLet,vimLineComment,vimMap,vimMark,vimNorm,vimNotation,vimNotFunc,vimNumber,vimOper,vimOperParen,vimRegion,vimRegister,vimSearch,vimSet,vimSpecFile,vimString,vimSubst,vimSynLine,vimUnmap,vimUserCommand
syn match vimFunction "\<fu\%[nction]!\=\s\+\%(<[sS][iI][dD]>\|[sSgGbBwWtTlL]:\)\=\%(\i\|[#.]\|{.\{-1,}}\)*\ze\s*(" contains=@vimFuncList nextgroup=vimFuncBody
if exists("g:vimsyn_folding") && g:vimsyn_folding =~# 'f'
@@ -301,7 +301,7 @@ syn region vimPatSepZone oneline contained matchgroup=vimPatSepZ start="\\%\
syn region vimPatRegion contained transparent matchgroup=vimPatSepR start="\\[z%]\=(" end="\\)" contains=@vimSubstList oneline
syn match vimNotPatSep contained "\\\\"
syn cluster vimStringGroup contains=vimEscapeBrace,vimPatSep,vimNotPatSep,vimPatSepErr,vimPatSepZone,@Spell
-syn region vimString oneline keepend start=+[^a-zA-Z>!\\@]"+lc=1 skip=+\\\\\|\\"+ end=+"+ contains=@vimStringGroup
+syn region vimString oneline keepend start=+[^a-zA-Z>!\\@]"+lc=1 skip=+\\\\\|\\"+ matchgroup=vimStringEnd end=+"+ contains=@vimStringGroup
syn region vimString oneline keepend start=+[^a-zA-Z>!\\@]'+lc=1 end=+'+
syn region vimString oneline start=+=!+lc=1 skip=+\\\\\|\\!+ end=+!+ contains=@vimStringGroup
syn region vimString oneline start="=+"lc=1 skip="\\\\\|\\+" end="+" contains=@vimStringGroup
@@ -319,6 +319,7 @@ syn match vimSubst "\%(^\|[^\\]\)\<s\%[ubstitute]\>[:#[:alpha:]]\@!" nextgroup=v
syn match vimSubst "/\zs\<s\%[ubstitute]\>\ze/" nextgroup=vimSubstPat
syn match vimSubst "\(:\+\s*\|^\s*\)s\ze#.\{-}#.\{-}#" nextgroup=vimSubstPat
syn match vimSubst1 contained "\<s\%[ubstitute]\>" nextgroup=vimSubstPat
+syn match vimSubst2 contained "s\%[ubstitute]\>" nextgroup=vimSubstPat
syn region vimSubstPat contained matchgroup=vimSubstDelim start="\z([^a-zA-Z( \t[\]&]\)"rs=s+1 skip="\\\\\|\\\z1" end="\z1"re=e-1,me=e-1 contains=@vimSubstList nextgroup=vimSubstRep4 oneline
syn region vimSubstRep4 contained matchgroup=vimSubstDelim start="\z(.\)" skip="\\\\\|\\\z1" end="\z1" matchgroup=vimNotation end="<[cC][rR]>" contains=@vimSubstRepList nextgroup=vimSubstFlagErr oneline
syn region vimCollection contained transparent start="\\\@<!\[" skip="\\\[" end="\]" contains=vimCollClass
@@ -338,7 +339,7 @@ syn match vimMark "'[<>]\ze[-+,!]" nextgroup=vimOper,vimMarkNumber,vimSubst
syn match vimMark ",\zs'[<>]\ze" nextgroup=vimOper,vimMarkNumber,vimSubst
syn match vimMark "[!,:]\zs'[a-zA-Z0-9]" nextgroup=vimOper,vimMarkNumber,vimSubst
syn match vimMark "\<norm\%[al]\s\zs'[a-zA-Z0-9]" nextgroup=vimOper,vimMarkNumber,vimSubst
-syn match vimMarkNumber "[-+]\d\+" nextgroup=vimSubst contained contains=vimOper
+syn match vimMarkNumber "[-+]\d\+" contained contains=vimOper nextgroup=vimSubst2
syn match vimPlainMark contained "'[a-zA-Z0-9]"
syn match vimRegister '[^,;[{: \t]\zs"[a-zA-Z0-9.%#:_\-/]\ze[^a-zA-Z_":0-9]'
@@ -358,9 +359,9 @@ syn match vimCmplxRepeat '[^a-zA-Z_/\\()]q[0-9a-zA-Z"]\>'lc=1
syn match vimCmplxRepeat '@[0-9a-z".=@:]\ze\($\|[^a-zA-Z]\>\)'
" Set command and associated set-options (vimOptions) with comment {{{2
-syn region vimSet matchgroup=vimCommand start="\<\%(setl\%[ocal]\|setg\%[lobal]\|se\%[t]\)\>" skip="\%(\\\\\)*\\." end="$" matchgroup=vimNotation end="<[cC][rR]>" keepend oneline contains=vimSetEqual,vimOption,vimErrSetting,vimComment,vimSetString,vimSetMod
-syn region vimSetEqual contained start="[=:]\|[-+^]=" skip="\\\\\|\\\s" end="[| \t]\|$"me=e-1 contains=vimCtrlChar,vimSetSep,vimNotation,vimEnvvar oneline
-syn region vimSetString contained start=+="+hs=s+1 skip=+\\\\\|\\"+ end=+"+ contains=vimCtrlChar
+syn region vimSet matchgroup=vimCommand start="\<\%(setl\%[ocal]\|setg\%[lobal]\|se\%[t]\)\>" skip="\%(\\\\\)*\\." end="$" end="|" matchgroup=vimNotation end="<[cC][rR]>" keepend oneline contains=vimSetEqual,vimOption,vimErrSetting,vimComment,vimSetString,vimSetMod
+syn region vimSetEqual contained start="[=:]\|[-+^]=" skip="\\\\\|\\\s" end="[| \t]\|$"me=e-1 contains=vimCtrlChar,vimSetSep,vimNotation,vimEnvvar oneline
+syn region vimSetString contained start=+="+hs=s+1 skip=+\\\\\|\\"+ end=+"+ contains=vimCtrlChar
syn match vimSetSep contained "[,:]" skipwhite nextgroup=vimCommand
syn match vimSetMod contained "&vim\=\|[!&?<]\|all&"
@@ -418,7 +419,7 @@ syn match vimMenuBang "!" contained skipwhite nextgroup=@vimMenuList
" Angle-Bracket Notation (tnx to Michael Geddes) {{{2
" ======================
syn case ignore
-syn match vimNotation "\%#=1\(\\\|<lt>\)\=<\([scamd]-\)\{0,4}x\=\(f\d\{1,2}\|[^ \t:]\|cr\|lf\|linefeed\|return\|k\=del\%[ete]\|bs\|backspace\|tab\|esc\|right\|left\|help\|undo\|insert\|ins\|k\=home\|k\=end\|kplus\|kminus\|kdivide\|kmultiply\|kenter\|kpoint\|space\|k\=\(page\)\=\(\|down\|up\|k\d\>\)\)>" contains=vimBracket
+syn match vimNotation "\%#=1\(\\\|<lt>\)\=<\([scamd]-\)\{0,4}x\=\(f\d\{1,2}\|[^ \t:]\|cr\|lf\|linefeed\|return\|k\=del\%[ete]\|bs\|backspace\|tab\|esc\|right\|left\|help\|undo\|insert\|ins\|mouse\|k\=home\|k\=end\|kplus\|kminus\|kdivide\|kmultiply\|kenter\|kpoint\|space\|k\=\(page\)\=\(\|down\|up\|k\d\>\)\)>" contains=vimBracket
syn match vimNotation "\%#=1\(\\\|<lt>\)\=<\([scam2-4]-\)\{0,4}\(right\|left\|middle\)\(mouse\)\=\(drag\|release\)\=>" contains=vimBracket
syn match vimNotation "\%#=1\(\\\|<lt>\)\=<\(bslash\|plug\|sid\|space\|bar\|nop\|nul\|lt\)>" contains=vimBracket
syn match vimNotation '\(\\\|<lt>\)\=<C-R>[0-9a-z"%#:.\-=]'he=e-1 contains=vimBracket
@@ -596,7 +597,9 @@ syn match vimHiNmbr contained '\d\+'
syn keyword vimHiClear contained clear nextgroup=vimHiGroup
" Highlight: link {{{2
-syn region vimHiLink contained oneline matchgroup=vimCommand start="\(\<hi\%[ghlight]\s\+\)\@<=\(\(def\%[ault]\s\+\)\=link\>\|\<def\>\)" end="$" contains=vimHiGroup,vimGroup,vimHLGroup,vimNotation
+" see tst24 (hi def vs hi) (Jul 06, 2018)
+"syn region vimHiLink contained oneline matchgroup=vimCommand start="\(\<hi\%[ghlight]\s\+\)\@<=\(\(def\%[ault]\s\+\)\=link\>\|\<def\>\)" end="$" contains=vimHiGroup,vimGroup,vimHLGroup,vimNotation
+syn region vimHiLink contained oneline matchgroup=vimCommand start="\(\<hi\%[ghlight]\s\+\)\@<=\(\(def\%[ault]\s\+\)\=link\>\|\<def\>\)" end="$" contains=@vimHiCluster
syn cluster vimFuncBodyList add=vimHiLink
" Control Characters {{{2
@@ -902,7 +905,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimOper Operator
hi def link vimOption PreProc
hi def link vimParenSep Delimiter
- hi def link vimPatSepErr vimPatSep
+ hi def link vimPatSepErr vimError
hi def link vimPatSepR vimPatSep
hi def link vimPatSep SpecialChar
hi def link vimPatSepZone vimString
@@ -924,6 +927,7 @@ if !exists("skip_vim_syntax_inits")
hi def link vimStatement Statement
hi def link vimStringCont vimString
hi def link vimString String
+ hi def link vimStringEnd vimString
hi def link vimSubst1 vimSubst
hi def link vimSubstDelim Delimiter
hi def link vimSubstFlags Special
diff --git a/runtime/syntax/wast.vim b/runtime/syntax/wast.vim
new file mode 100644
index 0000000..245d5f6
--- /dev/null
+++ b/runtime/syntax/wast.vim
@@ -0,0 +1,84 @@
+" Vim syntax file
+" Language: WebAssembly
+" Maintainer: rhysd <lin90162@yahoo.co.jp>
+" Last Change: Jul 29, 2018
+" For bugs, patches and license go to https://github.com/rhysd/vim-wasm
+
+if exists("b:current_syntax")
+ finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syn cluster wastCluster contains=wastModule,wastInstWithType,wastInstGeneral,wastParamInst,wastControlInst,wastString,wastNamedVar,wastUnnamedVar,wastFloat,wastNumber,wastComment,wastList,wastType
+
+" Instructions
+" https://webassembly.github.io/spec/core/text/instructions.html
+" Note: memarg (align=,offset=) can be added to memory instructions
+syn match wastInstWithType "\%((\s*\)\@<=\<\%(i32\|i64\|f32\|f64\|memory\)\.[[:alnum:]_]\+\%(/\%(i32\|i64\|f32\|f64\)\)\=\>\%(\s\+\%(align\|offset\)=\)\=" contained display
+syn match wastInstGeneral "\%((\s*\)\@<=\<[[:alnum:]_]\+\>" contained display
+" https://webassembly.github.io/spec/core/text/instructions.html#control-instructions
+syn match wastControlInst "\%((\s*\)\@<=\<\%(block\|end\|loop\|if\|else\|unreachable\|nop\|br\|br_if\|br_table\|return\|call\|call_indirect\)\>" contained display
+" https://webassembly.github.io/spec/core/text/instructions.html#parametric-instructions
+syn match wastParamInst "\%((\s*\)\@<=\<\%(drop\|select\)\>" contained display
+
+" Identifiers
+" https://webassembly.github.io/spec/core/text/values.html#text-id
+syn match wastNamedVar "$\+[[:alnum:]!#$%&'∗./:=><?@\\^_`~+-]*" contained display
+syn match wastUnnamedVar "$\+\d\+[[:alnum:]!#$%&'∗./:=><?@\\^_`~+-]\@!" contained display
+
+" String literals
+" https://webassembly.github.io/spec/core/text/values.html#strings
+syn region wastString start=+"+ skip=+\\\\\|\\"+ end=+"+ contained contains=wastStringSpecial
+syn match wastStringSpecial "\\\x\x\|\\[tnr'\\\"]\|\\u\x\+" contained containedin=wastString
+
+" Float literals
+" https://webassembly.github.io/spec/core/text/values.html#floating-point
+syn match wastFloat "\<-\=\d\%(_\=\d\)*\%(\.\d\%(_\=\d\)*\)\=\%([eE][-+]\=\d\%(_\=\d\)*\)\=" display contained
+syn match wastFloat "\<-\=0x\x\%(_\=\d\)*\%(\.\x\%(_\=\x\)*\)\=\%([pP][-+]\=\d\%(_\=\d\)*\)\=" display contained
+syn keyword wastFloat inf nan contained
+
+" Integer literals
+" https://webassembly.github.io/spec/core/text/values.html#integers
+syn match wastNumber "\<-\=\d\%(_\=\d\)*\>" display contained
+syn match wastNumber "\<-\=0x\x\%(_\=\x\)*\>" display contained
+
+" Comments
+" https://webassembly.github.io/spec/core/text/lexical.html#comments
+syn region wastComment start=";;" end="$" display
+syn region wastComment start="(;;\@!" end=";)"
+
+syn region wastList matchgroup=wastListDelimiter start="(;\@!" matchgroup=wastListDelimiter end=";\@<!)" contains=@wastCluster
+
+" Types
+" https://webassembly.github.io/spec/core/text/types.html
+syn keyword wastType i64 i32 f64 f32 param result anyfunc mut contained
+syn match wastType "\%((\_s*\)\@<=func\%(\_s*[()]\)\@=" display contained
+
+" Modules
+" https://webassembly.github.io/spec/core/text/modules.html
+syn keyword wastModule module type export import table memory global data elem contained
+syn match wastModule "\%((\_s*\)\@<=func\%(\_s\+\$\)\@=" display contained
+
+syn sync lines=100
+
+hi def link wastModule PreProc
+hi def link wastListDelimiter Delimiter
+hi def link wastInstWithType Operator
+hi def link wastInstGeneral Operator
+hi def link wastControlInst Statement
+hi def link wastParamInst Conditional
+hi def link wastString String
+hi def link wastStringSpecial Special
+hi def link wastNamedVar Identifier
+hi def link wastUnnamedVar PreProc
+hi def link wastFloat Float
+hi def link wastNumber Number
+hi def link wastComment Comment
+hi def link wastType Type
+
+let b:current_syntax = "wast"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/runtime/tutor/tutor.it b/runtime/tutor/tutor.it
index 57d578f..80862ed 100644
--- a/runtime/tutor/tutor.it
+++ b/runtime/tutor/tutor.it
@@ -14,7 +14,7 @@
I comandi nelle lezioni modificano questo testo. Fai una copia di questo
file per esercitarti (se hai usato "vimtutor", stai gi usando una copia).
- E' importante non scordare che questa guida vuole insegnare tramite
+ importante non scordare che questa guida vuole insegnare tramite
l'uso. Questo vuol dire che devi eseguire i comandi per impararli
davvero. Se leggi il testo e basta, dimenticherai presto i comandi!
@@ -406,7 +406,7 @@ NOTA: Se batti solo il movimento mentre sei in Modalit Normale, senza
---> Ammattendo quetta lince, qualcuno ho predato alcuni tosti sballiati!
---> Immettendo questa linea, qualcuno ha premuto alcuni tasti sbagliati!
- 5. Ora passa alla Lezione 3.2.
+ 5. Ora passa alla Lezione 3.3.
NOTA: Ricordati che dovresti imparare con la pratica, non solo leggendo.
@@ -956,7 +956,7 @@ NOTA: Il completamento disponibile per molti comandi. Prova a battere
Quest'altro libro pi su Vi che su Vim, ma pure consigliato:
Learning the Vi Editor - di Linda Lamb e Arnold Robbins
Editore: O'Reilly & Associates Inc.
- E' un buon libro per imparare quasi tutto ci che puoi voler fare con Vi.
+ un buon libro per imparare quasi tutto ci che puoi voler fare con Vi.
Ne esiste una traduzione italiana, basata su una vecchia edizione.
Questa guida stata scritta da Michael C. Pierce e Robert K. Ware,
diff --git a/runtime/tutor/tutor.it.utf-8 b/runtime/tutor/tutor.it.utf-8
index 74c8120..c1602b5 100644
--- a/runtime/tutor/tutor.it.utf-8
+++ b/runtime/tutor/tutor.it.utf-8
@@ -14,7 +14,7 @@
I comandi nelle lezioni modificano questo testo. Fai una copia di questo
file per esercitarti (se hai usato "vimtutor", stai già usando una copia).
- E' importante non scordare che questa guida vuole insegnare tramite
+ È importante non scordare che questa guida vuole insegnare tramite
l'uso. Questo vuol dire che devi eseguire i comandi per impararli
davvero. Se leggi il testo e basta, dimenticherai presto i comandi!
@@ -406,7 +406,7 @@ NOTA: Se batti solo il movimento mentre sei in Modalità Normale, senza
---> Ammattendo quetta lince, qualcuno ho predato alcuni tosti sballiati!
---> Immettendo questa linea, qualcuno ha premuto alcuni tasti sbagliati!
- 5. Ora passa alla Lezione 3.2.
+ 5. Ora passa alla Lezione 3.3.
NOTA: Ricordati che dovresti imparare con la pratica, non solo leggendo.
@@ -612,7 +612,7 @@ NOTA: Questo è molto utile nel "debug" di un programma con parentesi errate!
visualizza una lista della tua directory, proprio come se fossi in una
"shell". Usa :!dir se ls non funziona. [Unix: ls MS-DOS: dir]
-NOTA: E' possibile in questo modo eseguire un comando a piacere, specificando
+NOTA: È possibile in questo modo eseguire un comando a piacere, specificando
anche dei parametri per i comandi stessi.
NOTA: Tutti i comandi : devono essere terminati premendo <INVIO>
@@ -956,7 +956,7 @@ NOTA: Il completamento è disponibile per molti comandi. Prova a battere
Quest'altro libro è più su Vi che su Vim, ma è pure consigliato:
Learning the Vi Editor - di Linda Lamb e Arnold Robbins
Editore: O'Reilly & Associates Inc.
- E' un buon libro per imparare quasi tutto ciò che puoi voler fare con Vi.
+ È un buon libro per imparare quasi tutto ciò che puoi voler fare con Vi.
Ne esiste una traduzione italiana, basata su una vecchia edizione.
Questa guida è stata scritta da Michael C. Pierce e Robert K. Ware,
diff --git a/src/Make_all.mak b/src/Make_all.mak
index 9831f7b..49ad4f0 100644
--- a/src/Make_all.mak
+++ b/src/Make_all.mak
@@ -12,6 +12,7 @@ NEW_TESTS = \
test_autocmd \
test_autoload \
test_backspace_opt \
+ test_backup \
test_blockedit \
test_breakindent \
test_bufline \
diff --git a/src/auto/configure b/src/auto/configure
index de1fd60..0ab7e23 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -7606,6 +7606,9 @@ $as_echo "$rubyhdrdir" >&6; }
if test "$enable_rubyinterp" = "dynamic"; then
libruby_soname=`$vi_cv_path_ruby -r rbconfig -e "puts $ruby_rbconfig::CONFIG['LIBRUBY_ALIASES'].split[0]"`
+ if test -z "$libruby_soname"; then
+ libruby_soname=`$vi_cv_path_ruby -r rbconfig -e "puts $ruby_rbconfig::CONFIG['LIBRUBY_SO']"`
+ fi
$as_echo "#define DYNAMIC_RUBY 1" >>confdefs.h
RUBY_CFLAGS="-DDYNAMIC_RUBY_DLL=\\\"$libruby_soname\\\" -DDYNAMIC_RUBY_VER=$rubyversion $RUBY_CFLAGS"
diff --git a/src/buffer.c b/src/buffer.c
index 1f1833f..2ca131d 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -204,13 +204,8 @@ open_buffer(
#endif
#ifdef UNIX
perm = mch_getperm(curbuf->b_ffname);
- if (perm >= 0 && (0
-# ifdef S_ISFIFO
- || S_ISFIFO(perm)
-# endif
-# ifdef S_ISSOCK
+ if (perm >= 0 && (S_ISFIFO(perm)
|| S_ISSOCK(perm)
-# endif
# ifdef OPEN_CHR_FILES
|| (S_ISCHR(perm) && is_dev_fd_file(curbuf->b_ffname))
# endif
@@ -1040,7 +1035,14 @@ handle_swap_exists(bufref_T *old_curbuf)
buf = old_curbuf->br_buf;
if (buf != NULL)
{
+ int old_msg_silent = msg_silent;
+
+ if (shortmess(SHM_FILEINFO))
+ msg_silent = 1; // prevent fileinfo message
enter_buffer(buf);
+ // restore msg_silent, so that the command line will be shown
+ msg_silent = old_msg_silent;
+
# ifdef FEAT_SYN_HL
if (old_tw != curbuf->b_p_tw)
check_colorcolumn(curwin);
@@ -1179,26 +1181,14 @@ do_bufdel(
else if (deleted >= p_report)
{
if (command == DOBUF_UNLOAD)
- {
- if (deleted == 1)
- MSG(_("1 buffer unloaded"));
- else
- smsg((char_u *)_("%d buffers unloaded"), deleted);
- }
+ smsg((char_u *)NGETTEXT("%d buffer unloaded",
+ "%d buffers unloaded", deleted), deleted);
else if (command == DOBUF_DEL)
- {
- if (deleted == 1)
- MSG(_("1 buffer deleted"));
- else
- smsg((char_u *)_("%d buffers deleted"), deleted);
- }
+ smsg((char_u *)NGETTEXT("%d buffer deleted",
+ "%d buffers deleted", deleted), deleted);
else
- {
- if (deleted == 1)
- MSG(_("1 buffer wiped out"));
- else
- smsg((char_u *)_("%d buffers wiped out"), deleted);
- }
+ smsg((char_u *)NGETTEXT("%d buffer wiped out",
+ "%d buffers wiped out", deleted), deleted);
}
}
@@ -3490,19 +3480,14 @@ fileinfo(
n = (int)(((long)curwin->w_cursor.lnum * 100L) /
(long)curbuf->b_ml.ml_line_count);
if (curbuf->b_ml.ml_flags & ML_EMPTY)
- {
vim_snprintf_add((char *)buffer, IOSIZE, "%s", _(no_lines_msg));
- }
#ifdef FEAT_CMDL_INFO
else if (p_ru)
- {
/* Current line and column are already on the screen -- webb */
- if (curbuf->b_ml.ml_line_count == 1)
- vim_snprintf_add((char *)buffer, IOSIZE, _("1 line --%d%%--"), n);
- else
- vim_snprintf_add((char *)buffer, IOSIZE, _("%ld lines --%d%%--"),
- (long)curbuf->b_ml.ml_line_count, n);
- }
+ vim_snprintf_add((char *)buffer, IOSIZE,
+ NGETTEXT("%ld line --%d%%--", "%ld lines --%d%%--",
+ curbuf->b_ml.ml_line_count),
+ (long)curbuf->b_ml.ml_line_count, n);
#endif
else
{
@@ -3798,7 +3783,8 @@ value_changed(char_u *str, char_u **last)
if (str == NULL)
{
*last = NULL;
- mch_restore_title(last == &lasttitle ? 1 : 2);
+ mch_restore_title(
+ last == &lasttitle ? SAVE_RESTORE_TITLE : SAVE_RESTORE_ICON);
}
else
{
@@ -4229,7 +4215,7 @@ build_stl_str_hl(
#ifdef FEAT_EVAL
vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum);
- set_internal_string_var((char_u *)"actual_curbuf", tmp);
+ set_internal_string_var((char_u *)"g:actual_curbuf", tmp);
save_curbuf = curbuf;
save_curwin = curwin;
@@ -5627,6 +5613,15 @@ write_viminfo_bufferlist(FILE *fp)
#endif
/*
+ * Return TRUE if "buf" is a normal buffer, 'buftype' is empty.
+ */
+ int
+bt_normal(buf_T *buf)
+{
+ return buf != NULL && buf->b_p_bt[0] == NUL;
+}
+
+/*
* Return TRUE if "buf" is the quickfix buffer.
*/
int
diff --git a/src/channel.c b/src/channel.c
index de2f50d..282340e 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -138,7 +138,7 @@ ch_log_active(void)
}
static void
-ch_log_lead(const char *what, channel_T *ch)
+ch_log_lead(const char *what, channel_T *ch, ch_part_T part)
{
if (log_fd != NULL)
{
@@ -150,7 +150,13 @@ ch_log_lead(const char *what, channel_T *ch)
fprintf(log_fd, "%s ", profile_msg(&log_now));
#endif
if (ch != NULL)
- fprintf(log_fd, "%son %d: ", what, ch->ch_id);
+ {
+ if (part < PART_COUNT)
+ fprintf(log_fd, "%son %d(%s): ",
+ what, ch->ch_id, part_names[part]);
+ else
+ fprintf(log_fd, "%son %d: ", what, ch->ch_id);
+ }
else
fprintf(log_fd, "%s: ", what);
}
@@ -166,7 +172,7 @@ ch_log(channel_T *ch, const char *fmt, ...)
{
va_list ap;
- ch_log_lead("", ch);
+ ch_log_lead("", ch, PART_COUNT);
va_start(ap, fmt);
vfprintf(log_fd, fmt, ap);
va_end(ap);
@@ -191,7 +197,7 @@ ch_error(channel_T *ch, const char *fmt, ...)
{
va_list ap;
- ch_log_lead("ERR ", ch);
+ ch_log_lead("ERR ", ch, PART_COUNT);
va_start(ap, fmt);
vfprintf(log_fd, fmt, ap);
va_end(ap);
@@ -1849,7 +1855,7 @@ channel_save(channel_T *channel, ch_part_T part, char_u *buf, int len,
if (ch_log_active() && lead != NULL)
{
- ch_log_lead(lead, channel);
+ ch_log_lead(lead, channel, part);
fprintf(log_fd, "'");
ignored = (int)fwrite(buf, len, 1, log_fd);
fprintf(log_fd, "'\n");
@@ -3718,7 +3724,7 @@ channel_send(
if (ch_log_active())
{
- ch_log_lead("SEND ", channel);
+ ch_log_lead("SEND ", channel, part);
fprintf(log_fd, "'");
ignored = (int)fwrite(buf_arg, len_arg, 1, log_fd);
fprintf(log_fd, "'\n");
diff --git a/src/configure.ac b/src/configure.ac
index 0d8ea32..8994f3c 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1956,6 +1956,9 @@ if test "$enable_rubyinterp" = "yes" -o "$enable_rubyinterp" = "dynamic"; then
AC_DEFINE(FEAT_RUBY)
if test "$enable_rubyinterp" = "dynamic"; then
libruby_soname=`$vi_cv_path_ruby -r rbconfig -e "puts $ruby_rbconfig::CONFIG[['LIBRUBY_ALIASES']].split[[0]]"`
+ if test -z "$libruby_soname"; then
+ libruby_soname=`$vi_cv_path_ruby -r rbconfig -e "puts $ruby_rbconfig::CONFIG[['LIBRUBY_SO']]"`
+ fi
AC_DEFINE(DYNAMIC_RUBY)
RUBY_CFLAGS="-DDYNAMIC_RUBY_DLL=\\\"$libruby_soname\\\" -DDYNAMIC_RUBY_VER=$rubyversion $RUBY_CFLAGS"
RUBY_LIBS=
diff --git a/src/dosinst.c b/src/dosinst.c
index 64edbbd..182546e 100644
--- a/src/dosinst.c
+++ b/src/dosinst.c
@@ -1575,18 +1575,13 @@ install_registry(void)
}
printf("Creating an uninstall entry\n");
+ sprintf(display_name, "Vim " VIM_VERSION_SHORT);
/* For the NSIS installer use the generated uninstaller. */
if (interactive)
- {
- sprintf(display_name, "Vim " VIM_VERSION_SHORT);
sprintf(uninstall_string, "%s\\uninstal.exe", installdir);
- }
else
- {
- sprintf(display_name, "Vim " VIM_VERSION_SHORT " (self-installing)");
sprintf(uninstall_string, "%s\\uninstall-gui.exe", installdir);
- }
lRet = register_uninstall(
HKEY_LOCAL_MACHINE,
diff --git a/src/edit.c b/src/edit.c
index b0b44e6..ff45bb7 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -279,6 +279,7 @@ static colnr_T get_nolist_virtcol(void);
#if defined(FEAT_EVAL)
static char_u *do_insert_char_pre(int c);
#endif
+static int ins_apply_autocmds(event_T event);
static colnr_T Insstart_textlen; /* length of line when insert started */
static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */
@@ -411,7 +412,7 @@ edit(
set_vim_var_string(VV_INSERTMODE, ptr, 1);
set_vim_var_string(VV_CHAR, NULL, -1); /* clear v:char */
#endif
- apply_autocmds(EVENT_INSERTENTER, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_INSERTENTER);
/* Make sure the cursor didn't move. Do call check_cursor_col() in
* case the text was modified. Since Insert mode was not started yet
@@ -1061,8 +1062,7 @@ doESCkey:
if (ins_esc(&count, cmdchar, nomove))
{
if (cmdchar != 'r' && cmdchar != 'v')
- apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL,
- FALSE, curbuf);
+ ins_apply_autocmds(EVENT_INSERTLEAVE);
did_cursorhold = FALSE;
return (c == Ctrl_O);
}
@@ -1275,7 +1275,7 @@ doESCkey:
break;
case K_CURSORHOLD: /* Didn't type something for a while. */
- apply_autocmds(EVENT_CURSORHOLDI, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_CURSORHOLDI);
did_cursorhold = TRUE;
break;
@@ -1698,7 +1698,7 @@ ins_redraw(
/* Make sure curswant is correct, an autocommand may call
* getcurpos(). */
update_curswant();
- apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_CURSORMOVEDI);
}
# ifdef FEAT_CONCEAL
if (curwin->w_p_cole > 0)
@@ -1721,12 +1721,16 @@ ins_redraw(
)
{
aco_save_T aco;
+ varnumber_T tick = CHANGEDTICK(curbuf);
// save and restore curwin and curbuf, in case the autocmd changes them
aucmd_prepbuf(&aco, curbuf);
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
aucmd_restbuf(&aco);
curbuf->b_last_changedtick = CHANGEDTICK(curbuf);
+ if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds()
+ u_save(curwin->w_cursor.lnum,
+ (linenr_T)(curwin->w_cursor.lnum + 1));
}
#ifdef FEAT_INS_EXPAND
@@ -1738,12 +1742,16 @@ ins_redraw(
&& pum_visible())
{
aco_save_T aco;
+ varnumber_T tick = CHANGEDTICK(curbuf);
// save and restore curwin and curbuf, in case the autocmd changes them
aucmd_prepbuf(&aco, curbuf);
apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, FALSE, curbuf);
aucmd_restbuf(&aco);
curbuf->b_last_changedtick_pum = CHANGEDTICK(curbuf);
+ if (tick != CHANGEDTICK(curbuf)) // see ins_apply_autocmds()
+ u_save(curwin->w_cursor.lnum,
+ (linenr_T)(curwin->w_cursor.lnum + 1));
}
#endif
@@ -4112,13 +4120,13 @@ ins_compl_prep(int c)
#endif
/* Trigger the CompleteDone event to give scripts a chance to act
* upon the completion. */
- apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_COMPLETEDONE);
}
}
else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
/* Trigger the CompleteDone event to give scripts a chance to act
* upon the (possibly failed) completion. */
- apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_COMPLETEDONE);
/* reset continue_* if we left expansion-mode, if we stay they'll be
* (re)set properly in ins_complete() */
@@ -4239,7 +4247,7 @@ expand_by_function(
curbuf_save = curbuf;
/* Call a function, which returns a list or dict. */
- if (call_vim_function(funcname, 2, args, &rettv, FALSE) == OK)
+ if (call_vim_function(funcname, 2, args, &rettv) == OK)
{
switch (rettv.v_type)
{
@@ -4419,10 +4427,15 @@ ins_compl_get_exp(pos_T *ini)
? (char_u *)"." : curbuf->b_p_cpt;
last_match_pos = first_match_pos = *ini;
}
+ else if (ins_buf != curbuf && !buf_valid(ins_buf))
+ ins_buf = curbuf; // In case the buffer was wiped out.
compl_old_match = compl_curr_match; /* remember the last current match */
pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
- /* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
+
+ /*
+ * For ^N/^P loop over all the flags/windows/buffers in 'complete'.
+ */
for (;;)
{
found_new_match = FAIL;
@@ -5569,7 +5582,7 @@ ins_complete(int c, int enable_pum)
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
- col = call_func_retnr(funcname, 2, args, FALSE);
+ col = call_func_retnr(funcname, 2, args);
if (curwin_save != curwin || curbuf_save != curbuf)
{
EMSG(_(e_complwin));
@@ -8927,7 +8940,7 @@ ins_insert(int replaceState)
: replaceState == VREPLACE ? "v"
: "r"), 1);
# endif
- apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_INSERTCHANGE);
if (State & REPLACE_FLAG)
State = INSERT | (State & LANGMAP);
else
@@ -10721,7 +10734,7 @@ do_insert_char_pre(int c)
set_vim_var_string(VV_CHAR, buf, -1); /* set v:char */
res = NULL;
- if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf))
+ if (ins_apply_autocmds(EVENT_INSERTCHARPRE))
{
/* Get the value of v:char. It may be empty or more than one
* character. Only use it when changed, otherwise continue with the
@@ -10736,3 +10749,22 @@ do_insert_char_pre(int c)
return res;
}
#endif
+
+/*
+ * Trigger "event" and take care of fixing undo.
+ */
+ static int
+ins_apply_autocmds(event_T event)
+{
+ varnumber_T tick = CHANGEDTICK(curbuf);
+ int r;
+
+ r = apply_autocmds(event, NULL, NULL, FALSE, curbuf);
+
+ // If u_savesub() was called then we are not prepared to start
+ // a new line. Call u_save() with no contents to fix that.
+ if (tick != CHANGEDTICK(curbuf))
+ u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1));
+
+ return r;
+}
diff --git a/src/eval.c b/src/eval.c
index 6034cd2..3a27521 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1021,29 +1021,15 @@ call_vim_function(
char_u *func,
int argc,
typval_T *argv,
- typval_T *rettv,
- int safe) /* use the sandbox */
+ typval_T *rettv)
{
int doesrange;
- void *save_funccalp = NULL;
int ret;
- if (safe)
- {
- save_funccalp = save_funccal();
- ++sandbox;
- }
-
rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
ret = call_func(func, (int)STRLEN(func), rettv, argc, argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, TRUE, NULL, NULL);
- if (safe)
- {
- --sandbox;
- restore_funccal(save_funccalp);
- }
-
if (ret == FAIL)
clear_tv(rettv);
@@ -1060,13 +1046,12 @@ call_vim_function(
call_func_retnr(
char_u *func,
int argc,
- typval_T *argv,
- int safe) /* use the sandbox */
+ typval_T *argv)
{
typval_T rettv;
varnumber_T retval;
- if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
+ if (call_vim_function(func, argc, argv, &rettv) == FAIL)
return -1;
retval = get_tv_number_chk(&rettv, NULL);
@@ -1088,13 +1073,12 @@ call_func_retnr(
call_func_retstr(
char_u *func,
int argc,
- typval_T *argv,
- int safe) /* use the sandbox */
+ typval_T *argv)
{
typval_T rettv;
char_u *retval;
- if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
+ if (call_vim_function(func, argc, argv, &rettv) == FAIL)
return NULL;
retval = vim_strsave(get_tv_string(&rettv));
@@ -1113,12 +1097,11 @@ call_func_retstr(
call_func_retlist(
char_u *func,
int argc,
- typval_T *argv,
- int safe) /* use the sandbox */
+ typval_T *argv)
{
typval_T rettv;
- if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
+ if (call_vim_function(func, argc, argv, &rettv) == FAIL)
return NULL;
if (rettv.v_type != VAR_LIST)
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 31096d7..3c64212 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -398,6 +398,7 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
static void f_strwidth(typval_T *argvars, typval_T *rettv);
static void f_submatch(typval_T *argvars, typval_T *rettv);
static void f_substitute(typval_T *argvars, typval_T *rettv);
+static void f_swapinfo(typval_T *argvars, typval_T *rettv);
static void f_synID(typval_T *argvars, typval_T *rettv);
static void f_synIDattr(typval_T *argvars, typval_T *rettv);
static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
@@ -463,6 +464,7 @@ static void f_win_screenpos(typval_T *argvars, typval_T *rettv);
static void f_winbufnr(typval_T *argvars, typval_T *rettv);
static void f_wincol(typval_T *argvars, typval_T *rettv);
static void f_winheight(typval_T *argvars, typval_T *rettv);
+static void f_winlayout(typval_T *argvars, typval_T *rettv);
static void f_winline(typval_T *argvars, typval_T *rettv);
static void f_winnr(typval_T *argvars, typval_T *rettv);
static void f_winrestcmd(typval_T *argvars, typval_T *rettv);
@@ -858,6 +860,7 @@ static struct fst
{"strwidth", 1, 1, f_strwidth},
{"submatch", 1, 2, f_submatch},
{"substitute", 4, 4, f_substitute},
+ {"swapinfo", 1, 1, f_swapinfo},
{"synID", 3, 3, f_synID},
{"synIDattr", 2, 3, f_synIDattr},
{"synIDtrans", 1, 1, f_synIDtrans},
@@ -952,6 +955,7 @@ static struct fst
{"winbufnr", 1, 1, f_winbufnr},
{"wincol", 0, 0, f_wincol},
{"winheight", 1, 1, f_winheight},
+ {"winlayout", 0, 1, f_winlayout},
{"winline", 0, 0, f_winline},
{"winnr", 0, 1, f_winnr},
{"winrestcmd", 0, 0, f_winrestcmd},
@@ -5088,63 +5092,22 @@ f_getftype(typval_T *argvars, typval_T *rettv)
rettv->v_type = VAR_STRING;
if (mch_lstat((char *)fname, &st) >= 0)
{
-#ifdef S_ISREG
if (S_ISREG(st.st_mode))
t = "file";
else if (S_ISDIR(st.st_mode))
t = "dir";
-# ifdef S_ISLNK
else if (S_ISLNK(st.st_mode))
t = "link";
-# endif
-# ifdef S_ISBLK
else if (S_ISBLK(st.st_mode))
t = "bdev";
-# endif
-# ifdef S_ISCHR
else if (S_ISCHR(st.st_mode))
t = "cdev";
-# endif
-# ifdef S_ISFIFO
else if (S_ISFIFO(st.st_mode))
t = "fifo";
-# endif
-# ifdef S_ISSOCK
else if (S_ISSOCK(st.st_mode))
- t = "fifo";
-# endif
+ t = "socket";
else
t = "other";
-#else
-# ifdef S_IFMT
- switch (st.st_mode & S_IFMT)
- {
- case S_IFREG: t = "file"; break;
- case S_IFDIR: t = "dir"; break;
-# ifdef S_IFLNK
- case S_IFLNK: t = "link"; break;
-# endif
-# ifdef S_IFBLK
- case S_IFBLK: t = "bdev"; break;
-# endif
-# ifdef S_IFCHR
- case S_IFCHR: t = "cdev"; break;
-# endif
-# ifdef S_IFIFO
- case S_IFIFO: t = "fifo"; break;
-# endif
-# ifdef S_IFSOCK
- case S_IFSOCK: t = "socket"; break;
-# endif
- default: t = "other";
- }
-# else
- if (mch_isdir(fname))
- t = "dir";
- else
- t = "file";
-# endif
-#endif
type = vim_strsave((char_u *)t);
}
rettv->vval.v_string = type;
@@ -12353,6 +12316,16 @@ f_substitute(typval_T *argvars, typval_T *rettv)
}
/*
+ * "swapinfo(swap_filename)" function
+ */
+ static void
+f_swapinfo(typval_T *argvars, typval_T *rettv)
+{
+ if (rettv_dict_alloc(rettv) == OK)
+ get_b0_dict(get_tv_string(argvars), rettv->vval.v_dict);
+}
+
+/*
* "synID(lnum, col, trans)" function
*/
static void
@@ -13784,6 +13757,29 @@ f_winheight(typval_T *argvars, typval_T *rettv)
}
/*
+ * "winlayout()" function
+ */
+ static void
+f_winlayout(typval_T *argvars, typval_T *rettv)
+{
+ tabpage_T *tp;
+
+ if (rettv_list_alloc(rettv) != OK)
+ return;
+
+ if (argvars[0].v_type == VAR_UNKNOWN)
+ tp = curtab;
+ else
+ {
+ tp = find_tabpage((int)get_tv_number(&argvars[0]));
+ if (tp == NULL)
+ return;
+ }
+
+ get_framelayout(tp->tp_topframe, rettv->vval.v_list, TRUE);
+}
+
+/*
* "winline()" function
*/
static void
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index a30178b..6e713c4 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -281,7 +281,7 @@ linelen(int *has_tab)
*last = NUL;
len = linetabsize(line); /* get line length */
if (has_tab != NULL) /* check for embedded TAB */
- *has_tab = (vim_strrchr(first, TAB) != NULL);
+ *has_tab = (vim_strchr(first, TAB) != NULL);
*last = save;
return len;
@@ -985,12 +985,8 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest)
ml_delete(line1 + extra, TRUE);
if (!global_busy && num_lines > p_report)
- {
- if (num_lines == 1)
- MSG(_("1 line moved"));
- else
- smsg((char_u *)_("%ld lines moved"), num_lines);
- }
+ smsg((char_u *)NGETTEXT("%ld line moved", "%ld lines moved", num_lines),
+ (long)num_lines);
/*
* Leave the cursor on the last of the moved lines.
@@ -5940,23 +5936,29 @@ do_sub_msg(
|| count_only)
&& messaging())
{
+ char *msg_single;
+ char *msg_plural;
+
if (got_int)
STRCPY(msg_buf, _("(Interrupted) "));
else
*msg_buf = NUL;
- if (sub_nsubs == 1)
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- "%s", count_only ? _("1 match") : _("1 substitution"));
- else
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- count_only ? _("%ld matches") : _("%ld substitutions"),
- sub_nsubs);
- if (sub_nlines == 1)
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- "%s", _(" on 1 line"));
- else
- vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
- _(" on %ld lines"), (long)sub_nlines);
+
+ msg_single = count_only
+ ? NGETTEXT("%ld match on %ld line",
+ "%ld matches on %ld line", sub_nsubs)
+ : NGETTEXT("%ld substitution on %ld line",
+ "%ld substitutions on %ld line", sub_nsubs);
+ msg_plural = count_only
+ ? NGETTEXT("%ld match on %ld lines",
+ "%ld matches on %ld lines", sub_nsubs)
+ : NGETTEXT("%ld substitution on %ld lines",
+ "%ld substitutions on %ld lines", sub_nsubs);
+
+ vim_snprintf_add((char *)msg_buf, sizeof(msg_buf),
+ NGETTEXT(msg_single, msg_plural, sub_nlines),
+ sub_nsubs, (long)sub_nlines);
+
if (msg(msg_buf))
/* save message to display it after redraw */
set_keep_msg(msg_buf, 0);
@@ -6584,6 +6586,7 @@ find_help_tags(
"/*", "/\\*", "\"*", "**",
"cpo-*", "/\\(\\)", "/\\%(\\)",
"?", ":?", "?<CR>", "g?", "g?g?", "g??",
+ "-?", "q?", "v_g?",
"/\\?", "/\\z(\\)", "\\=", ":s\\=",
"[count]", "[quotex]",
"[range]", ":[range]",
@@ -6594,26 +6597,42 @@ find_help_tags(
"/star", "/\\\\star", "quotestar", "starstar",
"cpo-star", "/\\\\(\\\\)", "/\\\\%(\\\\)",
"?", ":?", "?<CR>", "g?", "g?g?", "g??",
+ "-?", "q?", "v_g?",
"/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
"\\[count]", "\\[quotex]",
"\\[range]", ":\\[range]",
"\\[pattern]", "\\\\bar", "/\\\\%\\$",
"s/\\\\\\~", "s/\\\\U", "s/\\\\L",
"s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"};
+ static char *(expr_table[]) = {"!=?", "!~?", "<=?", "<?", "==?", "=~?",
+ ">=?", ">?", "is?", "isnot?"};
int flags;
d = IObuff; /* assume IObuff is long enough! */
- /*
- * Recognize a few exceptions to the rule. Some strings that contain '*'
- * with "star". Otherwise '*' is recognized as a wildcard.
- */
- for (i = (int)(sizeof(mtable) / sizeof(char *)); --i >= 0; )
- if (STRCMP(arg, mtable[i]) == 0)
- {
- STRCPY(d, rtable[i]);
- break;
- }
+ if (STRNICMP(arg, "expr-", 5) == 0)
+ {
+ // When the string starting with "expr-" and containing '?' and matches
+ // the table, it is taken literally. Otherwise '?' is recognized as a
+ // wildcard.
+ for (i = (int)(sizeof(expr_table) / sizeof(char *)); --i >= 0; )
+ if (STRCMP(arg + 5, expr_table[i]) == 0)
+ {
+ STRCPY(d, arg);
+ break;
+ }
+ }
+ else
+ {
+ // Recognize a few exceptions to the rule. Some strings that contain
+ // '*' with "star". Otherwise '*' is recognized as a wildcard.
+ for (i = (int)(sizeof(mtable) / sizeof(char *)); --i >= 0; )
+ if (STRCMP(arg, mtable[i]) == 0)
+ {
+ STRCPY(d, rtable[i]);
+ break;
+ }
+ }
if (i < 0) /* no match in table */
{
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 045bfcb..187efea 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1792,6 +1792,12 @@ struct exarg
#ifdef FEAT_EVAL
struct condstack *cstack; /* condition stack for ":if" etc. */
#endif
+ long verbose_save; // saved value of p_verbose
+ int save_msg_silent; // saved value of msg_silent
+ int did_esilent; // how many times emsg_silent was incremented
+#ifdef HAVE_SANDBOX
+ int did_sandbox; // when TRUE did ++sandbox
+#endif
};
#define FORCE_BIN 1 /* ":edit ++bin file" */
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 6682286..fc2b20e 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -68,6 +68,7 @@ static char_u *do_one_cmd(char_u **, int, struct condstack *, char_u *(*fgetline
static char_u *do_one_cmd(char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie);
static int if_level = 0; /* depth in :if */
#endif
+static void free_cmdmod(void);
static void append_command(char_u *cmd);
static char_u *find_command(exarg_T *eap, int *full);
@@ -1709,17 +1710,10 @@ do_one_cmd(
char_u *errormsg = NULL; /* error message */
char_u *after_modifier = NULL;
exarg_T ea; /* Ex command arguments */
- long verbose_save = -1;
int save_msg_scroll = msg_scroll;
- int save_msg_silent = -1;
- int did_esilent = 0;
-#ifdef HAVE_SANDBOX
- int did_sandbox = FALSE;
-#endif
cmdmod_T save_cmdmod;
int ni; /* set when Not Implemented */
char_u *cmd;
- int address_count = 1;
vim_memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
@@ -1743,236 +1737,26 @@ do_one_cmd(
* recursive calls.
*/
save_cmdmod = cmdmod;
- vim_memset(&cmdmod, 0, sizeof(cmdmod));
/* "#!anything" is handled like a comment. */
if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!')
goto doend;
- /*
- * Repeat until no more command modifiers are found.
- */
- ea.cmd = *cmdlinep;
- for (;;)
- {
/*
* 1. Skip comment lines and leading white space and colons.
- */
- while (*ea.cmd == ' ' || *ea.cmd == '\t' || *ea.cmd == ':')
- ++ea.cmd;
-
- /* in ex mode, an empty line works like :+ */
- if (*ea.cmd == NUL && exmode_active
- && (getline_equal(fgetline, cookie, getexmodeline)
- || getline_equal(fgetline, cookie, getexline))
- && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
- {
- ea.cmd = (char_u *)"+";
- ex_pressedreturn = TRUE;
- }
-
- /* ignore comment and empty lines */
- if (*ea.cmd == '"')
- goto doend;
- if (*ea.cmd == NUL)
- {
- ex_pressedreturn = TRUE;
- goto doend;
- }
-
-/*
* 2. Handle command modifiers.
*/
- p = skip_range(ea.cmd, NULL);
- switch (*p)
- {
- /* When adding an entry, also modify cmd_exists(). */
- case 'a': if (!checkforcmd(&ea.cmd, "aboveleft", 3))
- break;
- cmdmod.split |= WSP_ABOVE;
- continue;
-
- case 'b': if (checkforcmd(&ea.cmd, "belowright", 3))
- {
- cmdmod.split |= WSP_BELOW;
- continue;
- }
- if (checkforcmd(&ea.cmd, "browse", 3))
- {
-#ifdef FEAT_BROWSE_CMD
- cmdmod.browse = TRUE;
-#endif
- continue;
- }
- if (!checkforcmd(&ea.cmd, "botright", 2))
- break;
- cmdmod.split |= WSP_BOT;
- continue;
-
- case 'c': if (!checkforcmd(&ea.cmd, "confirm", 4))
- break;
-#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
- cmdmod.confirm = TRUE;
-#endif
- continue;
-
- case 'k': if (checkforcmd(&ea.cmd, "keepmarks", 3))
- {
- cmdmod.keepmarks = TRUE;
- continue;
- }
- if (checkforcmd(&ea.cmd, "keepalt", 5))
- {
- cmdmod.keepalt = TRUE;
- continue;
- }
- if (checkforcmd(&ea.cmd, "keeppatterns", 5))
- {
- cmdmod.keeppatterns = TRUE;
- continue;
- }
- if (!checkforcmd(&ea.cmd, "keepjumps", 5))
- break;
- cmdmod.keepjumps = TRUE;
- continue;
-
- case 'f': /* only accept ":filter {pat} cmd" */
- {
- char_u *reg_pat;
-
- if (!checkforcmd(&p, "filter", 4)
- || *p == NUL || ends_excmd(*p))
- break;
- if (*p == '!')
- {
- cmdmod.filter_force = TRUE;
- p = skipwhite(p + 1);
- if (*p == NUL || ends_excmd(*p))
- break;
- }
- p = skip_vimgrep_pat(p, &reg_pat, NULL);
- if (p == NULL || *p == NUL)
- break;
- cmdmod.filter_regmatch.regprog =
- vim_regcomp(reg_pat, RE_MAGIC);
- if (cmdmod.filter_regmatch.regprog == NULL)
- break;
- ea.cmd = p;
- continue;
- }
-
- /* ":hide" and ":hide | cmd" are not modifiers */
- case 'h': if (p != ea.cmd || !checkforcmd(&p, "hide", 3)
- || *p == NUL || ends_excmd(*p))
- break;
- ea.cmd = p;
- cmdmod.hide = TRUE;
- continue;
-
- case 'l': if (checkforcmd(&ea.cmd, "lockmarks", 3))
- {
- cmdmod.lockmarks = TRUE;
- continue;
- }
-
- if (!checkforcmd(&ea.cmd, "leftabove", 5))
- break;
- cmdmod.split |= WSP_ABOVE;
- continue;
-
- case 'n': if (checkforcmd(&ea.cmd, "noautocmd", 3))
- {
- if (cmdmod.save_ei == NULL)
- {
- /* Set 'eventignore' to "all". Restore the
- * existing option value later. */
- cmdmod.save_ei = vim_strsave(p_ei);
- set_string_option_direct((char_u *)"ei", -1,
- (char_u *)"all", OPT_FREE, SID_NONE);
- }
- continue;
- }
- if (!checkforcmd(&ea.cmd, "noswapfile", 3))
- break;
- cmdmod.noswapfile = TRUE;
- continue;
-
- case 'r': if (!checkforcmd(&ea.cmd, "rightbelow", 6))
- break;
- cmdmod.split |= WSP_BELOW;
- continue;
-
- case 's': if (checkforcmd(&ea.cmd, "sandbox", 3))
- {
-#ifdef HAVE_SANDBOX
- if (!did_sandbox)
- ++sandbox;
- did_sandbox = TRUE;
+ // The "ea" structure holds the arguments that can be used.
+ ea.cmd = *cmdlinep;
+ ea.cmdlinep = cmdlinep;
+ ea.getline = fgetline;
+ ea.cookie = cookie;
+#ifdef FEAT_EVAL
+ ea.cstack = cstack;
#endif
- continue;
- }
- if (!checkforcmd(&ea.cmd, "silent", 3))
- break;
- if (save_msg_silent == -1)
- save_msg_silent = msg_silent;
- ++msg_silent;
- if (*ea.cmd == '!' && !VIM_ISWHITE(ea.cmd[-1]))
- {
- /* ":silent!", but not "silent !cmd" */
- ea.cmd = skipwhite(ea.cmd + 1);
- ++emsg_silent;
- ++did_esilent;
- }
- continue;
-
- case 't': if (checkforcmd(&p, "tab", 3))
- {
- long tabnr = get_address(&ea, &ea.cmd, ADDR_TABS,
- ea.skip, FALSE, 1);
- if (tabnr == MAXLNUM)
- cmdmod.tab = tabpage_index(curtab) + 1;
- else
- {
- if (tabnr < 0 || tabnr > LAST_TAB_NR)
- {
- errormsg = (char_u *)_(e_invrange);
- goto doend;
- }
- cmdmod.tab = tabnr + 1;
- }
- ea.cmd = p;
- continue;
- }
- if (!checkforcmd(&ea.cmd, "topleft", 2))
- break;
- cmdmod.split |= WSP_TOP;
- continue;
-
- case 'u': if (!checkforcmd(&ea.cmd, "unsilent", 3))
- break;
- if (save_msg_silent == -1)
- save_msg_silent = msg_silent;
- msg_silent = 0;
- continue;
+ if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL)
+ goto doend;
- case 'v': if (checkforcmd(&ea.cmd, "vertical", 4))
- {
- cmdmod.split |= WSP_VERT;
- continue;
- }
- if (!checkforcmd(&p, "verbose", 4))
- break;
- if (verbose_save < 0)
- verbose_save = p_verbose;
- if (vim_isdigit(*ea.cmd))
- p_verbose = atoi((char *)ea.cmd);
- else
- p_verbose = 1;
- ea.cmd = p;
- continue;
- }
- break;
- }
after_modifier = ea.cmd;
#ifdef FEAT_EVAL
@@ -1982,17 +1766,51 @@ do_one_cmd(
ea.skip = (if_level > 0);
#endif
+/*
+ * 3. Skip over the range to find the command. Let "p" point to after it.
+ *
+ * We need the command to know what kind of range it uses.
+ */
+ cmd = ea.cmd;
+ ea.cmd = skip_range(ea.cmd, NULL);
+ if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
+ ea.cmd = skipwhite(ea.cmd + 1);
+ p = find_command(&ea, NULL);
+
#ifdef FEAT_EVAL
# ifdef FEAT_PROFILE
- /* Count this line for profiling if ea.skip is FALSE. */
- if (do_profiling == PROF_YES && !ea.skip)
- {
- if (getline_equal(fgetline, cookie, get_func_line))
- func_line_exec(getline_cookie(fgetline, cookie));
- else if (getline_equal(fgetline, cookie, getsourceline))
- script_line_exec();
+ // Count this line for profiling if skip is TRUE.
+ if (do_profiling == PROF_YES
+ && (!ea.skip || cstack->cs_idx == 0 || (cstack->cs_idx > 0
+ && (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE))))
+ {
+ int skip = did_emsg || got_int || did_throw;
+
+ if (ea.cmdidx == CMD_catch)
+ skip = !skip && !(cstack->cs_idx >= 0
+ && (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN)
+ && !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT));
+ else if (ea.cmdidx == CMD_else || ea.cmdidx == CMD_elseif)
+ skip = skip || !(cstack->cs_idx >= 0
+ && !(cstack->cs_flags[cstack->cs_idx]
+ & (CSF_ACTIVE | CSF_TRUE)));
+ else if (ea.cmdidx == CMD_finally)
+ skip = FALSE;
+ else if (ea.cmdidx != CMD_endif
+ && ea.cmdidx != CMD_endfor
+ && ea.cmdidx != CMD_endtry
+ && ea.cmdidx != CMD_endwhile)
+ skip = ea.skip;
+
+ if (!skip)
+ {
+ if (getline_equal(fgetline, cookie, get_func_line))
+ func_line_exec(getline_cookie(fgetline, cookie));
+ else if (getline_equal(fgetline, cookie, getsourceline))
+ script_line_exec();
+ }
}
-#endif
+# endif
/* May go to debug mode. If this happens and the ">quit" debug command is
* used, throw an interrupt exception and skip the next command. */
@@ -2005,17 +1823,6 @@ do_one_cmd(
#endif
/*
- * 3. Skip over the range to find the command. Let "p" point to after it.
- *
- * We need the command to know what kind of range it uses.
- */
- cmd = ea.cmd;
- ea.cmd = skip_range(ea.cmd, NULL);
- if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
- ea.cmd = skipwhite(ea.cmd + 1);
- p = find_command(&ea, NULL);
-
-/*
* 4. parse a range specifier of the form: addr [,addr] [;addr] ..
*
* where 'addr' is:
@@ -2045,168 +1852,9 @@ do_one_cmd(
get_wincmd_addr_type(skipwhite(p), &ea);
}
- /* repeat for all ',' or ';' separated addresses */
ea.cmd = cmd;
- for (;;)
- {
- ea.line1 = ea.line2;
- switch (ea.addr_type)
- {
- case ADDR_LINES:
- /* default is current line number */
- ea.line2 = curwin->w_cursor.lnum;
- break;
- case ADDR_WINDOWS:
- ea.line2 = CURRENT_WIN_NR;
- break;
- case ADDR_ARGUMENTS:
- ea.line2 = curwin->w_arg_idx + 1;
- if (ea.line2 > ARGCOUNT)
- ea.line2 = ARGCOUNT;
- break;
- case ADDR_LOADED_BUFFERS:
- case ADDR_BUFFERS:
- ea.line2 = curbuf->b_fnum;
- break;
- case ADDR_TABS:
- ea.line2 = CURRENT_TAB_NR;
- break;
- case ADDR_TABS_RELATIVE:
- ea.line2 = 1;
- break;
-#ifdef FEAT_QUICKFIX
- case ADDR_QUICKFIX:
- ea.line2 = qf_get_cur_valid_idx(&ea);
- break;
-#endif
- }
- ea.cmd = skipwhite(ea.cmd);
- lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip,
- ea.addr_count == 0, address_count++);
- if (ea.cmd == NULL) /* error detected */
- goto doend;
- if (lnum == MAXLNUM)
- {
- if (*ea.cmd == '%') /* '%' - all lines */
- {
- ++ea.cmd;
- switch (ea.addr_type)
- {
- case ADDR_LINES:
- ea.line1 = 1;
- ea.line2 = curbuf->b_ml.ml_line_count;
- break;
- case ADDR_LOADED_BUFFERS:
- {
- buf_T *buf = firstbuf;
-
- while (buf->b_next != NULL
- && buf->b_ml.ml_mfp == NULL)
- buf = buf->b_next;
- ea.line1 = buf->b_fnum;
- buf = lastbuf;
- while (buf->b_prev != NULL
- && buf->b_ml.ml_mfp == NULL)
- buf = buf->b_prev;
- ea.line2 = buf->b_fnum;
- break;
- }
- case ADDR_BUFFERS:
- ea.line1 = firstbuf->b_fnum;
- ea.line2 = lastbuf->b_fnum;
- break;
- case ADDR_WINDOWS:
- case ADDR_TABS:
- if (IS_USER_CMDIDX(ea.cmdidx))
- {
- ea.line1 = 1;
- ea.line2 = ea.addr_type == ADDR_WINDOWS
- ? LAST_WIN_NR : LAST_TAB_NR;
- }
- else
- {
- /* there is no Vim command which uses '%' and
- * ADDR_WINDOWS or ADDR_TABS */
- errormsg = (char_u *)_(e_invrange);
- goto doend;
- }
- break;
- case ADDR_TABS_RELATIVE:
- errormsg = (char_u *)_(e_invrange);
- goto doend;
- break;
- case ADDR_ARGUMENTS:
- if (ARGCOUNT == 0)
- ea.line1 = ea.line2 = 0;
- else
- {
- ea.line1 = 1;
- ea.line2 = ARGCOUNT;
- }
- break;
-#ifdef FEAT_QUICKFIX
- case ADDR_QUICKFIX:
- ea.line1 = 1;
- ea.line2 = qf_get_size(&ea);
- if (ea.line2 == 0)
- ea.line2 = 1;
- break;
-#endif
- }
- ++ea.addr_count;
- }
- /* '*' - visual area */
- else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
- {
- pos_T *fp;
-
- if (ea.addr_type != ADDR_LINES)
- {
- errormsg = (char_u *)_(e_invrange);
- goto doend;
- }
-
- ++ea.cmd;
- if (!ea.skip)
- {
- fp = getmark('<', FALSE);
- if (check_mark(fp) == FAIL)
- goto doend;
- ea.line1 = fp->lnum;
- fp = getmark('>', FALSE);
- if (check_mark(fp) == FAIL)
- goto doend;
- ea.line2 = fp->lnum;
- ++ea.addr_count;
- }
- }
- }
- else
- ea.line2 = lnum;
- ea.addr_count++;
-
- if (*ea.cmd == ';')
- {
- if (!ea.skip)
- {
- curwin->w_cursor.lnum = ea.line2;
- /* don't leave the cursor on an illegal line or column */
- check_cursor();
- }
- }
- else if (*ea.cmd != ',')
- break;
- ++ea.cmd;
- }
-
- /* One address given: set start and end lines */
- if (ea.addr_count == 1)
- {
- ea.line1 = ea.line2;
- /* ... but only implicit: really no address given */
- if (lnum == MAXLNUM)
- ea.addr_count = 0;
- }
+ if (parse_cmd_address(&ea, &errormsg) == FAIL)
+ goto doend;
/*
* 5. Parse the command.
@@ -2848,25 +2496,17 @@ do_one_cmd(
/* The :try command saves the emsg_silent flag, reset it here when
* ":silent! try" was used, it should only apply to :try itself. */
- if (ea.cmdidx == CMD_try && did_esilent > 0)
+ if (ea.cmdidx == CMD_try && ea.did_esilent > 0)
{
- emsg_silent -= did_esilent;
+ emsg_silent -= ea.did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
- did_esilent = 0;
+ ea.did_esilent = 0;
}
/*
* 7. Execute the command.
- *
- * The "ea" structure holds the arguments that can be used.
*/
- ea.cmdlinep = cmdlinep;
- ea.getline = fgetline;
- ea.cookie = cookie;
-#ifdef FEAT_EVAL
- ea.cstack = cstack;
-#endif
#ifdef FEAT_USR_CMDS
if (IS_USER_CMDIDX(ea.cmdidx))
@@ -2935,29 +2575,19 @@ doend:
? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
#endif
- if (verbose_save >= 0)
- p_verbose = verbose_save;
-
- if (cmdmod.save_ei != NULL)
- {
- /* Restore 'eventignore' to the value before ":noautocmd". */
- set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
- OPT_FREE, SID_NONE);
- free_string_option(cmdmod.save_ei);
- }
-
- if (cmdmod.filter_regmatch.regprog != NULL)
- vim_regfree(cmdmod.filter_regmatch.regprog);
+ if (ea.verbose_save >= 0)
+ p_verbose = ea.verbose_save;
+ free_cmdmod();
cmdmod = save_cmdmod;
- if (save_msg_silent != -1)
+ if (ea.save_msg_silent != -1)
{
/* messages could be enabled for a serious error, need to check if the
* counters don't become negative */
- if (!did_emsg || msg_silent > save_msg_silent)
- msg_silent = save_msg_silent;
- emsg_silent -= did_esilent;
+ if (!did_emsg || msg_silent > ea.save_msg_silent)
+ msg_silent = ea.save_msg_silent;
+ emsg_silent -= ea.did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
/* Restore msg_scroll, it's set by file I/O commands, even when no
@@ -2971,7 +2601,7 @@ doend:
}
#ifdef HAVE_SANDBOX
- if (did_sandbox)
+ if (ea.did_sandbox)
--sandbox;
#endif
@@ -2989,6 +2619,463 @@ doend:
#endif
/*
+ * Parse and skip over command modifiers:
+ * - update eap->cmd
+ * - store flags in "cmdmod".
+ * - Set ex_pressedreturn for an empty command line.
+ * - set msg_silent for ":silent"
+ * - set 'eventignore' to "all" for ":noautocmd"
+ * - set p_verbose for ":verbose"
+ * - Increment "sandbox" for ":sandbox"
+ * When "skip_only" is TRUE the global variables are not changed, except for
+ * "cmdmod".
+ * Return FAIL when the command is not to be executed.
+ * May set "errormsg" to an error message.
+ */
+ int
+parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only)
+{
+ char_u *p;
+
+ vim_memset(&cmdmod, 0, sizeof(cmdmod));
+ eap->verbose_save = -1;
+ eap->save_msg_silent = -1;
+
+ // Repeat until no more command modifiers are found.
+ for (;;)
+ {
+ while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':')
+ ++eap->cmd;
+
+ /* in ex mode, an empty line works like :+ */
+ if (*eap->cmd == NUL && exmode_active
+ && (getline_equal(eap->getline, eap->cookie, getexmodeline)
+ || getline_equal(eap->getline, eap->cookie, getexline))
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
+ {
+ eap->cmd = (char_u *)"+";
+ if (!skip_only)
+ ex_pressedreturn = TRUE;
+ }
+
+ /* ignore comment and empty lines */
+ if (*eap->cmd == '"')
+ return FAIL;
+ if (*eap->cmd == NUL)
+ {
+ if (!skip_only)
+ ex_pressedreturn = TRUE;
+ return FAIL;
+ }
+
+ p = skip_range(eap->cmd, NULL);
+ switch (*p)
+ {
+ /* When adding an entry, also modify cmd_exists(). */
+ case 'a': if (!checkforcmd(&eap->cmd, "aboveleft", 3))
+ break;
+ cmdmod.split |= WSP_ABOVE;
+ continue;
+
+ case 'b': if (checkforcmd(&eap->cmd, "belowright", 3))
+ {
+ cmdmod.split |= WSP_BELOW;
+ continue;
+ }
+ if (checkforcmd(&eap->cmd, "browse", 3))
+ {
+#ifdef FEAT_BROWSE_CMD
+ cmdmod.browse = TRUE;
+#endif
+ continue;
+ }
+ if (!checkforcmd(&eap->cmd, "botright", 2))
+ break;
+ cmdmod.split |= WSP_BOT;
+ continue;
+
+ case 'c': if (!checkforcmd(&eap->cmd, "confirm", 4))
+ break;
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+ cmdmod.confirm = TRUE;
+#endif
+ continue;
+
+ case 'k': if (checkforcmd(&eap->cmd, "keepmarks", 3))
+ {
+ cmdmod.keepmarks = TRUE;
+ continue;
+ }
+ if (checkforcmd(&eap->cmd, "keepalt", 5))
+ {
+ cmdmod.keepalt = TRUE;
+ continue;
+ }
+ if (checkforcmd(&eap->cmd, "keeppatterns", 5))
+ {
+ cmdmod.keeppatterns = TRUE;
+ continue;
+ }
+ if (!checkforcmd(&eap->cmd, "keepjumps", 5))
+ break;
+ cmdmod.keepjumps = TRUE;
+ continue;
+
+ case 'f': /* only accept ":filter {pat} cmd" */
+ {
+ char_u *reg_pat;
+
+ if (!checkforcmd(&p, "filter", 4)
+ || *p == NUL || ends_excmd(*p))
+ break;
+ if (*p == '!')
+ {
+ cmdmod.filter_force = TRUE;
+ p = skipwhite(p + 1);
+ if (*p == NUL || ends_excmd(*p))
+ break;
+ }
+ if (skip_only)
+ p = skip_vimgrep_pat(p, NULL, NULL);
+ else
+ // NOTE: This puts a NUL after the pattern.
+ p = skip_vimgrep_pat(p, &reg_pat, NULL);
+ if (p == NULL || *p == NUL)
+ break;
+ if (!skip_only)
+ {
+ cmdmod.filter_regmatch.regprog =
+ vim_regcomp(reg_pat, RE_MAGIC);
+ if (cmdmod.filter_regmatch.regprog == NULL)
+ break;
+ }
+ eap->cmd = p;
+ continue;
+ }
+
+ /* ":hide" and ":hide | cmd" are not modifiers */
+ case 'h': if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
+ || *p == NUL || ends_excmd(*p))
+ break;
+ eap->cmd = p;
+ cmdmod.hide = TRUE;
+ continue;
+
+ case 'l': if (checkforcmd(&eap->cmd, "lockmarks", 3))
+ {
+ cmdmod.lockmarks = TRUE;
+ continue;
+ }
+
+ if (!checkforcmd(&eap->cmd, "leftabove", 5))
+ break;
+ cmdmod.split |= WSP_ABOVE;
+ continue;
+
+ case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3))
+ {
+ if (cmdmod.save_ei == NULL && !skip_only)
+ {
+ /* Set 'eventignore' to "all". Restore the
+ * existing option value later. */
+ cmdmod.save_ei = vim_strsave(p_ei);
+ set_string_option_direct((char_u *)"ei", -1,
+ (char_u *)"all", OPT_FREE, SID_NONE);
+ }
+ continue;
+ }
+ if (!checkforcmd(&eap->cmd, "noswapfile", 3))
+ break;
+ cmdmod.noswapfile = TRUE;
+ continue;
+
+ case 'r': if (!checkforcmd(&eap->cmd, "rightbelow", 6))
+ break;
+ cmdmod.split |= WSP_BELOW;
+ continue;
+
+ case 's': if (checkforcmd(&eap->cmd, "sandbox", 3))
+ {
+#ifdef HAVE_SANDBOX
+ if (!skip_only)
+ {
+ if (!eap->did_sandbox)
+ ++sandbox;
+ eap->did_sandbox = TRUE;
+ }
+#endif
+ continue;
+ }
+ if (!checkforcmd(&eap->cmd, "silent", 3))
+ break;
+ if (!skip_only)
+ {
+ if (eap->save_msg_silent == -1)
+ eap->save_msg_silent = msg_silent;
+ ++msg_silent;
+ }
+ if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
+ {
+ /* ":silent!", but not "silent !cmd" */
+ eap->cmd = skipwhite(eap->cmd + 1);
+ if (!skip_only)
+ {
+ ++emsg_silent;
+ ++eap->did_esilent;
+ }
+ }
+ continue;
+
+ case 't': if (checkforcmd(&p, "tab", 3))
+ {
+ long tabnr = get_address(eap, &eap->cmd, ADDR_TABS,
+ eap->skip, FALSE, 1);
+ if (tabnr == MAXLNUM)
+ cmdmod.tab = tabpage_index(curtab) + 1;
+ else
+ {
+ if (tabnr < 0 || tabnr > LAST_TAB_NR)
+ {
+ *errormsg = (char_u *)_(e_invrange);
+ return FAIL;
+ }
+ cmdmod.tab = tabnr + 1;
+ }
+ eap->cmd = p;
+ continue;
+ }
+ if (!checkforcmd(&eap->cmd, "topleft", 2))
+ break;
+ cmdmod.split |= WSP_TOP;
+ continue;
+
+ case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
+ break;
+ if (!skip_only)
+ {
+ if (eap->save_msg_silent == -1)
+ eap->save_msg_silent = msg_silent;
+ msg_silent = 0;
+ }
+ continue;
+
+ case 'v': if (checkforcmd(&eap->cmd, "vertical", 4))
+ {
+ cmdmod.split |= WSP_VERT;
+ continue;
+ }
+ if (!checkforcmd(&p, "verbose", 4))
+ break;
+ if (!skip_only)
+ {
+ if (eap->verbose_save < 0)
+ eap->verbose_save = p_verbose;
+ if (vim_isdigit(*eap->cmd))
+ p_verbose = atoi((char *)eap->cmd);
+ else
+ p_verbose = 1;
+ }
+ eap->cmd = p;
+ continue;
+ }
+ break;
+ }
+
+ return OK;
+}
+
+/*
+ * Free contents of "cmdmod".
+ */
+ static void
+free_cmdmod(void)
+{
+ if (cmdmod.save_ei != NULL)
+ {
+ /* Restore 'eventignore' to the value before ":noautocmd". */
+ set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
+ OPT_FREE, SID_NONE);
+ free_string_option(cmdmod.save_ei);
+ }
+
+ if (cmdmod.filter_regmatch.regprog != NULL)
+ vim_regfree(cmdmod.filter_regmatch.regprog);
+}
+
+/*
+ * Parse the address range, if any, in "eap".
+ * Return FAIL and set "errormsg" or return OK.
+ */
+ int
+parse_cmd_address(exarg_T *eap, char_u **errormsg)
+{
+ int address_count = 1;
+ linenr_T lnum;
+
+ // Repeat for all ',' or ';' separated addresses.
+ for (;;)
+ {
+ eap->line1 = eap->line2;
+ switch (eap->addr_type)
+ {
+ case ADDR_LINES:
+ // default is current line number
+ eap->line2 = curwin->w_cursor.lnum;
+ break;
+ case ADDR_WINDOWS:
+ eap->line2 = CURRENT_WIN_NR;
+ break;
+ case ADDR_ARGUMENTS:
+ eap->line2 = curwin->w_arg_idx + 1;
+ if (eap->line2 > ARGCOUNT)
+ eap->line2 = ARGCOUNT;
+ break;
+ case ADDR_LOADED_BUFFERS:
+ case ADDR_BUFFERS:
+ eap->line2 = curbuf->b_fnum;
+ break;
+ case ADDR_TABS:
+ eap->line2 = CURRENT_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ eap->line2 = 1;
+ break;
+#ifdef FEAT_QUICKFIX
+ case ADDR_QUICKFIX:
+ eap->line2 = qf_get_cur_valid_idx(eap);
+ break;
+#endif
+ }
+ eap->cmd = skipwhite(eap->cmd);
+ lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip,
+ eap->addr_count == 0, address_count++);
+ if (eap->cmd == NULL) // error detected
+ return FAIL;
+ if (lnum == MAXLNUM)
+ {
+ if (*eap->cmd == '%') // '%' - all lines
+ {
+ ++eap->cmd;
+ switch (eap->addr_type)
+ {
+ case ADDR_LINES:
+ eap->line1 = 1;
+ eap->line2 = curbuf->b_ml.ml_line_count;
+ break;
+ case ADDR_LOADED_BUFFERS:
+ {
+ buf_T *buf = firstbuf;
+
+ while (buf->b_next != NULL
+ && buf->b_ml.ml_mfp == NULL)
+ buf = buf->b_next;
+ eap->line1 = buf->b_fnum;
+ buf = lastbuf;
+ while (buf->b_prev != NULL
+ && buf->b_ml.ml_mfp == NULL)
+ buf = buf->b_prev;
+ eap->line2 = buf->b_fnum;
+ break;
+ }
+ case ADDR_BUFFERS:
+ eap->line1 = firstbuf->b_fnum;
+ eap->line2 = lastbuf->b_fnum;
+ break;
+ case ADDR_WINDOWS:
+ case ADDR_TABS:
+ if (IS_USER_CMDIDX(eap->cmdidx))
+ {
+ eap->line1 = 1;
+ eap->line2 = eap->addr_type == ADDR_WINDOWS
+ ? LAST_WIN_NR : LAST_TAB_NR;
+ }
+ else
+ {
+ // there is no Vim command which uses '%' and
+ // ADDR_WINDOWS or ADDR_TABS
+ *errormsg = (char_u *)_(e_invrange);
+ return FAIL;
+ }
+ break;
+ case ADDR_TABS_RELATIVE:
+ *errormsg = (char_u *)_(e_invrange);
+ return FAIL;
+ case ADDR_ARGUMENTS:
+ if (ARGCOUNT == 0)
+ eap->line1 = eap->line2 = 0;
+ else
+ {
+ eap->line1 = 1;
+ eap->line2 = ARGCOUNT;
+ }
+ break;
+#ifdef FEAT_QUICKFIX
+ case ADDR_QUICKFIX:
+ eap->line1 = 1;
+ eap->line2 = qf_get_size(eap);
+ if (eap->line2 == 0)
+ eap->line2 = 1;
+ break;
+#endif
+ }
+ ++eap->addr_count;
+ }
+ else if (*eap->cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
+ {
+ pos_T *fp;
+
+ // '*' - visual area
+ if (eap->addr_type != ADDR_LINES)
+ {
+ *errormsg = (char_u *)_(e_invrange);
+ return FAIL;
+ }
+
+ ++eap->cmd;
+ if (!eap->skip)
+ {
+ fp = getmark('<', FALSE);
+ if (check_mark(fp) == FAIL)
+ return FAIL;
+ eap->line1 = fp->lnum;
+ fp = getmark('>', FALSE);
+ if (check_mark(fp) == FAIL)
+ return FAIL;
+ eap->line2 = fp->lnum;
+ ++eap->addr_count;
+ }
+ }
+ }
+ else
+ eap->line2 = lnum;
+ eap->addr_count++;
+
+ if (*eap->cmd == ';')
+ {
+ if (!eap->skip)
+ {
+ curwin->w_cursor.lnum = eap->line2;
+ // don't leave the cursor on an illegal line or column
+ check_cursor();
+ }
+ }
+ else if (*eap->cmd != ',')
+ break;
+ ++eap->cmd;
+ }
+
+ // One address given: set start and end lines.
+ if (eap->addr_count == 1)
+ {
+ eap->line1 = eap->line2;
+ // ... but only implicit: really no address given
+ if (lnum == MAXLNUM)
+ eap->addr_count = 0;
+ }
+ return OK;
+}
+
+/*
* Check for an Ex command with optional tail.
* If there is a match advance "pp" to the argument and return TRUE.
*/
@@ -4292,7 +4379,7 @@ set_one_cmd_context(
}
/*
- * skip a range specifier of the form: addr [,addr] [;addr] ..
+ * Skip a range specifier of the form: addr [,addr] [;addr] ..
*
* Backslashed delimiters after / or ? will be skipped, and commands will
* not be expanded between /'s and ?'s or after "'".
@@ -5685,22 +5772,16 @@ check_more(
{
char_u buff[DIALOG_MSG_SIZE];
- if (n == 1)
- vim_strncpy(buff,
- (char_u *)_("1 more file to edit. Quit anyway?"),
- DIALOG_MSG_SIZE - 1);
- else
- vim_snprintf((char *)buff, DIALOG_MSG_SIZE,
- _("%d more files to edit. Quit anyway?"), n);
+ vim_snprintf((char *)buff, DIALOG_MSG_SIZE,
+ NGETTEXT("%d more file to edit. Quit anyway?",
+ "%d more files to edit. Quit anyway?", n), n);
if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 1) == VIM_YES)
return OK;
return FAIL;
}
#endif
- if (n == 1)
- EMSG(_("E173: 1 more file to edit"));
- else
- EMSGN(_("E173: %ld more files to edit"), n);
+ EMSGN(NGETTEXT("E173: %ld more file to edit",
+ "E173: %ld more files to edit", n), n);
quitmore = 2; /* next try to quit is allowed */
}
return FAIL;
@@ -7750,7 +7831,7 @@ ex_stop(exarg_T *eap)
stoptermcap();
out_flush(); /* needed for SUN to restore xterm buffer */
#ifdef FEAT_TITLE
- mch_restore_title(3); /* restore window titles */
+ mch_restore_title(SAVE_RESTORE_BOTH); /* restore window titles */
#endif
ui_suspend(); /* call machine specific function */
#ifdef FEAT_TITLE
@@ -11768,7 +11849,7 @@ put_view(
*/
if ((*flagp & SSOP_FOLDS)
&& wp->w_buffer->b_ffname != NULL
- && (*wp->w_buffer->b_p_bt == NUL || bt_help(wp->w_buffer)))
+ && (bt_normal(wp->w_buffer) || bt_help(wp->w_buffer)))
{
if (put_folds(fd, wp) == FAIL)
return FAIL;
@@ -12465,6 +12546,20 @@ ex_folddo(exarg_T *eap)
}
#endif
+#ifdef FEAT_QUICKFIX
+/*
+ * Returns TRUE if the supplied Ex cmdidx is for a location list command
+ * instead of a quickfix command.
+ */
+ int
+is_loclist_cmd(int cmdidx)
+{
+ if (cmdidx < 0 || cmdidx > CMD_SIZE)
+ return FALSE;
+ return cmdnames[cmdidx].cmd_name[0] == 'l';
+}
+#endif
+
# if defined(FEAT_TIMERS) || defined(PROTO)
int
get_pressedreturn(void)
diff --git a/src/ex_getln.c b/src/ex_getln.c
index e659c1a..1cb3c8b 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -13,6 +13,10 @@
#include "vim.h"
+#ifndef MAX
+# define MAX(x,y) ((x) > (y) ? (x) : (y))
+#endif
+
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
* These need to be saved when using CTRL-R |, that's why they are in a
@@ -141,9 +145,6 @@ _RTLENTRYF
#endif
sort_func_compare(const void *s1, const void *s2);
#endif
-#ifdef FEAT_SEARCH_EXTRA
-static void set_search_match(pos_T *t);
-#endif
static void
@@ -185,9 +186,8 @@ empty_pattern(char_u *p)
n -= 2;
return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
}
-#endif
-#ifdef FEAT_SEARCH_EXTRA
+// Struct to store the viewstate during 'incsearch' highlighting.
typedef struct {
colnr_T vs_curswant;
colnr_T vs_leftcol;
@@ -224,6 +224,517 @@ restore_viewstate(viewstate_T *vs)
curwin->w_botline = vs->vs_botline;
curwin->w_empty_rows = vs->vs_empty_rows;
}
+
+// Struct to store the state of 'incsearch' highlighting.
+typedef struct {
+ pos_T search_start; // where 'incsearch' starts searching
+ pos_T save_cursor;
+ viewstate_T init_viewstate;
+ viewstate_T old_viewstate;
+ pos_T match_start;
+ pos_T match_end;
+ int did_incsearch;
+ int incsearch_postponed;
+ int magic_save;
+} incsearch_state_T;
+
+ static void
+init_incsearch_state(incsearch_state_T *is_state)
+{
+ is_state->match_start = curwin->w_cursor;
+ is_state->did_incsearch = FALSE;
+ is_state->incsearch_postponed = FALSE;
+ is_state->magic_save = p_magic;
+ CLEAR_POS(&is_state->match_end);
+ is_state->save_cursor = curwin->w_cursor; // may be restored later
+ is_state->search_start = curwin->w_cursor;
+ save_viewstate(&is_state->init_viewstate);
+ save_viewstate(&is_state->old_viewstate);
+}
+
+/*
+ * First move cursor to end of match, then to the start. This
+ * moves the whole match onto the screen when 'nowrap' is set.
+ */
+ static void
+set_search_match(pos_T *t)
+{
+ t->lnum += search_match_lines;
+ t->col = search_match_endcol;
+ if (t->lnum > curbuf->b_ml.ml_line_count)
+ {
+ t->lnum = curbuf->b_ml.ml_line_count;
+ coladvance((colnr_T)MAXCOL);
+ }
+}
+
+/*
+ * Return TRUE when 'incsearch' highlighting is to be done.
+ * Sets search_first_line and search_last_line to the address range.
+ */
+ static int
+do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
+ int *skiplen, int *patlen)
+{
+ char_u *cmd;
+ cmdmod_T save_cmdmod = cmdmod;
+ char_u *p;
+ int delim_optional = FALSE;
+ int delim;
+ char_u *end;
+ char_u *dummy;
+ exarg_T ea;
+ pos_T save_cursor;
+ int use_last_pat;
+
+ *skiplen = 0;
+ *patlen = ccline.cmdlen;
+
+ if (!p_is || cmd_silent)
+ return FALSE;
+
+ // by default search all lines
+ search_first_line = 0;
+ search_last_line = MAXLNUM;
+
+ if (firstc == '/' || firstc == '?')
+ return TRUE;
+ if (firstc != ':')
+ return FALSE;
+
+ vim_memset(&ea, 0, sizeof(ea));
+ ea.line1 = 1;
+ ea.line2 = 1;
+ ea.cmd = ccline.cmdbuff;
+ ea.addr_type = ADDR_LINES;
+
+ parse_command_modifiers(&ea, &dummy, TRUE);
+ cmdmod = save_cmdmod;
+
+ cmd = skip_range(ea.cmd, NULL);
+ if (vim_strchr((char_u *)"sgvl", *cmd) == NULL)
+ return FALSE;
+
+ // Skip over "substitute" to find the pattern separator.
+ for (p = cmd; ASCII_ISALPHA(*p); ++p)
+ ;
+ if (*skipwhite(p) == NUL)
+ return FALSE;
+
+ if (STRNCMP(cmd, "substitute", p - cmd) == 0
+ || STRNCMP(cmd, "smagic", p - cmd) == 0
+ || STRNCMP(cmd, "snomagic", MAX(p - cmd, 3)) == 0
+ || STRNCMP(cmd, "vglobal", p - cmd) == 0)
+ {
+ if (*cmd == 's' && cmd[1] == 'm')
+ p_magic = TRUE;
+ else if (*cmd == 's' && cmd[1] == 'n')
+ p_magic = FALSE;
+ }
+ else if (STRNCMP(cmd, "sort", MAX(p - cmd, 3)) == 0)
+ {
+ // skip over flags
+ while (ASCII_ISALPHA(*(p = skipwhite(p))))
+ ++p;
+ if (*p == NUL)
+ return FALSE;
+ }
+ else if (STRNCMP(cmd, "vimgrep", MAX(p - cmd, 3)) == 0
+ || STRNCMP(cmd, "vimgrepadd", MAX(p - cmd, 8)) == 0
+ || STRNCMP(cmd, "lvimgrep", MAX(p - cmd, 2)) == 0
+ || STRNCMP(cmd, "lvimgrepadd", MAX(p - cmd, 9)) == 0
+ || STRNCMP(cmd, "global", p - cmd) == 0)
+ {
+ // skip over "!"
+ if (*p == '!')
+ {
+ p++;
+ if (*skipwhite(p) == NUL)
+ return FALSE;
+ }
+ if (*cmd != 'g')
+ delim_optional = TRUE;
+ }
+ else
+ return FALSE;
+
+ p = skipwhite(p);
+ delim = (delim_optional && vim_isIDc(*p)) ? ' ' : *p++;
+ end = skip_regexp(p, delim, p_magic, NULL);
+
+ use_last_pat = end == p && *end == delim;
+
+ if (end == p && !use_last_pat)
+ return FALSE;
+
+ // Don't do 'hlsearch' highlighting if the pattern matches everything.
+ if (!use_last_pat)
+ {
+ char c = *end;
+ int empty;
+
+ *end = NUL;
+ empty = empty_pattern(p);
+ *end = c;
+ if (empty)
+ return FALSE;
+ }
+
+ // found a non-empty pattern or //
+ *skiplen = (int)(p - ccline.cmdbuff);
+ *patlen = (int)(end - p);
+
+ // parse the address range
+ save_cursor = curwin->w_cursor;
+ curwin->w_cursor = is_state->search_start;
+ parse_cmd_address(&ea, &dummy);
+ if (ea.addr_count > 0)
+ {
+ // Allow for reverse match.
+ if (ea.line2 < ea.line1)
+ {
+ search_first_line = ea.line2;
+ search_last_line = ea.line1;
+ }
+ else
+ {
+ search_first_line = ea.line1;
+ search_last_line = ea.line2;
+ }
+ }
+ else if (cmd[0] == 's' && cmd[1] != 'o')
+ {
+ // :s defaults to the current line
+ search_first_line = curwin->w_cursor.lnum;
+ search_last_line = curwin->w_cursor.lnum;
+ }
+
+ curwin->w_cursor = save_cursor;
+ return TRUE;
+}
+
+ static void
+finish_incsearch_highlighting(
+ int gotesc,
+ incsearch_state_T *is_state,
+ int call_update_screen)
+{
+ if (is_state->did_incsearch)
+ {
+ is_state->did_incsearch = FALSE;
+ if (gotesc)
+ curwin->w_cursor = is_state->save_cursor;
+ else
+ {
+ if (!EQUAL_POS(is_state->save_cursor, is_state->search_start))
+ {
+ // put the '" mark at the original position
+ curwin->w_cursor = is_state->save_cursor;
+ setpcmark();
+ }
+ curwin->w_cursor = is_state->search_start;
+ }
+ restore_viewstate(&is_state->old_viewstate);
+ highlight_match = FALSE;
+ validate_cursor(); /* needed for TAB */
+ if (call_update_screen)
+ update_screen(SOME_VALID);
+ else
+ redraw_all_later(SOME_VALID);
+ p_magic = is_state->magic_save;
+ }
+}
+
+/*
+ * Do 'incsearch' highlighting if desired.
+ */
+ static void
+may_do_incsearch_highlighting(
+ int firstc,
+ long count,
+ incsearch_state_T *is_state)
+{
+ int skiplen, patlen;
+ int i;
+ pos_T end_pos;
+ struct cmdline_info save_ccline;
+#ifdef FEAT_RELTIME
+ proftime_T tm;
+#endif
+ int next_char;
+ int use_last_pat;
+
+ if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
+ {
+ finish_incsearch_highlighting(FALSE, is_state, TRUE);
+ return;
+ }
+
+ // If there is a character waiting, search and redraw later.
+ if (char_avail())
+ {
+ is_state->incsearch_postponed = TRUE;
+ return;
+ }
+ is_state->incsearch_postponed = FALSE;
+
+ if (search_first_line == 0)
+ // start at the original cursor position
+ curwin->w_cursor = is_state->search_start;
+ else
+ {
+ // start at the first line in the range
+ curwin->w_cursor.lnum = search_first_line;
+ curwin->w_cursor.col = 0;
+ }
+ save_last_search_pattern();
+
+ // Use the previous pattern for ":s//".
+ next_char = ccline.cmdbuff[skiplen + patlen];
+ use_last_pat = patlen == 0 && skiplen > 0
+ && ccline.cmdbuff[skiplen - 1] == next_char;
+
+ // If there is no pattern, don't do anything.
+ if (patlen == 0 && !use_last_pat)
+ {
+ i = 0;
+ set_no_hlsearch(TRUE); // turn off previous highlight
+ redraw_all_later(SOME_VALID);
+ }
+ else
+ {
+ int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
+
+ cursor_off(); // so the user knows we're busy
+ out_flush();
+ ++emsg_off; // so it doesn't beep if bad expr
+#ifdef FEAT_RELTIME
+ // Set the time limit to half a second.
+ profile_setlimit(500L, &tm);
+#endif
+ if (!p_hls)
+ search_flags += SEARCH_KEEP;
+ if (search_first_line != 0)
+ search_flags += SEARCH_START;
+ ccline.cmdbuff[skiplen + patlen] = NUL;
+ i = do_search(NULL, firstc == ':' ? '/' : firstc,
+ ccline.cmdbuff + skiplen, count, search_flags,
+#ifdef FEAT_RELTIME
+ &tm, NULL
+#else
+ NULL, NULL
+#endif
+ );
+ ccline.cmdbuff[skiplen + patlen] = next_char;
+ --emsg_off;
+
+ if (curwin->w_cursor.lnum < search_first_line
+ || curwin->w_cursor.lnum > search_last_line)
+ {
+ // match outside of address range
+ i = 0;
+ curwin->w_cursor = is_state->search_start;
+ }
+
+ // if interrupted while searching, behave like it failed
+ if (got_int)
+ {
+ (void)vpeekc(); // remove <C-C> from input stream
+ got_int = FALSE; // don't abandon the command line
+ i = 0;
+ }
+ else if (char_avail())
+ // cancelled searching because a char was typed
+ is_state->incsearch_postponed = TRUE;
+ }
+ if (i != 0)
+ highlight_match = TRUE; // highlight position
+ else
+ highlight_match = FALSE; // remove highlight
+
+ // First restore the old curwin values, so the screen is positioned in the
+ // same way as the actual search command.
+ restore_viewstate(&is_state->old_viewstate);
+ changed_cline_bef_curs();
+ update_topline();
+
+ if (i != 0)
+ {
+ pos_T save_pos = curwin->w_cursor;
+
+ is_state->match_start = curwin->w_cursor;
+ set_search_match(&curwin->w_cursor);
+ validate_cursor();
+ end_pos = curwin->w_cursor;
+ is_state->match_end = end_pos;
+ curwin->w_cursor = save_pos;
+ }
+ else
+ end_pos = curwin->w_cursor; // shutup gcc 4
+
+ validate_cursor();
+ // May redraw the status line to show the cursor position.
+ if (p_ru && curwin->w_status_height > 0)
+ curwin->w_redr_status = TRUE;
+
+ save_cmdline(&save_ccline);
+ update_screen(SOME_VALID);
+ restore_cmdline(&save_ccline);
+ restore_last_search_pattern();
+
+ // Leave it at the end to make CTRL-R CTRL-W work.
+ if (i != 0)
+ curwin->w_cursor = end_pos;
+
+ msg_starthere();
+ redrawcmdline();
+ is_state->did_incsearch = TRUE;
+}
+
+/*
+ * May adjust 'incsearch' highlighting for typing CTRL-G and CTRL-T, go to next
+ * or previous match.
+ * Returns FAIL when jumping to cmdline_not_changed;
+ */
+ static int
+may_adjust_incsearch_highlighting(
+ int firstc,
+ long count,
+ incsearch_state_T *is_state,
+ int c)
+{
+ int skiplen, patlen;
+ pos_T t;
+ char_u *pat;
+ int search_flags = SEARCH_NOOF;
+ int i;
+ int save;
+
+ if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
+ return OK;
+ if (patlen == 0 && ccline.cmdbuff[skiplen] == NUL)
+ return FAIL;
+
+ if (firstc == ccline.cmdbuff[skiplen])
+ {
+ pat = last_search_pattern();
+ skiplen = 0;
+ patlen = (int)STRLEN(pat);
+ }
+ else
+ pat = ccline.cmdbuff + skiplen;
+
+ save_last_search_pattern();
+ cursor_off();
+ out_flush();
+ if (c == Ctrl_G)
+ {
+ t = is_state->match_end;
+ if (LT_POS(is_state->match_start, is_state->match_end))
+ // Start searching at the end of the match not at the beginning of
+ // the next column.
+ (void)decl(&t);
+ search_flags += SEARCH_COL;
+ }
+ else
+ t = is_state->match_start;
+ if (!p_hls)
+ search_flags += SEARCH_KEEP;
+ ++emsg_off;
+ save = pat[patlen];
+ pat[patlen] = NUL;
+ i = searchit(curwin, curbuf, &t,
+ c == Ctrl_G ? FORWARD : BACKWARD,
+ pat, count, search_flags,
+ RE_SEARCH, 0, NULL, NULL);
+ --emsg_off;
+ pat[patlen] = save;
+ if (i)
+ {
+ is_state->search_start = is_state->match_start;
+ is_state->match_end = t;
+ is_state->match_start = t;
+ if (c == Ctrl_T && firstc != '?')
+ {
+ // Move just before the current match, so that when nv_search
+ // finishes the cursor will be put back on the match.
+ is_state->search_start = t;
+ (void)decl(&is_state->search_start);
+ }
+ else if (c == Ctrl_G && firstc == '?')
+ {
+ // Move just after the current match, so that when nv_search
+ // finishes the cursor will be put back on the match.
+ is_state->search_start = t;
+ (void)incl(&is_state->search_start);
+ }
+ if (LT_POS(t, is_state->search_start) && c == Ctrl_G)
+ {
+ // wrap around
+ is_state->search_start = t;
+ if (firstc == '?')
+ (void)incl(&is_state->search_start);
+ else
+ (void)decl(&is_state->search_start);
+ }
+
+ set_search_match(&is_state->match_end);
+ curwin->w_cursor = is_state->match_start;
+ changed_cline_bef_curs();
+ update_topline();
+ validate_cursor();
+ highlight_match = TRUE;
+ save_viewstate(&is_state->old_viewstate);
+ update_screen(NOT_VALID);
+ redrawcmdline();
+ }
+ else
+ vim_beep(BO_ERROR);
+ restore_last_search_pattern();
+ return FAIL;
+}
+
+/*
+ * When CTRL-L typed: add character from the match to the pattern.
+ * May set "*c" to the added character.
+ * Return OK when jumping to cmdline_not_changed.
+ */
+ static int
+may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state)
+{
+ int skiplen, patlen;
+
+ if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen))
+ return FAIL;
+
+ // Add a character from under the cursor for 'incsearch'.
+ if (is_state->did_incsearch)
+ {
+ curwin->w_cursor = is_state->match_end;
+ if (!EQUAL_POS(curwin->w_cursor, is_state->search_start))
+ {
+ *c = gchar_cursor();
+
+ // If 'ignorecase' and 'smartcase' are set and the
+ // command line has no uppercase characters, convert
+ // the character to lowercase.
+ if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff + skiplen))
+ *c = MB_TOLOWER(*c);
+ if (*c != NUL)
+ {
+ if (*c == firstc || vim_strchr((char_u *)(
+ p_magic ? "\\~^$.*[" : "\\^$"), *c) != NULL)
+ {
+ // put a backslash before special characters
+ stuffcharReadbuff(*c);
+ *c = '\\';
+ }
+ return FAIL;
+ }
+ }
+ }
+ return OK;
+}
#endif
/*
@@ -262,14 +773,7 @@ getcmdline(
int histype; /* history type to be used */
#endif
#ifdef FEAT_SEARCH_EXTRA
- pos_T search_start; /* where 'incsearch' starts searching */
- pos_T save_cursor;
- viewstate_T init_viewstate;
- viewstate_T old_viewstate;
- pos_T match_start = curwin->w_cursor;
- pos_T match_end;
- int did_incsearch = FALSE;
- int incsearch_postponed = FALSE;
+ incsearch_state_T is_state;
#endif
int did_wild_list = FALSE; /* did wild_list() recently */
int wim_index = 0; /* index in wim_flags[] */
@@ -287,7 +791,7 @@ getcmdline(
#endif
expand_T xpc;
long *b_im_ptr = NULL;
-#if defined(FEAT_WILDMENU) || defined(FEAT_EVAL) || defined(FEAT_SEARCH_EXTRA)
+#if defined(FEAT_WILDMENU) || defined(FEAT_EVAL)
/* Everything that may work recursively should save and restore the
* current command line in save_ccline. That includes update_screen(), a
* custom status line may invoke ":normal". */
@@ -309,12 +813,9 @@ getcmdline(
#endif
ccline.overstrike = FALSE; /* always start in insert mode */
+
#ifdef FEAT_SEARCH_EXTRA
- CLEAR_POS(&match_end);
- save_cursor = curwin->w_cursor; /* may be restored later */
- search_start = curwin->w_cursor;
- save_viewstate(&init_viewstate);
- save_viewstate(&old_viewstate);
+ init_incsearch_state(&is_state);
#endif
/*
@@ -1089,10 +1590,10 @@ getcmdline(
#ifdef FEAT_SEARCH_EXTRA
if (ccline.cmdlen == 0)
{
- search_start = save_cursor;
+ is_state.search_start = is_state.save_cursor;
/* save view settings, so that the screen
* won't be restored at the wrong position */
- old_viewstate = init_viewstate;
+ is_state.old_viewstate = is_state.init_viewstate;
}
#endif
redrawcmd();
@@ -1121,7 +1622,7 @@ getcmdline(
}
#ifdef FEAT_SEARCH_EXTRA
if (ccline.cmdlen == 0)
- search_start = save_cursor;
+ is_state.search_start = is_state.save_cursor;
#endif
redraw_cmdline = TRUE;
goto returncmd; /* back to cmd mode */
@@ -1208,7 +1709,7 @@ getcmdline(
ccline.cmdbuff[ccline.cmdlen] = NUL;
#ifdef FEAT_SEARCH_EXTRA
if (ccline.cmdlen == 0)
- search_start = save_cursor;
+ is_state.search_start = is_state.save_cursor;
#endif
redrawcmd();
goto cmdline_changed;
@@ -1545,38 +2046,8 @@ getcmdline(
case Ctrl_L:
#ifdef FEAT_SEARCH_EXTRA
- if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
- {
- /* Add a character from under the cursor for 'incsearch' */
- if (did_incsearch)
- {
- curwin->w_cursor = match_end;
- if (!EQUAL_POS(curwin->w_cursor, search_start))
- {
- c = gchar_cursor();
- /* If 'ignorecase' and 'smartcase' are set and the
- * command line has no uppercase characters, convert
- * the character to lowercase */
- if (p_ic && p_scs
- && !pat_has_uppercase(ccline.cmdbuff))
- c = MB_TOLOWER(c);
- if (c != NUL)
- {
- if (c == firstc || vim_strchr((char_u *)(
- p_magic ? "\\~^$.*[" : "\\^$"), c)
- != NULL)
- {
- /* put a backslash before special
- * characters */
- stuffcharReadbuff(c);
- c = '\\';
- }
- break;
- }
- }
- }
+ if (may_add_char_to_search(firstc, &c, &is_state) == OK)
goto cmdline_not_changed;
- }
#endif
/* completion: longest common part */
@@ -1742,88 +2213,9 @@ getcmdline(
#ifdef FEAT_SEARCH_EXTRA
case Ctrl_G: /* next match */
case Ctrl_T: /* previous match */
- if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
- {
- pos_T t;
- char_u *pat;
- int search_flags = SEARCH_NOOF;
-
- if (ccline.cmdlen == 0)
- goto cmdline_not_changed;
-
- if (firstc == ccline.cmdbuff[0])
- pat = last_search_pattern();
- else
- pat = ccline.cmdbuff;
-
- save_last_search_pattern();
- cursor_off();
- out_flush();
- if (c == Ctrl_G)
- {
- t = match_end;
- if (LT_POS(match_start, match_end))
- /* start searching at the end of the match
- * not at the beginning of the next column */
- (void)decl(&t);
- search_flags += SEARCH_COL;
- }
- else
- t = match_start;
- if (!p_hls)
- search_flags += SEARCH_KEEP;
- ++emsg_off;
- i = searchit(curwin, curbuf, &t,
- c == Ctrl_G ? FORWARD : BACKWARD,
- pat, count, search_flags,
- RE_SEARCH, 0, NULL, NULL);
- --emsg_off;
- if (i)
- {
- search_start = match_start;
- match_end = t;
- match_start = t;
- if (c == Ctrl_T && firstc == '/')
- {
- /* move just before the current match, so that
- * when nv_search finishes the cursor will be
- * put back on the match */
- search_start = t;
- (void)decl(&search_start);
- }
- else if (c == Ctrl_G && firstc == '?')
- {
- /* move just after the current match, so that
- * when nv_search finishes the cursor will be
- * put back on the match */
- search_start = t;
- (void)incl(&search_start);
- }
- if (LT_POS(t, search_start) && c == Ctrl_G)
- {
- /* wrap around */
- search_start = t;
- if (firstc == '?')
- (void)incl(&search_start);
- else
- (void)decl(&search_start);
- }
-
- set_search_match(&match_end);
- curwin->w_cursor = match_start;
- changed_cline_bef_curs();
- update_topline();
- validate_cursor();
- highlight_match = TRUE;
- save_viewstate(&old_viewstate);
- update_screen(NOT_VALID);
- redrawcmdline();
- }
- else
- vim_beep(BO_ERROR);
- restore_last_search_pattern();
+ if (may_adjust_incsearch_highlighting(
+ firstc, count, &is_state, c) == FAIL)
goto cmdline_not_changed;
- }
break;
#endif
@@ -1951,7 +2343,7 @@ getcmdline(
*/
cmdline_not_changed:
#ifdef FEAT_SEARCH_EXTRA
- if (!incsearch_postponed)
+ if (!is_state.incsearch_postponed)
continue;
#endif
@@ -1960,115 +2352,7 @@ cmdline_changed:
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
#ifdef FEAT_SEARCH_EXTRA
- /*
- * 'incsearch' highlighting.
- */
- if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
- {
- pos_T end_pos;
-#ifdef FEAT_RELTIME
- proftime_T tm;
-#endif
-
- /* if there is a character waiting, search and redraw later */
- if (char_avail())
- {
- incsearch_postponed = TRUE;
- continue;
- }
- incsearch_postponed = FALSE;
- curwin->w_cursor = search_start; /* start at old position */
- save_last_search_pattern();
-
- /* If there is no command line, don't do anything */
- if (ccline.cmdlen == 0)
- {
- i = 0;
- set_no_hlsearch(TRUE); /* turn off previous highlight */
- redraw_all_later(SOME_VALID);
- }
- else
- {
- int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
- cursor_off(); /* so the user knows we're busy */
- out_flush();
- ++emsg_off; /* So it doesn't beep if bad expr */
-#ifdef FEAT_RELTIME
- /* Set the time limit to half a second. */
- profile_setlimit(500L, &tm);
-#endif
- if (!p_hls)
- search_flags += SEARCH_KEEP;
- i = do_search(NULL, firstc, ccline.cmdbuff, count,
- search_flags,
-#ifdef FEAT_RELTIME
- &tm, NULL
-#else
- NULL, NULL
-#endif
- );
- --emsg_off;
- /* if interrupted while searching, behave like it failed */
- if (got_int)
- {
- (void)vpeekc(); /* remove <C-C> from input stream */
- got_int = FALSE; /* don't abandon the command line */
- i = 0;
- }
- else if (char_avail())
- /* cancelled searching because a char was typed */
- incsearch_postponed = TRUE;
- }
- if (i != 0)
- highlight_match = TRUE; /* highlight position */
- else
- highlight_match = FALSE; /* remove highlight */
-
- /* first restore the old curwin values, so the screen is
- * positioned in the same way as the actual search command */
- restore_viewstate(&old_viewstate);
- changed_cline_bef_curs();
- update_topline();
-
- if (i != 0)
- {
- pos_T save_pos = curwin->w_cursor;
-
- match_start = curwin->w_cursor;
- set_search_match(&curwin->w_cursor);
- validate_cursor();
- end_pos = curwin->w_cursor;
- match_end = end_pos;
- curwin->w_cursor = save_pos;
- }
- else
- end_pos = curwin->w_cursor; /* shutup gcc 4 */
-
- /* Disable 'hlsearch' highlighting if the pattern matches
- * everything. Avoids a flash when typing "foo\|". */
- if (empty_pattern(ccline.cmdbuff))
- set_no_hlsearch(TRUE);
-
- validate_cursor();
- /* May redraw the status line to show the cursor position. */
- if (p_ru && curwin->w_status_height > 0)
- curwin->w_redr_status = TRUE;
-
- save_cmdline(&save_ccline);
- update_screen(SOME_VALID);
- restore_cmdline(&save_ccline);
- restore_last_search_pattern();
-
- /* Leave it at the end to make CTRL-R CTRL-W work. */
- if (i != 0)
- curwin->w_cursor = end_pos;
-
- msg_starthere();
- redrawcmdline();
- did_incsearch = TRUE;
- }
-#else /* FEAT_SEARCH_EXTRA */
- ;
+ may_do_incsearch_highlighting(firstc, count, &is_state);
#endif
#ifdef FEAT_RIGHTLEFT
@@ -2100,25 +2384,7 @@ returncmd:
ccline.xpc = NULL;
#ifdef FEAT_SEARCH_EXTRA
- if (did_incsearch)
- {
- if (gotesc)
- curwin->w_cursor = save_cursor;
- else
- {
- if (!EQUAL_POS(save_cursor, search_start))
- {
- /* put the '" mark at the original position */
- curwin->w_cursor = save_cursor;
- setpcmark();
- }
- curwin->w_cursor = search_start;
- }
- restore_viewstate(&old_viewstate);
- highlight_match = FALSE;
- validate_cursor(); /* needed for TAB */
- redraw_all_later(SOME_VALID);
- }
+ finish_incsearch_highlighting(gotesc, &is_state, FALSE);
#endif
if (ccline.cmdbuff != NULL)
@@ -5279,7 +5545,7 @@ expand_shellcmd(
*/
static void *
call_user_expand_func(
- void *(*user_expand_func)(char_u *, int, typval_T *, int),
+ void *(*user_expand_func)(char_u *, int, typval_T *),
expand_T *xp,
int *num_file,
char_u ***file)
@@ -5318,7 +5584,7 @@ call_user_expand_func(
ccline.cmdprompt = NULL;
current_SID = xp->xp_scriptID;
- ret = user_expand_func(xp->xp_arg, 3, args, FALSE);
+ ret = user_expand_func(xp->xp_arg, 3, args);
ccline = save_ccline;
current_SID = save_current_SID;
@@ -7239,21 +7505,3 @@ script_get(exarg_T *eap, char_u *cmd)
return (char_u *)ga.ga_data;
}
-
-#ifdef FEAT_SEARCH_EXTRA
- static void
-set_search_match(pos_T *t)
-{
- /*
- * First move cursor to end of match, then to the start. This
- * moves the whole match onto the screen when 'nowrap' is set.
- */
- t->lnum += search_match_lines;
- t->col = search_match_endcol;
- if (t->lnum > curbuf->b_ml.ml_line_count)
- {
- t->lnum = curbuf->b_ml.ml_line_count;
- coladvance((colnr_T)MAXCOL);
- }
-}
-#endif
diff --git a/src/feature.h b/src/feature.h
index efe349d..6ae3ac2 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -355,6 +355,10 @@
# endif
#endif
+#ifdef FEAT_EVAL
+# define HAVE_SANDBOX
+#endif
+
/*
* +profile Profiling for functions and scripts.
*/
diff --git a/src/fileio.c b/src/fileio.c
index 07b241e..d00dc5e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -424,12 +424,8 @@ readfile(
*/
perm = mch_getperm(fname);
if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */
-# ifdef S_ISFIFO
&& !S_ISFIFO(perm) /* ... or fifo */
-# endif
-# ifdef S_ISSOCK
&& !S_ISSOCK(perm) /* ... or socket */
-# endif
# ifdef OPEN_CHR_FILES
&& !(S_ISCHR(perm) && is_dev_fd_file(fname))
/* ... or a character special file named /dev/fd/<n> */
@@ -2497,28 +2493,16 @@ failed:
c = FALSE;
#ifdef UNIX
-# ifdef S_ISFIFO
- if (S_ISFIFO(perm)) /* fifo or socket */
- {
- STRCAT(IObuff, _("[fifo/socket]"));
- c = TRUE;
- }
-# else
-# ifdef S_IFIFO
- if ((perm & S_IFMT) == S_IFIFO) /* fifo */
+ if (S_ISFIFO(perm)) /* fifo */
{
STRCAT(IObuff, _("[fifo]"));
c = TRUE;
}
-# endif
-# ifdef S_IFSOCK
- if ((perm & S_IFMT) == S_IFSOCK) /* or socket */
+ if (S_ISSOCK(perm)) /* or socket */
{
STRCAT(IObuff, _("[socket]"));
c = TRUE;
}
-# endif
-# endif
# ifdef OPEN_CHR_FILES
if (S_ISCHR(perm)) /* or character special */
{
@@ -3850,6 +3834,9 @@ buf_write(
stat_T st_new;
char_u *dirp;
char_u *rootname;
+#if defined(UNIX) || defined(WIN3264)
+ char_u *p;
+#endif
#if defined(UNIX)
int did_set_shortname;
mode_t umask_save;
@@ -3887,6 +3874,17 @@ buf_write(
* Isolate one directory name, using an entry in 'bdir'.
*/
(void)copy_option_part(&dirp, copybuf, BUFSIZE, ",");
+
+#if defined(UNIX) || defined(WIN3264)
+ p = copybuf + STRLEN(copybuf);
+ if (after_pathsep(copybuf, p) && p[-1] == p[-2])
+ // Ends with '//', use full path
+ if ((p = make_percent_swname(copybuf, fname)) != NULL)
+ {
+ backup = modname(p, backup_ext, FALSE);
+ vim_free(p);
+ }
+#endif
rootname = get_file_in_dir(fname, copybuf);
if (rootname == NULL)
{
@@ -3904,9 +3902,10 @@ buf_write(
for (;;)
{
/*
- * Make backup file name.
+ * Make the backup file name.
*/
- backup = buf_modname((buf->b_p_sn || buf->b_shortname),
+ if (backup == NULL)
+ backup = buf_modname((buf->b_p_sn || buf->b_shortname),
rootname, backup_ext, FALSE);
if (backup == NULL)
{
@@ -4108,14 +4107,29 @@ buf_write(
* Isolate one directory name and make the backup file name.
*/
(void)copy_option_part(&dirp, IObuff, IOSIZE, ",");
- rootname = get_file_in_dir(fname, IObuff);
- if (rootname == NULL)
- backup = NULL;
- else
+
+#if defined(UNIX) || defined(WIN3264)
+ p = IObuff + STRLEN(IObuff);
+ if (after_pathsep(IObuff, p) && p[-1] == p[-2])
+ // path ends with '//', use full path
+ if ((p = make_percent_swname(IObuff, fname)) != NULL)
+ {
+ backup = modname(p, backup_ext, FALSE);
+ vim_free(p);
+ }
+#endif
+ if (backup == NULL)
{
- backup = buf_modname((buf->b_p_sn || buf->b_shortname),
- rootname, backup_ext, FALSE);
- vim_free(rootname);
+ rootname = get_file_in_dir(fname, IObuff);
+ if (rootname == NULL)
+ backup = NULL;
+ else
+ {
+ backup = buf_modname(
+ (buf->b_p_sn || buf->b_shortname),
+ rootname, backup_ext, FALSE);
+ vim_free(rootname);
+ }
}
if (backup != NULL)
@@ -5335,16 +5349,11 @@ msg_add_lines(
"%ldL, %lldC", lnum, (long long)nchars);
else
{
- if (lnum == 1)
- STRCPY(p, _("1 line, "));
- else
- sprintf((char *)p, _("%ld lines, "), lnum);
+ sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
p += STRLEN(p);
- if (nchars == 1)
- STRCPY(p, _("1 character"));
- else
- vim_snprintf((char *)p, IOSIZE - (p - IObuff),
- _("%lld characters"), (long long)nchars);
+ vim_snprintf((char *)p, IOSIZE - (p - IObuff),
+ NGETTEXT("%lld character", "%lld characters", nchars),
+ (long long)nchars);
}
}
@@ -6252,7 +6261,7 @@ shorten_filenames(char_u **fnames, int count)
#endif
/*
- * add extension to file name - change path/fo.o.h to path/fo.o.h.ext or
+ * Add extension to file name - change path/fo.o.h to path/fo.o.h.ext or
* fo_o_h.ext for MSDOS or when shortname option set.
*
* Assumed that fname is a valid name found in the filesystem we assure that
@@ -6897,7 +6906,7 @@ buf_check_timestamp(
* this buffer. */
if (buf->b_ffname == NULL
|| buf->b_ml.ml_mfp == NULL
- || *buf->b_p_bt != NUL
+ || !bt_normal(buf)
|| buf->b_saving
|| busy
#ifdef FEAT_NETBEANS_INTG
diff --git a/src/globals.h b/src/globals.h
index 9cf8455..fa5b493 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -345,9 +345,13 @@ EXTERN int t_colors INIT(= 0); /* int value of T_CCO */
* a match within one line), search_match_endcol the column number of the
* character just after the match in the last line.
*/
-EXTERN int highlight_match INIT(= FALSE); /* show search match pos */
-EXTERN linenr_T search_match_lines; /* lines of of matched string */
-EXTERN colnr_T search_match_endcol; /* col nr of match end */
+EXTERN int highlight_match INIT(= FALSE); // show search match pos
+EXTERN linenr_T search_match_lines; // lines of of matched string
+EXTERN colnr_T search_match_endcol; // col nr of match end
+#ifdef FEAT_SEARCH_EXTRA
+EXTERN linenr_T search_first_line INIT(= 0); // for :{FIRST},{last}s/pat
+EXTERN linenr_T search_last_line INIT(= MAXLNUM); // for :{first},{LAST}s/pat
+#endif
EXTERN int no_smartcase INIT(= FALSE); /* don't use 'smartcase' once */
@@ -514,7 +518,7 @@ EXTERN char *foreground_argument INIT(= NULL);
*
* volatile because it is used in signal handler sig_sysmouse().
*/
-EXTERN volatile int hold_gui_events INIT(= 0);
+EXTERN volatile sig_atomic_t hold_gui_events INIT(= 0);
/*
* When resizing the shell is postponed, remember the new size, and call
@@ -651,7 +655,7 @@ EXTERN int entered_free_all_mem INIT(= FALSE);
/* TRUE when in or after free_all_mem() */
#endif
/* volatile because it is used in signal handler deathtrap(). */
-EXTERN volatile int full_screen INIT(= FALSE);
+EXTERN volatile sig_atomic_t full_screen INIT(= FALSE);
/* TRUE when doing full-screen output
* otherwise only writing some messages */
@@ -674,8 +678,7 @@ EXTERN int allbuf_lock INIT(= 0);
* changed, no buffer can be deleted and
* current directory can't be changed.
* Used for SwapExists et al. */
-#ifdef FEAT_EVAL
-# define HAVE_SANDBOX
+#ifdef HAVE_SANDBOX
EXTERN int sandbox INIT(= 0);
/* Non-zero when evaluating an expression in a
* "sandbox". Several things are not allowed
@@ -797,11 +800,11 @@ EXTERN JMP_BUF x_jump_env;
EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */
# ifdef SIGHASARG
/* volatile because it is used in signal handlers. */
-EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal
+EXTERN volatile sig_atomic_t lc_signal; /* caught signal number, 0 when no was signal
caught; used for mch_libcall() */
# endif
/* volatile because it is used in signal handler deathtrap(). */
-EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
+EXTERN volatile sig_atomic_t lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
#endif
#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
@@ -1034,7 +1037,7 @@ EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */
/* volatile because it is used in signal handler catch_sigint(). */
-EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
+EXTERN volatile sig_atomic_t got_int INIT(= FALSE); /* set to TRUE when interrupt
signal occurred */
#ifdef USE_TERM_CONSOLE
EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
diff --git a/src/gui_beval.c b/src/gui_beval.c
index 49694cf..0321600 100644
--- a/src/gui_beval.c
+++ b/src/gui_beval.c
@@ -944,6 +944,8 @@ drawBalloon(BalloonEval *beval)
GtkRequisition requisition;
int screen_w;
int screen_h;
+ int screen_x;
+ int screen_y;
int x;
int y;
int x_offset = EVAL_OFFSET_X;
@@ -956,8 +958,8 @@ drawBalloon(BalloonEval *beval)
screen = gtk_widget_get_screen(beval->target);
gtk_window_set_screen(GTK_WINDOW(beval->balloonShell), screen);
# endif
- gui_gtk_get_screen_size_of_win(beval->balloonShell,
- &screen_w, &screen_h);
+ gui_gtk_get_screen_geom_of_win(beval->balloonShell,
+ &screen_x, &screen_y, &screen_w, &screen_h);
# if !GTK_CHECK_VERSION(3,0,0)
gtk_widget_ensure_style(beval->balloonShell);
gtk_widget_ensure_style(beval->balloonLabel);
@@ -998,14 +1000,16 @@ drawBalloon(BalloonEval *beval)
y += beval->y;
/* Get out of the way of the mouse pointer */
- if (x + x_offset + requisition.width > screen_w)
+ if (x + x_offset + requisition.width > screen_x + screen_w)
y_offset += 15;
- if (y + y_offset + requisition.height > screen_h)
+ if (y + y_offset + requisition.height > screen_y + screen_h)
y_offset = -requisition.height - EVAL_OFFSET_Y;
/* Sanitize values */
- x = CLAMP(x + x_offset, 0, MAX(0, screen_w - requisition.width));
- y = CLAMP(y + y_offset, 0, MAX(0, screen_h - requisition.height));
+ x = CLAMP(x + x_offset, 0,
+ MAX(0, screen_x + screen_w - requisition.width));
+ y = CLAMP(y + y_offset, 0,
+ MAX(0, screen_y + screen_h - requisition.height));
/* Show the balloon */
# if GTK_CHECK_VERSION(3,0,0)
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 9c7e8d5..196c9dc 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -788,6 +788,29 @@ property_event(GtkWidget *widget,
}
#endif /* defined(FEAT_CLIENTSERVER) */
+/*
+ * Handle changes to the "Xft/DPI" setting
+ */
+ static void
+gtk_settings_xft_dpi_changed_cb(GtkSettings *gtk_settings UNUSED,
+ GParamSpec *pspec UNUSED,
+ gpointer data UNUSED)
+{
+ // Create a new PangoContext for this screen, and initialize it
+ // with the current font if necessary.
+ if (gui.text_context != NULL)
+ g_object_unref(gui.text_context);
+
+ gui.text_context = gtk_widget_create_pango_context(gui.mainwin);
+ pango_context_set_base_dir(gui.text_context, PANGO_DIRECTION_LTR);
+
+ if (gui.norm_font != NULL)
+ {
+ // force default font
+ gui_mch_init_font(*p_guifont == NUL ? NULL : p_guifont, FALSE);
+ gui_set_shellsize(TRUE, FALSE, RESIZE_BOTH);
+ }
+}
#if GTK_CHECK_VERSION(3,0,0)
typedef gboolean timeout_cb_type;
@@ -4383,6 +4406,15 @@ gui_mch_init(void)
/* Pretend we don't have input focus, we will get an event if we do. */
gui.in_focus = FALSE;
+ // Handle changes to the "Xft/DPI" setting.
+ {
+ GtkSettings *gtk_settings =
+ gtk_settings_get_for_screen(gdk_screen_get_default());
+
+ g_signal_connect(gtk_settings, "notify::gtk-xft-dpi",
+ G_CALLBACK(gtk_settings_xft_dpi_changed_cb), NULL);
+ }
+
return OK;
}
@@ -4976,27 +5008,35 @@ gui_mch_set_shellsize(int width, int height,
}
void
-gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height)
+gui_gtk_get_screen_geom_of_win(
+ GtkWidget *wid,
+ int *screen_x,
+ int *screen_y,
+ int *width,
+ int *height)
{
+ GdkRectangle geometry;
+ GdkWindow *win = gtk_widget_get_window(wid);
#if GTK_CHECK_VERSION(3,22,0)
GdkDisplay *dpy = gtk_widget_get_display(wid);
- GdkWindow *win = gtk_widget_get_window(wid);
GdkMonitor *monitor = gdk_display_get_monitor_at_window(dpy, win);
- GdkRectangle geometry;
gdk_monitor_get_geometry(monitor, &geometry);
- *width = geometry.width;
- *height = geometry.height;
#else
GdkScreen* screen;
+ int monitor;
if (wid != NULL && gtk_widget_has_screen(wid))
screen = gtk_widget_get_screen(wid);
else
screen = gdk_screen_get_default();
- *width = gdk_screen_get_width(screen);
- *height = gdk_screen_get_height(screen);
+ monitor = gdk_screen_get_monitor_at_window(screen, win);
+ gdk_screen_get_monitor_geometry(screen, monitor, &geometry);
#endif
+ *screen_x = geometry.x;
+ *screen_y = geometry.y;
+ *width = geometry.width;
+ *height = geometry.height;
}
/*
@@ -5007,7 +5047,9 @@ gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height)
void
gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
{
- gui_gtk_get_screen_size_of_win(gui.mainwin, screen_w, screen_h);
+ int x, y;
+
+ gui_gtk_get_screen_geom_of_win(gui.mainwin, &x, &y, screen_w, screen_h);
/* Subtract 'guiheadroom' from the height to allow some room for the
* window manager (task list and window title bar). */
diff --git a/src/if_cscope.c b/src/if_cscope.c
index d621a14..186179c 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -550,7 +550,7 @@ staterr:
}
/* if filename is a directory, append the cscope database name to it */
- if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
+ if (S_ISDIR(statbuf.st_mode))
{
fname2 = (char *)alloc((unsigned)(strlen(CSCOPE_DBFILE) + strlen(fname) + 2));
if (fname2 == NULL)
@@ -581,12 +581,7 @@ staterr:
i = cs_insert_filelist(fname2, ppath, flags, &statbuf);
}
-#if defined(UNIX)
else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
-#else
- /* WIN32 - substitute define S_ISREG from os_unix.h */
- else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
-#endif
{
i = cs_insert_filelist(fname, ppath, flags, &statbuf);
}
diff --git a/src/if_lua.c b/src/if_lua.c
index 7602c80..6e33734 100644
--- a/src/if_lua.c
+++ b/src/if_lua.c
@@ -164,7 +164,11 @@ static luaV_Funcref *luaV_pushfuncref(lua_State *L, typval_T *tv);
#define lua_rawget dll_lua_rawget
#define lua_rawgeti dll_lua_rawgeti
#define lua_createtable dll_lua_createtable
-#define lua_newuserdata dll_lua_newuserdata
+#if LUA_VERSION_NUM >= 504
+ #define lua_newuserdatauv dll_lua_newuserdatauv
+#else
+ #define lua_newuserdata dll_lua_newuserdata
+#endif
#define lua_getmetatable dll_lua_getmetatable
#define lua_setfield dll_lua_setfield
#define lua_rawset dll_lua_rawset
@@ -261,7 +265,11 @@ int (*dll_lua_rawget) (lua_State *L, int idx);
int (*dll_lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
#endif
void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
+#if LUA_VERSION_NUM >= 504
+void *(*dll_lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue);
+#else
void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
+#endif
int (*dll_lua_getmetatable) (lua_State *L, int objindex);
void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
void (*dll_lua_rawset) (lua_State *L, int idx);
@@ -362,7 +370,11 @@ static const luaV_Reg luaV_dll[] = {
{"lua_rawget", (luaV_function) &dll_lua_rawget},
{"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
{"lua_createtable", (luaV_function) &dll_lua_createtable},
+#if LUA_VERSION_NUM >= 504
+ {"lua_newuserdatauv", (luaV_function) &dll_lua_newuserdatauv},
+#else
{"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
+#endif
{"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
{"lua_setfield", (luaV_function) &dll_lua_setfield},
{"lua_rawset", (luaV_function) &dll_lua_rawset},
diff --git a/src/if_perl.xs b/src/if_perl.xs
index bc15efa..9fd2196 100644
--- a/src/if_perl.xs
+++ b/src/if_perl.xs
@@ -831,8 +831,7 @@ newWINrv(SV *rv, win_T *ptr)
ptr->w_perl_private = newSV(0);
sv_setiv(ptr->w_perl_private, PTR2IV(ptr));
}
- else
- SvREFCNT_inc_void_NN(ptr->w_perl_private);
+ SvREFCNT_inc_void_NN(ptr->w_perl_private);
SvRV(rv) = ptr->w_perl_private;
SvROK_on(rv);
return sv_bless(rv, gv_stashpv("VIWIN", TRUE));
@@ -847,8 +846,7 @@ newBUFrv(SV *rv, buf_T *ptr)
ptr->b_perl_private = newSV(0);
sv_setiv(ptr->b_perl_private, PTR2IV(ptr));
}
- else
- SvREFCNT_inc_void_NN(ptr->b_perl_private);
+ SvREFCNT_inc_void_NN(ptr->b_perl_private);
SvRV(rv) = ptr->b_perl_private;
SvROK_on(rv);
return sv_bless(rv, gv_stashpv("VIBUF", TRUE));
@@ -918,12 +916,13 @@ I32 cur_val(IV iv, SV *sv)
else
rv = newBUFrv(newSV(0), curbuf);
- if (SvRV(sv) == SvRV(rv))
- SvREFCNT_dec(SvRV(rv));
- else // XXX: Not sure if the `else` condition are right
- // Test_SvREFCNT() pass in all case.
+ if (SvRV(sv) != SvRV(rv))
+ // XXX: This magic variable is a bit confusing...
+ // Is curently refcounted ?
sv_setsv(sv, rv);
+ SvREFCNT_dec(rv);
+
return 0;
}
#endif /* !PROTO */
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 459bc50..cdd7460 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -544,27 +544,57 @@ PythonIO_Init_io(void)
}
#if PY_VERSION_HEX < 0x030700f0
+static PyObject *call_load_module(char *name, int len, PyObject *find_module_result);
+
typedef struct
{
PyObject_HEAD
- PyObject *module;
+ char *fullname;
+ PyObject *result;
} LoaderObject;
static PyTypeObject LoaderType;
static void
LoaderDestructor(LoaderObject *self)
{
- Py_DECREF(self->module);
+ vim_free(self->fullname);
+ Py_XDECREF(self->result);
DESTRUCTOR_FINISH(self);
}
static PyObject *
LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
{
- PyObject *ret = self->module;
+ char *fullname = self->fullname;
+ PyObject *result = self->result;
+ PyObject *module;
- Py_INCREF(ret);
- return ret;
+ if (!fullname)
+ {
+ module = result ? result : Py_None;
+ Py_INCREF(module);
+ return module;
+ }
+
+ module = call_load_module(fullname, (int)STRLEN(fullname), result);
+
+ self->fullname = NULL;
+ self->result = module;
+
+ vim_free(fullname);
+ Py_DECREF(result);
+
+ if (!module)
+ {
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ Py_INCREF(module);
+ return module;
}
static struct PyMethodDef LoaderMethods[] = {
@@ -1252,7 +1282,11 @@ find_module(char *fullname, char *tail, PyObject *new_path)
if (!(find_module_result = PyObject_CallFunction(py_find_module,
"s#O", tail, partlen, new_path)))
+ {
+ if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
+ PyErr_Clear();
return NULL;
+ }
if (!(module = call_load_module(
fullname,
@@ -1273,30 +1307,23 @@ find_module(char *fullname, char *tail, PyObject *new_path)
Py_DECREF(module);
- module = find_module(fullname, dot + 1, newest_path);
+ find_module_result = find_module(fullname, dot + 1, newest_path);
Py_DECREF(newest_path);
- return module;
+ return find_module_result;
}
else
{
if (!(find_module_result = PyObject_CallFunction(py_find_module,
"sO", tail, new_path)))
- return NULL;
-
- if (!(module = call_load_module(
- fullname,
- (int)STRLEN(fullname),
- find_module_result)))
{
- Py_DECREF(find_module_result);
+ if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
+ PyErr_Clear();
return NULL;
}
- Py_DECREF(find_module_result);
-
- return module;
+ return find_module_result;
}
}
@@ -1304,7 +1331,7 @@ find_module(char *fullname, char *tail, PyObject *new_path)
FinderFindModule(PyObject *self, PyObject *args)
{
char *fullname;
- PyObject *module;
+ PyObject *result;
PyObject *new_path;
LoaderObject *loader;
@@ -1314,31 +1341,35 @@ FinderFindModule(PyObject *self, PyObject *args)
if (!(new_path = Vim_GetPaths(self)))
return NULL;
- module = find_module(fullname, fullname, new_path);
+ result = find_module(fullname, fullname, new_path);
Py_DECREF(new_path);
- if (!module)
+ if (!result)
{
if (PyErr_Occurred())
- {
- if (PyErr_ExceptionMatches(PyExc_ImportError))
- PyErr_Clear();
- else
- return NULL;
- }
+ return NULL;
Py_INCREF(Py_None);
return Py_None;
}
+ if (!(fullname = (char *)vim_strsave((char_u *)fullname)))
+ {
+ Py_DECREF(result);
+ PyErr_NoMemory();
+ return NULL;
+ }
+
if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
{
- Py_DECREF(module);
+ vim_free(fullname);
+ Py_DECREF(result);
return NULL;
}
- loader->module = module;
+ loader->fullname = fullname;
+ loader->result = result;
return (PyObject *) loader;
}
diff --git a/src/if_ruby.c b/src/if_ruby.c
index 2e1f8d7..fd6e552 100644
--- a/src/if_ruby.c
+++ b/src/if_ruby.c
@@ -93,6 +93,11 @@
# define RUBY20_OR_LATER 1
#endif
+#if (defined(RUBY_VERSION) && RUBY_VERSION >= 21) \
+ || (defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 21)
+# define RUBY21_OR_LATER 1
+#endif
+
#if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 19
/* Ruby 1.9 defines a number of static functions which use rb_num2long and
* rb_int2big */
@@ -238,11 +243,22 @@ static void ruby_vim_init(void);
# define rb_eRuntimeError (*dll_rb_eRuntimeError)
# define rb_eStandardError (*dll_rb_eStandardError)
# define rb_eval_string_protect dll_rb_eval_string_protect
+# ifdef RUBY21_OR_LATER
+# define rb_funcallv dll_rb_funcallv
+# else
+# define rb_funcall2 dll_rb_funcall2
+# endif
# define rb_global_variable dll_rb_global_variable
# define rb_hash_aset dll_rb_hash_aset
# define rb_hash_new dll_rb_hash_new
# define rb_inspect dll_rb_inspect
# define rb_int2inum dll_rb_int2inum
+
+// ruby.h may redefine rb_intern to use RUBY_CONST_ID_CACHE(), but that won't
+// work. Not using the cache appears to be the best solution.
+# undef rb_intern
+# define rb_intern dll_rb_intern
+
# if VIM_SIZEOF_INT < VIM_SIZEOF_LONG /* 64 bits only */
# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER <= 18
# define rb_fix2int dll_rb_fix2int
@@ -283,6 +299,11 @@ static void ruby_vim_init(void);
# define rb_string_value_ptr dll_rb_string_value_ptr
# define rb_float_new dll_rb_float_new
# define rb_ary_new dll_rb_ary_new
+# ifdef rb_ary_new4
+# define RB_ARY_NEW4_MACRO 1
+# undef rb_ary_new4
+# endif
+# define rb_ary_new4 dll_rb_ary_new4
# define rb_ary_push dll_rb_ary_push
# if defined(RUBY19_OR_LATER) || defined(RUBY_INIT_STACK)
# ifdef __ia64
@@ -367,11 +388,17 @@ static VALUE *dll_rb_eIndexError;
static VALUE *dll_rb_eRuntimeError;
static VALUE *dll_rb_eStandardError;
static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
+# ifdef RUBY21_OR_LATER
+static VALUE (*dll_rb_funcallv) (VALUE, ID, int, const VALUE*);
+# else
+static VALUE (*dll_rb_funcall2) (VALUE, ID, int, const VALUE*);
+# endif
static void (*dll_rb_global_variable) (VALUE*);
static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE);
static VALUE (*dll_rb_hash_new) (void);
static VALUE (*dll_rb_inspect) (VALUE);
static VALUE (*dll_rb_int2inum) (long);
+static ID (*dll_rb_intern) (const char*);
# if VIM_SIZEOF_INT < VIM_SIZEOF_LONG /* 64 bits only */
static long (*dll_rb_fix2int) (VALUE);
static long (*dll_rb_num2int) (VALUE);
@@ -419,6 +446,7 @@ static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
static char * (*dll_rb_string_value_ptr) (volatile VALUE*);
static VALUE (*dll_rb_float_new) (double);
static VALUE (*dll_rb_ary_new) (void);
+static VALUE (*dll_rb_ary_new4) (long n, const VALUE *elts);
static VALUE (*dll_rb_ary_push) (VALUE, VALUE);
# if defined(RUBY19_OR_LATER) || defined(RUBY_INIT_STACK)
# ifdef __ia64
@@ -561,11 +589,17 @@ static struct
{"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError},
{"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError},
{"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect},
+# ifdef RUBY21_OR_LATER
+ {"rb_funcallv", (RUBY_PROC*)&dll_rb_funcallv},
+# else
+ {"rb_funcall2", (RUBY_PROC*)&dll_rb_funcall2},
+# endif
{"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable},
{"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset},
{"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new},
{"rb_inspect", (RUBY_PROC*)&dll_rb_inspect},
{"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum},
+ {"rb_intern", (RUBY_PROC*)&dll_rb_intern},
# if VIM_SIZEOF_INT < VIM_SIZEOF_LONG /* 64 bits only */
{"rb_fix2int", (RUBY_PROC*)&dll_rb_fix2int},
{"rb_num2int", (RUBY_PROC*)&dll_rb_num2int},
@@ -619,6 +653,11 @@ static struct
{"rb_float_new_in_heap", (RUBY_PROC*)&dll_rb_float_new},
# endif
{"rb_ary_new", (RUBY_PROC*)&dll_rb_ary_new},
+# ifdef RB_ARY_NEW4_MACRO
+ {"rb_ary_new_from_values", (RUBY_PROC*)&dll_rb_ary_new4},
+# else
+ {"rb_ary_new4", (RUBY_PROC*)&dll_rb_ary_new4},
+# endif
{"rb_ary_push", (RUBY_PROC*)&dll_rb_ary_push},
# endif
# ifdef RUBY19_OR_LATER
@@ -926,9 +965,13 @@ static void error_print(int state)
RUBYEXTERN VALUE ruby_errinfo;
#endif
#endif
+ VALUE error;
VALUE eclass;
VALUE einfo;
+ VALUE bt;
+ int attr;
char buff[BUFSIZ];
+ long i;
#define TAG_RETURN 0x1
#define TAG_BREAK 0x2
@@ -960,12 +1003,12 @@ static void error_print(int state)
case TAG_RAISE:
case TAG_FATAL:
#ifdef RUBY19_OR_LATER
- eclass = CLASS_OF(rb_errinfo());
- einfo = rb_obj_as_string(rb_errinfo());
+ error = rb_errinfo();
#else
- eclass = CLASS_OF(ruby_errinfo);
- einfo = rb_obj_as_string(ruby_errinfo);
+ error = ruby_errinfo;
#endif
+ eclass = CLASS_OF(error);
+ einfo = rb_obj_as_string(error);
if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0)
{
EMSG(_("E272: unhandled exception"));
@@ -982,6 +1025,17 @@ static void error_print(int state)
if (p) *p = '\0';
EMSG(buff);
}
+
+ attr = syn_name2attr((char_u *)"Error");
+# ifdef RUBY21_OR_LATER
+ bt = rb_funcallv(error, rb_intern("backtrace"), 0, 0);
+ for (i = 0; i < RARRAY_LEN(bt); i++)
+ msg_attr((char_u *)RSTRING_PTR(RARRAY_AREF(bt, i)), attr);
+# else
+ bt = rb_funcall2(error, rb_intern("backtrace"), 0, 0);
+ for (i = 0; i < RARRAY_LEN(bt); i++)
+ msg_attr((char_u *)RSTRING_PTR(RARRAY_PTR(bt)[i]), attr);
+# endif
break;
default:
vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
@@ -1534,6 +1588,7 @@ static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
{
int i;
VALUE str = rb_str_new("", 0);
+ VALUE ret = Qnil;
for (i = 0; i < argc; i++)
{
@@ -1541,7 +1596,12 @@ static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED)
rb_str_concat(str, rb_inspect(argv[i]));
}
MSG(RSTRING_PTR(str));
- return Qnil;
+
+ if (argc == 1)
+ ret = argv[0];
+ else if (argc > 1)
+ ret = rb_ary_new4(argc, argv);
+ return ret;
}
static void ruby_io_init(void)
diff --git a/src/main.c b/src/main.c
index f677066..d3a509b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -706,6 +706,10 @@ vim_main2(void)
scroll_region_reset(); /* In case Rows changed */
scroll_start(); /* may scroll the screen to the right position */
+#if defined(FEAT_TITLE) && (defined(UNIX) || defined(VMS) || defined(MACOS_X))
+ term_push_title(SAVE_RESTORE_BOTH);
+#endif
+
/*
* Don't clear the screen when starting in Ex mode, unless using the GUI.
*/
diff --git a/src/mbyte.c b/src/mbyte.c
index 1f85246..ee1d572 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -4825,7 +4825,7 @@ call_imactivatefunc(int active)
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = active ? 1 : 0;
argv[1].v_type = VAR_UNKNOWN;
- (void)call_func_retnr(p_imaf, 1, argv, FALSE);
+ (void)call_func_retnr(p_imaf, 1, argv);
}
static int
@@ -4839,7 +4839,7 @@ call_imstatusfunc(void)
/* FIXME: :py print 'xxx' is shown duplicate result.
* Use silent to avoid it. */
++msg_silent;
- is_active = call_func_retnr(p_imsf, 0, NULL, FALSE);
+ is_active = call_func_retnr(p_imsf, 0, NULL);
--msg_silent;
return (is_active > 0);
}
@@ -4951,24 +4951,26 @@ im_add_to_input(char_u *str, int len)
static void
im_preedit_window_set_position(void)
{
- int x, y, w, h, sw, sh;
+ int x, y, width, height;
+ int screen_x, screen_y, screen_width, screen_height;
if (preedit_window == NULL)
return;
- gui_gtk_get_screen_size_of_win(preedit_window, &sw, &sh);
+ gui_gtk_get_screen_geom_of_win(gui.drawarea,
+ &screen_x, &screen_y, &screen_width, &screen_height);
#if GTK_CHECK_VERSION(3,0,0)
gdk_window_get_origin(gtk_widget_get_window(gui.drawarea), &x, &y);
#else
gdk_window_get_origin(gui.drawarea->window, &x, &y);
#endif
- gtk_window_get_size(GTK_WINDOW(preedit_window), &w, &h);
+ gtk_window_get_size(GTK_WINDOW(preedit_window), &width, &height);
x = x + FILL_X(gui.col);
y = y + FILL_Y(gui.row);
- if (x + w > sw)
- x = sw - w;
- if (y + h > sh)
- y = sh - h;
+ if (x + width > screen_x + screen_width)
+ x = screen_x + screen_width - width;
+ if (y + height > screen_y + screen_height)
+ y = screen_y + screen_height - height;
gtk_window_move(GTK_WINDOW(preedit_window), x, y);
}
diff --git a/src/memline.c b/src/memline.c
index be395fc..3d82af0 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -262,9 +262,6 @@ static int fnamecmp_ino(char_u *, char_u *, long);
#endif
static void long_to_char(long, char_u *);
static long char_to_long(char_u *);
-#if defined(UNIX) || defined(WIN3264)
-static char_u *make_percent_swname(char_u *dir, char_u *name);
-#endif
#ifdef FEAT_CRYPT
static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading);
#endif
@@ -831,10 +828,13 @@ ml_open_file(buf_T *buf)
*/
void
check_need_swap(
- int newfile) /* reading file into new buffer */
+ int newfile) // reading file into new buffer
{
+ int old_msg_silent = msg_silent; // might be reset by an E325 message
+
if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
ml_open_file(curbuf);
+ msg_silent = old_msg_silent;
}
/*
@@ -2007,18 +2007,18 @@ recover_names(
return file_count;
}
-#if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */
+#if defined(UNIX) || defined(WIN3264) || defined(PROTO)
/*
+ * Need _very_ long file names.
* Append the full path to name with path separators made into percent
* signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
*/
- static char_u *
+ char_u *
make_percent_swname(char_u *dir, char_u *name)
{
- char_u *d, *s, *f;
+ char_u *d = NULL, *s, *f;
- f = fix_fname(name != NULL ? name : (char_u *) "");
- d = NULL;
+ f = fix_fname(name != NULL ? name : (char_u *)"");
if (f != NULL)
{
s = alloc((unsigned)(STRLEN(f) + 1));
@@ -2041,6 +2041,53 @@ make_percent_swname(char_u *dir, char_u *name)
static int process_still_running;
#endif
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return information found in swapfile "fname" in dictionary "d".
+ * This is used by the swapinfo() function.
+ */
+ void
+get_b0_dict(char_u *fname, dict_T *d)
+{
+ int fd;
+ struct block0 b0;
+
+ if ((fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0)
+ {
+ if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
+ {
+ if (ml_check_b0_id(&b0) == FAIL)
+ dict_add_string(d, "error",
+ vim_strsave((char_u *)"Not a swap file"));
+ else if (b0_magic_wrong(&b0))
+ dict_add_string(d, "error",
+ vim_strsave((char_u *)"Magic number mismatch"));
+ else
+ {
+ /* we have swap information */
+ dict_add_string(d, "version", vim_strsave(b0.b0_version));
+ dict_add_string(d, "user", vim_strsave(b0.b0_uname));
+ dict_add_string(d, "host", vim_strsave(b0.b0_hname));
+ dict_add_string(d, "fname", vim_strsave(b0.b0_fname));
+
+ dict_add_number(d, "pid", char_to_long(b0.b0_pid));
+ dict_add_number(d, "mtime", char_to_long(b0.b0_mtime));
+ dict_add_number(d, "dirty", b0.b0_dirty ? 1 : 0);
+# ifdef CHECK_INODE
+ dict_add_number(d, "inode", char_to_long(b0.b0_ino));
+# endif
+ }
+ }
+ else
+ dict_add_string(d, "error",
+ vim_strsave((char_u *)"Cannot read file"));
+ close(fd);
+ }
+ else
+ dict_add_string(d, "error", vim_strsave((char_u *)"Cannot open file"));
+}
+#endif
+
/*
* Give information about an existing swap file.
* Returns timestamp (0 when unknown).
@@ -4070,8 +4117,6 @@ attention_message(
}
#if defined(FEAT_EVAL)
-static int do_swapexists(buf_T *buf, char_u *fname);
-
/*
* Trigger the SwapExists autocommands.
* Returns a value for equivalent to do_dialog() (see below):
@@ -5272,7 +5317,7 @@ ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
/* Don't count the last line break if 'noeol' and ('bin' or
* 'nofixeol'). */
if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
- && buf->b_ml.ml_line_count == lnum)
+ && lnum > buf->b_ml.ml_line_count)
size -= ffdos + 1;
}
diff --git a/src/misc1.c b/src/misc1.c
index 1647aa9..f2aa96b 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3802,24 +3802,12 @@ msgmore(long n)
if (pn > p_report)
{
- if (pn == 1)
- {
- if (n > 0)
- vim_strncpy(msg_buf, (char_u *)_("1 more line"),
- MSG_BUF_LEN - 1);
- else
- vim_strncpy(msg_buf, (char_u *)_("1 line less"),
- MSG_BUF_LEN - 1);
- }
+ if (n > 0)
+ vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
+ NGETTEXT("%ld more line", "%ld more lines", pn), pn);
else
- {
- if (n > 0)
- vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
- _("%ld more lines"), pn);
- else
- vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
- _("%ld fewer lines"), pn);
- }
+ vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
+ NGETTEXT("%ld line less", "%ld fewer lines", pn), pn);
if (got_int)
vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN);
if (msg(msg_buf))
diff --git a/src/normal.c b/src/normal.c
index f3cd664..41c7623 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -2248,7 +2248,7 @@ op_function(oparg_T *oap UNUSED)
virtual_op = MAYBE;
# endif
- (void)call_func_retnr(p_opfunc, 1, argv, FALSE);
+ (void)call_func_retnr(p_opfunc, 1, argv);
# ifdef FEAT_VIRTUALEDIT
virtual_op = save_virtual_op;
diff --git a/src/ops.c b/src/ops.c
index 50ebf44..3384556 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -244,7 +244,6 @@ op_shift(oparg_T *oap, int curs_top, int amount)
{
long i;
int first_char;
- char_u *s;
int block_col = 0;
if (u_save((linenr_T)(oap->start.lnum - 1),
@@ -297,26 +296,21 @@ op_shift(oparg_T *oap, int curs_top, int amount)
if (oap->line_count > p_report)
{
+ char *op;
+ char *msg_line_single;
+ char *msg_line_plural;
+
if (oap->op_type == OP_RSHIFT)
- s = (char_u *)">";
- else
- s = (char_u *)"<";
- if (oap->line_count == 1)
- {
- if (amount == 1)
- sprintf((char *)IObuff, _("1 line %sed 1 time"), s);
- else
- sprintf((char *)IObuff, _("1 line %sed %d times"), s, amount);
- }
+ op = ">";
else
- {
- if (amount == 1)
- sprintf((char *)IObuff, _("%ld lines %sed 1 time"),
- oap->line_count, s);
- else
- sprintf((char *)IObuff, _("%ld lines %sed %d times"),
- oap->line_count, s, amount);
- }
+ op = "<";
+ msg_line_single = NGETTEXT("%ld line %sed %d time",
+ "%ld line %sed %d times", amount);
+ msg_line_plural = NGETTEXT("%ld lines %sed %d time",
+ "%ld lines %sed %d times", amount);
+ vim_snprintf((char *)IObuff, IOSIZE,
+ NGETTEXT(msg_line_single, msg_line_plural, oap->line_count),
+ oap->line_count, op, amount);
msg(IObuff);
}
@@ -789,10 +783,8 @@ op_reindent(oparg_T *oap, int (*how)(void))
if (oap->line_count > p_report)
{
i = oap->line_count - (i + 1);
- if (i == 1)
- MSG(_("1 line indented "));
- else
- smsg((char_u *)_("%ld lines indented "), i);
+ smsg((char_u *)NGETTEXT("%ld line indented ",
+ "%ld lines indented ", i), i);
}
/* set '[ and '] marks */
curbuf->b_op_start = oap->start;
@@ -2529,12 +2521,8 @@ op_tilde(oparg_T *oap)
curbuf->b_op_end = oap->end;
if (oap->line_count > p_report)
- {
- if (oap->line_count == 1)
- MSG(_("1 line changed"));
- else
- smsg((char_u *)_("%ld lines changed"), oap->line_count);
- }
+ smsg((char_u *)NGETTEXT("%ld line changed", "%ld lines changed",
+ oap->line_count), oap->line_count);
}
/*
@@ -3348,19 +3336,18 @@ op_yank(oparg_T *oap, int deleting, int mess)
/* redisplay now, so message is not deleted */
update_topline_redraw();
- if (yanklines == 1)
+ if (oap->block_mode)
{
- if (oap->block_mode)
- smsg((char_u *)_("block of 1 line yanked%s"), namebuf);
- else
- smsg((char_u *)_("1 line yanked%s"), namebuf);
+ smsg((char_u *)NGETTEXT("block of %ld line yanked%s",
+ "block of %ld lines yanked%s", yanklines),
+ yanklines, namebuf);
}
- else if (oap->block_mode)
- smsg((char_u *)_("block of %ld lines yanked%s"),
- yanklines, namebuf);
else
- smsg((char_u *)_("%ld lines yanked%s"), yanklines,
- namebuf);
+ {
+ smsg((char_u *)NGETTEXT("%ld line yanked%s",
+ "%ld lines yanked%s", yanklines),
+ yanklines, namebuf);
+ }
}
}
@@ -5653,12 +5640,8 @@ op_addsub(
curbuf->b_op_start = startpos;
if (change_cnt > p_report)
- {
- if (change_cnt == 1)
- MSG(_("1 line changed"));
- else
- smsg((char_u *)_("%ld lines changed"), change_cnt);
- }
+ smsg((char_u *)NGETTEXT("%ld line changed", "%ld lines changed",
+ change_cnt), change_cnt);
}
}
diff --git a/src/option.c b/src/option.c
index f86b1b1..a7a6ebb 100644
--- a/src/option.c
+++ b/src/option.c
@@ -3192,7 +3192,9 @@ static struct vimoption options[] =
p_term("t_RB", T_RBG)
p_term("t_RC", T_CRC)
p_term("t_RI", T_CRI)
+ p_term("t_Ri", T_SRI)
p_term("t_RS", T_CRS)
+ p_term("t_RT", T_CRT)
p_term("t_RV", T_CRV)
p_term("t_Sb", T_CSB)
p_term("t_SC", T_CSC)
@@ -3200,9 +3202,11 @@ static struct vimoption options[] =
p_term("t_Sf", T_CSF)
p_term("t_SH", T_CSH)
p_term("t_SI", T_CSI)
+ p_term("t_Si", T_SSI)
p_term("t_so", T_SO)
p_term("t_SR", T_CSR)
p_term("t_sr", T_SR)
+ p_term("t_ST", T_CST)
p_term("t_Te", T_STE)
p_term("t_te", T_TE)
p_term("t_ti", T_TI)
@@ -10414,7 +10418,7 @@ clear_termoptions(void)
mch_setmouse(FALSE); /* switch mouse off */
#endif
#ifdef FEAT_TITLE
- mch_restore_title(3); /* restore window titles */
+ mch_restore_title(SAVE_RESTORE_BOTH); /* restore window titles */
#endif
#if defined(FEAT_XCLIPBOARD) && defined(FEAT_GUI)
/* When starting the GUI close the display opened for the clipboard.
@@ -11219,8 +11223,8 @@ buf_copy_options(buf_T *buf, int flags)
buf->b_p_isk = NULL;
}
/*
- * Always free the allocated strings.
- * If not already initialized, set 'readonly' and copy 'fileformat'.
+ * Always free the allocated strings. If not already initialized,
+ * reset 'readonly' and copy 'fileformat'.
*/
if (!buf->b_p_initialized)
{
diff --git a/src/os_amiga.c b/src/os_amiga.c
index 39fb222..767cbfa 100644
--- a/src/os_amiga.c
+++ b/src/os_amiga.c
@@ -617,14 +617,14 @@ mch_settitle(char_u *title, char_u *icon)
/*
* Restore the window/icon title.
* which is one of:
- * 1 Just restore title
- * 2 Just restore icon (which we don't have)
- * 3 Restore title and icon (which we don't have)
+ * SAVE_RESTORE_TITLE Just restore title
+ * SAVE_RESTORE_ICON Just restore icon (which we don't have)
+ * SAVE_RESTORE_BOTH Restore title and icon (which we don't have)
*/
void
mch_restore_title(int which)
{
- if (which & 1)
+ if (which & SAVE_RESTORE_TITLE)
mch_settitle(oldwindowtitle, NULL);
}
@@ -907,7 +907,7 @@ mch_exit(int r)
}
#ifdef FEAT_TITLE
- mch_restore_title(3); /* restore window title */
+ mch_restore_title(SAVE_RESTORE_BOTH); /* restore window title */
#endif
ml_close_all(TRUE); /* remove all memfiles */
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 5dbfd0e..2112b0c 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -304,9 +304,9 @@ mch_settitle(
/*
* Restore the window/icon title.
* which is one of:
- * 1: Just restore title
- * 2: Just restore icon (which we don't have)
- * 3: Restore title and icon (which we don't have)
+ * SAVE_RESTORE_TITLE: Just restore title
+ * SAVE_RESTORE_ICON: Just restore icon (which we don't have)
+ * SAVE_RESTORE_BOTH: Restore title and icon (which we don't have)
*/
void
mch_restore_title(int which UNUSED)
diff --git a/src/os_unix.c b/src/os_unix.c
index 3649276..080f03c 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -161,6 +161,7 @@ static int get_x11_title(int);
static int get_x11_icon(int);
static char_u *oldtitle = NULL;
+static volatile sig_atomic_t oldtitle_outdated = FALSE;
static int did_set_title = FALSE;
static char_u *oldicon = NULL;
static int did_set_icon = FALSE;
@@ -204,7 +205,7 @@ static RETSIGTYPE catch_sigpwr SIGPROTOARG;
# define SET_SIG_ALARM
static RETSIGTYPE sig_alarm SIGPROTOARG;
/* volatile because it is used in signal handler sig_alarm(). */
-static volatile int sig_alarm_called;
+static volatile sig_atomic_t sig_alarm_called;
#endif
static RETSIGTYPE deathtrap SIGPROTOARG;
@@ -230,13 +231,13 @@ static int save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***fil
#endif
/* volatile because it is used in signal handler sig_winch(). */
-static volatile int do_resize = FALSE;
+static volatile sig_atomic_t do_resize = FALSE;
static char_u *extra_shell_arg = NULL;
static int show_shell_mess = TRUE;
/* volatile because it is used in signal handler deathtrap(). */
-static volatile int deadly_signal = 0; /* The signal we caught */
+static volatile sig_atomic_t deadly_signal = 0; /* The signal we caught */
/* volatile because it is used in signal handler deathtrap(). */
-static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */
+static volatile sig_atomic_t in_mch_delay = FALSE; /* sleeping in mch_delay() */
#if defined(FEAT_JOB_CHANNEL) && !defined(USE_SYSTEM)
static int dont_check_job_ended = 0;
@@ -1227,18 +1228,39 @@ deathtrap SIGDEFARG(sigarg)
SIGRETURN;
}
-#if defined(_REENTRANT) && defined(SIGCONT)
/*
- * On Solaris with multi-threading, suspending might not work immediately.
- * Catch the SIGCONT signal, which will be used as an indication whether the
- * suspending has been done or not.
+ * Invoked after receiving SIGCONT. We don't know what happened while
+ * sleeping, deal with part of that.
+ */
+ static void
+after_sigcont(void)
+{
+# ifdef FEAT_TITLE
+ // Don't change "oldtitle" in a signal handler, set a flag to obtain it
+ // again later.
+ oldtitle_outdated = TRUE;
+# endif
+ settmode(TMODE_RAW);
+ need_check_timestamps = TRUE;
+ did_check_timestamps = FALSE;
+}
+
+#if defined(SIGCONT)
+static RETSIGTYPE sigcont_handler SIGPROTOARG;
+static volatile sig_atomic_t in_mch_suspend = FALSE;
+
+/*
+ * With multi-threading, suspending might not work immediately. Catch the
+ * SIGCONT signal, which will be used as an indication whether the suspending
+ * has been done or not.
*
* On Linux, signal is not always handled immediately either.
* See https://bugs.launchpad.net/bugs/291373
+ * Probably because the signal is handled in another thread.
*
* volatile because it is used in signal handler sigcont_handler().
*/
-static volatile int sigcont_received;
+static volatile sig_atomic_t sigcont_received;
static RETSIGTYPE sigcont_handler SIGPROTOARG;
/*
@@ -1247,7 +1269,22 @@ static RETSIGTYPE sigcont_handler SIGPROTOARG;
static RETSIGTYPE
sigcont_handler SIGDEFARG(sigarg)
{
- sigcont_received = TRUE;
+ if (in_mch_suspend)
+ {
+ sigcont_received = TRUE;
+ }
+ else
+ {
+ // We didn't suspend ourselves, assume we were stopped by a SIGSTOP
+ // signal (which can't be intercepted) and get a SIGCONT. Need to get
+ // back to a sane mode. We should redraw, but we can't really do that
+ // in a signal handler, do a redraw later.
+ after_sigcont();
+ redraw_later(CLEAR);
+ cursor_on_force();
+ out_flush();
+ }
+
SIGRETURN;
}
#endif
@@ -1330,6 +1367,8 @@ mch_suspend(void)
{
/* BeOS does have SIGTSTP, but it doesn't work. */
#if defined(SIGTSTP) && !defined(__BEOS__)
+ in_mch_suspend = TRUE;
+
out_flush(); /* needed to make cursor visible on some systems */
settmode(TMODE_COOK);
out_flush(); /* needed to disable mouse on some systems */
@@ -1337,40 +1376,32 @@ mch_suspend(void)
# if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
loose_clipboard();
# endif
-
-# if defined(_REENTRANT) && defined(SIGCONT)
+# if defined(SIGCONT)
sigcont_received = FALSE;
# endif
+
kill(0, SIGTSTP); /* send ourselves a STOP signal */
-# if defined(_REENTRANT) && defined(SIGCONT)
+
+# if defined(SIGCONT)
/*
* Wait for the SIGCONT signal to be handled. It generally happens
- * immediately, but somehow not all the time. Do not call pause()
- * because there would be race condition which would hang Vim if
- * signal happened in between the test of sigcont_received and the
- * call to pause(). If signal is not yet received, call sleep(0)
- * to just yield CPU. Signal should then be received. If somehow
- * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
- * further if signal is not received after 1+2+3+4 ms (not expected
- * to happen).
+ * immediately, but somehow not all the time, probably because it's handled
+ * in another thread. Do not call pause() because there would be race
+ * condition which would hang Vim if signal happened in between the test of
+ * sigcont_received and the call to pause(). If signal is not yet received,
+ * sleep 0, 1, 2, 3 ms. Don't bother waiting further if signal is not
+ * received after 1+2+3 ms (not expected to happen).
*/
{
long wait_time;
+
for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
- /* Loop is not entered most of the time */
mch_delay(wait_time, FALSE);
}
# endif
+ in_mch_suspend = FALSE;
-# ifdef FEAT_TITLE
- /*
- * Set oldtitle to NULL, so the current title is obtained again.
- */
- VIM_CLEAR(oldtitle);
-# endif
- settmode(TMODE_RAW);
- need_check_timestamps = TRUE;
- did_check_timestamps = FALSE;
+ after_sigcont();
#else
suspend_shell();
#endif
@@ -1410,7 +1441,7 @@ set_signals(void)
#ifdef SIGTSTP
signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
#endif
-#if defined(_REENTRANT) && defined(SIGCONT)
+#if defined(SIGCONT)
signal(SIGCONT, sigcont_handler);
#endif
@@ -1469,7 +1500,7 @@ catch_int_signal(void)
reset_signals(void)
{
catch_signals(SIG_DFL, SIG_DFL);
-#if defined(_REENTRANT) && defined(SIGCONT)
+#if defined(SIGCONT)
/* SIGCONT isn't in the list, because its default action is ignore */
signal(SIGCONT, SIG_DFL);
#endif
@@ -1532,7 +1563,7 @@ block_signals(sigset_t *set)
for (i = 0; signal_info[i].sig != -1; i++)
sigaddset(&newset, signal_info[i].sig);
-# if defined(_REENTRANT) && defined(SIGCONT)
+# if defined(SIGCONT)
/* SIGCONT isn't in the list, because its default action is ignore */
sigaddset(&newset, SIGCONT);
# endif
@@ -2239,6 +2270,11 @@ mch_settitle(char_u *title, char_u *icon)
*/
if ((type || *T_TS != NUL) && title != NULL)
{
+ if (oldtitle_outdated)
+ {
+ oldtitle_outdated = FALSE;
+ VIM_CLEAR(oldtitle);
+ }
if (oldtitle == NULL
#ifdef FEAT_GUI
&& !gui.in_use
@@ -2294,17 +2330,21 @@ mch_settitle(char_u *title, char_u *icon)
/*
* Restore the window/icon title.
* "which" is one of:
- * 1 only restore title
- * 2 only restore icon
- * 3 restore title and icon
+ * SAVE_RESTORE_TITLE only restore title
+ * SAVE_RESTORE_ICON only restore icon
+ * SAVE_RESTORE_BOTH restore title and icon
*/
void
mch_restore_title(int which)
{
/* only restore the title or icon when it has been set */
- mch_settitle(((which & 1) && did_set_title) ?
+ mch_settitle(((which & SAVE_RESTORE_TITLE) && did_set_title) ?
(oldtitle ? oldtitle : p_titleold) : NULL,
- ((which & 2) && did_set_icon) ? oldicon : NULL);
+ ((which & SAVE_RESTORE_ICON) && did_set_icon) ? oldicon : NULL);
+
+ // pop and push from/to the stack
+ term_pop_title(which);
+ term_push_title(which);
}
#endif /* FEAT_TITLE */
@@ -3092,11 +3132,7 @@ mch_isdir(char_u *name)
return FALSE;
if (stat((char *)name, &statb))
return FALSE;
-#ifdef _POSIX_SOURCE
return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
-#else
- return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
-#endif
}
/*
@@ -3113,11 +3149,7 @@ mch_isrealdir(char_u *name)
return FALSE;
if (mch_lstat((char *)name, &statb))
return FALSE;
-#ifdef _POSIX_SOURCE
return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
-#else
- return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
-#endif
}
static int executable_file(char_u *name);
@@ -3370,7 +3402,9 @@ mch_exit(int r)
{
settmode(TMODE_COOK);
#ifdef FEAT_TITLE
- mch_restore_title(3); /* restore xterm title and icon name */
+ // restore xterm title and icon name
+ mch_restore_title(SAVE_RESTORE_BOTH);
+ term_pop_title(SAVE_RESTORE_BOTH);
#endif
/*
* When t_ti is not empty but it doesn't cause swapping terminal
diff --git a/src/os_unix.h b/src/os_unix.h
index 4146529..ca2ce70 100644
--- a/src/os_unix.h
+++ b/src/os_unix.h
@@ -458,25 +458,6 @@ int mch_rename(const char *src, const char *dest);
# endif
#endif
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-#if !defined(S_ISREG) && defined(S_IFREG)
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-#if !defined(S_ISBLK) && defined(S_IFBLK)
-# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#endif
-#if !defined(S_ISSOCK) && defined(S_IFSOCK)
-# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-#endif
-#if !defined(S_ISFIFO) && defined(S_IFIFO)
-# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#endif
-#if !defined(S_ISCHR) && defined(S_IFCHR)
-# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#endif
-
/* Note: Some systems need both string.h and strings.h (Savage). However,
* some systems can't handle both, only use string.h in that case. */
#ifdef HAVE_STRING_H
diff --git a/src/os_win32.c b/src/os_win32.c
index f8884e4..dc98d6a 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -2695,7 +2695,7 @@ mch_exit(int r)
if (g_fWindInitCalled)
{
#ifdef FEAT_TITLE
- mch_restore_title(3);
+ mch_restore_title(SAVE_RESTORE_BOTH);
/*
* Restore both the small and big icons of the console window to
* what they were at startup. Don't do this when the window is
@@ -3108,6 +3108,9 @@ mch_dirname(
char_u *buf,
int len)
{
+ char_u abuf[_MAX_PATH + 1];
+ DWORD lfnlen;
+
/*
* Originally this was:
* return (getcwd(buf, len) != NULL ? OK : FAIL);
@@ -3121,7 +3124,21 @@ mch_dirname(
if (GetCurrentDirectoryW(_MAX_PATH, wbuf) != 0)
{
- char_u *p = utf16_to_enc(wbuf, NULL);
+ WCHAR wcbuf[_MAX_PATH + 1];
+ char_u *p = NULL;
+
+ if (GetLongPathNameW(wbuf, wcbuf, _MAX_PATH) != 0)
+ {
+ p = utf16_to_enc(wcbuf, NULL);
+ if (STRLEN(p) >= (size_t)len)
+ {
+ // long path name is too long, fall back to short one
+ vim_free(p);
+ p = NULL;
+ }
+ }
+ if (p == NULL)
+ p = utf16_to_enc(wbuf, NULL);
if (p != NULL)
{
@@ -3133,7 +3150,16 @@ mch_dirname(
return FAIL;
}
#endif
- return (GetCurrentDirectory(len, (LPSTR)buf) != 0 ? OK : FAIL);
+ if (GetCurrentDirectory(len, (LPSTR)buf) == 0)
+ return FAIL;
+ lfnlen = GetLongPathNameA((LPCSTR)buf, (LPSTR)abuf, _MAX_PATH);
+ if (lfnlen == 0 || lfnlen >= (DWORD)len)
+ // Failed to get long path name or it's too long: fall back to the
+ // short path name.
+ return OK;
+
+ STRCPY(buf, abuf);
+ return OK;
}
/*
@@ -3967,6 +3993,48 @@ mch_get_shellsize(void)
}
/*
+ * Resize console buffer to 'COORD'
+ */
+ static void
+ResizeConBuf(
+ HANDLE hConsole,
+ COORD coordScreen)
+{
+ if (!SetConsoleScreenBufferSize(hConsole, coordScreen))
+ {
+#ifdef MCH_WRITE_DUMP
+ if (fdDump)
+ {
+ fprintf(fdDump, "SetConsoleScreenBufferSize failed: %lx\n",
+ GetLastError());
+ fflush(fdDump);
+ }
+#endif
+ }
+}
+
+/*
+ * Resize console window size to 'srWindowRect'
+ */
+ static void
+ResizeWindow(
+ HANDLE hConsole,
+ SMALL_RECT srWindowRect)
+{
+ if (!SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect))
+ {
+#ifdef MCH_WRITE_DUMP
+ if (fdDump)
+ {
+ fprintf(fdDump, "SetConsoleWindowInfo failed: %lx\n",
+ GetLastError());
+ fflush(fdDump);
+ }
+#endif
+ }
+}
+
+/*
* Set a console window to `xSize' * `ySize'
*/
static void
@@ -4019,32 +4087,20 @@ ResizeConBufAndWindow(
}
}
- if (!SetConsoleWindowInfo(g_hConOut, TRUE, &srWindowRect))
- {
-#ifdef MCH_WRITE_DUMP
- if (fdDump)
- {
- fprintf(fdDump, "SetConsoleWindowInfo failed: %lx\n",
- GetLastError());
- fflush(fdDump);
- }
-#endif
- }
-
- /* define the new console buffer size */
+ // define the new console buffer size
coordScreen.X = xSize;
coordScreen.Y = ySize;
- if (!SetConsoleScreenBufferSize(hConsole, coordScreen))
+ // In the new console call API in reverse order
+ if (!vtp_working)
{
-#ifdef MCH_WRITE_DUMP
- if (fdDump)
- {
- fprintf(fdDump, "SetConsoleScreenBufferSize failed: %lx\n",
- GetLastError());
- fflush(fdDump);
- }
-#endif
+ ResizeWindow(hConsole, srWindowRect);
+ ResizeConBuf(hConsole, coordScreen);
+ }
+ else
+ {
+ ResizeConBuf(hConsole, coordScreen);
+ ResizeWindow(hConsole, srWindowRect);
}
}
diff --git a/src/os_win32.h b/src/os_win32.h
index 5017f53..4b1fc39 100644
--- a/src/os_win32.h
+++ b/src/os_win32.h
@@ -89,6 +89,7 @@
#define FNAME_ILLEGAL "\"*?><|" /* illegal characters in a file name */
+#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
diff --git a/src/osdef1.h.in b/src/osdef1.h.in
index 5519104..825fe94 100644
--- a/src/osdef1.h.in
+++ b/src/osdef1.h.in
@@ -65,8 +65,10 @@ extern void memmove(char *, char *, int);
# endif
# endif
#endif
-/* used inside of FD_ZERO macro: */
+#ifndef __BIONIC__ // Android's libc #defines bzero to memset.
+// used inside of FD_ZERO macro
extern void bzero(void *, size_t);
+#endif
#ifdef HAVE_SETSID
extern pid_t setsid(void);
#endif
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
index 9e63fb6..6820d97 100644
--- a/src/proto/buffer.pro
+++ b/src/proto/buffer.pro
@@ -56,6 +56,7 @@ void ex_buffer_all(exarg_T *eap);
void do_modelines(int flags);
int read_viminfo_bufferlist(vir_T *virp, int writing);
void write_viminfo_bufferlist(FILE *fp);
+int bt_normal(buf_T *buf);
int bt_quickfix(buf_T *buf);
int bt_terminal(buf_T *buf);
int bt_help(buf_T *buf);
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 98f6656..537b649 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -19,10 +19,10 @@ varnumber_T eval_to_number(char_u *expr);
list_T *eval_spell_expr(char_u *badword, char_u *expr);
int get_spellword(list_T *list, char_u **pp);
typval_T *eval_expr(char_u *arg, char_u **nextcmd);
-int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv, int safe);
-varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv, int safe);
-void *call_func_retstr(char_u *func, int argc, typval_T *argv, int safe);
-void *call_func_retlist(char_u *func, int argc, typval_T *argv, int safe);
+int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
+varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv);
+void *call_func_retstr(char_u *func, int argc, typval_T *argv);
+void *call_func_retlist(char_u *func, int argc, typval_T *argv);
int eval_foldexpr(char_u *arg, int *cp);
void ex_let(exarg_T *eap);
void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index ada1a9a..04bc0c3 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -4,6 +4,8 @@ int do_cmdline_cmd(char_u *cmd);
int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int), void *cookie, int flags);
int getline_equal(char_u *(*fgetline)(int, void *, int), void *cookie, char_u *(*func)(int, void *, int));
void *getline_cookie(char_u *(*fgetline)(int, void *, int), void *cookie);
+int parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only);
+int parse_cmd_address(exarg_T *eap, char_u **errormsg);
int checkforcmd(char_u **pp, char *cmd, int len);
int modifier_len(char_u *cmd);
int cmd_exists(char_u *name);
@@ -68,6 +70,7 @@ char_u *get_behave_arg(expand_T *xp, int idx);
char_u *get_messages_arg(expand_T *xp, int idx);
char_u *get_mapclear_arg(expand_T *xp, int idx);
void set_no_hlsearch(int flag);
+int is_loclist_cmd(int cmdidx);
int get_pressedreturn(void);
void set_pressedreturn(int val);
/* vim: set ft=c : */
diff --git a/src/proto/gui_gtk_x11.pro b/src/proto/gui_gtk_x11.pro
index aea8d0b..111cac7 100644
--- a/src/proto/gui_gtk_x11.pro
+++ b/src/proto/gui_gtk_x11.pro
@@ -25,7 +25,7 @@ int gui_mch_maximized(void);
void gui_mch_unmaximize(void);
void gui_mch_newfont(void);
void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction);
-void gui_gtk_get_screen_size_of_win(GtkWidget *wid, int *width, int *height);
+void gui_gtk_get_screen_geom_of_win(GtkWidget *wid, int *screen_x, int *screen_y, int *width, int *height);
void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h);
void gui_mch_settitle(char_u *title, char_u *icon);
void gui_mch_enable_menu(int showit);
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
index bddb902..d18ede3 100644
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -11,6 +11,8 @@ void ml_close_notmod(void);
void ml_timestamp(buf_T *buf);
void ml_recover(void);
int recover_names(char_u *fname, int list, int nr, char_u **fname_out);
+char_u *make_percent_swname(char_u *dir, char_u *name);
+void get_b0_dict(char_u *fname, dict_T *d);
void ml_sync_all(int check_file, int check_char);
void ml_preserve(buf_T *buf, int message);
char_u *ml_get(linenr_T lnum);
diff --git a/src/proto/term.pro b/src/proto/term.pro
index 7eafdef..1b8ab5f 100644
--- a/src/proto/term.pro
+++ b/src/proto/term.pro
@@ -31,6 +31,8 @@ void term_bg_color(int n);
void term_fg_rgb_color(guicolor_T rgb);
void term_bg_rgb_color(guicolor_T rgb);
void term_settitle(char_u *title);
+void term_push_title(int which);
+void term_pop_title(int which);
void ttest(int pairs);
void add_long_to_buf(long_u val, char_u *dst);
void check_shellsize(void);
@@ -50,6 +52,7 @@ void setmouse(void);
int mouse_has(int c);
int mouse_model_popup(void);
void scroll_start(void);
+void cursor_on_force(void);
void cursor_on(void);
void cursor_off(void);
void term_cursor_mode(int forced);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 7ed8042..c31e599 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -94,4 +94,5 @@ void win_id2tabwin(typval_T *argvars, list_T *list);
win_T *win_id2wp(typval_T *argvars);
int win_id2win(typval_T *argvars);
void win_findbuf(typval_T *argvars, list_T *list);
+void get_framelayout(frame_T *fr, list_T *l, int topframe);
/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index aac1e34..6248c21 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -159,6 +159,11 @@ static qf_info_T *ll_get_or_alloc_list(win_T *);
#define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL)
/* Location list window check helper macro */
#define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+
+// Quickfix and location list stack check helper macros
+#define IS_QF_STACK(qi) (qi == &ql_info)
+#define IS_LL_STACK(qi) (qi != &ql_info)
+
/*
* Return location list for window 'wp'
* For location list window, return the referenced location list
@@ -201,106 +206,109 @@ static struct fmtpattern
/*
* Convert an errorformat pattern to a regular expression pattern.
- * See fmt_pat definition above for the list of supported patterns.
+ * See fmt_pat definition above for the list of supported patterns. The
+ * pattern specifier is supplied in "efmpat". The converted pattern is stored
+ * in "regpat". Returns a pointer to the location after the pattern.
*/
static char_u *
-fmtpat_to_regpat(
- char_u *efmp,
- efm_T *fmt_ptr,
+efmpat_to_regpat(
+ char_u *efmpat,
+ char_u *regpat,
+ efm_T *efminfo,
int idx,
int round,
- char_u *ptr,
char_u *errmsg)
{
char_u *srcptr;
- if (fmt_ptr->addr[idx])
+ if (efminfo->addr[idx])
{
/* Each errorformat pattern can occur only once */
sprintf((char *)errmsg,
- _("E372: Too many %%%c in format string"), *efmp);
+ _("E372: Too many %%%c in format string"), *efmpat);
EMSG(errmsg);
return NULL;
}
if ((idx && idx < 6
- && vim_strchr((char_u *)"DXOPQ", fmt_ptr->prefix) != NULL)
+ && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
|| (idx == 6
- && vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL))
+ && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
{
sprintf((char *)errmsg,
- _("E373: Unexpected %%%c in format string"), *efmp);
+ _("E373: Unexpected %%%c in format string"), *efmpat);
EMSG(errmsg);
return NULL;
}
- fmt_ptr->addr[idx] = (char_u)++round;
- *ptr++ = '\\';
- *ptr++ = '(';
+ efminfo->addr[idx] = (char_u)++round;
+ *regpat++ = '\\';
+ *regpat++ = '(';
#ifdef BACKSLASH_IN_FILENAME
- if (*efmp == 'f')
+ if (*efmpat == 'f')
{
/* Also match "c:" in the file name, even when
* checking for a colon next: "%f:".
* "\%(\a:\)\=" */
- STRCPY(ptr, "\\%(\\a:\\)\\=");
- ptr += 10;
+ STRCPY(regpat, "\\%(\\a:\\)\\=");
+ regpat += 10;
}
#endif
- if (*efmp == 'f' && efmp[1] != NUL)
+ if (*efmpat == 'f' && efmpat[1] != NUL)
{
- if (efmp[1] != '\\' && efmp[1] != '%')
+ if (efmpat[1] != '\\' && efmpat[1] != '%')
{
/* A file name may contain spaces, but this isn't
* in "\f". For "%f:%l:%m" there may be a ":" in
* the file name. Use ".\{-1,}x" instead (x is
* the next character), the requirement that :999:
* follows should work. */
- STRCPY(ptr, ".\\{-1,}");
- ptr += 7;
+ STRCPY(regpat, ".\\{-1,}");
+ regpat += 7;
}
else
{
/* File name followed by '\\' or '%': include as
* many file name chars as possible. */
- STRCPY(ptr, "\\f\\+");
- ptr += 4;
+ STRCPY(regpat, "\\f\\+");
+ regpat += 4;
}
}
else
{
srcptr = (char_u *)fmt_pat[idx].pattern;
- while ((*ptr = *srcptr++) != NUL)
- ++ptr;
+ while ((*regpat = *srcptr++) != NUL)
+ ++regpat;
}
- *ptr++ = '\\';
- *ptr++ = ')';
+ *regpat++ = '\\';
+ *regpat++ = ')';
- return ptr;
+ return regpat;
}
/*
* Convert a scanf like format in 'errorformat' to a regular expression.
+ * Returns a pointer to the location after the pattern.
*/
static char_u *
scanf_fmt_to_regpat(
+ char_u **pefmp,
char_u *efm,
int len,
- char_u **pefmp,
- char_u *ptr,
+ char_u *regpat,
char_u *errmsg)
{
char_u *efmp = *pefmp;
- if (*++efmp == '[' || *efmp == '\\')
+ if (*efmp == '[' || *efmp == '\\')
{
- if ((*ptr++ = *efmp) == '[') /* %*[^a-z0-9] etc. */
+ if ((*regpat++ = *efmp) == '[') /* %*[^a-z0-9] etc. */
{
if (efmp[1] == '^')
- *ptr++ = *++efmp;
+ *regpat++ = *++efmp;
if (efmp < efm + len)
{
- *ptr++ = *++efmp; /* could be ']' */
+ *regpat++ = *++efmp; /* could be ']' */
while (efmp < efm + len
- && (*ptr++ = *++efmp) != ']')
+ && (*regpat++ = *++efmp) != ']')
/* skip */;
if (efmp == efm + len)
{
@@ -310,9 +318,9 @@ scanf_fmt_to_regpat(
}
}
else if (efmp < efm + len) /* %*\D, %*\s etc. */
- *ptr++ = *++efmp;
- *ptr++ = '\\';
- *ptr++ = '+';
+ *regpat++ = *++efmp;
+ *regpat++ = '\\';
+ *regpat++ = '+';
}
else
{
@@ -325,36 +333,35 @@ scanf_fmt_to_regpat(
*pefmp = efmp;
- return ptr;
+ return regpat;
}
/*
* Analyze/parse an errorformat prefix.
*/
- static int
-efm_analyze_prefix(char_u **pefmp, efm_T *fmt_ptr, char_u *errmsg)
+ static char_u *
+efm_analyze_prefix(char_u *efmp, efm_T *efminfo, char_u *errmsg)
{
- char_u *efmp = *pefmp;
-
if (vim_strchr((char_u *)"+-", *efmp) != NULL)
- fmt_ptr->flags = *efmp++;
+ efminfo->flags = *efmp++;
if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
- fmt_ptr->prefix = *efmp;
+ efminfo->prefix = *efmp;
else
{
sprintf((char *)errmsg,
_("E376: Invalid %%%c in format string prefix"), *efmp);
EMSG(errmsg);
- return FAIL;
+ return NULL;
}
- *pefmp = efmp;
-
- return OK;
+ return efmp;
}
/*
- * Converts a 'errorformat' string to regular expression pattern
+ * Converts a 'errorformat' string part in 'efm' to a regular expression
+ * pattern. The resulting regex pattern is returned in "regpat". Additional
+ * information about the 'erroformat' pattern is returned in "fmt_ptr".
+ * Returns OK or FAIL.
*/
static int
efm_to_regpat(
@@ -370,7 +377,7 @@ efm_to_regpat(
int idx = 0;
/*
- * Build regexp pattern from current 'errorformat' option
+ * Build a regexp pattern for a 'errorformat' option part
*/
ptr = regpat;
*ptr++ = '^';
@@ -385,17 +392,18 @@ efm_to_regpat(
break;
if (idx < FMT_PATTERNS)
{
- ptr = fmtpat_to_regpat(efmp, fmt_ptr, idx, round, ptr,
+ ptr = efmpat_to_regpat(efmp, ptr, fmt_ptr, idx, round,
errmsg);
if (ptr == NULL)
- return -1;
+ return FAIL;
round++;
}
else if (*efmp == '*')
{
- ptr = scanf_fmt_to_regpat(efm, len, &efmp, ptr, errmsg);
+ ++efmp;
+ ptr = scanf_fmt_to_regpat(&efmp, efm, len, ptr, errmsg);
if (ptr == NULL)
- return -1;
+ return FAIL;
}
else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
*ptr++ = *efmp; /* regexp magic characters */
@@ -405,15 +413,20 @@ efm_to_regpat(
fmt_ptr->conthere = TRUE;
else if (efmp == efm + 1) /* analyse prefix */
{
- if (efm_analyze_prefix(&efmp, fmt_ptr, errmsg) == FAIL)
- return -1;
+ /*
+ * prefix is allowed only at the beginning of the errorformat
+ * option part
+ */
+ efmp = efm_analyze_prefix(efmp, fmt_ptr, errmsg);
+ if (efmp == NULL)
+ return FAIL;
}
else
{
sprintf((char *)errmsg,
_("E377: Invalid %%%c in format string"), *efmp);
EMSG(errmsg);
- return -1;
+ return FAIL;
}
}
else /* copy normal character */
@@ -429,9 +442,12 @@ efm_to_regpat(
*ptr++ = '$';
*ptr = NUL;
- return 0;
+ return OK;
}
+/*
+ * Free the 'errorformat' information list
+ */
static void
free_efm_list(efm_T **efm_first)
{
@@ -446,7 +462,48 @@ free_efm_list(efm_T **efm_first)
fmt_start = NULL;
}
-/* Parse 'errorformat' option */
+/*
+ * Compute the size of the buffer used to convert a 'errorformat' pattern into
+ * a regular expression pattern.
+ */
+ static int
+efm_regpat_bufsz(char_u *efm)
+{
+ int sz;
+ int i;
+
+ sz = (FMT_PATTERNS * 3) + ((int)STRLEN(efm) << 2);
+ for (i = FMT_PATTERNS; i > 0; )
+ sz += (int)STRLEN(fmt_pat[--i].pattern);
+#ifdef BACKSLASH_IN_FILENAME
+ sz += 12; /* "%f" can become twelve chars longer (see efm_to_regpat) */
+#else
+ sz += 2; /* "%f" can become two chars longer */
+#endif
+
+ return sz;
+}
+
+/*
+ * Return the length of a 'errorformat' option part (separated by ",").
+ */
+ static int
+efm_option_part_len(char_u *efm)
+{
+ int len;
+
+ for (len = 0; efm[len] != NUL && efm[len] != ','; ++len)
+ if (efm[len] == '\\' && efm[len + 1] != NUL)
+ ++len;
+
+ return len;
+}
+
+/*
+ * Parse the 'errorformat' option. Multiple parts in the 'errorformat' option
+ * are parsed and converted to regular expressions. Returns information about
+ * the parsed 'errorformat' option.
+ */
static efm_T *
parse_efm_option(char_u *efm)
{
@@ -457,8 +514,7 @@ parse_efm_option(char_u *efm)
efm_T *fmt_last = NULL;
char_u *fmtstr = NULL;
int len;
- int i;
- int round;
+ int sz;
errmsglen = CMDBUFFSIZE + 1;
errmsg = alloc_id(errmsglen, aid_qf_errmsg);
@@ -473,15 +529,8 @@ parse_efm_option(char_u *efm)
/*
* Get some space to modify the format string into.
*/
- i = (FMT_PATTERNS * 3) + ((int)STRLEN(efm) << 2);
- for (round = FMT_PATTERNS; round > 0; )
- i += (int)STRLEN(fmt_pat[--round].pattern);
-#ifdef BACKSLASH_IN_FILENAME
- i += 12; /* "%f" can become twelve chars longer (see efm_to_regpat) */
-#else
- i += 2; /* "%f" can become two chars longer */
-#endif
- if ((fmtstr = alloc(i)) == NULL)
+ sz = efm_regpat_bufsz(efm);
+ if ((fmtstr = alloc(sz)) == NULL)
goto parse_efm_error;
while (efm[0] != NUL)
@@ -501,11 +550,9 @@ parse_efm_option(char_u *efm)
/*
* Isolate one part in the 'errorformat' option
*/
- for (len = 0; efm[len] != NUL && efm[len] != ','; ++len)
- if (efm[len] == '\\' && efm[len + 1] != NUL)
- ++len;
+ len = efm_option_part_len(efm);
- if (efm_to_regpat(efm, len, fmt_ptr, fmtstr, errmsg) == -1)
+ if (efm_to_regpat(efm, len, fmt_ptr, fmtstr, errmsg) == FAIL)
goto parse_efm_error;
if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL)
goto parse_efm_error;
@@ -539,6 +586,10 @@ enum {
QF_MULTISCAN = 5,
};
+/*
+ * State information used to parse lines and add entries to a quickfix/location
+ * list.
+ */
typedef struct {
char_u *linebuf;
int linelen;
@@ -554,6 +605,9 @@ typedef struct {
vimconv_T vc;
} qfstate_T;
+/*
+ * Allocate more memory for the line buffer used for parsing lines.
+ */
static char_u *
qf_grow_linebuf(qfstate_T *state, int newsz)
{
@@ -861,10 +915,251 @@ typedef struct {
} qffields_T;
/*
- * Parse the error format matches in 'regmatch' and set the values in 'fields'.
- * fmt_ptr contains the 'efm' format specifiers/prefixes that have a match.
- * Returns QF_OK if all the matches are successfully parsed. On failure,
- * returns QF_FAIL or QF_NOMEM.
+ * Parse the match for filename ('%f') pattern in regmatch.
+ * Return the matched value in "fields->namebuf".
+ */
+ static int
+qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix)
+{
+ int c;
+
+ if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL)
+ return QF_FAIL;
+
+ /* Expand ~/file and $HOME/file to full path. */
+ c = *rmp->endp[midx];
+ *rmp->endp[midx] = NUL;
+ expand_env(rmp->startp[midx], fields->namebuf, CMDBUFFSIZE);
+ *rmp->endp[midx] = c;
+
+ /*
+ * For separate filename patterns (%O, %P and %Q), the specified file
+ * should exist.
+ */
+ if (vim_strchr((char_u *)"OPQ", prefix) != NULL
+ && mch_getperm(fields->namebuf) == -1)
+ return QF_FAIL;
+
+ return QF_OK;
+}
+
+/*
+ * Parse the match for error number ('%n') pattern in regmatch.
+ * Return the matched value in "fields->enr".
+ */
+ static int
+qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ fields->enr = (int)atol((char *)rmp->startp[midx]);
+ return QF_OK;
+}
+
+/*
+ * Parse the match for line number (%l') pattern in regmatch.
+ * Return the matched value in "fields->lnum".
+ */
+ static int
+qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ fields->lnum = atol((char *)rmp->startp[midx]);
+ return QF_OK;
+}
+
+/*
+ * Parse the match for column number ('%c') pattern in regmatch.
+ * Return the matched value in "fields->col".
+ */
+ static int
+qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ fields->col = (int)atol((char *)rmp->startp[midx]);
+ return QF_OK;
+}
+
+/*
+ * Parse the match for error type ('%t') pattern in regmatch.
+ * Return the matched value in "fields->type".
+ */
+ static int
+qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ fields->type = *rmp->startp[midx];
+ return QF_OK;
+}
+
+/*
+ * Parse the match for '%+' format pattern. The whole matching line is included
+ * in the error string. Return the matched line in "fields->errmsg".
+ */
+ static int
+qf_parse_fmt_plus(char_u *linebuf, int linelen, qffields_T *fields)
+{
+ char_u *p;
+
+ if (linelen >= fields->errmsglen)
+ {
+ /* linelen + null terminator */
+ if ((p = vim_realloc(fields->errmsg, linelen + 1)) == NULL)
+ return QF_NOMEM;
+ fields->errmsg = p;
+ fields->errmsglen = linelen + 1;
+ }
+ vim_strncpy(fields->errmsg, linebuf, linelen);
+ return QF_OK;
+}
+
+/*
+ * Parse the match for error message ('%m') pattern in regmatch.
+ * Return the matched value in "fields->errmsg".
+ */
+ static int
+qf_parse_fmt_m(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ char_u *p;
+ int len;
+
+ if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL)
+ return QF_FAIL;
+ len = (int)(rmp->endp[midx] - rmp->startp[midx]);
+ if (len >= fields->errmsglen)
+ {
+ /* len + null terminator */
+ if ((p = vim_realloc(fields->errmsg, len + 1)) == NULL)
+ return QF_NOMEM;
+ fields->errmsg = p;
+ fields->errmsglen = len + 1;
+ }
+ vim_strncpy(fields->errmsg, rmp->startp[midx], len);
+ return QF_OK;
+}
+
+/*
+ * Parse the match for rest of a single-line file message ('%r') pattern.
+ * Return the matched value in "tail".
+ */
+ static int
+qf_parse_fmt_r(regmatch_T *rmp, int midx, char_u **tail)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ *tail = rmp->startp[midx];
+ return QF_OK;
+}
+
+/*
+ * Parse the match for the pointer line ('%p') pattern in regmatch.
+ * Return the matched value in "fields->col".
+ */
+ static int
+qf_parse_fmt_p(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ char_u *match_ptr;
+
+ if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL)
+ return QF_FAIL;
+ fields->col = 0;
+ for (match_ptr = rmp->startp[midx]; match_ptr != rmp->endp[midx];
+ ++match_ptr)
+ {
+ ++fields->col;
+ if (*match_ptr == TAB)
+ {
+ fields->col += 7;
+ fields->col -= fields->col % 8;
+ }
+ }
+ ++fields->col;
+ fields->use_viscol = TRUE;
+ return QF_OK;
+}
+
+/*
+ * Parse the match for the virtual column number ('%v') pattern in regmatch.
+ * Return the matched value in "fields->col".
+ */
+ static int
+qf_parse_fmt_v(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ fields->col = (int)atol((char *)rmp->startp[midx]);
+ fields->use_viscol = TRUE;
+ return QF_OK;
+}
+
+/*
+ * Parse the match for the search text ('%s') pattern in regmatch.
+ * Return the matched value in "fields->pattern".
+ */
+ static int
+qf_parse_fmt_s(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ int len;
+
+ if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL)
+ return QF_FAIL;
+ len = (int)(rmp->endp[midx] - rmp->startp[midx]);
+ if (len > CMDBUFFSIZE - 5)
+ len = CMDBUFFSIZE - 5;
+ STRCPY(fields->pattern, "^\\V");
+ STRNCAT(fields->pattern, rmp->startp[midx], len);
+ fields->pattern[len + 3] = '\\';
+ fields->pattern[len + 4] = '$';
+ fields->pattern[len + 5] = NUL;
+ return QF_OK;
+}
+
+/*
+ * Parse the match for the module ('%o') pattern in regmatch.
+ * Return the matched value in "fields->module".
+ */
+ static int
+qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ int len;
+
+ if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL)
+ return QF_FAIL;
+ len = (int)(rmp->endp[midx] - rmp->startp[midx]);
+ if (len > CMDBUFFSIZE)
+ len = CMDBUFFSIZE;
+ STRNCAT(fields->module, rmp->startp[midx], len);
+ return QF_OK;
+}
+
+/*
+ * 'errorformat' format pattern parser functions.
+ * The '%f' and '%r' formats are parsed differently from other formats.
+ * See qf_parse_match() for details.
+ */
+static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
+{
+ NULL,
+ qf_parse_fmt_n,
+ qf_parse_fmt_l,
+ qf_parse_fmt_c,
+ qf_parse_fmt_t,
+ qf_parse_fmt_m,
+ NULL,
+ qf_parse_fmt_p,
+ qf_parse_fmt_v,
+ qf_parse_fmt_s,
+ qf_parse_fmt_o
+};
+
+/*
+ * Parse the error format pattern matches in "regmatch" and set the values in
+ * "fields". fmt_ptr contains the 'efm' format specifiers/prefixes that have a
+ * match. Returns QF_OK if all the matches are successfully parsed. On
+ * failure, returns QF_FAIL or QF_NOMEM.
*/
static int
qf_parse_match(
@@ -877,10 +1172,10 @@ qf_parse_match(
int qf_multiscan,
char_u **tail)
{
- char_u *p;
int idx = fmt_ptr->prefix;
int i;
- int len;
+ int midx;
+ int status;
if ((idx == 'C' || idx == 'Z') && !qf_multiline)
return QF_FAIL;
@@ -893,128 +1188,26 @@ qf_parse_match(
* We check for an actual submatch, because "\[" and "\]" in
* the 'errorformat' may cause the wrong submatch to be used.
*/
- if ((i = (int)fmt_ptr->addr[0]) > 0) /* %f */
+ for (i = 0; i < FMT_PATTERNS; i++)
{
- int c;
-
- if (regmatch->startp[i] == NULL || regmatch->endp[i] == NULL)
- return QF_FAIL;
-
- /* Expand ~/file and $HOME/file to full path. */
- c = *regmatch->endp[i];
- *regmatch->endp[i] = NUL;
- expand_env(regmatch->startp[i], fields->namebuf, CMDBUFFSIZE);
- *regmatch->endp[i] = c;
-
- if (vim_strchr((char_u *)"OPQ", idx) != NULL
- && mch_getperm(fields->namebuf) == -1)
- return QF_FAIL;
- }
- if ((i = (int)fmt_ptr->addr[1]) > 0) /* %n */
- {
- if (regmatch->startp[i] == NULL)
- return QF_FAIL;
- fields->enr = (int)atol((char *)regmatch->startp[i]);
- }
- if ((i = (int)fmt_ptr->addr[2]) > 0) /* %l */
- {
- if (regmatch->startp[i] == NULL)
- return QF_FAIL;
- fields->lnum = atol((char *)regmatch->startp[i]);
- }
- if ((i = (int)fmt_ptr->addr[3]) > 0) /* %c */
- {
- if (regmatch->startp[i] == NULL)
- return QF_FAIL;
- fields->col = (int)atol((char *)regmatch->startp[i]);
- }
- if ((i = (int)fmt_ptr->addr[4]) > 0) /* %t */
- {
- if (regmatch->startp[i] == NULL)
- return QF_FAIL;
- fields->type = *regmatch->startp[i];
- }
- if (fmt_ptr->flags == '+' && !qf_multiscan) /* %+ */
- {
- if (linelen >= fields->errmsglen)
+ status = QF_OK;
+ midx = (int)fmt_ptr->addr[i];
+ if (i == 0 && midx > 0) /* %f */
+ status = qf_parse_fmt_f(regmatch, midx, fields, idx);
+ else if (i == 5)
{
- /* linelen + null terminator */
- if ((p = vim_realloc(fields->errmsg, linelen + 1)) == NULL)
- return QF_NOMEM;
- fields->errmsg = p;
- fields->errmsglen = linelen + 1;
+ if (fmt_ptr->flags == '+' && !qf_multiscan) /* %+ */
+ status = qf_parse_fmt_plus(linebuf, linelen, fields);
+ else if (midx > 0) /* %m */
+ status = qf_parse_fmt_m(regmatch, midx, fields);
}
- vim_strncpy(fields->errmsg, linebuf, linelen);
- }
- else if ((i = (int)fmt_ptr->addr[5]) > 0) /* %m */
- {
- if (regmatch->startp[i] == NULL || regmatch->endp[i] == NULL)
- return QF_FAIL;
- len = (int)(regmatch->endp[i] - regmatch->startp[i]);
- if (len >= fields->errmsglen)
- {
- /* len + null terminator */
- if ((p = vim_realloc(fields->errmsg, len + 1)) == NULL)
- return QF_NOMEM;
- fields->errmsg = p;
- fields->errmsglen = len + 1;
- }
- vim_strncpy(fields->errmsg, regmatch->startp[i], len);
- }
- if ((i = (int)fmt_ptr->addr[6]) > 0) /* %r */
- {
- if (regmatch->startp[i] == NULL)
- return QF_FAIL;
- *tail = regmatch->startp[i];
- }
- if ((i = (int)fmt_ptr->addr[7]) > 0) /* %p */
- {
- char_u *match_ptr;
+ else if (i == 6 && midx > 0) /* %r */
+ status = qf_parse_fmt_r(regmatch, midx, tail);
+ else if (midx > 0) /* others */
+ status = (qf_parse_fmt[i])(regmatch, midx, fields);
- if (regmatch->startp[i] == NULL || regmatch->endp[i] == NULL)
- return QF_FAIL;
- fields->col = 0;
- for (match_ptr = regmatch->startp[i];
- match_ptr != regmatch->endp[i]; ++match_ptr)
- {
- ++fields->col;
- if (*match_ptr == TAB)
- {
- fields->col += 7;
- fields->col -= fields->col % 8;
- }
- }
- ++fields->col;
- fields->use_viscol = TRUE;
- }
- if ((i = (int)fmt_ptr->addr[8]) > 0) /* %v */
- {
- if (regmatch->startp[i] == NULL)
- return QF_FAIL;
- fields->col = (int)atol((char *)regmatch->startp[i]);
- fields->use_viscol = TRUE;
- }
- if ((i = (int)fmt_ptr->addr[9]) > 0) /* %s */
- {
- if (regmatch->startp[i] == NULL || regmatch->endp[i] == NULL)
- return QF_FAIL;
- len = (int)(regmatch->endp[i] - regmatch->startp[i]);
- if (len > CMDBUFFSIZE - 5)
- len = CMDBUFFSIZE - 5;
- STRCPY(fields->pattern, "^\\V");
- STRNCAT(fields->pattern, regmatch->startp[i], len);
- fields->pattern[len + 3] = '\\';
- fields->pattern[len + 4] = '$';
- fields->pattern[len + 5] = NUL;
- }
- if ((i = (int)fmt_ptr->addr[10]) > 0) /* %o */
- {
- if (regmatch->startp[i] == NULL || regmatch->endp[i] == NULL)
- return QF_FAIL;
- len = (int)(regmatch->endp[i] - regmatch->startp[i]);
- if (len > CMDBUFFSIZE)
- len = CMDBUFFSIZE;
- STRNCAT(fields->module, regmatch->startp[i], len);
+ if (status != QF_OK)
+ return status;
}
return QF_OK;
@@ -1308,6 +1501,17 @@ restofline:
}
/*
+ * Returns TRUE if the specified quickfix/location list is empty.
+ */
+ static int
+qf_list_empty(qf_info_T *qi, int qf_idx)
+{
+ if (qi == NULL || qf_idx < 0 || qf_idx >= LISTCOUNT)
+ return TRUE;
+ return qi->qf_lists[qf_idx].qf_count <= 0;
+}
+
+/*
* Allocate the fields used for parsing lines and populating a quickfix list.
*/
static int
@@ -1450,7 +1654,7 @@ qf_init_ext(
{
/* Adding to existing list, use last entry. */
adding = TRUE;
- if (qi->qf_lists[qf_idx].qf_count > 0)
+ if (!qf_list_empty(qi, qf_idx))
old_last = qi->qf_lists[qf_idx].qf_last;
}
@@ -1741,7 +1945,7 @@ qf_add_entry(
qfp->qf_fnum = bufnum;
if (buf != NULL)
buf->b_has_qf_entry |=
- (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
+ IS_QF_STACK(qi) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
}
else
qfp->qf_fnum = qf_get_fnum(qi, qf_idx, dir, fname);
@@ -1777,8 +1981,7 @@ qf_add_entry(
qfp->qf_valid = valid;
lastp = &qi->qf_lists[qf_idx].qf_last;
- if (qi->qf_lists[qf_idx].qf_count == 0)
- /* first element in the list */
+ if (qf_list_empty(qi, qf_idx)) /* first element in the list */
{
qi->qf_lists[qf_idx].qf_start = qfp;
qi->qf_lists[qf_idx].qf_ptr = qfp;
@@ -1813,13 +2016,9 @@ ll_new_list(void)
{
qf_info_T *qi;
- qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
+ qi = (qf_info_T *)alloc_clear((unsigned)sizeof(qf_info_T));
if (qi != NULL)
- {
- vim_memset(qi, 0, (size_t)(sizeof(qf_info_T)));
qi->qf_refcount++;
- }
-
return qi;
}
@@ -1875,7 +2074,7 @@ copy_loclist(win_T *from, win_T *to)
to->w_llist->qf_listcount = qi->qf_listcount;
/* Copy the location lists one at a time */
- for (idx = 0; idx < qi->qf_listcount; idx++)
+ for (idx = 0; idx < qi->qf_listcount; ++idx)
{
qf_list_T *from_qfl;
qf_list_T *to_qfl;
@@ -2030,7 +2229,7 @@ qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *directory, char_u *fname)
return 0;
buf->b_has_qf_entry =
- (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
+ IS_QF_STACK(qi) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
return buf->b_fnum;
}
@@ -2437,7 +2636,7 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80)
flags |= WSP_TOP;
- if (qi != &ql_info)
+ if (IS_LL_STACK(qi))
flags |= WSP_NEWLOC; /* don't copy the location list */
if (win_split(0, flags) == FAIL)
@@ -2448,7 +2647,7 @@ jump_to_help_window(qf_info_T *qi, int *opened_window)
if (curwin->w_height < p_hh)
win_setheight((int)p_hh);
- if (qi != &ql_info) /* not a quickfix list */
+ if (IS_LL_STACK(qi)) // not a quickfix list
{
/* The new window should use the supplied location list */
curwin->w_llist = qi;
@@ -2487,7 +2686,7 @@ qf_find_win_with_normal_buf(void)
win_T *wp;
FOR_ALL_WINDOWS(wp)
- if (wp->w_buffer->b_p_bt[0] == NUL)
+ if (bt_normal(wp->w_buffer))
return wp;
return NULL;
@@ -2563,7 +2762,7 @@ qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref)
win = curwin;
do
{
- if (win->w_buffer->b_p_bt[0] == NUL)
+ if (bt_normal(win->w_buffer))
break;
if (win->w_prev == NULL)
win = lastwin; /* wrap around the top */
@@ -2620,8 +2819,7 @@ qf_goto_win_with_qfl_file(int qf_fnum)
}
/* Remember a usable window. */
- if (altwin == NULL && !win->w_p_pvw
- && win->w_buffer->b_p_bt[0] == NUL)
+ if (altwin == NULL && !win->w_p_pvw && bt_normal(win->w_buffer))
altwin = win;
}
@@ -2725,7 +2923,7 @@ qf_jump_edit_buffer(
retval = buflist_getfile(qf_ptr->qf_fnum,
(linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
- if (qi != &ql_info)
+ if (IS_LL_STACK(qi))
{
/*
* Location list. Check whether the associated window is still
@@ -2746,7 +2944,7 @@ qf_jump_edit_buffer(
else if (old_qf_curlist != qi->qf_curlist
|| !is_qf_entry_present(qi, qf_ptr))
{
- if (qi == &ql_info)
+ if (IS_QF_STACK(qi))
EMSG(_("E925: Current quickfix was changed"));
else
EMSG(_(e_loc_list_changed));
@@ -2817,6 +3015,7 @@ qf_jump_goto_line(
++screen_col;
}
}
+ curwin->w_set_curswant = TRUE;
check_cursor();
}
else
@@ -2908,7 +3107,7 @@ qf_jump(qf_info_T *qi,
qi = &ql_info;
if (qi->qf_curlist >= qi->qf_listcount
- || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+ || qf_list_empty(qi, qi->qf_curlist))
{
EMSG(_(e_quickfix));
return;
@@ -3034,29 +3233,110 @@ theend:
}
/*
+ * Highlight attributes used for displaying entries from the quickfix list.
+ */
+static int qfFileAttr;
+static int qfSepAttr;
+static int qfLineAttr;
+
+/*
+ * Display information about a single entry from the quickfix/location list.
+ * Used by ":clist/:llist" commands.
+ */
+ static void
+qf_list_entry(qf_info_T *qi, qfline_T *qfp, int qf_idx)
+{
+ char_u *fname;
+ buf_T *buf;
+ int filter_entry;
+
+ fname = NULL;
+ if (qfp->qf_module != NULL && *qfp->qf_module != NUL)
+ vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx,
+ (char *)qfp->qf_module);
+ else {
+ if (qfp->qf_fnum != 0
+ && (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
+ {
+ fname = buf->b_fname;
+ if (qfp->qf_type == 1) /* :helpgrep */
+ fname = gettail(fname);
+ }
+ if (fname == NULL)
+ sprintf((char *)IObuff, "%2d", qf_idx);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
+ qf_idx, (char *)fname);
+ }
+
+ // Support for filtering entries using :filter /pat/ clist
+ // Match against the module name, file name, search pattern and
+ // text of the entry.
+ filter_entry = TRUE;
+ if (qfp->qf_module != NULL && *qfp->qf_module != NUL)
+ filter_entry &= message_filtered(qfp->qf_module);
+ if (filter_entry && fname != NULL)
+ filter_entry &= message_filtered(fname);
+ if (filter_entry && qfp->qf_pattern != NULL)
+ filter_entry &= message_filtered(qfp->qf_pattern);
+ if (filter_entry)
+ filter_entry &= message_filtered(qfp->qf_text);
+ if (filter_entry)
+ return;
+
+ msg_putchar('\n');
+ msg_outtrans_attr(IObuff, qf_idx == qi->qf_lists[qi->qf_curlist].qf_index
+ ? HL_ATTR(HLF_QFL) : qfFileAttr);
+
+ if (qfp->qf_lnum != 0)
+ msg_puts_attr((char_u *)":", qfSepAttr);
+ if (qfp->qf_lnum == 0)
+ IObuff[0] = NUL;
+ else if (qfp->qf_col == 0)
+ sprintf((char *)IObuff, "%ld", qfp->qf_lnum);
+ else
+ sprintf((char *)IObuff, "%ld col %d",
+ qfp->qf_lnum, qfp->qf_col);
+ sprintf((char *)IObuff + STRLEN(IObuff), "%s",
+ (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+ msg_puts_attr(IObuff, qfLineAttr);
+ msg_puts_attr((char_u *)":", qfSepAttr);
+ if (qfp->qf_pattern != NULL)
+ {
+ qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
+ msg_puts(IObuff);
+ msg_puts_attr((char_u *)":", qfSepAttr);
+ }
+ msg_puts((char_u *)" ");
+
+ /* Remove newlines and leading whitespace from the text. For an
+ * unrecognized line keep the indent, the compiler may mark a word
+ * with ^^^^. */
+ qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
+ ? skipwhite(qfp->qf_text) : qfp->qf_text,
+ IObuff, IOSIZE);
+ msg_prt_line(IObuff, FALSE);
+ out_flush(); /* show one line at a time */
+}
+
+/*
* ":clist": list all errors
* ":llist": list all locations
*/
void
qf_list(exarg_T *eap)
{
- buf_T *buf;
- char_u *fname;
qfline_T *qfp;
int i;
int idx1 = 1;
int idx2 = -1;
char_u *arg = eap->arg;
int plus = FALSE;
- int qfFileAttr;
- int qfSepAttr;
- int qfLineAttr;
- int filter_entry;
int all = eap->forceit; /* if not :cl!, only show
recognised errors */
qf_info_T *qi = &ql_info;
- if (eap->cmdidx == CMD_llist)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3067,7 +3347,7 @@ qf_list(exarg_T *eap)
}
if (qi->qf_curlist >= qi->qf_listcount
- || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+ || qf_list_empty(qi, qi->qf_curlist))
{
EMSG(_(e_quickfix));
return;
@@ -3124,75 +3404,9 @@ qf_list(exarg_T *eap)
if (got_int)
break;
- fname = NULL;
- if (qfp->qf_module != NULL && *qfp->qf_module != NUL)
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", i, (char *)qfp->qf_module);
- else {
- if (qfp->qf_fnum != 0
- && (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
- {
- fname = buf->b_fname;
- if (qfp->qf_type == 1) /* :helpgrep */
- fname = gettail(fname);
- }
- if (fname == NULL)
- sprintf((char *)IObuff, "%2d", i);
- else
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
- i, (char *)fname);
- }
-
- // Support for filtering entries using :filter /pat/ clist
- // Match against the module name, file name, search pattern and
- // text of the entry.
- filter_entry = TRUE;
- if (qfp->qf_module != NULL && *qfp->qf_module != NUL)
- filter_entry &= message_filtered(qfp->qf_module);
- if (filter_entry && fname != NULL)
- filter_entry &= message_filtered(fname);
- if (filter_entry && qfp->qf_pattern != NULL)
- filter_entry &= message_filtered(qfp->qf_pattern);
- if (filter_entry)
- filter_entry &= message_filtered(qfp->qf_text);
- if (filter_entry)
- goto next_entry;
-
- msg_putchar('\n');
- msg_outtrans_attr(IObuff, i == qi->qf_lists[qi->qf_curlist].qf_index
- ? HL_ATTR(HLF_QFL) : qfFileAttr);
-
- if (qfp->qf_lnum != 0)
- msg_puts_attr((char_u *)":", qfSepAttr);
- if (qfp->qf_lnum == 0)
- IObuff[0] = NUL;
- else if (qfp->qf_col == 0)
- sprintf((char *)IObuff, "%ld", qfp->qf_lnum);
- else
- sprintf((char *)IObuff, "%ld col %d",
- qfp->qf_lnum, qfp->qf_col);
- sprintf((char *)IObuff + STRLEN(IObuff), "%s",
- (char *)qf_types(qfp->qf_type, qfp->qf_nr));
- msg_puts_attr(IObuff, qfLineAttr);
- msg_puts_attr((char_u *)":", qfSepAttr);
- if (qfp->qf_pattern != NULL)
- {
- qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
- msg_puts(IObuff);
- msg_puts_attr((char_u *)":", qfSepAttr);
- }
- msg_puts((char_u *)" ");
-
- /* Remove newlines and leading whitespace from the text. For an
- * unrecognized line keep the indent, the compiler may mark a word
- * with ^^^^. */
- qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
- ? skipwhite(qfp->qf_text) : qfp->qf_text,
- IObuff, IOSIZE);
- msg_prt_line(IObuff, FALSE);
- out_flush(); /* show one line at a time */
+ qf_list_entry(qi, qfp, i);
}
-next_entry:
qfp = qfp->qf_next;
if (qfp == NULL)
break;
@@ -3270,7 +3484,7 @@ qf_age(exarg_T *eap)
qf_info_T *qi = &ql_info;
int count;
- if (eap->cmdidx == CMD_lolder || eap->cmdidx == CMD_lnewer)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3318,10 +3532,10 @@ qf_history(exarg_T *eap)
qf_info_T *qi = &ql_info;
int i;
- if (eap->cmdidx == CMD_lhistory)
+ if (is_loclist_cmd(eap->cmdidx))
qi = GET_LOC_LIST(curwin);
if (qi == NULL || (qi->qf_listcount == 0
- && qi->qf_lists[qi->qf_curlist].qf_count == 0))
+ && qf_list_empty(qi, qi->qf_curlist)))
MSG(_("No entries"));
else
for (i = 0; i < qi->qf_listcount; ++i)
@@ -3422,7 +3636,7 @@ qf_mark_adjust(
}
for (idx = 0; idx < qi->qf_listcount; ++idx)
- if (qi->qf_lists[idx].qf_count)
+ if (!qf_list_empty(qi, idx))
for (i = 0, qfp = qi->qf_lists[idx].qf_start;
i < qi->qf_lists[idx].qf_count && qfp != NULL;
++i, qfp = qfp->qf_next)
@@ -3504,7 +3718,7 @@ qf_view_result(int split)
if (IS_LL_WINDOW(curwin))
qi = GET_LOC_LIST(curwin);
- if (qi == NULL || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+ if (qf_list_empty(qi, qi->qf_curlist))
{
EMSG(_(e_quickfix));
return;
@@ -3537,7 +3751,7 @@ ex_cwindow(exarg_T *eap)
qf_info_T *qi = &ql_info;
win_T *win;
- if (eap->cmdidx == CMD_lwindow)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3553,7 +3767,7 @@ ex_cwindow(exarg_T *eap)
* it if we have errors; otherwise, leave it closed.
*/
if (qi->qf_lists[qi->qf_curlist].qf_nonevalid
- || qi->qf_lists[qi->qf_curlist].qf_count == 0
+ || qf_list_empty(qi, qi->qf_curlist)
|| qi->qf_curlist >= qi->qf_listcount)
{
if (win != NULL)
@@ -3573,7 +3787,7 @@ ex_cclose(exarg_T *eap)
win_T *win = NULL;
qf_info_T *qi = &ql_info;
- if (eap->cmdidx == CMD_lclose || eap->cmdidx == CMD_lwindow)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3600,7 +3814,7 @@ ex_copen(exarg_T *eap)
buf_T *qf_buf;
win_T *oldwin = curwin;
- if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3745,12 +3959,12 @@ qf_win_goto(win_T *win, linenr_T lnum)
* :cbottom/:lbottom commands.
*/
void
-ex_cbottom(exarg_T *eap UNUSED)
+ex_cbottom(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
win_T *win;
- if (eap->cmdidx == CMD_lbottom)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -3831,8 +4045,8 @@ is_qf_win(win_T *win, qf_info_T *qi)
* pointing to the location list.
*/
if (bt_quickfix(win->w_buffer))
- if ((qi == &ql_info && win->w_llist_ref == NULL)
- || (qi != &ql_info && win->w_llist_ref == qi))
+ if ((IS_QF_STACK(qi) && win->w_llist_ref == NULL)
+ || (IS_LL_STACK(qi) && win->w_llist_ref == qi))
return TRUE;
return FALSE;
@@ -4127,6 +4341,43 @@ qf_id2nr(qf_info_T *qi, int_u qfid)
}
/*
+ * If the current list is not "save_qfid" and we can find the list with that ID
+ * then make it the current list.
+ * This is used when autocommands may have changed the current list.
+ * Returns OK if successfully restored the list. Returns FAIL if the list with
+ * the specified identifier (save_qfid) is not found in the stack.
+ */
+ static int
+qf_restore_list(qf_info_T *qi, int_u save_qfid)
+{
+ int curlist;
+
+ if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid)
+ {
+ curlist = qf_id2nr(qi, save_qfid);
+ if (curlist < 0)
+ // list is not present
+ return FAIL;
+ qi->qf_curlist = curlist;
+ }
+ return OK;
+}
+
+/*
+ * Jump to the first entry if there is one.
+ */
+ static void
+qf_jump_first(qf_info_T *qi, int_u save_qfid, int forceit)
+{
+ if (qf_restore_list(qi, save_qfid) == FAIL)
+ return;
+
+ // Autocommands might have cleared the list, check for that.
+ if (!qf_list_empty(qi, qi->qf_curlist))
+ qf_jump(qi, 0, 0, forceit);
+}
+
+/*
* Return TRUE when using ":vimgrep" for ":grep".
*/
int
@@ -4185,8 +4436,7 @@ ex_make(exarg_T *eap)
enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
#endif
- if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
- || eap->cmdidx == CMD_lgrepadd)
+ if (is_loclist_cmd(eap->cmdidx))
wp = curwin;
autowrite_all();
@@ -4248,12 +4498,8 @@ ex_make(exarg_T *eap)
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf);
if (res > 0 && !eap->forceit && qflist_valid(wp, save_qfid))
- {
- // If autocommands changed the current list, then restore it
- if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid)
- qi->qf_curlist = qf_id2nr(qi, save_qfid);
- qf_jump(qi, 0, 0, FALSE); /* display first error */
- }
+ // display the first error
+ qf_jump_first(qi, save_qfid, FALSE);
cleanup:
mch_remove(fname);
@@ -4329,7 +4575,7 @@ qf_get_size(exarg_T *eap)
int i, sz = 0;
int prev_fnum = 0;
- if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo)
+ if (is_loclist_cmd(eap->cmdidx))
{
/* Location list */
qi = GET_LOC_LIST(curwin);
@@ -4366,7 +4612,7 @@ qf_get_cur_idx(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
- if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo)
+ if (is_loclist_cmd(eap->cmdidx))
{
/* Location list */
qi = GET_LOC_LIST(curwin);
@@ -4390,7 +4636,7 @@ qf_get_cur_valid_idx(exarg_T *eap)
int i, eidx = 0;
int prev_fnum = 0;
- if (eap->cmdidx == CMD_ldo || eap->cmdidx == CMD_lfdo)
+ if (is_loclist_cmd(eap->cmdidx))
{
/* Location list */
qi = GET_LOC_LIST(curwin);
@@ -4483,12 +4729,7 @@ ex_cc(exarg_T *eap)
qf_info_T *qi = &ql_info;
int errornr;
- if (eap->cmdidx == CMD_ll
- || eap->cmdidx == CMD_lrewind
- || eap->cmdidx == CMD_lfirst
- || eap->cmdidx == CMD_llast
- || eap->cmdidx == CMD_ldo
- || eap->cmdidx == CMD_lfdo)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -4502,13 +4743,18 @@ ex_cc(exarg_T *eap)
errornr = (int)eap->line2;
else
{
- if (eap->cmdidx == CMD_cc || eap->cmdidx == CMD_ll)
- errornr = 0;
- else if (eap->cmdidx == CMD_crewind || eap->cmdidx == CMD_lrewind
- || eap->cmdidx == CMD_cfirst || eap->cmdidx == CMD_lfirst)
- errornr = 1;
- else
- errornr = 32767;
+ switch (eap->cmdidx)
+ {
+ case CMD_cc: case CMD_ll:
+ errornr = 0;
+ break;
+ case CMD_crewind: case CMD_lrewind: case CMD_cfirst:
+ case CMD_lfirst:
+ errornr = 1;
+ break;
+ default:
+ errornr = 32767;
+ }
}
/* For cdo and ldo commands, jump to the nth valid error.
@@ -4533,15 +4779,9 @@ ex_cnext(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
int errornr;
+ int dir;
- if (eap->cmdidx == CMD_lnext
- || eap->cmdidx == CMD_lNext
- || eap->cmdidx == CMD_lprevious
- || eap->cmdidx == CMD_lnfile
- || eap->cmdidx == CMD_lNfile
- || eap->cmdidx == CMD_lpfile
- || eap->cmdidx == CMD_ldo
- || eap->cmdidx == CMD_lfdo)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = GET_LOC_LIST(curwin);
if (qi == NULL)
@@ -4558,17 +4798,28 @@ ex_cnext(exarg_T *eap)
else
errornr = 1;
- qf_jump(qi, (eap->cmdidx == CMD_cnext || eap->cmdidx == CMD_lnext
- || eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo)
- ? FORWARD
- : (eap->cmdidx == CMD_cnfile || eap->cmdidx == CMD_lnfile
- || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo)
- ? FORWARD_FILE
- : (eap->cmdidx == CMD_cpfile || eap->cmdidx == CMD_lpfile
- || eap->cmdidx == CMD_cNfile || eap->cmdidx == CMD_lNfile)
- ? BACKWARD_FILE
- : BACKWARD,
- errornr, eap->forceit);
+ // Depending on the command jump to either next or previous entry/file.
+ switch (eap->cmdidx)
+ {
+ case CMD_cnext: case CMD_lnext: case CMD_cdo: case CMD_ldo:
+ dir = FORWARD;
+ break;
+ case CMD_cprevious: case CMD_lprevious: case CMD_cNext:
+ case CMD_lNext:
+ dir = BACKWARD;
+ break;
+ case CMD_cnfile: case CMD_lnfile: case CMD_cfdo: case CMD_lfdo:
+ dir = FORWARD_FILE;
+ break;
+ case CMD_cpfile: case CMD_lpfile: case CMD_cNfile: case CMD_lNfile:
+ dir = BACKWARD_FILE;
+ break;
+ default:
+ dir = FORWARD;
+ break;
+ }
+
+ qf_jump(qi, dir, errornr, eap->forceit);
}
/*
@@ -4616,9 +4867,7 @@ ex_cfile(exarg_T *eap)
if (*eap->arg != NUL)
set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE, 0);
- if (eap->cmdidx == CMD_lfile
- || eap->cmdidx == CMD_lgetfile
- || eap->cmdidx == CMD_laddfile)
+ if (is_loclist_cmd(eap->cmdidx))
wp = curwin;
/*
@@ -4650,12 +4899,8 @@ ex_cfile(exarg_T *eap)
// free the list.
if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile)
&& qflist_valid(wp, save_qfid))
- {
- // If autocommands changed the current list, then restore it
- if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid)
- qi->qf_curlist = qf_id2nr(qi, save_qfid);
- qf_jump(qi, 0, 0, eap->forceit); /* display first error */
- }
+ // display the first error
+ qf_jump_first(qi, save_qfid, eap->forceit);
}
/*
@@ -4793,10 +5038,8 @@ vgr_qflist_valid(
}
}
- if (qi->qf_lists[qi->qf_curlist].qf_id != qfid)
- /* Autocommands changed the quickfix list. Find the one we were
- * using and restore it. */
- qi->qf_curlist = qf_id2nr(qi, qfid);
+ if (qf_restore_list(qi, qfid) == FAIL)
+ return FALSE;
return TRUE;
}
@@ -4943,10 +5186,7 @@ ex_vimgrep(exarg_T *eap)
#endif
}
- if (eap->cmdidx == CMD_lgrep
- || eap->cmdidx == CMD_lvimgrep
- || eap->cmdidx == CMD_lgrepadd
- || eap->cmdidx == CMD_lvimgrepadd)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = ll_get_or_alloc_list(curwin);
if (qi == NULL)
@@ -5142,12 +5382,11 @@ ex_vimgrep(exarg_T *eap)
if (!qflist_valid(wp, save_qfid))
goto theend;
- // If autocommands changed the current list, then restore it
- if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid)
- qi->qf_curlist = qf_id2nr(qi, save_qfid);
+ if (qf_restore_list(qi, save_qfid) == FAIL)
+ goto theend;
- /* Jump to first match. */
- if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+ // Jump to first match.
+ if (!qf_list_empty(qi, qi->qf_curlist))
{
if ((flags & VGR_NOJUMP) == 0)
vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy,
@@ -5380,8 +5619,7 @@ get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list)
if (qf_idx == INVALID_QFIDX)
qf_idx = qi->qf_curlist;
- if (qf_idx >= qi->qf_listcount
- || qi->qf_lists[qf_idx].qf_count == 0)
+ if (qf_idx >= qi->qf_listcount || qf_list_empty(qi, qf_idx))
return FAIL;
qfp = qi->qf_lists[qf_idx].qf_start;
@@ -5466,12 +5704,9 @@ qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
if (l == NULL)
return FAIL;
- qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
+ qi = ll_new_list();
if (qi != NULL)
{
- vim_memset(qi, 0, (size_t)(sizeof(qf_info_T)));
- qi->qf_refcount++;
-
if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
TRUE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
{
@@ -5702,7 +5937,7 @@ qf_getprop_ctx(qf_info_T *qi, int qf_idx, dict_T *retdict)
qf_getprop_idx(qf_info_T *qi, int qf_idx, dict_T *retdict)
{
int idx = qi->qf_lists[qf_idx].qf_index;
- if (qi->qf_lists[qf_idx].qf_count == 0)
+ if (qf_list_empty(qi, qf_idx))
/* For empty lists, qf_index is set to 1 */
idx = 0;
return dict_add_number(retdict, "idx", idx);
@@ -5791,7 +6026,7 @@ qf_add_entries(
qf_new_list(qi, title);
qf_idx = qi->qf_curlist;
}
- else if (action == 'a' && qi->qf_lists[qf_idx].qf_count > 0)
+ else if (action == 'a' && !qf_list_empty(qi, qf_idx))
/* Adding to existing list, use last entry. */
old_last = qi->qf_lists[qf_idx].qf_last;
else if (action == 'r')
@@ -5880,7 +6115,7 @@ qf_add_entries(
{
qi->qf_lists[qf_idx].qf_ptr =
qi->qf_lists[qf_idx].qf_start;
- if (qi->qf_lists[qf_idx].qf_count > 0)
+ if (!qf_list_empty(qi, qf_idx))
qi->qf_lists[qf_idx].qf_index = 1;
}
@@ -6295,9 +6530,7 @@ ex_cbuffer(exarg_T *eap)
}
/* Must come after autocommands. */
- if (eap->cmdidx == CMD_lbuffer
- || eap->cmdidx == CMD_lgetbuffer
- || eap->cmdidx == CMD_laddbuffer)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = ll_get_or_alloc_list(curwin);
if (qi == NULL)
@@ -6361,12 +6594,8 @@ ex_cbuffer(exarg_T *eap)
if (res > 0 && (eap->cmdidx == CMD_cbuffer ||
eap->cmdidx == CMD_lbuffer)
&& qflist_valid(wp, save_qfid))
- {
- // If autocommands changed the current list, then restore it
- if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid)
- qi->qf_curlist = qf_id2nr(qi, save_qfid);
- qf_jump(qi, 0, 0, eap->forceit); /* display first error */
- }
+ // display the first error
+ qf_jump_first(qi, save_qfid, eap->forceit);
}
}
}
@@ -6405,9 +6634,7 @@ ex_cexpr(exarg_T *eap)
#endif
}
- if (eap->cmdidx == CMD_lexpr
- || eap->cmdidx == CMD_lgetexpr
- || eap->cmdidx == CMD_laddexpr)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = ll_get_or_alloc_list(curwin);
if (qi == NULL)
@@ -6443,12 +6670,8 @@ ex_cexpr(exarg_T *eap)
if (res > 0 && (eap->cmdidx == CMD_cexpr
|| eap->cmdidx == CMD_lexpr)
&& qflist_valid(wp, save_qfid))
- {
- // If autocommands changed the current list, then restore it
- if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid)
- qi->qf_curlist = qf_id2nr(qi, save_qfid);
- qf_jump(qi, 0, 0, eap->forceit);
- }
+ // display the first error
+ qf_jump_first(qi, save_qfid, eap->forceit);
}
else
EMSG(_("E777: String or List expected"));
@@ -6621,16 +6844,13 @@ hgr_search_files_in_dir(
/*
* Search for a pattern in all the help files in the 'runtimepath'
* and add the matches to a quickfix list.
- * 'arg' is the language specifier. If supplied, then only matches in the
+ * 'lang' is the language specifier. If supplied, then only matches in the
* specified language are found.
*/
static void
-hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *arg)
+hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *lang)
{
char_u *p;
-#ifdef FEAT_MULTI_LANG
- char_u *lang;
-#endif
#ifdef FEAT_MBYTE
vimconv_T vc;
@@ -6642,10 +6862,6 @@ hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *arg)
convert_setup(&vc, (char_u *)"utf-8", p_enc);
#endif
-#ifdef FEAT_MULTI_LANG
- /* Check for a specified language */
- lang = check_help_lang(arg);
-#endif
/* Go through all the directories in 'runtimepath' */
p = p_rtp;
@@ -6680,6 +6896,7 @@ ex_helpgrep(exarg_T *eap)
qf_info_T *qi = &ql_info;
int new_qi = FALSE;
char_u *au_name = NULL;
+ char_u *lang = NULL;
switch (eap->cmdidx)
{
@@ -6696,25 +6913,29 @@ ex_helpgrep(exarg_T *eap)
#endif
}
- /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
+ // Make 'cpoptions' empty, the 'l' flag should not be used here.
save_cpo = p_cpo;
p_cpo = empty_option;
- if (eap->cmdidx == CMD_lhelpgrep)
+ if (is_loclist_cmd(eap->cmdidx))
{
qi = hgr_get_ll(&new_qi);
if (qi == NULL)
return;
}
+#ifdef FEAT_MULTI_LANG
+ // Check for a specified language
+ lang = check_help_lang(eap->arg);
+#endif
regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
regmatch.rm_ic = FALSE;
if (regmatch.regprog != NULL)
{
- /* create a new quickfix list */
+ // create a new quickfix list
qf_new_list(qi, qf_cmdtitle(*eap->cmdlinep));
- hgr_search_in_rtp(qi, &regmatch, eap->arg);
+ hgr_search_in_rtp(qi, &regmatch, lang);
vim_regfree(regmatch.regprog);
@@ -6727,7 +6948,7 @@ ex_helpgrep(exarg_T *eap)
if (p_cpo == empty_option)
p_cpo = save_cpo;
else
- /* Darn, some plugin changed the value. */
+ // Darn, some plugin changed the value.
free_string_option(save_cpo);
qf_list_changed(qi, qi->qf_curlist);
@@ -6737,21 +6958,21 @@ ex_helpgrep(exarg_T *eap)
{
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf);
- if (!new_qi && qi != &ql_info && qf_find_buf(qi) == NULL)
+ if (!new_qi && IS_LL_STACK(qi) && qf_find_buf(qi) == NULL)
/* autocommands made "qi" invalid */
return;
}
/* Jump to first match. */
- if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
+ if (!qf_list_empty(qi, qi->qf_curlist))
qf_jump(qi, 0, 0, FALSE);
else
EMSG2(_(e_nomatch2), eap->arg);
if (eap->cmdidx == CMD_lhelpgrep)
{
- /* If the help window is not opened or if it already points to the
- * correct location list, then free the new location list. */
+ // If the help window is not opened or if it already points to the
+ // correct location list, then free the new location list.
if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi)
{
if (new_qi)
diff --git a/src/screen.c b/src/screen.c
index cab5731..a4eef32 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -7892,6 +7892,13 @@ next_search_hl(
long nmatched;
int save_called_emsg = called_emsg;
+ // for :{range}s/pat only highlight inside the range
+ if (lnum < search_first_line || lnum > search_last_line)
+ {
+ shl->lnum = 0;
+ return;
+ }
+
if (shl->lnum != 0)
{
/* Check for three situations:
diff --git a/src/search.c b/src/search.c
index 66ae647..a12a1d3 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4106,9 +4106,10 @@ again:
}
curwin->w_cursor = end_pos;
- /* If we now have the same text as before reset "do_include" and try
- * again. */
- if (EQUAL_POS(start_pos, old_start) && EQUAL_POS(end_pos, old_end))
+ // If we are in Visual mode and now have the same text as before set
+ // "do_include" and try again.
+ if (VIsual_active && EQUAL_POS(start_pos, old_start)
+ && EQUAL_POS(end_pos, old_end))
{
do_include = TRUE;
curwin->w_cursor = old_start;
diff --git a/src/term.c b/src/term.c
index 209a03f..cede4b8 100644
--- a/src/term.c
+++ b/src/term.c
@@ -922,6 +922,10 @@ static struct builtin_term builtin_termcaps[] =
# endif
{(int)KS_CBE, IF_EB("\033[?2004h", ESC_STR "[?2004h")},
{(int)KS_CBD, IF_EB("\033[?2004l", ESC_STR "[?2004l")},
+ {(int)KS_CST, IF_EB("\033[22;2t", ESC_STR "[22;2t")},
+ {(int)KS_CRT, IF_EB("\033[23;2t", ESC_STR "[23;2t")},
+ {(int)KS_SSI, IF_EB("\033[22;1t", ESC_STR "[22;1t")},
+ {(int)KS_SRI, IF_EB("\033[23;1t", ESC_STR "[23;1t")},
{K_UP, IF_EB("\033O*A", ESC_STR "O*A")},
{K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")},
@@ -1600,6 +1604,8 @@ get_term_entries(int *height, int *width)
{KS_8F, "8f"}, {KS_8B, "8b"},
{KS_CBE, "BE"}, {KS_CBD, "BD"},
{KS_CPS, "PS"}, {KS_CPE, "PE"},
+ {KS_CST, "ST"}, {KS_CRT, "RT"},
+ {KS_SSI, "Si"}, {KS_SRI, "Ri"},
{(enum SpecialKey)0, NULL}
};
int i;
@@ -2974,6 +2980,45 @@ term_settitle(char_u *title)
out_str(T_FS); /* set title end */
out_flush();
}
+
+/*
+ * Tell the terminal to push (save) the title and/or icon, so that it can be
+ * popped (restored) later.
+ */
+ void
+term_push_title(int which)
+{
+ if ((which & SAVE_RESTORE_TITLE) && *T_CST != NUL)
+ {
+ OUT_STR(T_CST);
+ out_flush();
+ }
+
+ if ((which & SAVE_RESTORE_ICON) && *T_SSI != NUL)
+ {
+ OUT_STR(T_SSI);
+ out_flush();
+ }
+}
+
+/*
+ * Tell the terminal to pop the title and/or icon.
+ */
+ void
+term_pop_title(int which)
+{
+ if ((which & SAVE_RESTORE_TITLE) && *T_CRT != NUL)
+ {
+ OUT_STR(T_CRT);
+ out_flush();
+ }
+
+ if ((which & SAVE_RESTORE_ICON) && *T_SRI != NUL)
+ {
+ OUT_STR(T_SRI);
+ out_flush();
+ }
+}
#endif
/*
@@ -3789,16 +3834,23 @@ scroll_start(void)
static int cursor_is_off = FALSE;
/*
- * Enable the cursor.
+ * Enable the cursor without checking if it's already enabled.
+ */
+ void
+cursor_on_force(void)
+{
+ out_str(T_VE);
+ cursor_is_off = FALSE;
+}
+
+/*
+ * Enable the cursor if it's currently off.
*/
void
cursor_on(void)
{
if (cursor_is_off)
- {
- out_str(T_VE);
- cursor_is_off = FALSE;
- }
+ cursor_on_force();
}
/*
diff --git a/src/term.h b/src/term.h
index 8808f7d..219a208 100644
--- a/src/term.h
+++ b/src/term.h
@@ -101,10 +101,14 @@ enum SpecialKey
KS_CBE, /* enable bracketed paste mode */
KS_CBD, /* disable bracketed paste mode */
KS_CPS, /* start of bracketed paste */
- KS_CPE /* end of bracketed paste */
+ KS_CPE, /* end of bracketed paste */
+ KS_CST, /* save window title */
+ KS_CRT, /* restore window title */
+ KS_SSI, /* save icon text */
+ KS_SRI /* restore icon text */
};
-#define KS_LAST KS_CPE
+#define KS_LAST KS_SRI
/*
* the terminal capabilities are stored in this array
@@ -196,6 +200,10 @@ extern char_u *(term_strings[]); /* current terminal strings */
#define T_BD (TERM_STR(KS_CBD)) /* disable bracketed paste mode */
#define T_PS (TERM_STR(KS_CPS)) /* start of bracketed paste */
#define T_PE (TERM_STR(KS_CPE)) /* end of bracketed paste */
+#define T_CST (TERM_STR(KS_CST)) /* save window title */
+#define T_CRT (TERM_STR(KS_CRT)) /* restore window title */
+#define T_SSI (TERM_STR(KS_SSI)) /* save icon text */
+#define T_SRI (TERM_STR(KS_SRI)) /* restore icon text */
#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */
#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */
diff --git a/src/terminal.c b/src/terminal.c
index 22b90c8..66a7369 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -529,6 +529,8 @@ term_start(
set_string_option_direct((char_u *)"buftype", -1,
(char_u *)"terminal", OPT_FREE|OPT_LOCAL, 0);
+ // Avoid that 'buftype' is reset when this buffer is entered.
+ curbuf->b_p_initialized = TRUE;
/* Mark the buffer as not modifiable. It can only be made modifiable after
* the job finished. */
@@ -2816,11 +2818,17 @@ term_after_channel_closed(term_T *term)
if (term->tl_finish == TL_FINISH_CLOSE)
{
aco_save_T aco;
+ int do_set_w_closing = term->tl_buffer->b_nwindows == 0;
- /* ++close or term_finish == "close" */
+ // ++close or term_finish == "close"
ch_log(NULL, "terminal job finished, closing window");
aucmd_prepbuf(&aco, term->tl_buffer);
+ // Avoid closing the window if we temporarily use it.
+ if (do_set_w_closing)
+ curwin->w_closing = TRUE;
do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
+ if (do_set_w_closing)
+ curwin->w_closing = FALSE;
aucmd_restbuf(&aco);
return TRUE;
}
diff --git a/src/testdir/dumps/Test_incsearch_sort_01.dump b/src/testdir/dumps/Test_incsearch_sort_01.dump
new file mode 100644
index 0000000..6c003af
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_sort_01.dump
@@ -0,0 +1,9 @@
+|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
+|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
+|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|~| @68
+|~| @68
+|:+0#0000000&|s|o|r|t| |n|i| |u| |/|o|n> @55
diff --git a/src/testdir/dumps/Test_incsearch_substitute_01.dump b/src/testdir/dumps/Test_incsearch_substitute_01.dump
new file mode 100644
index 0000000..63886f5
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_01.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f|o@1| |2| @64
+|f+1&&|o@1| +0&&|3| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|:|.|,|.|+|2|s|/|f|o@1> @58
diff --git a/src/testdir/dumps/Test_incsearch_substitute_02.dump b/src/testdir/dumps/Test_incsearch_substitute_02.dump
new file mode 100644
index 0000000..fd1f912
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_02.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f|o@1| |2| @64
+|f|o@1| |3| @64
+|f+1&&|o@1| +0&&|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|:|.|,|.|+|2|s|/@1> @60
diff --git a/src/testdir/dumps/Test_incsearch_substitute_03.dump b/src/testdir/dumps/Test_incsearch_substitute_03.dump
new file mode 100644
index 0000000..5d7afa0
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_03.dump
@@ -0,0 +1,9 @@
+|f+0&#ffff4012|o@1| +0&#ffffff0|1| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|2| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|3| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|6| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|7| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|8| @64
+|:|.|,|.|+|2|s|/> @61
diff --git a/src/testdir/dumps/Test_incsearch_substitute_04.dump b/src/testdir/dumps/Test_incsearch_substitute_04.dump
new file mode 100644
index 0000000..bae6c7b
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_04.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f+1&&|o@1| +0&&|2| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|3| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|:|5|,|2|s|/|f|o@1> @60
diff --git a/src/testdir/dumps/Test_incsearch_substitute_05.dump b/src/testdir/dumps/Test_incsearch_substitute_05.dump
new file mode 100644
index 0000000..6ec8ea3
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_05.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |1| @64
+|f+1&&|o|o+0&&| |2| @64
+|f+0&#ffff4012|o|o+0&#ffffff0| |3| @64
+|f|o@1| |4| @64
+|f|o@1| |5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|:|2|,|3|s|u|b| @1|/|f|o> @57
diff --git a/src/testdir/dumps/Test_incsearch_substitute_06.dump b/src/testdir/dumps/Test_incsearch_substitute_06.dump
new file mode 100644
index 0000000..8a66620
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_06.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |3| @64
+|f+1&&|o@1| +0&&|4| @64
+|f+0&#ffff4012|o@1| +0&#ffffff0|5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|:|a|b|o|v|e| |b|e|l|o|w| |b|r|o|w|s|e| |b|o|t|r| |c|o|n|f|i|r|m| |k|e@1|p|m|a|r| |k|e@1|p|a|l|t| |k|e@1|p@1|a|t| |k|e@1|p|j|u|m| |f|i|l|t|e
+|r| |x@2| |h|i|d|e| |l|o|c|k|m| |l|e|f|t|a|b|o|v|e| |n|o|a|u| |n|o|s|w|a|p| |r|i|g|h|t|b|e|l| |s|a|n|d|b|o|x| |s|i|l|e|n|t| |s|i|l|e|n|t|!
+| |$|t|a|b| |t|o|p| |u|n|s|i|l| |v|e|r|t| |v|e|r|b|o|s|e| |4|,|5|s|/|f|o|.> @32
diff --git a/src/testdir/dumps/Test_incsearch_substitute_07.dump b/src/testdir/dumps/Test_incsearch_substitute_07.dump
new file mode 100644
index 0000000..7b4dc6e
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_07.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |4| @64
+|f|o@1| |5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|f|o@1| |9| @64
+|f|o@1| |1|0| @63
+|b+9&&|a|r| +8&&|1@1| @63
+|:+0&&|9|,|1@1|s|/|b|a|r> @59
diff --git a/src/testdir/dumps/Test_incsearch_substitute_08.dump b/src/testdir/dumps/Test_incsearch_substitute_08.dump
new file mode 100644
index 0000000..d87e507
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_08.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |4| @64
+|f|o@1| |5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|f+8&&|o@1| |9| @64
+|f+0&&|o@1| |1|0| @63
+|b|a|r| |1@1| @63
+|:|9|,|1|0|s|/|b|a|r> @59
diff --git a/src/testdir/dumps/Test_incsearch_substitute_09.dump b/src/testdir/dumps/Test_incsearch_substitute_09.dump
new file mode 100644
index 0000000..633e7d8
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_substitute_09.dump
@@ -0,0 +1,9 @@
+|f+0&#ffffff0|o@1| |3| @64
+|f+8&&|o@1| |4| @64
+|f+0&&|o@1| |5| @64
+|f|o@1| |6| @64
+|f|o@1| |7| @64
+|f|o@1| |8| @64
+|f|o@1| |9| @64
+|f|o@1| |1|0| @63
+|:|6|,|7|s|/|\|v> @61
diff --git a/src/testdir/dumps/Test_incsearch_vimgrep_01.dump b/src/testdir/dumps/Test_incsearch_vimgrep_01.dump
new file mode 100644
index 0000000..955d030
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_vimgrep_01.dump
@@ -0,0 +1,9 @@
+|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
+|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
+|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|~| @68
+|~| @68
+|:+0#0000000&|v|i|m|g|r|e|p| |o|n> @58
diff --git a/src/testdir/dumps/Test_incsearch_vimgrep_02.dump b/src/testdir/dumps/Test_incsearch_vimgrep_02.dump
new file mode 100644
index 0000000..a5d94ea
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_vimgrep_02.dump
@@ -0,0 +1,9 @@
+|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
+|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
+|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|~| @68
+|~| @68
+|:+0#0000000&|v|i|m|g| |/|o|n|/| |*|.|t|x|t> @53
diff --git a/src/testdir/dumps/Test_incsearch_vimgrep_03.dump b/src/testdir/dumps/Test_incsearch_vimgrep_03.dump
new file mode 100644
index 0000000..038ceb9
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_vimgrep_03.dump
@@ -0,0 +1,9 @@
+|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56
+|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59
+|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|~| @68
+|~| @68
+|:+0#0000000&|v|i|m|g|r|e|p|a|d@1| |"|\|<|o|n> @52
diff --git a/src/testdir/dumps/Test_incsearch_vimgrep_04.dump b/src/testdir/dumps/Test_incsearch_vimgrep_04.dump
new file mode 100644
index 0000000..92dd78d
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_vimgrep_04.dump
@@ -0,0 +1,9 @@
+|a+0&#ffffff0|n|o|t|h|e|r| |o|n|e| |2| @56
+|t+1&&|h|a|t+0&&| |o|n|e| |3| @59
+|t|h|e| |o|n|e| |1| @60
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|~| @68
+|~| @68
+|:+0#0000000&|l|v| |"|t|h|a> @61
diff --git a/src/testdir/dumps/Test_incsearch_vimgrep_05.dump b/src/testdir/dumps/Test_incsearch_vimgrep_05.dump
new file mode 100644
index 0000000..e11ff57
--- /dev/null
+++ b/src/testdir/dumps/Test_incsearch_vimgrep_05.dump
@@ -0,0 +1,9 @@
+|a+0&#ffffff0|n|o|t+1&&|h|e|r+0&&| |o|n|e| |2| @56
+|t|h|a|t| |o|n|e| |3| @59
+|t+0&#ffff4012|h|e| +0&#ffffff0|o|n|e| |1| @60
+|~+0#4040ff13&| @68
+|~| @68
+|~| @68
+|~| @68
+|~| @68
+|:+0#0000000&|l|v|i|m|g|r|e|p|a| |"|t|h|e|"| |*@1|/|*|.|t|x|t> @44
diff --git a/src/testdir/runtest.vim b/src/testdir/runtest.vim
index 4f508a4..c341491 100644
--- a/src/testdir/runtest.vim
+++ b/src/testdir/runtest.vim
@@ -272,6 +272,7 @@ let s:flaky = [
\ 'Test_paused()',
\ 'Test_pipe_through_sort_all()',
\ 'Test_pipe_through_sort_some()',
+ \ 'Test_popup_and_window_resize()',
\ 'Test_quoteplus()',
\ 'Test_quotestar()',
\ 'Test_reltime()',
diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok
index f8d4ceb..24d3fd4 100644
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -701,7 +701,7 @@ vim.foreach_rtp(FailingCall()):NotImplementedError:('call',)
vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',)
> import
import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
-import failing_import:ImportError:('No module named failing_import',)
+import failing_import:ImportError:()
import failing:NotImplementedError:()
> Options
>> OptionsItem
diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok
index 9ca4b62..a7d4f64 100644
--- a/src/testdir/test87.ok
+++ b/src/testdir/test87.ok
@@ -701,7 +701,7 @@ vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedErr
vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
> import
import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
-import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
+import failing_import:(<class 'ImportError'>, ImportError())
import failing:(<class 'NotImplementedError'>, NotImplementedError())
> Options
>> OptionsItem
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index 1465a7a..16a3f7f 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -2,6 +2,7 @@
" This makes testing go faster, since Vim doesn't need to restart.
source test_assign.vim
+source test_backup.vim
source test_bufline.vim
source test_cd.vim
source test_changedtick.vim
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 19c54d1..3d650e4 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -587,7 +587,7 @@ func Test_OptionSet()
" Cleanup
au! OptionSet
for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
- exe printf(":set %s&vi", opt)
+ exe printf(":set %s&vim", opt)
endfor
call test_override('starting', 0)
delfunc! AutoCommandOptionSet
@@ -1313,6 +1313,29 @@ func Test_ChangedP()
bw!
endfunc
+let g:setline_handled = v:false
+func! SetLineOne()
+ if !g:setline_handled
+ call setline(1, "(x)")
+ let g:setline_handled = v:true
+ endif
+endfunc
+
+func Test_TextChangedI_with_setline()
+ new
+ call test_override('char_avail', 1)
+ autocmd TextChangedI <buffer> call SetLineOne()
+ call feedkeys("i(\<CR>\<Esc>", 'tx')
+ call assert_equal('(', getline(1))
+ call assert_equal('x)', getline(2))
+ undo
+ call assert_equal('', getline(1))
+ call assert_equal('', getline(2))
+
+ call test_override('starting', 0)
+ bwipe!
+endfunc
+
func Test_Changed_FirstTime()
if !has('terminal') || has('gui_running')
return
diff --git a/src/testdir/test_backup.vim b/src/testdir/test_backup.vim
new file mode 100644
index 0000000..ce2bfe7
--- /dev/null
+++ b/src/testdir/test_backup.vim
@@ -0,0 +1,58 @@
+" Tests for the backup function
+
+func Test_backup()
+ set backup backupdir=. backupskip=
+ new
+ call setline(1, ['line1', 'line2'])
+ :f Xbackup.txt
+ :w! Xbackup.txt
+ " backup file is only created after
+ " writing a second time (before overwriting)
+ :w! Xbackup.txt
+ let l = readfile('Xbackup.txt~')
+ call assert_equal(['line1', 'line2'], l)
+ bw!
+ set backup&vim backupdir&vim backupskip&vim
+ call delete('Xbackup.txt')
+ call delete('Xbackup.txt~')
+endfunc
+
+func Test_backup2()
+ set backup backupdir=.// backupskip=
+ new
+ call setline(1, ['line1', 'line2', 'line3'])
+ :f Xbackup.txt
+ :w! Xbackup.txt
+ " backup file is only created after
+ " writing a second time (before overwriting)
+ :w! Xbackup.txt
+ sp *Xbackup.txt~
+ call assert_equal(['line1', 'line2', 'line3'], getline(1,'$'))
+ let f=expand('%')
+ call assert_match('%testdir%Xbackup.txt\~', f)
+ bw!
+ bw!
+ call delete('Xbackup.txt')
+ call delete(f)
+ set backup&vim backupdir&vim backupskip&vim
+endfunc
+
+func Test_backup2_backupcopy()
+ set backup backupdir=.// backupcopy=yes backupskip=
+ new
+ call setline(1, ['line1', 'line2', 'line3'])
+ :f Xbackup.txt
+ :w! Xbackup.txt
+ " backup file is only created after
+ " writing a second time (before overwriting)
+ :w! Xbackup.txt
+ sp *Xbackup.txt~
+ call assert_equal(['line1', 'line2', 'line3'], getline(1,'$'))
+ let f=expand('%')
+ call assert_match('%testdir%Xbackup.txt\~', f)
+ bw!
+ bw!
+ call delete('Xbackup.txt')
+ call delete(f)
+ set backup&vim backupdir&vim backupcopy&vim backupskip&vim
+endfunc
diff --git a/src/testdir/test_cscope.vim b/src/testdir/test_cscope.vim
index 71d5487..63f2c18 100644
--- a/src/testdir/test_cscope.vim
+++ b/src/testdir/test_cscope.vim
@@ -259,7 +259,12 @@ endfunc
" Test ":cs add {dir}" (add the {dir}/cscope.out database)
func Test_cscope_add_dir()
call mkdir('Xcscopedir', 'p')
- call system('cscope -bk -fXcscopedir/cscope.out ../memfile_test.c')
+
+ " Cscope doesn't handle symlinks, so this needs to be resolved in case a
+ " shadow directory is being used.
+ let memfile = resolve('../memfile_test.c')
+ call system('cscope -bk -fXcscopedir/cscope.out ' . memfile)
+
cs add Xcscopedir
let a = execute('cscope show')
let lines = split(a, "\n", 1)
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 41996bd..848e798 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -208,6 +208,21 @@ func Test_simplify()
call assert_fails('call simplify(1.2)', 'E806:')
endfunc
+func Test_pathshorten()
+ call assert_equal('', pathshorten(''))
+ call assert_equal('foo', pathshorten('foo'))
+ call assert_equal('/foo', pathshorten('/foo'))
+ call assert_equal('f/', pathshorten('foo/'))
+ call assert_equal('f/bar', pathshorten('foo/bar'))
+ call assert_equal('f/b/foobar', pathshorten('foo/bar/foobar'))
+ call assert_equal('/f/b/foobar', pathshorten('/foo/bar/foobar'))
+ call assert_equal('.f/bar', pathshorten('.foo/bar'))
+ call assert_equal('~f/bar', pathshorten('~foo/bar'))
+ call assert_equal('~.f/bar', pathshorten('~.foo/bar'))
+ call assert_equal('.~f/bar', pathshorten('.~foo/bar'))
+ call assert_equal('~/f/bar', pathshorten('~/foo/bar'))
+endfunc
+
func Test_strpart()
call assert_equal('de', strpart('abcdefg', 3, 2))
call assert_equal('ab', strpart('abcdefg', -2, 4))
@@ -667,6 +682,7 @@ endfunc
func Test_byte2line_line2byte()
new
+ set endofline
call setline(1, ['a', 'bc', 'd'])
set fileformat=unix
@@ -687,7 +703,16 @@ func Test_byte2line_line2byte()
call assert_equal([-1, -1, 1, 4, 8, 11, -1],
\ map(range(-1, 5), 'line2byte(v:val)'))
- set fileformat&
+ bw!
+ set noendofline nofixendofline
+ normal a-
+ for ff in ["unix", "mac", "dos"]
+ let &fileformat = ff
+ call assert_equal(1, line2byte(1))
+ call assert_equal(2, line2byte(2)) " line2byte(line("$") + 1) is the buffer size plus one (as per :help line2byte).
+ endfor
+
+ set endofline& fixendofline& fileformat&
bw!
endfunc
diff --git a/src/testdir/test_help_tagjump.vim b/src/testdir/test_help_tagjump.vim
index 51b006c..46aa6a1 100644
--- a/src/testdir/test_help_tagjump.vim
+++ b/src/testdir/test_help_tagjump.vim
@@ -26,6 +26,34 @@ func Test_help_tagjump()
call assert_true(getline('.') =~ '\*:?\*')
helpclose
+ help q?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*q?\*')
+ call assert_true(expand('<cword>') == 'q?')
+ helpclose
+
+ help -?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*-?\*')
+ helpclose
+
+ help v_g?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*v_g?\*')
+ helpclose
+
+ help expr-!=?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*expr-!=?\*')
+ call assert_true(expand('<cword>') == 'expr-!=?')
+ helpclose
+
+ help expr-isnot?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*expr-isnot?\*')
+ call assert_true(expand('<cword>') == 'expr-isnot?')
+ helpclose
+
help FileW*Post
call assert_equal("help", &filetype)
call assert_true(getline('.') =~ '\*FileWritePost\*')
diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim
index 2cd29b5..f7e1590 100644
--- a/src/testdir/test_ins_complete.vim
+++ b/src/testdir/test_ins_complete.vim
@@ -262,6 +262,19 @@ function Test_CompleteDoneList()
au! CompleteDone
endfunc
+func Test_CompleteDone_undo()
+ au CompleteDone * call append(0, "prepend1")
+ new
+ call setline(1, ["line1", "line2"])
+ call feedkeys("Go\<C-X>\<C-N>\<CR>\<ESC>", "tx")
+ call assert_equal(["prepend1", "line1", "line2", "line1", ""],
+ \ getline(1, '$'))
+ undo
+ call assert_equal(["line1", "line2"], getline(1, '$'))
+ bwipe!
+ au! CompleteDone
+endfunc
+
" Check that when using feedkeys() typeahead does not interrupt searching for
" completions.
func Test_compl_feedkeys()
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 460a569..2d4a97a 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -344,7 +344,7 @@ func Test_backupskip()
for var in ['$TEMPDIR', '$TMP', '$TEMP']
if exists(var)
let varvalue = substitute(expand(var), '\\', '/', 'g')
- call assert_match(varvalue . '.\*', bskvalue)
+ call assert_match(varvalue . '/\=\*', bskvalue)
endif
endfor
endfunc
@@ -414,3 +414,24 @@ func Test_shortmess_F()
set shortmess&
bwipe
endfunc
+
+func Test_shortmess_F2()
+ e file1
+ e file2
+ call assert_match('file1', execute('bn', ''))
+ call assert_match('file2', execute('bn', ''))
+ set shortmess+=F
+ call assert_true(empty(execute('bn', '')))
+ call assert_true(empty(execute('bn', '')))
+ set hidden
+ call assert_true(empty(execute('bn', '')))
+ call assert_true(empty(execute('bn', '')))
+ set nohidden
+ call assert_true(empty(execute('bn', '')))
+ call assert_true(empty(execute('bn', '')))
+ set shortmess&
+ call assert_match('file1', execute('bn', ''))
+ call assert_match('file2', execute('bn', ''))
+ bwipe
+ bwipe
+endfunc
diff --git a/src/testdir/test_perl.vim b/src/testdir/test_perl.vim
index 661c65c..03c5fa0 100644
--- a/src/testdir/test_perl.vim
+++ b/src/testdir/test_perl.vim
@@ -4,6 +4,9 @@ if !has('perl')
finish
end
+" FIXME: RunTest don't see any error when Perl abort...
+perl $SIG{__WARN__} = sub { die "Unexpected warnings from perl: @_" };
+
func Test_change_buffer()
call setline(line('$'), ['1 line 1'])
perl VIM::DoCommand("normal /^1\n")
@@ -229,6 +232,15 @@ func Test_000_SvREFCNT()
#line 5 "Test_000_SvREFCNT()"
my ($b, $w);
+ my $num = 0;
+ for ( 0 .. 100 ) {
+ if ( ++$num >= 8 ) { $num = 0 }
+ VIM::DoCommand("buffer X$num");
+ $b = $curbuf;
+ }
+
+ VIM::DoCommand("buffer t");
+
$b = $curbuf for 0 .. 100;
$w = $curwin for 0 .. 100;
() = VIM::Buffers for 0 .. 100;
@@ -240,12 +252,13 @@ func Test_000_SvREFCNT()
my $cw = Internals::SvREFCNT($$w);
VIM::Eval("assert_equal(2, $cb, 'T1')");
VIM::Eval("assert_equal(2, $cw, 'T2')");
+ my $strongref;
foreach ( VIM::Buffers, VIM::Windows ) {
+ VIM::DoCommand("%bw!");
my $c = Internals::SvREFCNT($_);
VIM::Eval("assert_equal(2, $c, 'T3')");
$c = Internals::SvREFCNT($$_);
- # Why only one ref?
- # Look wrong but work. Maybe not portable...
+ next if $c == 2 && !$strongref++;
VIM::Eval("assert_equal(1, $c, 'T4')");
}
$cb = Internals::SvREFCNT($$curbuf);
diff --git a/src/testdir/test_profile.vim b/src/testdir/test_profile.vim
index 6c24d31..cf9f346 100644
--- a/src/testdir/test_profile.vim
+++ b/src/testdir/test_profile.vim
@@ -67,7 +67,7 @@ func Test_profile_func()
call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13])
call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14])
call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15])
- call assert_match('^\s*100\s\+.*\sendwhile$', lines[16])
+ call assert_match('^\s*101\s\+.*\sendwhile$', lines[16])
call assert_equal('', lines[17])
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18])
call assert_equal('count total (s) self (s) function', lines[19])
@@ -84,6 +84,227 @@ func Test_profile_func()
call delete('Xprofile_func.log')
endfunc
+func Test_profile_func_with_ifelse()
+ let lines = [
+ \ "func! Foo1()",
+ \ " if 1",
+ \ " let x = 0",
+ \ " elseif 1",
+ \ " let x = 1",
+ \ " else",
+ \ " let x = 2",
+ \ " endif",
+ \ "endfunc",
+ \ "func! Foo2()",
+ \ " if 0",
+ \ " let x = 0",
+ \ " elseif 1",
+ \ " let x = 1",
+ \ " else",
+ \ " let x = 2",
+ \ " endif",
+ \ "endfunc",
+ \ "func! Foo3()",
+ \ " if 0",
+ \ " let x = 0",
+ \ " elseif 0",
+ \ " let x = 1",
+ \ " else",
+ \ " let x = 2",
+ \ " endif",
+ \ "endfunc",
+ \ "call Foo1()",
+ \ "call Foo2()",
+ \ "call Foo3()",
+ \ ]
+
+ call writefile(lines, 'Xprofile_func.vim')
+ call system(v:progpath
+ \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ \ . ' -c "profile start Xprofile_func.log"'
+ \ . ' -c "profile func Foo*"'
+ \ . ' -c "so Xprofile_func.vim"'
+ \ . ' -c "qall!"')
+ call assert_equal(0, v:shell_error)
+
+ let lines = readfile('Xprofile_func.log')
+
+ " - Foo1() should pass 'if' block.
+ " - Foo2() should pass 'elseif' block.
+ " - Foo3() should pass 'else' block.
+ call assert_equal(54, len(lines))
+
+ call assert_equal('FUNCTION Foo1()', lines[0])
+ call assert_equal('Called 1 time', lines[1])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
+ call assert_equal('', lines[4])
+ call assert_equal('count total (s) self (s)', lines[5])
+ call assert_match('^\s*1\s\+.*\sif 1$', lines[6])
+ call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7])
+ call assert_match( '^\s\+elseif 1$', lines[8])
+ call assert_match( '^\s\+let x = 1$', lines[9])
+ call assert_match( '^\s\+else$', lines[10])
+ call assert_match( '^\s\+let x = 2$', lines[11])
+ call assert_match('^\s*1\s\+.*\sendif$', lines[12])
+ call assert_equal('', lines[13])
+ call assert_equal('FUNCTION Foo2()', lines[14])
+ call assert_equal('Called 1 time', lines[15])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17])
+ call assert_equal('', lines[18])
+ call assert_equal('count total (s) self (s)', lines[19])
+ call assert_match('^\s*1\s\+.*\sif 0$', lines[20])
+ call assert_match( '^\s\+let x = 0$', lines[21])
+ call assert_match('^\s*1\s\+.*\selseif 1$', lines[22])
+ call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23])
+ call assert_match( '^\s\+else$', lines[24])
+ call assert_match( '^\s\+let x = 2$', lines[25])
+ call assert_match('^\s*1\s\+.*\sendif$', lines[26])
+ call assert_equal('', lines[27])
+ call assert_equal('FUNCTION Foo3()', lines[28])
+ call assert_equal('Called 1 time', lines[29])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31])
+ call assert_equal('', lines[32])
+ call assert_equal('count total (s) self (s)', lines[33])
+ call assert_match('^\s*1\s\+.*\sif 0$', lines[34])
+ call assert_match( '^\s\+let x = 0$', lines[35])
+ call assert_match('^\s*1\s\+.*\selseif 0$', lines[36])
+ call assert_match( '^\s\+let x = 1$', lines[37])
+ call assert_match('^\s*1\s\+.*\selse$', lines[38])
+ call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39])
+ call assert_match('^\s*1\s\+.*\sendif$', lines[40])
+ call assert_equal('', lines[41])
+ call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42])
+ call assert_equal('count total (s) self (s) function', lines[43])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46])
+ call assert_equal('', lines[47])
+ call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48])
+ call assert_equal('count total (s) self (s) function', lines[49])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52])
+ call assert_equal('', lines[53])
+
+ call delete('Xprofile_func.vim')
+ call delete('Xprofile_func.log')
+endfunc
+
+func Test_profile_func_with_trycatch()
+ let lines = [
+ \ "func! Foo1()",
+ \ " try",
+ \ " let x = 0",
+ \ " catch",
+ \ " let x = 1",
+ \ " finally",
+ \ " let x = 2",
+ \ " endtry",
+ \ "endfunc",
+ \ "func! Foo2()",
+ \ " try",
+ \ " throw 0",
+ \ " catch",
+ \ " let x = 1",
+ \ " finally",
+ \ " let x = 2",
+ \ " endtry",
+ \ "endfunc",
+ \ "func! Foo3()",
+ \ " try",
+ \ " throw 0",
+ \ " catch",
+ \ " throw 1",
+ \ " finally",
+ \ " let x = 2",
+ \ " endtry",
+ \ "endfunc",
+ \ "call Foo1()",
+ \ "call Foo2()",
+ \ "try",
+ \ " call Foo3()",
+ \ "catch",
+ \ "endtry",
+ \ ]
+
+ call writefile(lines, 'Xprofile_func.vim')
+ call system(v:progpath
+ \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ \ . ' -c "profile start Xprofile_func.log"'
+ \ . ' -c "profile func Foo*"'
+ \ . ' -c "so Xprofile_func.vim"'
+ \ . ' -c "qall!"')
+ call assert_equal(0, v:shell_error)
+
+ let lines = readfile('Xprofile_func.log')
+
+ " - Foo1() should pass 'try' 'finally' blocks.
+ " - Foo2() should pass 'catch' 'finally' blocks.
+ " - Foo3() should not pass 'endtry'.
+ call assert_equal(54, len(lines))
+
+ call assert_equal('FUNCTION Foo1()', lines[0])
+ call assert_equal('Called 1 time', lines[1])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
+ call assert_equal('', lines[4])
+ call assert_equal('count total (s) self (s)', lines[5])
+ call assert_match('^\s*1\s\+.*\stry$', lines[6])
+ call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7])
+ call assert_match( '^\s\+catch$', lines[8])
+ call assert_match( '^\s\+let x = 1$', lines[9])
+ call assert_match('^\s*1\s\+.*\sfinally$', lines[10])
+ call assert_match('^\s*1\s\+.*\s let x = 2$', lines[11])
+ call assert_match('^\s*1\s\+.*\sendtry$', lines[12])
+ call assert_equal('', lines[13])
+ call assert_equal('FUNCTION Foo2()', lines[14])
+ call assert_equal('Called 1 time', lines[15])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17])
+ call assert_equal('', lines[18])
+ call assert_equal('count total (s) self (s)', lines[19])
+ call assert_match('^\s*1\s\+.*\stry$', lines[20])
+ call assert_match('^\s*1\s\+.*\s throw 0$', lines[21])
+ call assert_match('^\s*1\s\+.*\scatch$', lines[22])
+ call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23])
+ call assert_match('^\s*1\s\+.*\sfinally$', lines[24])
+ call assert_match('^\s*1\s\+.*\s let x = 2$', lines[25])
+ call assert_match('^\s*1\s\+.*\sendtry$', lines[26])
+ call assert_equal('', lines[27])
+ call assert_equal('FUNCTION Foo3()', lines[28])
+ call assert_equal('Called 1 time', lines[29])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31])
+ call assert_equal('', lines[32])
+ call assert_equal('count total (s) self (s)', lines[33])
+ call assert_match('^\s*1\s\+.*\stry$', lines[34])
+ call assert_match('^\s*1\s\+.*\s throw 0$', lines[35])
+ call assert_match('^\s*1\s\+.*\scatch$', lines[36])
+ call assert_match('^\s*1\s\+.*\s throw 1$', lines[37])
+ call assert_match('^\s*1\s\+.*\sfinally$', lines[38])
+ call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39])
+ call assert_match( '^\s\+endtry$', lines[40])
+ call assert_equal('', lines[41])
+ call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42])
+ call assert_equal('count total (s) self (s) function', lines[43])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46])
+ call assert_equal('', lines[47])
+ call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48])
+ call assert_equal('count total (s) self (s) function', lines[49])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52])
+ call assert_equal('', lines[53])
+
+ call delete('Xprofile_func.vim')
+ call delete('Xprofile_func.log')
+endfunc
+
func Test_profile_file()
let lines = [
\ 'func! Foo()',
@@ -123,7 +344,7 @@ func Test_profile_file()
call assert_equal(' " a comment', lines[9])
" if self and total are equal we only get one number
call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10])
- call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$', lines[11])
+ call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$', lines[11])
" if self and total are equal we only get one number
call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
call assert_equal('', lines[13])
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index d41815f..6063fd6 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -3091,6 +3091,20 @@ func Test_qf_tick()
call Xqftick_tests('l')
endfunc
+" Test helpgrep with lang specifier
+func Xtest_helpgrep_with_lang_specifier(cchar)
+ call s:setup_commands(a:cchar)
+ Xhelpgrep Vim@en
+ call assert_equal('help', &filetype)
+ call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
+ new | only
+endfunc
+
+func Test_helpgrep_with_lang_specifier()
+ call Xtest_helpgrep_with_lang_specifier('c')
+ call Xtest_helpgrep_with_lang_specifier('l')
+endfunc
+
" The following test used to crash Vim.
" Open the location list window and close the regular window associated with
" the location list. When the garbage collection runs now, it incorrectly
@@ -3478,6 +3492,30 @@ func Xautocmd_changelist(cchar)
call assert_equal(5, line('.'))
autocmd! QuickFixCmdPost
+ " Test for autocommands clearing the quickfix list before jumping to the
+ " first error. This should not result in an error
+ autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
+ let v:errmsg = ''
+ " Test for cfile/lfile
+ Xfile Xerr
+ call assert_true(v:errmsg !~# 'E42:')
+ " Test for cbuffer/lbuffer
+ edit Xerr
+ Xbuffer
+ call assert_true(v:errmsg !~# 'E42:')
+ " Test for cexpr/lexpr
+ Xexpr 'Xtestfile2:4:Line4'
+ call assert_true(v:errmsg !~# 'E42:')
+ " Test for grep/lgrep
+ " The grepprg may not be set on non-Unix systems
+ if has('unix')
+ silent Xgrep Line5 Xtestfile2
+ call assert_true(v:errmsg !~# 'E42:')
+ endif
+ " Test for vimgrep/lvimgrep
+ call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
+ autocmd! QuickFixCmdPost
+
call delete('Xerr')
call delete('Xtestfile1')
call delete('Xtestfile2')
@@ -3522,3 +3560,12 @@ func Test_view_result_split()
call Xview_result_split_tests('c')
call Xview_result_split_tests('l')
endfunc
+
+" Test that :cc sets curswant
+func Test_curswant()
+ helpgrep quickfix
+ normal! llll
+ 1cc
+ call assert_equal(getcurpos()[4], virtcol('.'))
+ cclose | helpclose
+endfunc
diff --git a/src/testdir/test_ruby.vim b/src/testdir/test_ruby.vim
index 8d7943e..5476e51 100644
--- a/src/testdir/test_ruby.vim
+++ b/src/testdir/test_ruby.vim
@@ -363,4 +363,17 @@ func Test_p()
ruby p 'Just a test'
let messages = split(execute('message'), "\n")
call assert_equal('"Just a test"', messages[-1])
+
+ " Check return values of p method
+
+ call assert_equal('123', RubyEval('p(123)'))
+ call assert_equal('[1, 2, 3]', RubyEval('p(1, 2, 3)'))
+
+ " Avoid the "message maintainer" line.
+ let $LANG = ''
+ messages clear
+ call assert_equal('true', RubyEval('p() == nil'))
+
+ let messages = split(execute('message'), "\n")
+ call assert_equal(0, len(messages))
endfunc
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index 28f0463..ba2d21a 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -342,24 +342,98 @@ func Test_searchc()
bw!
endfunc
-func Test_search_cmdline3()
- if !exists('+incsearch')
- return
- endif
+func Cmdline3_prep()
" need to disable char_avail,
" so that expansion of commandline works
call test_override("char_avail", 1)
new
call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
set incsearch
+endfunc
+
+func Incsearch_cleanup()
+ set noincsearch
+ call test_override("char_avail", 0)
+ bw!
+endfunc
+
+func Test_search_cmdline3()
+ if !exists('+incsearch')
+ return
+ endif
+ call Cmdline3_prep()
1
" first match
call feedkeys("/the\<c-l>\<cr>", 'tx')
call assert_equal(' 2 the~e', getline('.'))
- " clean up
- set noincsearch
- call test_override("char_avail", 0)
- bw!
+
+ call Incsearch_cleanup()
+endfunc
+
+func Test_search_cmdline3s()
+ if !exists('+incsearch')
+ return
+ endif
+ call Cmdline3_prep()
+ 1
+ call feedkeys(":%s/the\<c-l>/xxx\<cr>", 'tx')
+ call assert_equal(' 2 xxxe', getline('.'))
+ undo
+ call feedkeys(":%subs/the\<c-l>/xxx\<cr>", 'tx')
+ call assert_equal(' 2 xxxe', getline('.'))
+ undo
+ call feedkeys(":%substitute/the\<c-l>/xxx\<cr>", 'tx')
+ call assert_equal(' 2 xxxe', getline('.'))
+ undo
+ call feedkeys(":%smagic/the.e/xxx\<cr>", 'tx')
+ call assert_equal(' 2 xxx', getline('.'))
+ undo
+ call assert_fails(":%snomagic/the.e/xxx\<cr>", 'E486')
+ "
+ call feedkeys(":%snomagic/the\\.e/xxx\<cr>", 'tx')
+ call assert_equal(' 2 xxx', getline('.'))
+
+ call Incsearch_cleanup()
+endfunc
+
+func Test_search_cmdline3g()
+ if !exists('+incsearch')
+ return
+ endif
+ call Cmdline3_prep()
+ 1
+ call feedkeys(":g/the\<c-l>/d\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline(2))
+ undo
+ call feedkeys(":global/the\<c-l>/d\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline(2))
+ undo
+ call feedkeys(":g!/the\<c-l>/d\<cr>", 'tx')
+ call assert_equal(1, line('$'))
+ call assert_equal(' 2 the~e', getline(1))
+ undo
+ call feedkeys(":global!/the\<c-l>/d\<cr>", 'tx')
+ call assert_equal(1, line('$'))
+ call assert_equal(' 2 the~e', getline(1))
+
+ call Incsearch_cleanup()
+endfunc
+
+func Test_search_cmdline3v()
+ if !exists('+incsearch')
+ return
+ endif
+ call Cmdline3_prep()
+ 1
+ call feedkeys(":v/the\<c-l>/d\<cr>", 'tx')
+ call assert_equal(1, line('$'))
+ call assert_equal(' 2 the~e', getline(1))
+ undo
+ call feedkeys(":vglobal/the\<c-l>/d\<cr>", 'tx')
+ call assert_equal(1, line('$'))
+ call assert_equal(' 2 the~e', getline(1))
+
+ call Incsearch_cleanup()
endfunc
func Test_search_cmdline4()
@@ -466,7 +540,7 @@ func Test_search_cmdline7()
" so that expansion of commandline works
call test_override("char_avail", 1)
new
- let @/='b'
+ let @/ = 'b'
call setline(1, [' bbvimb', ''])
set incsearch
" first match
@@ -739,6 +813,192 @@ func Test_incsearch_scrolling()
call delete('Xscript')
endfunc
+func Test_incsearch_substitute()
+ if !exists('+incsearch')
+ return
+ endif
+ call test_override("char_avail", 1)
+ new
+ set incsearch
+ for n in range(1, 10)
+ call setline(n, 'foo ' . n)
+ endfor
+ 4
+ call feedkeys(":.,.+2s/foo\<BS>o\<BS>o/xxx\<cr>", 'tx')
+ call assert_equal('foo 3', getline(3))
+ call assert_equal('xxx 4', getline(4))
+ call assert_equal('xxx 5', getline(5))
+ call assert_equal('xxx 6', getline(6))
+ call assert_equal('foo 7', getline(7))
+
+ call Incsearch_cleanup()
+endfunc
+
+" Similar to Test_incsearch_substitute() but with a screendump halfway.
+func Test_incsearch_substitute_dump()
+ if !exists('+incsearch')
+ return
+ endif
+ if !CanRunVimInTerminal()
+ return
+ endif
+ call writefile([
+ \ 'set incsearch hlsearch scrolloff=0',
+ \ 'for n in range(1, 10)',
+ \ ' call setline(n, "foo " . n)',
+ \ 'endfor',
+ \ 'call setline(11, "bar 11")',
+ \ '3',
+ \ ], 'Xis_subst_script')
+ let buf = RunVimInTerminal('-S Xis_subst_script', {'rows': 9, 'cols': 70})
+ " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
+ " the 'ambiwidth' check.
+ sleep 100m
+
+ " Need to send one key at a time to force a redraw.
+ " Select three lines at the cursor with typed pattern.
+ call term_sendkeys(buf, ':.,.+2s/')
+ sleep 100m
+ call term_sendkeys(buf, 'f')
+ sleep 100m
+ call term_sendkeys(buf, 'o')
+ sleep 100m
+ call term_sendkeys(buf, 'o')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_01', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Select three lines at the cursor using previous pattern.
+ call term_sendkeys(buf, "/foo\<CR>")
+ sleep 100m
+ call term_sendkeys(buf, ':.,.+2s//')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_02', {})
+
+ " Deleting last slash should remove the match.
+ call term_sendkeys(buf, "\<BS>")
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_03', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Reverse range is accepted
+ call term_sendkeys(buf, ':5,2s/foo')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_04', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " White space after the command is skipped
+ call term_sendkeys(buf, ':2,3sub /fo')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Command modifiers are skipped
+ call term_sendkeys(buf, ':above below browse botr confirm keepmar keepalt keeppat keepjum filter xxx hide lockm leftabove noau noswap rightbel sandbox silent silent! $tab top unsil vert verbose 4,5s/fo.')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Cursorline highlighting at match
+ call term_sendkeys(buf, ":set cursorline\<CR>")
+ call term_sendkeys(buf, 'G9G')
+ call term_sendkeys(buf, ':9,11s/bar')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_07', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Cursorline highlighting at cursor when no match
+ call term_sendkeys(buf, ':9,10s/bar')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_08', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ " Only \v handled as empty pattern, does not move cursor
+ call term_sendkeys(buf, '3G4G')
+ call term_sendkeys(buf, ":nohlsearch\<CR>")
+ call term_sendkeys(buf, ':6,7s/\v')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_substitute_09', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call StopVimInTerminal(buf)
+ call delete('Xis_subst_script')
+endfunc
+
+" Similar to Test_incsearch_substitute_dump() for :sort
+func Test_incsearch_ssort_dump()
+ if !exists('+incsearch')
+ return
+ endif
+ if !CanRunVimInTerminal()
+ return
+ endif
+ call writefile([
+ \ 'set incsearch hlsearch scrolloff=0',
+ \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
+ \ ], 'Xis_sort_script')
+ let buf = RunVimInTerminal('-S Xis_sort_script', {'rows': 9, 'cols': 70})
+ " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
+ " the 'ambiwidth' check.
+ sleep 100m
+
+ " Need to send one key at a time to force a redraw.
+ call term_sendkeys(buf, ':sort ni u /on')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_sort_01', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call StopVimInTerminal(buf)
+ call delete('Xis_sort_script')
+endfunc
+
+" Similar to Test_incsearch_substitute_dump() for :vimgrep famiry
+func Test_incsearch_vimgrep_dump()
+ if !exists('+incsearch')
+ return
+ endif
+ if !CanRunVimInTerminal()
+ return
+ endif
+ call writefile([
+ \ 'set incsearch hlsearch scrolloff=0',
+ \ 'call setline(1, ["another one 2", "that one 3", "the one 1"])',
+ \ ], 'Xis_vimgrep_script')
+ let buf = RunVimInTerminal('-S Xis_vimgrep_script', {'rows': 9, 'cols': 70})
+ " Give Vim a chance to redraw to get rid of the spaces in line 2 caused by
+ " the 'ambiwidth' check.
+ sleep 100m
+
+ " Need to send one key at a time to force a redraw.
+ call term_sendkeys(buf, ':vimgrep on')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_01', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call term_sendkeys(buf, ':vimg /on/ *.txt')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_02', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call term_sendkeys(buf, ':vimgrepadd "\<on')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_03', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call term_sendkeys(buf, ':lv "tha')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_04', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call term_sendkeys(buf, ':lvimgrepa "the" **/*.txt')
+ sleep 100m
+ call VerifyScreenDump(buf, 'Test_incsearch_vimgrep_05', {})
+ call term_sendkeys(buf, "\<Esc>")
+
+ call StopVimInTerminal(buf)
+ call delete('Xis_vimgrep_script')
+endfunc
+
func Test_search_undefined_behaviour()
if !has("terminal")
return
diff --git a/src/testdir/test_stat.vim b/src/testdir/test_stat.vim
index 307cf5e..33509f0 100644
--- a/src/testdir/test_stat.vim
+++ b/src/testdir/test_stat.vim
@@ -122,6 +122,53 @@ func Test_nonexistent_file()
call assert_equal('', getfperm(fname))
endfunc
+func Test_getftype()
+ call assert_equal('file', getftype(v:progpath))
+ call assert_equal('dir', getftype('.'))
+
+ if !has('unix')
+ return
+ endif
+
+ silent !ln -s Xfile Xlink
+ call assert_equal('link', getftype('Xlink'))
+ call delete('Xlink')
+
+ if executable('mkfifo')
+ silent !mkfifo Xfifo
+ call assert_equal('fifo', getftype('Xfifo'))
+ call delete('Xfifo')
+ endif
+
+ for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null')
+ let type = getftype(cdevfile)
+ " ignore empty result, can happen if the file disappeared
+ if type != ''
+ call assert_equal('cdev', type)
+ endif
+ endfor
+
+ for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null')
+ let type = getftype(bdevfile)
+ " ignore empty result, can happen if the file disappeared
+ if type != ''
+ call assert_equal('bdev', type)
+ endif
+ endfor
+
+ " The /run/ directory typically contains socket files.
+ " If it does not, test won't fail but will not test socket files.
+ for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null')
+ let type = getftype(socketfile)
+ " ignore empty result, can happen if the file disappeared
+ if type != ''
+ call assert_equal('socket', type)
+ endif
+ endfor
+
+ " TODO: file type 'other' is not tested. How can we test it?
+endfunc
+
func Test_win32_symlink_dir()
" On Windows, non-admin users cannot create symlinks.
" So we use an existing symlink for this test.
diff --git a/src/testdir/test_swap.vim b/src/testdir/test_swap.vim
index da5da2d..ca4d8c2 100644
--- a/src/testdir/test_swap.vim
+++ b/src/testdir/test_swap.vim
@@ -97,3 +97,42 @@ func Test_missing_dir()
set directory&
call delete('Xswapdir', 'rf')
endfunc
+
+func Test_swapinfo()
+ new Xswapinfo
+ call setline(1, ['one', 'two', 'three'])
+ w
+ let fname = trim(execute('swapname'))
+ call assert_match('Xswapinfo', fname)
+ let info = swapinfo(fname)
+
+ let ver = printf('VIM %d.%d', v:version / 100, v:version % 100)
+ call assert_equal(ver, info.version)
+
+ call assert_match('\w', info.user)
+ " host name is truncated to 39 bytes in the swap file
+ call assert_equal(hostname()[:38], info.host)
+ call assert_match('Xswapinfo', info.fname)
+ call assert_match(0, info.dirty)
+ call assert_equal(getpid(), info.pid)
+ call assert_match('^\d*$', info.mtime)
+ if has_key(info, 'inode')
+ call assert_match('\d', info.inode)
+ endif
+ bwipe!
+ call delete(fname)
+ call delete('Xswapinfo')
+
+ let info = swapinfo('doesnotexist')
+ call assert_equal('Cannot open file', info.error)
+
+ call writefile(['burp'], 'Xnotaswapfile')
+ let info = swapinfo('Xnotaswapfile')
+ call assert_equal('Cannot read file', info.error)
+ call delete('Xnotaswapfile')
+
+ call writefile([repeat('x', 10000)], 'Xnotaswapfile')
+ let info = swapinfo('Xnotaswapfile')
+ call assert_equal('Not a swap file', info.error)
+ call delete('Xnotaswapfile')
+endfunc
diff --git a/src/testdir/test_tabpage.vim b/src/testdir/test_tabpage.vim
index f4fbf28..add9b3d 100644
--- a/src/testdir/test_tabpage.vim
+++ b/src/testdir/test_tabpage.vim
@@ -105,6 +105,19 @@ function Test_tabpage()
call assert_equal(4, tabpagenr())
7tabmove 5
call assert_equal(5, tabpagenr())
+
+ " The following are a no-op
+ norm! 2gt
+ call assert_equal(2, tabpagenr())
+ tabmove 2
+ call assert_equal(2, tabpagenr())
+ 2tabmove
+ call assert_equal(2, tabpagenr())
+ tabmove 1
+ call assert_equal(2, tabpagenr())
+ 1tabmove
+ call assert_equal(2, tabpagenr())
+
call assert_fails("99tabmove", 'E16:')
call assert_fails("+99tabmove", 'E16:')
call assert_fails("-99tabmove", 'E16:')
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index 7ab0cf8..b82dae1 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -1605,3 +1605,31 @@ func Test_zz2_terminal_guioptions_bang()
set guioptions&
call delete(filename)
endfunc
+
+func Test_terminal_hidden()
+ if !has('unix')
+ return
+ endif
+ term ++hidden cat
+ let bnr = bufnr('$')
+ call assert_equal('terminal', getbufvar(bnr, '&buftype'))
+ exe 'sbuf ' . bnr
+ call assert_equal('terminal', &buftype)
+ call term_sendkeys(bnr, "asdf\<CR>")
+ call WaitForAssert({-> assert_match('asdf', term_getline(bnr, 2))})
+ call term_sendkeys(bnr, "\<C-D>")
+ call WaitForAssert({-> assert_equal('finished', term_getstatus(bnr))})
+ bwipe!
+endfunc
+
+func Test_terminal_hidden_and_close()
+ if !has('unix')
+ return
+ endif
+ call assert_equal(1, winnr('$'))
+ term ++hidden ++close ls
+ let bnr = bufnr('$')
+ call assert_equal('terminal', getbufvar(bnr, '&buftype'))
+ call WaitForAssert({-> assert_false(bufexists(bnr))})
+ call assert_equal(1, winnr('$'))
+endfunc
diff --git a/src/testdir/test_textobjects.vim b/src/testdir/test_textobjects.vim
index f02619f..6a2f504 100644
--- a/src/testdir/test_textobjects.vim
+++ b/src/testdir/test_textobjects.vim
@@ -121,6 +121,23 @@ func Test_string_html_objects()
enew!
endfunc
+func Test_empty_html_tag()
+ new
+ call setline(1, '<div></div>')
+ normal 0citxxx
+ call assert_equal('<div>xxx</div>', getline(1))
+
+ call setline(1, '<div></div>')
+ normal 0f<cityyy
+ call assert_equal('<div>yyy</div>', getline(1))
+
+ call setline(1, '<div></div>')
+ normal 0f<vitsaaa
+ call assert_equal('aaa', getline(1))
+
+ bwipe!
+endfunc
+
" Tests for match() and matchstr()
func Test_match()
call assert_equal("b", matchstr("abcd", ".", 0, 2))
diff --git a/src/testdir/test_window_id.vim b/src/testdir/test_window_id.vim
index b3b506d..d10d831 100644
--- a/src/testdir/test_window_id.vim
+++ b/src/testdir/test_window_id.vim
@@ -101,3 +101,23 @@ func Test_win_getid_curtab()
call assert_equal(win_getid(1), win_getid(1, 1))
tabclose!
endfunc
+
+func Test_winlayout()
+ let w1 = win_getid()
+ call assert_equal(['leaf', w1], winlayout())
+
+ split
+ let w2 = win_getid()
+ call assert_equal(['col', [['leaf', w2], ['leaf', w1]]], winlayout())
+
+ split
+ let w3 = win_getid()
+ call assert_equal(['col', [['leaf', w3], ['leaf', w2], ['leaf', w1]]], winlayout())
+
+ 2wincmd w
+ vsplit
+ let w4 = win_getid()
+ call assert_equal(['col', [['leaf', w3], ['row', [['leaf', w4], ['leaf', w2]]], ['leaf', w1]]], winlayout())
+
+ only!
+endfunc
diff --git a/src/undo.c b/src/undo.c
index 040ec54..ebf18da 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -3124,8 +3124,13 @@ u_add_time(char_u *buf, size_t buflen, time_t tt)
}
else
#endif
- vim_snprintf((char *)buf, buflen, _("%ld seconds ago"),
- (long)(vim_time() - tt));
+ {
+ long seconds = (long)(vim_time() - tt);
+
+ vim_snprintf((char *)buf, buflen,
+ NGETTEXT("%ld second ago", "%ld seconds ago", seconds),
+ seconds);
+ }
}
/*
diff --git a/src/version.c b/src/version.c
index 5f7d908..d31f9e0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -795,6 +795,188 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 320,
+/**/
+ 319,
+/**/
+ 318,
+/**/
+ 317,
+/**/
+ 316,
+/**/
+ 315,
+/**/
+ 314,
+/**/
+ 313,
+/**/
+ 312,
+/**/
+ 311,
+/**/
+ 310,
+/**/
+ 309,
+/**/
+ 308,
+/**/
+ 307,
+/**/
+ 306,
+/**/
+ 305,
+/**/
+ 304,
+/**/
+ 303,
+/**/
+ 302,
+/**/
+ 301,
+/**/
+ 300,
+/**/
+ 299,
+/**/
+ 298,
+/**/
+ 297,
+/**/
+ 296,
+/**/
+ 295,
+/**/
+ 294,
+/**/
+ 293,
+/**/
+ 292,
+/**/
+ 291,
+/**/
+ 290,
+/**/
+ 289,
+/**/
+ 288,
+/**/
+ 287,
+/**/
+ 286,
+/**/
+ 285,
+/**/
+ 284,
+/**/
+ 283,
+/**/
+ 282,
+/**/
+ 281,
+/**/
+ 280,
+/**/
+ 279,
+/**/
+ 278,
+/**/
+ 277,
+/**/
+ 276,
+/**/
+ 275,
+/**/
+ 274,
+/**/
+ 273,
+/**/
+ 272,
+/**/
+ 271,
+/**/
+ 270,
+/**/
+ 269,
+/**/
+ 268,
+/**/
+ 267,
+/**/
+ 266,
+/**/
+ 265,
+/**/
+ 264,
+/**/
+ 263,
+/**/
+ 262,
+/**/
+ 261,
+/**/
+ 260,
+/**/
+ 259,
+/**/
+ 258,
+/**/
+ 257,
+/**/
+ 256,
+/**/
+ 255,
+/**/
+ 254,
+/**/
+ 253,
+/**/
+ 252,
+/**/
+ 251,
+/**/
+ 250,
+/**/
+ 249,
+/**/
+ 248,
+/**/
+ 247,
+/**/
+ 246,
+/**/
+ 245,
+/**/
+ 244,
+/**/
+ 243,
+/**/
+ 242,
+/**/
+ 241,
+/**/
+ 240,
+/**/
+ 239,
+/**/
+ 238,
+/**/
+ 237,
+/**/
+ 236,
+/**/
+ 235,
+/**/
+ 234,
+/**/
+ 233,
+/**/
+ 232,
+/**/
+ 231,
+/**/
+ 230,
+/**/
229,
/**/
228,
diff --git a/src/vim.h b/src/vim.h
index a85d47f..ece5414 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -553,6 +553,10 @@ extern int (*dyn_libintl_putenv)(const char *envstring);
/*
* The _() stuff is for using gettext(). It is a no-op when libintl.h is not
* found or the +multilang feature is disabled.
+ * Use NGETTEXT(single, multi, number) to get plural behavior:
+ * - single - message for singular form
+ * - multi - message for plural form
+ * - number - the count
*/
#ifdef FEAT_GETTEXT
# ifdef DYNAMIC_GETTEXT
@@ -2290,15 +2294,6 @@ typedef enum {
#endif
-/* ISSYMLINK(mode) tests if a file is a symbolic link. */
-#if (defined(S_IFMT) && defined(S_IFLNK)) || defined(S_ISLNK)
-# define HAVE_ISSYMLINK
-# if defined(S_IFMT) && defined(S_IFLNK)
-# define ISSYMLINK(mode) (((mode) & S_IFMT) == S_IFLNK)
-# else
-# define ISSYMLINK(mode) S_ISLNK(mode)
-# endif
-#endif
#define SIGN_BYTE 1 /* byte value used where sign is displayed;
attribute value is sign type */
@@ -2517,10 +2512,61 @@ typedef enum {
/* BSD is supposed to cover FreeBSD and similar systems. */
#if (defined(SUN_SYSTEM) || defined(BSD) || defined(__FreeBSD_kernel__)) \
- && defined(S_ISCHR)
+ && (defined(S_ISCHR) || defined(S_IFCHR))
# define OPEN_CHR_FILES
#endif
+/* stat macros */
+#ifndef S_ISDIR
+# ifdef S_IFDIR
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# else
+# define S_ISDIR(m) 0
+# endif
+#endif
+#ifndef S_ISREG
+# ifdef S_IFREG
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# else
+# define S_ISREG(m) 0
+# endif
+#endif
+#ifndef S_ISBLK
+# ifdef S_IFBLK
+# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+# else
+# define S_ISBLK(m) 0
+# endif
+#endif
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+#endif
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) 0
+# endif
+#endif
+#ifndef S_ISCHR
+# ifdef S_IFCHR
+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+# else
+# define S_ISCHR(m) 0
+# endif
+#endif
+#ifndef S_ISLNK
+# ifdef S_IFLNK
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# else
+# define S_ISLNK(m) 0
+# endif
+#endif
+
#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
# define ELAPSED_TIMEVAL
# define ELAPSED_INIT(v) gettimeofday(&v, NULL)
@@ -2548,4 +2594,9 @@ typedef enum {
#define TERM_START_FORCEIT 2
#define TERM_START_SYSTEM 4
+// Used for icon/title save and restore.
+#define SAVE_RESTORE_TITLE 1
+#define SAVE_RESTORE_ICON 2
+#define SAVE_RESTORE_BOTH (SAVE_RESTORE_TITLE | SAVE_RESTORE_ICON)
+
#endif /* VIM__H */
diff --git a/src/window.c b/src/window.c
index e1781d3..5671cf9 100644
--- a/src/window.c
+++ b/src/window.c
@@ -7236,4 +7236,53 @@ win_findbuf(typval_T *argvars, list_T *list)
list_append_number(list, wp->w_id);
}
+/*
+ * Get the layout of the given tab page for winlayout().
+ */
+ void
+get_framelayout(frame_T *fr, list_T *l, int outer)
+{
+ frame_T *child;
+ list_T *fr_list;
+ list_T *win_list;
+
+ if (fr == NULL)
+ return;
+
+ if (outer)
+ // outermost call from f_winlayout()
+ fr_list = l;
+ else
+ {
+ fr_list = list_alloc();
+ if (fr_list == NULL)
+ return;
+ list_append_list(l, fr_list);
+ }
+
+ if (fr->fr_layout == FR_LEAF)
+ {
+ if (fr->fr_win != NULL)
+ {
+ list_append_string(fr_list, (char_u *)"leaf", -1);
+ list_append_number(fr_list, fr->fr_win->w_id);
+ }
+ }
+ else
+ {
+ list_append_string(fr_list,
+ fr->fr_layout == FR_ROW ? (char_u *)"row" : (char_u *)"col", -1);
+
+ win_list = list_alloc();
+ if (win_list == NULL)
+ return;
+ list_append_list(fr_list, win_list);
+ child = fr->fr_child;
+ while (child != NULL)
+ {
+ get_framelayout(child, win_list, FALSE);
+ child = child->fr_next;
+ }
+ }
+}
#endif