aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rwxr-xr-xci/before_install.sh5
-rw-r--r--ci/build.ps114
-rw-r--r--ci/common/test.sh3
-rw-r--r--runtime/doc/autocmd.txt19
-rw-r--r--runtime/doc/eval.txt256
-rw-r--r--runtime/makemenu.vim35
-rw-r--r--runtime/synmenu.vim774
-rw-r--r--runtime/syntax/upstreamrpt.vim2
-rwxr-xr-xsrc/clint.py14
-rw-r--r--src/nvim/README.md4
-rw-r--r--src/nvim/api/vim.c62
-rw-r--r--src/nvim/context.c383
-rw-r--r--src/nvim/context.h46
-rw-r--r--src/nvim/diff.c2
-rw-r--r--src/nvim/edit.c51
-rw-r--r--src/nvim/eval.c267
-rw-r--r--src/nvim/eval.h7
-rw-r--r--src/nvim/eval.lua5
-rw-r--r--src/nvim/eval/executor.c4
-rw-r--r--src/nvim/ex_cmds2.c17
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/ex_getln.c53
-rw-r--r--src/nvim/fileio.c10
-rw-r--r--src/nvim/getchar.c189
-rw-r--r--src/nvim/macros.h3
-rw-r--r--src/nvim/mark.c4
-rw-r--r--src/nvim/memory.c2
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/ops.c82
-rw-r--r--src/nvim/option.c6
-rw-r--r--src/nvim/popupmnu.c3
-rw-r--r--src/nvim/quickfix.c9
-rw-r--r--src/nvim/regexp.c4
-rw-r--r--src/nvim/screen.c1
-rw-r--r--src/nvim/search.c12
-rw-r--r--src/nvim/shada.c316
-rw-r--r--src/nvim/shada.h11
-rw-r--r--src/nvim/sign.c6
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/testdir/test_arglist.vim19
-rw-r--r--src/nvim/testdir/test_cmdline.vim12
-rw-r--r--src/nvim/testdir/test_getvar.vim44
-rw-r--r--src/nvim/testdir/test_maparg.vim4
-rw-r--r--src/nvim/testdir/test_partial.vim5
-rw-r--r--src/nvim/testdir/test_popup.vim34
-rw-r--r--src/nvim/testdir/test_vimscript.vim39
-rw-r--r--src/nvim/ui_compositor.c2
-rw-r--r--src/nvim/version.c13
-rw-r--r--src/nvim/viml/parser/expressions.c2
-rw-r--r--test/functional/api/keymap_spec.lua5
-rw-r--r--test/functional/api/vim_spec.lua60
-rw-r--r--test/functional/autocmd/textyankpost_spec.lua5
-rw-r--r--test/functional/eval/ctx_functions_spec.lua408
-rw-r--r--test/functional/helpers.lua19
-rw-r--r--test/includes/pre/uv.h4
-rw-r--r--test/unit/os/fs_spec.lua4
57 files changed, 2485 insertions, 887 deletions
diff --git a/.travis.yml b/.travis.yml
index 5e29166d0f..1f4b83c184 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -125,12 +125,6 @@ jobs:
osx_image: xcode10.2 # macOS 10.14
env:
- *common-job-env
- - name: "macOS: gcc"
- os: osx
- compiler: gcc
- osx_image: xcode10.2 # macOS 10.14
- env:
- - *common-job-env
- name: gcc-coverage (gcc 9)
os: linux
diff --git a/ci/before_install.sh b/ci/before_install.sh
index 774c66d38f..5cb6894b8c 100755
--- a/ci/before_install.sh
+++ b/ci/before_install.sh
@@ -16,13 +16,16 @@ echo 'Python info:'
pip3 --version
pip2 --version
pip --version
+
+ pyenv --version
pyenv versions
) 2>&1 | sed 's/^/ /' || true
# Use pyenv, but not for OSX on Travis, where it only has the "system" version.
if [[ "${TRAVIS_OS_NAME}" != osx ]] && command -v pyenv; then
echo 'Setting Python versions via pyenv'
- # Prefer python2 as python for /usr/bin/asan_symbolize-4.0.
+
+ # Prefer Python 2 over 3 (more conservative).
pyenv global 2.7.15:3.7
echo 'Updated Python info:'
diff --git a/ci/build.ps1 b/ci/build.ps1
index 5f0f0de218..da1ad2f4b6 100644
--- a/ci/build.ps1
+++ b/ci/build.ps1
@@ -14,9 +14,11 @@ $depsCmakeVars = @{
$nvimCmakeVars = @{
CMAKE_BUILD_TYPE = $cmakeBuildType;
BUSTED_OUTPUT_TYPE = 'nvim';
- DEPS_BUILD_DIR=$(if ($env:DEPS_BUILD_DIR -ne $null) {$env:DEPS_BUILD_DIR} else {".deps"});
DEPS_PREFIX=$(if ($env:DEPS_PREFIX -ne $null) {$env:DEPS_PREFIX} else {".deps/usr"});
}
+if ($env:DEPS_BUILD_DIR -eq $null) {
+ $env:DEPS_BUILD_DIR = ".deps";
+}
$uploadToCodeCov = $false
function exitIfFailed() {
@@ -26,11 +28,11 @@ function exitIfFailed() {
}
}
-if (-Not (Test-Path -PathType container $nvimCmakeVars["DEPS_BUILD_DIR"])) {
- write-host "cache dir not found: $($nvimCmakeVars['DEPS_BUILD_DIR'])"
- mkdir $nvimCmakeVars["DEPS_BUILD_DIR"]
+if (-Not (Test-Path -PathType container $env:DEPS_BUILD_DIR)) {
+ write-host "cache dir not found: $($env:DEPS_BUILD_DIR)"
+ mkdir $env:DEPS_BUILD_DIR
} else {
- write-host "cache dir $($nvimCmakeVars['DEPS_BUILD_DIR']) size: $(Get-ChildItem $nvimCmakeVars['DEPS_BUILD_DIR'] -recurse | Measure-Object -property length -sum | Select -expand sum)"
+ write-host "cache dir $($env:DEPS_BUILD_DIR) size: $(Get-ChildItem $env:DEPS_BUILD_DIR -recurse | Measure-Object -property length -sum | Select -expand sum)"
}
if ($compiler -eq 'MINGW') {
@@ -96,7 +98,7 @@ function convertToCmakeArgs($vars) {
return $vars.GetEnumerator() | foreach { "-D$($_.Key)=$($_.Value)" }
}
-cd $nvimCmakeVars["DEPS_BUILD_DIR"]
+cd $env:DEPS_BUILD_DIR
cmake -G $cmakeGenerator $(convertToCmakeArgs($depsCmakeVars)) "$buildDir/third-party/" ; exitIfFailed
cmake --build . --config $cmakeBuildType -- $cmakeGeneratorArgs ; exitIfFailed
cd $buildDir
diff --git a/ci/common/test.sh b/ci/common/test.sh
index c184064236..fb2dcc077e 100644
--- a/ci/common/test.sh
+++ b/ci/common/test.sh
@@ -69,6 +69,7 @@ check_logs() {
for log in $(find "${1}" -type f -name "${2}" -size +0); do
cat "${log}"
err=1
+ rm "${log}"
done
if test -n "${err}" ; then
fail 'logs' E 'Runtime errors detected.'
@@ -81,7 +82,7 @@ valgrind_check() {
asan_check() {
if test "${CLANG_SANITIZER}" = "ASAN_UBSAN" ; then
- check_logs "${1}" "*san.*" | asan_symbolize
+ check_logs "${1}" "*san.*"
fi
}
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 461167015d..a3f13034a8 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -590,18 +590,19 @@ CompleteDone After Insert mode completion is done. Either
completed item.
CompleteChanged *CompleteChanged*
- After each time popup menu changed, not fired
- on popup menu hide, use |CompleteDone| for popup
- menu hide.
+ After each time the Insert mode completion
+ menu changed. Not fired on popup menu hide,
+ use |CompleteDone| for that. Never triggered
+ recursively.
Sets these |v:event| keys:
completed_item
- height
- width
- row
- col
- size
- scrollbar
+ height nr of items visible
+ width screen cells
+ row top screen row
+ col leftmost screen column
+ size total nr of items
+ scrollbar TRUE if visible
It is not allowed to change the text |textlock|.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 01bd2a0c65..752e368925 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -95,7 +95,7 @@ A List, Dictionary or Float is not a Number or String, thus evaluate to FALSE.
List, Dictionary and Funcref types are not automatically converted.
*E805* *E806* *E808*
-When mixing Number and Float the Number is converted to Float. Otherwise
+When mixing Number and Float the Number is converted to Float. Otherwise
there is no automatic conversion of Float. You can use str2float() for String
to Float, printf() for Float to String and float2nr() for Float to Number.
@@ -104,13 +104,14 @@ When expecting a Float a Number can also be used, but nothing else.
*no-type-checking*
You will not get an error if you try to change the type of a variable.
-
+
+
1.2 Function references ~
*Funcref* *E695* *E718*
-A Funcref variable is obtained with the |function()| function or created with
-the lambda expression |expr-lambda|. It can be used in an expression in the
-place of a function name, before the parenthesis around the arguments, to
-invoke the function it refers to. Example: >
+A Funcref variable is obtained with the |function()| function, the |funcref()|
+function or created with the lambda expression |expr-lambda|. It can be used
+in an expression in the place of a function name, before the parenthesis
+around the arguments, to invoke the function it refers to. Example: >
:let Fn = function("MyFunc")
:echo Fn()
@@ -142,8 +143,8 @@ arguments: >
*Partial*
A Funcref optionally binds a Dictionary and/or arguments. This is also called
a Partial. This is created by passing the Dictionary and/or arguments to
-function(). When calling the function the Dictionary and/or arguments will be
-passed to the function. Example: >
+function() or funcref(). When calling the function the Dictionary and/or
+arguments will be passed to the function. Example: >
let Cb = function('Callback', ['foo'], myDict)
call Cb()
@@ -177,7 +178,7 @@ Here "self" will be "myDict", because it was bound explicitly.
1.3 Lists ~
*list* *List* *Lists* *E686*
A List is an ordered sequence of items. An item can be of any type. Items
-can be accessed by their index number. Items can be added and removed at any
+can be accessed by their index number. Items can be added and removed at any
position in the sequence.
@@ -188,7 +189,7 @@ Examples: >
:let mylist = [1, two, 3, "four"]
:let emptylist = []
-An item can be any expression. Using a List for an item creates a
+An item can be any expression. Using a List for an item creates a
List of Lists: >
:let nestlist = [[11, 12], [21, 22], [31, 32]]
@@ -247,7 +248,7 @@ length minus one is used: >
:echo mylist[2:8] " result: [2, 3]
NOTE: mylist[s:e] means using the variable "s:e" as index. Watch out for
-using a single letter variable before the ":". Insert a space when needed:
+using a single letter variable before the ":". Insert a space when needed:
mylist[s : e].
@@ -376,7 +377,7 @@ This works like: >
If all you want to do is modify each item in the list then the |map()|
function will be a simpler method than a for loop.
-Just like the |:let| command, |:for| also accepts a list of variables. This
+Just like the |:let| command, |:for| also accepts a list of variables. This
requires the argument to be a list of lists. >
:for [lnum, col] in [[1, 3], [2, 8], [3, 0]]
: call Doit(lnum, col)
@@ -433,11 +434,11 @@ only appear once. Examples: >
< *E713* *E716* *E717*
A key is always a String. You can use a Number, it will be converted to a
String automatically. Thus the String '4' and the number 4 will find the same
-entry. Note that the String '04' and the Number 04 are different, since the
+entry. Note that the String '04' and the Number 04 are different, since the
Number will be converted to the String '4'. The empty string can be used as a
key.
-A value can be any expression. Using a Dictionary for a value creates a
+A value can be any expression. Using a Dictionary for a value creates a
nested Dictionary: >
:let nestdict = {1: {11: 'a', 12: 'b'}, 2: {21: 'c'}}
@@ -464,7 +465,7 @@ key lookup can be repeated: >
Dictionary to List conversion ~
-You may want to loop over the entries in a dictionary. For this you need to
+You may want to loop over the entries in a dictionary. For this you need to
turn the Dictionary into a List and pass it to |:for|.
Most often you want to loop over the keys, using the |keys()| function: >
@@ -531,7 +532,7 @@ This removes all entries from "dict" with a value not matching 'x'.
Dictionary function ~
*Dictionary-function* *self* *E725* *E862*
When a function is defined with the "dict" attribute it can be used in a
-special way with a dictionary. Example: >
+special way with a dictionary. Example: >
:function Mylen() dict
: return len(self.data)
:endfunction
@@ -555,7 +556,7 @@ assigned to a Dictionary in this way: >
:echo mydict.len()
The function will then get a number and the value of dict.len is a |Funcref|
-that references this function. The function can only be used through a
+that references this function. The function can only be used through a
|Funcref|. It will automatically be deleted when there is no |Funcref|
remaining that refers to it.
@@ -815,10 +816,10 @@ values are different: >
"is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case.
When comparing a String with a Number, the String is converted to a Number,
-and the comparison is done on Numbers. This means that: >
+and the comparison is done on Numbers. This means that: >
echo 0 == 'x'
1
-because 'x' converted to a Number is zero. However: >
+because 'x' converted to a Number is zero. However: >
echo [0] == ['x']
0
Inside a List or Dictionary this conversion is not used.
@@ -914,7 +915,7 @@ For '+' the number is unchanged.
A String will be converted to a Number first.
-These three can be repeated and mixed. Examples:
+These three can be repeated and mixed. Examples:
!-1 == 0
!!8 == 1
--9 == 9
@@ -948,7 +949,7 @@ compatibility). Use [-1:] to get the last byte.
If expr8 is a |List| then it results the item at index expr1. See |list-index|
for possible index values. If the index is out of range this results in an
-error. Example: >
+error. Example: >
:let item = mylist[-1] " get last item
Generally, if a |List| index is equal to or higher than the length of the
@@ -980,7 +981,7 @@ Examples: >
<
*slice*
If expr8 is a |List| this results in a new |List| with the items indicated by
-the indexes expr1a and expr1b. This works like with a String, as explained
+the indexes expr1a and expr1b. This works like with a String, as explained
just above. Also see |sublist| below. Examples: >
:let l = mylist[:3] " first four items
:let l = mylist[4:4] " List with one item
@@ -1040,7 +1041,7 @@ Floating point numbers can be written in two forms:
contain digits.
[-+] means there is an optional plus or minus sign.
{exp} is the exponent, power of 10.
-Only a decimal point is accepted, not a comma. No matter what the current
+Only a decimal point is accepted, not a comma. No matter what the current
locale is.
Examples:
@@ -1129,11 +1130,11 @@ literal-string *literal-string* *E115*
Note that single quotes are used.
-This string is taken as it is. No backslashes are removed or have a special
+This string is taken as it is. No backslashes are removed or have a special
meaning. The only exception is that two quotes stand for one quote.
Single quoted strings are useful for patterns, so that backslashes do not need
-to be doubled. These two commands are equivalent: >
+to be doubled. These two commands are equivalent: >
if a =~ "\\s*"
if a =~ '\s*'
@@ -1159,7 +1160,7 @@ register *expr-register* *@r*
The result is the contents of the named register, as a single string.
Newlines are inserted where required. To get the contents of the unnamed
-register use @" or @@. See |registers| for an explanation of the available
+register use @" or @@. See |registers| for an explanation of the available
registers.
When using the '=' register you get the expression itself, not what it
@@ -1321,7 +1322,7 @@ It is deleted when the tab page is closed.
*global-variable* *g:var* *g:*
Inside functions global variables are accessed with "g:". Omitting this will
-access a variable local to a function. But "g:" can also be used in any other
+access a variable local to a function. But "g:" can also be used in any other
place if you like.
*local-variable* *l:var* *l:*
@@ -1463,7 +1464,7 @@ v:cmdarg This variable is used for two purposes:
set before an autocommand event for a file read/write
command is triggered. There is a leading space to make it
possible to append this variable directly after the
- read/write command. Note: The "+cmd" argument isn't
+ read/write command. Note: The "+cmd" argument isn't
included here, because it will be executed anyway.
2. When printing a PostScript file with ":hardcopy" this is
the argument for the ":hardcopy" command. This can be used
@@ -1483,7 +1484,7 @@ v:completed_item
*v:count* *count-variable*
v:count The count given for the last Normal mode command. Can be used
- to get the count before a mapping. Read-only. Example: >
+ to get the count before a mapping. Read-only. Example: >
:map _x :<C-U>echo "the count is " . v:count<CR>
< Note: The <C-U> is required to remove the line range that you
get when typing ':' after a count.
@@ -1505,7 +1506,7 @@ v:ctype The current locale setting for characters of the runtime
See |multi-lang|.
*v:dying* *dying-variable*
-v:dying Normally zero. When a deadly signal is caught it's set to
+v:dying Normally zero. When a deadly signal is caught it's set to
one. When multiple signals are caught the number increases.
Can be used in an autocommand to check if Vim didn't
terminate normally. {only works on Unix}
@@ -1638,7 +1639,7 @@ v:fname_out The name of the output file. Only valid while
'diffexpr' output of diff
'patchexpr' resulting patched file
(*) When doing conversion for a write command (e.g., ":w
- file") it will be equal to v:fname_in. When doing conversion
+ file") it will be equal to v:fname_in. When doing conversion
for a read command (e.g., ":e file") it will be a temporary
file and different from v:fname_in.
@@ -1787,7 +1788,7 @@ v:prevcount The count given for the last but one Normal mode command.
< Read-only.
*v:profiling* *profiling-variable*
-v:profiling Normally zero. Set to one after using ":profile start".
+v:profiling Normally zero. Set to one after using ":profile start".
See |profiling|.
*v:progname* *progname-variable*
@@ -1867,14 +1868,14 @@ v:swapchoice |SwapExists| autocommands can set this to the selected choice
'd' Delete swapfile
'q' Quit
'a' Abort
- The value should be a single-character string. An empty value
+ The value should be a single-character string. An empty value
results in the user being asked, as would happen when there is
no SwapExists autocommand. The default is empty.
*v:swapcommand* *swapcommand-variable*
v:swapcommand Normal mode command to be executed after a file has been
opened. Can be used for a |SwapExists| autocommand to have
- another Vim open the file and jump to the right place. For
+ another Vim open the file and jump to the right place. For
example, when jumping to a tag the value is ":tag tagname\r".
For ":edit +cmd file" the value is ":cmd\r".
@@ -1917,7 +1918,7 @@ v:this_session Full filename of the last loaded or saved session file.
*v:throwpoint* *throwpoint-variable*
v:throwpoint The point where the exception most recently caught and not
- finished was thrown. Not set when commands are typed. See
+ finished was thrown. Not set when commands are typed. See
also |v:exception| and |throw-variables|.
Example: >
:try
@@ -1935,7 +1936,7 @@ v:true Special value used to put "true" in JSON and msgpack. See
|expr7| when used with numeric operators). Read-only.
*v:val* *val-variable*
-v:val Value of the current item of a |List| or |Dictionary|. Only
+v:val Value of the current item of a |List| or |Dictionary|. Only
valid while evaluating the expression used with |map()| and
|filter()|. Read-only.
@@ -2229,8 +2230,6 @@ msgpackdump({list}) List dump a list of objects to msgpack
msgpackparse({list}) List parse msgpack to a list of objects
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
nr2char({expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
-option_restore({list}) none restore options saved by option_save()
-option_save({list}) List save options values
nvim_...({args}...) any call nvim |api| functions
or({expr}, {expr}) Number bitwise OR
pathshorten({expr}) String shorten directory names in a path
@@ -2478,7 +2477,7 @@ append({lnum}, {text}) *append()*
the current buffer.
{lnum} can be zero to insert a line before the first one.
Returns 1 for failure ({lnum} out of range or out of memory),
- 0 for success. Example: >
+ 0 for success. Example: >
:let failed = append(line('$'), "# THE END")
:let failed = append(0, ["Chapter 1", "the beginning"])
<
@@ -2736,7 +2735,7 @@ bufname({expr}) *bufname()*
If {expr} is a Number, that buffer number's name is given.
Number zero is the alternate buffer for the current window.
If {expr} is a String, it is used as a |file-pattern| to match
- with the buffer names. This is always done like 'magic' is
+ with the buffer names. This is always done like 'magic' is
set and 'cpoptions' is empty. When there is more than one
match an empty string is returned.
"" or "%" can be used for the current buffer, "#" for the
@@ -2786,7 +2785,7 @@ bufwinid({expr}) *bufwinid()*
bufwinnr({expr}) *bufwinnr()*
The result is a Number, which is the number of the first
window associated with buffer {expr}. For the use of {expr},
- see |bufname()| above. If buffer {expr} doesn't exist or
+ see |bufname()| above. If buffer {expr} doesn't exist or
there is no such window, -1 is returned. Example: >
echo "A window containing buffer 1 is " . (bufwinnr(1))
@@ -2943,7 +2942,7 @@ col({expr}) The result is a Number, which is the byte index of the column
col("$") length of cursor line plus one
col("'t") column of mark t
col("'" . markname) column of mark markname
-< The first column is 1. 0 is returned for an error.
+< The first column is 1. 0 is returned for an error.
For an uppercase mark the column may actually be in another
buffer.
For the cursor position, when 'virtualedit' is active, the
@@ -2990,7 +2989,7 @@ complete_add({expr}) *complete_add()*
Returns 0 for failure (empty string or out of memory),
1 when the match was added, 2 when the match was already in
the list.
- See |complete-functions| for an explanation of {expr}. It is
+ See |complete-functions| for an explanation of {expr}. It is
the same as one item in the list that 'omnifunc' would return.
complete_check() *complete_check()*
@@ -3097,19 +3096,20 @@ confirm({msg} [, {choices} [, {default} [, {type}]]])
:endif
< In a GUI dialog, buttons are used. The layout of the buttons
depends on the 'v' flag in 'guioptions'. If it is included,
- the buttons are always put vertically. Otherwise, confirm()
+ the buttons are always put vertically. Otherwise, confirm()
tries to put the buttons in one horizontal line. If they
don't fit, a vertical layout is used anyway. For some systems
the horizontal layout is always used.
*copy()*
-copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
+copy({expr}) Make a copy of {expr}. For Numbers and Strings this isn't
different from using {expr} directly.
When {expr} is a |List| a shallow copy is created. This means
that the original |List| can be changed without changing the
copy, and vice versa. But the items are identical, thus
- changing an item changes the contents of both |Lists|. Also
- see |deepcopy()|.
+ changing an item changes the contents of both |Lists|.
+ A |Dictionary| is copied in a similar way as a |List|.
+ Also see |deepcopy()|.
cos({expr}) *cos()*
Return the cosine of {expr}, measured in radians, as a |Float|.
@@ -3217,7 +3217,7 @@ cursor({list})
deepcopy({expr}[, {noref}]) *deepcopy()* *E698*
- Make a copy of {expr}. For Numbers and Strings this isn't
+ Make a copy of {expr}. For Numbers and Strings this isn't
different from using {expr} directly.
When {expr} is a |List| a full copy is created. This means
that the original |List| can be changed without changing the
@@ -3374,10 +3374,10 @@ executable({expr}) *executable()*
searchpath for programs. *PATHEXT*
On Windows the ".exe", ".bat", etc. can
optionally be included. Then the extensions in $PATHEXT are
- tried. Thus if "foo.exe" does not exist, "foo.exe.bat" can be
- found. If $PATHEXT is not set then ".exe;.com;.bat;.cmd" is
+ tried. Thus if "foo.exe" does not exist, "foo.exe.bat" can be
+ found. If $PATHEXT is not set then ".exe;.com;.bat;.cmd" is
used. A dot by itself can be used in $PATHEXT to try using
- the name without an extension. When 'shell' looks like a
+ the name without an extension. When 'shell' looks like a
Unix shell, then the name is also tried without adding an
extension.
On Windows it only checks if the file exists and
@@ -3440,7 +3440,7 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is
|user-functions|). Also works for a
variable that is a Funcref.
varname internal variable (see
- |internal-variables|). Also works
+ |internal-variables|). Also works
for |curly-braces-names|, |Dictionary|
entries, |List| items, etc. Beware
that evaluating an index may cause an
@@ -3525,7 +3525,7 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
Otherwise the result is a String and when there are several
matches, they are separated by <NL> characters.
- If the expansion fails, the result is an empty string. A name
+ If the expansion fails, the result is an empty string. A name
for a non-existing file is not included, unless {expr} does
not start with '%', '#' or '<', see below.
@@ -3589,7 +3589,7 @@ expand({expr} [, {nosuf} [, {list}]]) *expand()*
slow, because a shell may be used to do the expansion. See
|expr-env-expand|.
The expanded variable is still handled like a list of file
- names. When an environment variable cannot be expanded, it is
+ names. When an environment variable cannot be expanded, it is
left unchanged. Thus ":echo expand('$FOOBAR')" results in
"$FOOBAR".
@@ -3612,7 +3612,7 @@ extend({expr1}, {expr2} [, {expr3}]) *extend()*
items copied is equal to the original length of the List.
E.g., when {expr3} is 1 you get N new copies of the first item
(where N is the original length of the List).
- Use |add()| to concatenate one item to a list. To concatenate
+ Use |add()| to concatenate one item to a list. To concatenate
two lists into a new list use the + operator: >
:let newlist = [1, 2, 3] + [4, 5]
<
@@ -3812,7 +3812,7 @@ fmod({expr1}, {expr2}) *fmod()*
fnameescape({string}) *fnameescape()*
- Escape {string} for use as file name command argument. All
+ Escape {string} for use as file name command argument. All
characters that have a special meaning, such as '%' and '|'
are escaped with a backslash.
For most systems the characters escaped are
@@ -3849,7 +3849,7 @@ foldclosedend({lnum}) *foldclosedend()*
foldlevel({lnum}) *foldlevel()*
The result is a Number, which is the foldlevel of line {lnum}
- in the current buffer. For nested folds the deepest level is
+ in the current buffer. For nested folds the deepest level is
returned. If there is no fold at line {lnum}, zero is
returned. It doesn't matter if the folds are open or closed.
When used while updating folds (from 'foldexpr') -1 is
@@ -3864,7 +3864,7 @@ foldtext() Returns a String, to be displayed for a closed fold. This is
|v:foldstart|, |v:foldend| and |v:folddashes| variables.
The returned string looks like this: >
+-- 45 lines: abcdef
-< The number of leading dashes depends on the foldlevel. The
+< The number of leading dashes depends on the foldlevel. The
"45" is the number of lines in the fold. "abcdef" is the text
in the first non-blank line of the fold. Leading white space,
"//" or "/*" and the text from the 'foldmarker' and
@@ -3883,7 +3883,7 @@ foldtextresult({lnum}) *foldtextresult()*
Useful when exporting folded text, e.g., to HTML.
*foreground()*
-foreground() Move the Vim window to the foreground. Useful when sent from
+foreground() Move the Vim window to the foreground. Useful when sent from
a client to a Vim server. |remote_send()|
On Win32 systems this might not work, the OS does not always
allow a window to bring itself to the foreground. Use
@@ -4185,7 +4185,7 @@ getcharmod() *getcharmod()*
96 mouse quadruple click (== 32 + 64)
128 command (Macintosh only)
Only the modifiers that have not been included in the
- character itself are obtained. Thus Shift-a results in "A"
+ character itself are obtained. Thus Shift-a results in "A"
without a modifier.
getcharsearch() *getcharsearch()*
@@ -4709,7 +4709,7 @@ getwinposx() The result is a Number, which is the X coordinate in pixels of
*getwinposy()*
getwinposy() The result is a Number, which is the Y coordinate in pixels of
- the top of the GUI Vim window. The result will be -1 if the
+ the top of the GUI Vim window. The result will be -1 if the
information is not available.
The value can be used with `:winpos`.
@@ -4776,7 +4776,7 @@ glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()*
:let tagfiles = glob("`find . -name tags -print`")
:let &tags = substitute(tagfiles, "\n", ",", "g")
< The result of the program inside the backticks should be one
- item per line. Spaces inside an item are allowed.
+ item per line. Spaces inside an item are allowed.
See |expand()| for expanding special Vim variables. See
|system()| for getting the raw output of an external command.
@@ -4791,7 +4791,7 @@ glob2regpat({expr}) *glob2regpat()*
< When {expr} is an empty string the result is "^$", match an
empty string.
Note that the result depends on the system. On MS-Windows
- a backslash usually means a patch separator.
+ a backslash usually means a path separator.
*globpath()*
globpath({path}, {expr} [, {nosuf} [, {list} [, {allinks}]]])
@@ -4913,7 +4913,7 @@ hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
When {mode} is omitted, "nvo" is used.
This function is useful to check if a mapping already exists
- to a function in a Vim script. Example: >
+ to a function in a Vim script. Example: >
:if !hasmapto('\ABCdoit')
: map <Leader>d \ABCdoit
:endif
@@ -5008,7 +5008,7 @@ hlID({name}) The result is a Number, which is the ID of the highlight group
with name {name}. When the highlight group doesn't exist,
zero is returned.
This can be used to retrieve information about the highlight
- group. For example, to get the background color of the
+ group. For example, to get the background color of the
"Comment" group: >
:echo synIDattr(synIDtrans(hlID("Comment")), "bg")
@@ -5078,7 +5078,7 @@ input({opts})
The highlighting set with |:echohl| is used for the prompt.
The input is entered just like a command-line, with the same
- editing commands and mappings. There is a separate history
+ editing commands and mappings. There is a separate history
for lines typed for input().
Example: >
:if input("Coffee or beer? ") == "beer"
@@ -5092,9 +5092,9 @@ input({opts})
< The optional {completion} argument specifies the type of
completion supported for the input. Without it completion is
- not performed. The supported completion types are the same as
+ not performed. The supported completion types are the same as
that can be supplied to a user-defined command using the
- "-complete=" argument. Refer to |:command-completion| for
+ "-complete=" argument. Refer to |:command-completion| for
more information. Example: >
let fname = input("File: ", "", "file")
@@ -5174,12 +5174,12 @@ inputlist({textlist}) *inputlist()*
displayed, one string per line. The user will be prompted to
enter a number, which is returned.
The user can also select an item by clicking on it with the
- mouse. For the first string 0 is returned. When clicking
+ mouse. For the first string 0 is returned. When clicking
above the first item a negative number is returned. When
clicking on the prompt one more than the length of {textlist}
is returned.
Make sure {textlist} has less than 'lines' entries, otherwise
- it won't work. It's a good idea to put the entry number at
+ it won't work. It's a good idea to put the entry number at
the start of the string. And put a prompt in the first item.
Example: >
let color = inputlist(['Select color:', '1. red',
@@ -5213,7 +5213,7 @@ inputsecret({prompt} [, {text}]) *inputsecret()*
insert({list}, {item} [, {idx}]) *insert()*
Insert {item} at the start of |List| {list}.
If {idx} is specified insert {item} before the item with index
- {idx}. If {idx} is zero it goes before the first item, just
+ {idx}. If {idx} is zero it goes before the first item, just
like omitting {idx}. A negative {idx} is also possible, see
|list-index|. -1 inserts just before the last item.
Returns the resulting |List|. Examples: >
@@ -5696,7 +5696,7 @@ match({expr}, {pat} [, {start} [, {count}]]) *match()*
first item where {pat} matches. Each item is used as a
String, |Lists| and |Dictionaries| are used as echoed.
- Otherwise, {expr} is used as a String. The result is a
+ Otherwise, {expr} is used as a String. The result is a
Number, which gives the index (byte offset) in {expr} where
{pat} matches.
@@ -5709,7 +5709,7 @@ match({expr}, {pat} [, {start} [, {count}]]) *match()*
:echo match([1, 'x'], '\a') " results in 1
< See |string-match| for how {pat} is used.
*strpbrk()*
- Vim doesn't have a strpbrk() function. But you can do: >
+ Vim doesn't have a strpbrk() function. But you can do: >
:let sepidx = match(line, '[.,;: \t]')
< *strcasestr()*
Vim doesn't have a strcasestr() function. But you can add
@@ -5746,7 +5746,7 @@ match({expr}, {pat} [, {start} [, {count}]]) *match()*
See |pattern| for the patterns that are accepted.
The 'ignorecase' option is used to set the ignore-caseness of
- the pattern. 'smartcase' is NOT used. The matching is always
+ the pattern. 'smartcase' is NOT used. The matching is always
done like 'magic' is set and 'cpoptions' is empty.
*matchadd()* *E798* *E799* *E801* *E957*
@@ -5762,7 +5762,7 @@ matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
concealed.
The optional {priority} argument assigns a priority to the
- match. A match with a high priority will have its
+ match. A match with a high priority will have its
highlighting overrule that of a match with a lower priority.
A priority is specified as an integer (negative numbers are no
exception). If the {priority} argument is not specified, the
@@ -5801,7 +5801,7 @@ matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
:call matchdelete(m)
< A list of matches defined by |matchadd()| and |:match| are
- available from |getmatches()|. All matches can be deleted in
+ available from |getmatches()|. All matches can be deleted in
one operation by |clearmatches()|.
*matchaddpos()*
@@ -5989,7 +5989,7 @@ mkdir({name} [, {path} [, {prot}]])
necessary. Otherwise it must be "".
If {prot} is given it is used to set the protection bits of
the new directory. The default is 0755 (rwxr-xr-x: r/w for
- the user readable for others). Use 0700 to make it unreadable
+ the user readable for others). Use 0700 to make it unreadable
for others.
{prot} is applied for all parts of {name}. Thus if you create
@@ -6270,7 +6270,7 @@ printf({fmt}, {expr1} ...) *printf()*
number produced by a signed conversion (d).
+ A sign must always be placed before a number
- produced by a signed conversion. A + overrides
+ produced by a signed conversion. A + overrides
a space if both are used.
field-width
@@ -6296,7 +6296,7 @@ printf({fmt}, {expr1} ...) *printf()*
A field width or precision, or both, may be indicated by an
asterisk '*' instead of a digit string. In this case, a
- Number argument supplies the field width or precision. A
+ Number argument supplies the field width or precision. A
negative field width is treated as a left adjustment flag
followed by a positive field width; a negative precision is
treated as though it were missing. Example: >
@@ -6530,7 +6530,7 @@ reltimestr({time}) *reltimestr()*
*remote_expr()* *E449*
remote_expr({server}, {string} [, {idvar} [, {timeout}]])
- Send the {string} to {server}. The string is sent as an
+ Send the {string} to {server}. The string is sent as an
expression and the result is returned after evaluation.
The result must be a String or a |List|. A |List| is turned
into a String by joining the items with a line break in
@@ -6572,7 +6572,7 @@ remote_foreground({server}) *remote_foreground()*
remote_peek({serverid} [, {retvar}]) *remote_peek()*
Returns a positive number if there are available strings
from {serverid}. Copies any reply string into the variable
- {retvar} if specified. {retvar} must be a string with the
+ {retvar} if specified. {retvar} must be a string with the
name of a variable.
Returns zero if none are available.
Returns -1 if something is wrong.
@@ -6595,7 +6595,7 @@ remote_read({serverid}, [{timeout}]) *remote_read()*
<
*remote_send()* *E241*
remote_send({server}, {string} [, {idvar}])
- Send the {string} to {server}. The string is sent as input
+ Send the {string} to {server}. The string is sent as input
keys and the function returns immediately. At the Vim server
the keys are not mapped |:map|.
If {idvar} is present, it is taken as the name of a variable
@@ -6654,7 +6654,7 @@ repeat({expr}, {count}) *repeat()*
:let separator = repeat('-', 80)
< When {count} is zero or negative the result is empty.
When {expr} is a |List| the result is {expr} concatenated
- {count} times. Example: >
+ {count} times. Example: >
:let longlist = repeat(['a', 'b'], 3)
< Results in ['a', 'b', 'a', 'b', 'a', 'b'].
@@ -6673,7 +6673,7 @@ resolve({filename}) *resolve()* *E655*
path name) and also keeps a trailing path separator.
*reverse()*
-reverse({list}) Reverse the order of items in {list} in-place. Returns
+reverse({list}) Reverse the order of items in {list} in-place. Returns
{list}.
If you want a list to remain unmodified make a copy first: >
:let revlist = reverse(copy(mylist))
@@ -6787,7 +6787,7 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
A zero value is equal to not giving the argument.
When the {timeout} argument is given the search stops when
- more than this many milliseconds have passed. Thus when
+ more than this many milliseconds have passed. Thus when
{timeout} is 500 the search stops after half a second.
The value must not be negative. A zero value is like not
giving the argument.
@@ -6906,7 +6906,7 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip}
< When starting at the "if 2", with the cursor on the "i", and
searching forwards, the "endif 2" is found. When starting on
the character just before the "if 2", the "endif 1" will be
- found. That's because the "if 2" will be found first, and
+ found. That's because the "if 2" will be found first, and
then this is considered to be a nested if/endif from "if 2" to
"endif 2".
When searching backwards and {end} is more than one character,
@@ -7064,7 +7064,7 @@ setcharsearch({dict}) *setcharsearch()*
setcmdpos({pos}) *setcmdpos()*
Set the cursor position in the command line to byte position
- {pos}. The first position is 1.
+ {pos}. The first position is 1.
Use |getcmdpos()| to obtain the current position.
Only works while editing the command line, thus you must use
|c_CTRL-\_e|, |c_CTRL-R_=| or |c_CTRL-R_CTRL-R| with '='. For
@@ -7119,7 +7119,7 @@ setline({lnum}, {text}) *setline()*
< Note: The '[ and '] marks are not set.
-setloclist({nr}, {list} [, {action}[, {what}]]) *setloclist()*
+setloclist({nr}, {list}[, {action}[, {what}]]) *setloclist()*
Create or replace or add to the location list for window {nr}.
{nr} can be the window number or the |window-ID|.
When {nr} is zero the current window is used.
@@ -8173,7 +8173,7 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
A "~" in {sub} is not replaced with the previous {sub}.
Note that some codes in {sub} have a special meaning
- |sub-replace-special|. For example, to replace something with
+ |sub-replace-special|. For example, to replace something with
"\n" (two characters), use "\\\\n" or '\\n'.
When {pat} does not match in {expr}, {expr} is returned
@@ -8194,9 +8194,9 @@ substitute({expr}, {pat}, {sub}, {flags}) *substitute()*
optional argument. Example: >
:echo substitute(s, '%\(\x\x\)', SubNr, 'g')
< The optional argument is a list which contains the whole
- matched string and up to nine submatches,like what
- |submatch()| returns. Example: >
- :echo substitute(s, '\(\x\x\)', {m -> '0x' . m[1]}, 'g')
+ matched string and up to nine submatches, like what
+ |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
@@ -8236,7 +8236,7 @@ synID({lnum}, {col}, {trans}) *synID()*
zero.
When {trans} is |TRUE|, transparent items are reduced to the
- item that they reveal. This is useful when wanting to know
+ item that they reveal. This is useful when wanting to know
the effective color. When {trans} is |FALSE|, the transparent
item is returned. This is useful when wanting to know which
syntax item is effective (e.g. inside parens).
@@ -8252,7 +8252,7 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
syntax ID {synID}. This can be used to obtain information
about a syntax item.
{mode} can be "gui", "cterm" or "term", to get the attributes
- for that mode. When {mode} is omitted, or an invalid value is
+ for that mode. When {mode} is omitted, or an invalid value is
used, the attributes for the currently active highlighting are
used (GUI, cterm or term).
Use synIDtrans() to follow linked highlight groups.
@@ -8481,7 +8481,7 @@ taglist({expr} [, {filename}]) *taglist()*
tempname() *tempname()* *temp-file-name*
The result is a String, which is the name of a file that
- doesn't exist. It can be used for a temporary file. Example: >
+ doesn't exist. It can be used for a temporary file. Example: >
:let tmpfile = tempname()
:exe "redir > " . tmpfile
< For Unix, the file will be in a private directory |tempfile|.
@@ -8739,7 +8739,7 @@ uniq({list} [, {func} [, {dict}]]) *uniq()* *E882*
each item. For the use of {func} and {dict} see |sort()|.
values({dict}) *values()*
- Return a |List| with all the values of {dict}. The |List| is
+ Return a |List| with all the values of {dict}. The |List| is
in arbitrary order.
@@ -8775,7 +8775,7 @@ virtcol({expr}) *virtcol()*
virtcol(".") with text "foo^Lbar", with cursor on the "^L", returns 5
virtcol("$") with text "foo^Lbar", returns 9
virtcol("'t") with text " there", with 't at 'h', returns 6
-< The first column is 1. 0 is returned for an error.
+< The first column is 1. 0 is returned for an error.
A more advanced example that echoes the maximum length of
all lines: >
echo max(map(range(1, line('$')), "virtcol([v:val, '$'])"))
@@ -8902,7 +8902,7 @@ winlayout([{tabnr}]) *winlayout()*
<
*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
+ in the window. This is counting screen lines from the top of
the window. The first line is one.
If the cursor was moved the view on the file will be updated
first, this may cause a scroll.
@@ -9110,9 +9110,9 @@ functions.
*:fu* *:function* *E128* *E129* *E123*
:fu[nction] List all functions and their arguments.
-:fu[nction] {name} List function {name}.
- {name} can also be a |Dictionary| entry that is a
- |Funcref|: >
+:fu[nction][!] {name} List function {name}, annotated with line numbers
+ unless "!" is given.
+ {name} may be a |Dictionary| |Funcref| entry: >
:function dict.init
:fu[nction] /{pattern} List functions with a name matching {pattern}.
@@ -9145,9 +9145,9 @@ See |:verbose-cmd| for more information.
{name} can also be a |Dictionary| entry that is a
|Funcref|: >
:function dict.init(arg)
-< "dict" must be an existing dictionary. The entry
+< "dict" must be an existing dictionary. The entry
"init" is added if it didn't exist yet. Otherwise [!]
- is required to overwrite an existing function. The
+ is required to overwrite an existing function. The
result is a |Funcref| to a numbered function. The
function can only be used with a |Funcref| and will be
deleted if there are no more references to it.
@@ -9176,7 +9176,7 @@ See |:verbose-cmd| for more information.
abort as soon as an error is detected.
*:func-dict*
When the [dict] argument is added, the function must
- be invoked through an entry in a |Dictionary|. The
+ be invoked through an entry in a |Dictionary|. The
local variable "self" will then be set to the
dictionary. See |Dictionary-function|.
*:func-closure* *E932*
@@ -9255,7 +9255,7 @@ See |:verbose-cmd| for more information.
returns at the outermost ":endtry".
*function-argument* *a:var*
-An argument can be defined by giving its name. In the function this can then
+An argument can be defined by giving its name. In the function this can then
be used as "a:name" ("a:" for argument).
*a:0* *a:1* *a:000* *E740* *...*
Up to 20 arguments can be given, separated by commas. After the named
@@ -9326,7 +9326,7 @@ This function can then be called with: >
itself, the function is executed for each line in the range,
with the cursor in the first column of that line. The cursor
is left at the last line (possibly moved by the last function
- call). The arguments are re-evaluated for each line. Thus
+ call). The arguments are re-evaluated for each line. Thus
this works:
*function-range-example* >
:function Mynumber(arg)
@@ -9371,7 +9371,7 @@ This is introduced in the user manual, section |41.14|.
The autocommand is useful if you have a plugin that is a long Vim script file.
You can define the autocommand and quickly quit the script with |:finish|.
-That makes Vim startup faster. The autocommand should then load the same file
+That makes Vim startup faster. The autocommand should then load the same file
again, setting a variable to skip the |:finish| command.
Use the FuncUndefined autocommand event with a pattern that matches the
@@ -9450,7 +9450,7 @@ name. So in the above example, if the variable "adjective" was set to
"adjective" was set to "quiet", then it would be to "my_quiet_variable".
One application for this is to create a set of variables governed by an option
-value. For example, the statement >
+value. For example, the statement >
echo my_{&background}_message
would output the contents of "my_dark_message" or "my_light_message" depending
@@ -9496,7 +9496,7 @@ This does NOT work: >
must be a valid index in that list. For nested list
the index can be repeated.
This cannot be used to add an item to a |List|.
- This cannot be used to set a byte in a String. You
+ This cannot be used to set a byte in a String. You
can do that like this: >
:let var = var[0:2] . 'X' . var[4:]
<
@@ -9545,7 +9545,7 @@ This does NOT work: >
that would match everywhere.
:let @{reg-name} .= {expr1}
- Append {expr1} to register {reg-name}. If the
+ Append {expr1} to register {reg-name}. If the
register was empty it's like setting it to {expr1}.
:let &{option-name} = {expr1} *:let-option* *:let-&*
@@ -9621,7 +9621,7 @@ This does NOT work: >
|List| item.
*E121*
-:let {var-name} .. List the value of variable {var-name}. Multiple
+:let {var-name} .. List the value of variable {var-name}. Multiple
variable names may be given. Special names recognized
here: *E738*
g: global variables
@@ -9803,7 +9803,7 @@ This does NOT work: >
:for item in copy(mylist)
< When not making a copy, Vim stores a reference to the
next item in the list, before executing the commands
- with the current item. Thus the current item can be
+ with the current item. Thus the current item can be
removed without effect. Removing any later item means
it will not be found. Thus the following example
works (an inefficient way to make a list empty): >
@@ -10022,7 +10022,7 @@ This does NOT work: >
message in the |message-history|. When used in a
script or function the line number will be added.
Spaces are placed between the arguments as with the
- :echo command. When used inside a try conditional,
+ :echo command. When used inside a try conditional,
the message is raised as an error exception instead
(see |try-echoerr|).
Example: >
@@ -10151,14 +10151,14 @@ the finally clause. It is resumed at the ":endtry", so that commands after
the ":endtry" are not executed and the exception might be caught elsewhere,
see |try-nesting|.
When during execution of a catch clause another exception is thrown, the
-remaining lines in that catch clause are not executed. The new exception is
+remaining lines in that catch clause are not executed. The new exception is
not matched against the patterns in any of the ":catch" commands of the same
try conditional and none of its catch clauses is taken. If there is, however,
a finally clause, it is executed, and the exception pends during its
execution. The commands following the ":endtry" are not executed. The new
exception might, however, be caught elsewhere, see |try-nesting|.
When during execution of the finally clause (if present) an exception is
-thrown, the remaining lines in the finally clause are skipped. If the finally
+thrown, the remaining lines in the finally clause are skipped. If the finally
clause has been taken because of an exception from the try block or one of the
catch clauses, the original (pending) exception is discarded. The commands
following the ":endtry" are not executed, and the exception from the finally
@@ -10192,7 +10192,7 @@ catch an exception thrown in its try block or throws a new exception from one
of its catch clauses or its finally clause, the outer try conditional is
checked according to the rules above. If the inner try conditional is in the
try block of the outer try conditional, its catch clauses are checked, but
-otherwise only the finally clause is executed. It does not matter for
+otherwise only the finally clause is executed. It does not matter for
nesting, whether the inner try conditional is directly contained in the outer
one, or whether the outer one sources a script or calls a function containing
the inner try conditional.
@@ -10255,7 +10255,7 @@ executed. >
however displays "in Bar" and throws 4711.
Any other command that takes an expression as argument might also be
-abandoned by an (uncaught) exception during the expression evaluation. The
+abandoned by an (uncaught) exception during the expression evaluation. The
exception is then propagated to the caller of the command.
Example: >
@@ -10439,13 +10439,13 @@ CLEANUP CODE *try-finally*
Scripts often change global settings and restore them at their end. If the
user however interrupts the script by pressing CTRL-C, the settings remain in
-an inconsistent state. The same may happen to you in the development phase of
+an inconsistent state. The same may happen to you in the development phase of
a script when an error occurs or you explicitly throw an exception without
catching it. You can solve these problems by using a try conditional with
a finally clause for restoring the settings. Its execution is guaranteed on
normal control flow, on error, on an explicit ":throw", and on interrupt.
(Note that errors and interrupts from inside the try conditional are converted
-to exceptions. When not caught, they terminate the script after the finally
+to exceptions. When not caught, they terminate the script after the finally
clause has been executed.)
Example: >
@@ -10503,7 +10503,7 @@ This displays "first", "cleanup", "second", "cleanup", and "end". >
:echo Foo() "returned by Foo"
This displays "cleanup" and "4711 returned by Foo". You don't need to add an
-extra ":return" in the finally clause. (Above all, this would override the
+extra ":return" in the finally clause. (Above all, this would override the
return value.)
*except-from-finally*
@@ -10547,7 +10547,7 @@ or >
Vim:{errmsg}
{cmdname} is the name of the command that failed; the second form is used when
-the command name is not known. {errmsg} is the error message usually produced
+the command name is not known. {errmsg} is the error message usually produced
when the error occurs outside try conditionals. It always begins with
a capital "E", followed by a two or three-digit error number, a colon, and
a space.
@@ -10652,7 +10652,7 @@ This works also when a try conditional is active.
CATCHING INTERRUPTS *catch-interrupt*
When there are active try conditionals, an interrupt (CTRL-C) is converted to
-the exception "Vim:Interrupt". You can catch it like every exception. The
+the exception "Vim:Interrupt". You can catch it like every exception. The
script is not terminated, then.
Example: >
@@ -10686,7 +10686,7 @@ script is not terminated, then.
:endwhile
You can interrupt a task here by pressing CTRL-C; the script then asks for
-a new command. If you press CTRL-C at the prompt, the script is terminated.
+a new command. If you press CTRL-C at the prompt, the script is terminated.
For testing what happens when CTRL-C would be pressed on a specific line in
your script, use the debug mode and execute the |>quit| or |>interrupt|
@@ -10843,7 +10843,7 @@ For some commands, the normal action can be replaced by a sequence of
autocommands. Exceptions from that sequence will be catchable by the caller
of the command.
Example: For the ":write" command, the caller cannot know whether the file
-had actually been written when the exception occurred. You need to tell it in
+had actually been written when the exception occurred. You need to tell it in
some way. >
:if !exists("cnt")
@@ -10991,8 +10991,8 @@ or ":endif". On the other hand, errors should be catchable as exceptions
This problem has been solved by converting errors to exceptions and using
immediate abortion (if not suppressed by ":silent!") only when a try
-conditional is active. This is no restriction since an (error) exception can
-be caught only from an active try conditional. If you want an immediate
+conditional is active. This is no restriction since an (error) exception can
+be caught only from an active try conditional. If you want an immediate
termination without catching the error, just use a try conditional without
catch clause. (You can cause cleanup code being executed before termination
by specifying a finally clause.)
@@ -11007,8 +11007,8 @@ conditional of a new script, you might change the control flow of the existing
script on error. You get the immediate abortion on error and can catch the
error in the new script. If however the sourced script suppresses error
messages by using the ":silent!" command (checking for errors by testing
-|v:errmsg| if appropriate), its execution path is not changed. The error is
-not converted to an exception. (See |:silent|.) So the only remaining cause
+|v:errmsg| if appropriate), its execution path is not changed. The error is
+not converted to an exception. (See |:silent|.) So the only remaining cause
where this happens is for scripts that don't care about errors and produce
error messages. You probably won't want to use such code from your new
scripts.
diff --git a/runtime/makemenu.vim b/runtime/makemenu.vim
index 839dbdac07..3d76b4240e 100644
--- a/runtime/makemenu.vim
+++ b/runtime/makemenu.vim
@@ -1,6 +1,6 @@
" Script to define the syntax menu in synmenu.vim
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2013 Jul 28
+" Last Change: 2018 May 17
" This is used by "make menu" in the src directory.
edit <sfile>:p:h/synmenu.vim
@@ -69,11 +69,13 @@ SynMenu AB.Applix\ ELF:elf
SynMenu AB.APT\ config:aptconf
SynMenu AB.Arc\ Macro\ Language:aml
SynMenu AB.Arch\ inventory:arch
+SynMenu AB.Arduino:arduino
SynMenu AB.ART:art
SynMenu AB.Ascii\ Doc:asciidoc
SynMenu AB.ASP\ with\ VBScript:aspvbs
SynMenu AB.ASP\ with\ Perl:aspperl
SynMenu AB.Assembly.680x0:asm68k
+SynMenu AB.Assembly.AVR:avra
SynMenu AB.Assembly.Flat:fasm
SynMenu AB.Assembly.GNU:asm
SynMenu AB.Assembly.GNU\ H-8300:asmh8300
@@ -89,6 +91,7 @@ SynMenu AB.ASN\.1:asn
SynMenu AB.Asterisk\ config:asterisk
SynMenu AB.Asterisk\ voicemail\ config:asteriskvm
SynMenu AB.Atlas:atlas
+SynMenu AB.Autodoc:autodoc
SynMenu AB.AutoHotKey:autohotkey
SynMenu AB.AutoIt:autoit
SynMenu AB.Automake:automake
@@ -103,6 +106,7 @@ SynMenu AB.Basic.IBasic:ibasic
SynMenu AB.Basic.QBasic:basic
SynMenu AB.Basic.Visual\ Basic:vb
SynMenu AB.Bazaar\ commit\ file:bzr
+SynMenu AB.Bazel:bzl
SynMenu AB.BC\ calculator:bc
SynMenu AB.BDF\ font:bdf
SynMenu AB.BibTeX.Bibliography\ database:bib
@@ -132,6 +136,7 @@ SynMenu C.Clever:cl
SynMenu C.Clipper:clipper
SynMenu C.Clojure:clojure
SynMenu C.Cmake:cmake
+SynMenu C.Cmod:cmod
SynMenu C.Cmusrc:cmusrc
SynMenu C.Cobol:cobol
SynMenu C.Coco/R:coco
@@ -158,6 +163,7 @@ SynMenu DE.D:d
SynMenu DE.Datascript:datascript
SynMenu DE.Debian.Debian\ ChangeLog:debchangelog
SynMenu DE.Debian.Debian\ Control:debcontrol
+SynMenu DE.Debian.Debian\ Copyright:debcopyright
SynMenu DE.Debian.Debian\ Sources\.list:debsources
SynMenu DE.Denyhosts:denyhosts
SynMenu DE.Desktop:desktop
@@ -166,12 +172,14 @@ SynMenu DE.Dictd\ config:dictdconf
SynMenu DE.Diff:diff
SynMenu DE.Digital\ Command\ Lang:dcl
SynMenu DE.Dircolors:dircolors
+SynMenu DE.Dirpager:dirpager
SynMenu DE.Django\ template:django
SynMenu DE.DNS/BIND\ zone:bindzone
SynMenu DE.Dnsmasq\ config:dnsmasq
SynMenu DE.DocBook.auto-detect:docbk
SynMenu DE.DocBook.SGML:docbksgml
SynMenu DE.DocBook.XML:docbkxml
+SynMenu DE.Dockerfile:dockerfile
SynMenu DE.Dot:dot
SynMenu DE.Doxygen.C\ with\ doxygen:c.doxygen
SynMenu DE.Doxygen.C++\ with\ doxygen:cpp.doxygen
@@ -199,6 +207,8 @@ SynMenu DE.ESQL-C:esqlc
SynMenu DE.Essbase\ script:csc
SynMenu DE.Esterel:esterel
SynMenu DE.Eterm\ config:eterm
+SynMenu DE.Euphoria\ 3:euphoria3
+SynMenu DE.Euphoria\ 4:euphoria4
SynMenu DE.Eviews:eviews
SynMenu DE.Exim\ conf:exim
SynMenu DE.Expect:expect
@@ -231,6 +241,8 @@ SynMenu FG.Git.Send\ Email:gitsendemail
SynMenu FG.Gitolite:gitolite
SynMenu FG.Gkrellmrc:gkrellmrc
SynMenu FG.Gnash:gnash
+SynMenu FG.Go:go
+SynMenu FG.Godoc:godoc
SynMenu FG.GP:gp
SynMenu FG.GPG:gpg
SynMenu FG.Grof:gprof
@@ -277,12 +289,14 @@ SynMenu HIJK.Inittab:inittab
SynMenu HIJK.Inno\ setup:iss
SynMenu HIJK.Innovation\ Data\ Processing.Upstream\ dat:upstreamdat
SynMenu HIJK.Innovation\ Data\ Processing.Upstream\ log:upstreamlog
+SynMenu HIJK.Innovation\ Data\ Processing.Upstream\ rpt:upstreamrpt
SynMenu HIJK.Innovation\ Data\ Processing.Upstream\ Install\ log:upstreaminstalllog
SynMenu HIJK.Innovation\ Data\ Processing.Usserver\ log:usserverlog
SynMenu HIJK.Innovation\ Data\ Processing.USW2KAgt\ log:usw2kagtlog
SynMenu HIJK.InstallShield\ script:ishd
SynMenu HIJK.Interactive\ Data\ Lang:idlang
SynMenu HIJK.IPfilter:ipfilter
+SynMenu HIJK.J:j
SynMenu HIJK.JAL:jal
SynMenu HIJK.JAM:jam
SynMenu HIJK.Jargon:jargon
@@ -294,9 +308,11 @@ SynMenu HIJK.JavaScript:javascript
SynMenu HIJK.Jess:jess
SynMenu HIJK.Jgraph:jgraph
SynMenu HIJK.Jovial:jovial
+SynMenu HIJK.JSON:json
SynMenu HIJK.Kconfig:kconfig
SynMenu HIJK.KDE\ script:kscript
SynMenu HIJK.Kimwitu++:kwt
+SynMenu HIJK.Kivy:kivy
SynMenu HIJK.KixTart:kix
SynMenu L.Lace:lace
@@ -305,6 +321,7 @@ SynMenu L.Latte:latte
SynMenu L.Ld\ script:ld
SynMenu L.LDAP.LDIF:ldif
SynMenu L.LDAP.Configuration:ldapconf
+SynMenu L.Less:less
SynMenu L.Lex:lex
SynMenu L.LFTP\ config:lftp
SynMenu L.Libao:libao
@@ -340,6 +357,7 @@ SynMenu M.Man\ page:man
SynMenu M.Man\.conf:manconf
SynMenu M.Maple\ V:maple
SynMenu M.Markdown:markdown
+SynMenu M.Markdown\ with\ R\ statements:rmd
SynMenu M.Mason:mason
SynMenu M.Mathematica:mma
SynMenu M.Matlab:matlab
@@ -349,6 +367,7 @@ SynMenu M.Messages\ (/var/log):messages
SynMenu M.Metafont:mf
SynMenu M.MetaPost:mp
SynMenu M.MGL:mgl
+SynMenu M.MIX:mix
SynMenu M.MMIX:mmix
SynMenu M.Modconf:modconf
SynMenu M.Model:model
@@ -356,6 +375,7 @@ SynMenu M.Modsim\ III:modsim3
SynMenu M.Modula\ 2:modula2
SynMenu M.Modula\ 3:modula3
SynMenu M.Monk:monk
+SynMenu M.Motorola\ S-Record:srec
SynMenu M.Mplayer\ config:mplayerconf
SynMenu M.MOO:moo
SynMenu M.Mrxvtrc:mrxvtrc
@@ -368,12 +388,15 @@ SynMenu M.MS-DOS/Windows.Registry:registry
SynMenu M.MS-DOS/Windows.Resource\ file:rc
SynMenu M.Msql:msql
SynMenu M.MuPAD:mupad
+SynMenu M.Murphi:murphi
SynMenu M.MUSHcode:mush
SynMenu M.Muttrc:muttrc
+SynMenu NO.N1QL:n1ql
SynMenu NO.Nanorc:nanorc
SynMenu NO.Nastran\ input/DMAP:nastran
SynMenu NO.Natural:natural
+SynMenu NO.NeoMutt\ setup\ files:neomuttrc
SynMenu NO.Netrc:netrc
SynMenu NO.Ninja:ninja
SynMenu NO.Novell\ NCF\ batch:ncf
@@ -461,14 +484,18 @@ SynMenu R.RockLinux\ package\ desc\.:desc
SynMenu R.Rpcgen:rpcgen
SynMenu R.RPL/2:rpl
SynMenu R.ReStructuredText:rst
+SynMenu M.ReStructuredText\ with\ R\ statements:rrst
SynMenu R.RTF:rtf
SynMenu R.Ruby:ruby
+SynMenu R.Rust:rust
SynMenu S-Sm.S-Lang:slang
SynMenu S-Sm.Samba\ config:samba
SynMenu S-Sm.SAS:sas
SynMenu S-Sm.Sass:sass
SynMenu S-Sm.Sather:sather
+SynMenu S-Sm.Sbt:sbt
+SynMenu S-Sm.Scala:scala
SynMenu S-Sm.Scheme:scheme
SynMenu S-Sm.Scilab:scilab
SynMenu S-Sm.Screen\ RC:screen
@@ -546,6 +573,8 @@ SynMenu Sn-Sy.Sudoers:sudoers
SynMenu Sn-Sy.SVG:svg
SynMenu Sn-Sy.Symbian\ meta-makefile:mmp
SynMenu Sn-Sy.Sysctl\.conf:sysctl
+SynMenu Sn-Sy.Systemd:systemd
+SynMenu Sn-Sy.SystemVerilog:systemverilog
SynMenu T.TADS:tads
SynMenu T.Tags:tags
@@ -560,6 +589,7 @@ SynMenu T.TealInfo:tli
SynMenu T.Telix\ Salt:tsalt
SynMenu T.Termcap/Printcap:ptcap
SynMenu T.Terminfo:terminfo
+SynMenu T.Tera\ Term:teraterm
SynMenu T.TeX.TeX/LaTeX:tex
SynMenu T.TeX.plain\ TeX:plaintex
SynMenu T.TeX.Initex:initex
@@ -569,6 +599,7 @@ SynMenu T.TeX.Texinfo:texinfo
SynMenu T.TF\ mud\ client:tf
SynMenu T.Tidy\ configuration:tidy
SynMenu T.Tilde:tilde
+SynMenu T.Tmux\ configuration:tmux
SynMenu T.TPP:tpp
SynMenu T.Trasys\ input:trasys
SynMenu T.Treetop:treetop
@@ -586,6 +617,7 @@ SynMenu UV.Updatedb\.conf:updatedb
SynMenu UV.Upstart:upstart
SynMenu UV.Valgrind:valgrind
SynMenu UV.Vera:vera
+SynMenu UV.Verbose\ TAP\ Output:tap
SynMenu UV.Verilog-AMS\ HDL:verilogams
SynMenu UV.Verilog\ HDL:verilog
SynMenu UV.Vgrindefs:vgrindefs
@@ -597,6 +629,7 @@ SynMenu UV.Virata\ config:virata
SynMenu UV.Visual\ Basic:vb
SynMenu UV.VOS\ CM\ macro:voscm
SynMenu UV.VRML:vrml
+SynMenu UV.Vroom:vroom
SynMenu UV.VSE\ JCL:vsejcl
SynMenu WXYZ.WEB.CWEB:cweb
diff --git a/runtime/synmenu.vim b/runtime/synmenu.vim
index 6814c60e88..ec4c48b3da 100644
--- a/runtime/synmenu.vim
+++ b/runtime/synmenu.vim
@@ -56,46 +56,50 @@ an 50.10.270 &Syntax.AB.Applix\ ELF :cal SetSyn("elf")<CR>
an 50.10.280 &Syntax.AB.APT\ config :cal SetSyn("aptconf")<CR>
an 50.10.290 &Syntax.AB.Arc\ Macro\ Language :cal SetSyn("aml")<CR>
an 50.10.300 &Syntax.AB.Arch\ inventory :cal SetSyn("arch")<CR>
-an 50.10.310 &Syntax.AB.ART :cal SetSyn("art")<CR>
-an 50.10.320 &Syntax.AB.Ascii\ Doc :cal SetSyn("asciidoc")<CR>
-an 50.10.330 &Syntax.AB.ASP\ with\ VBScript :cal SetSyn("aspvbs")<CR>
-an 50.10.340 &Syntax.AB.ASP\ with\ Perl :cal SetSyn("aspperl")<CR>
-an 50.10.350 &Syntax.AB.Assembly.680x0 :cal SetSyn("asm68k")<CR>
-an 50.10.360 &Syntax.AB.Assembly.Flat :cal SetSyn("fasm")<CR>
-an 50.10.370 &Syntax.AB.Assembly.GNU :cal SetSyn("asm")<CR>
-an 50.10.380 &Syntax.AB.Assembly.GNU\ H-8300 :cal SetSyn("asmh8300")<CR>
-an 50.10.390 &Syntax.AB.Assembly.Intel\ IA-64 :cal SetSyn("ia64")<CR>
-an 50.10.400 &Syntax.AB.Assembly.Microsoft :cal SetSyn("masm")<CR>
-an 50.10.410 &Syntax.AB.Assembly.Netwide :cal SetSyn("nasm")<CR>
-an 50.10.420 &Syntax.AB.Assembly.PIC :cal SetSyn("pic")<CR>
-an 50.10.430 &Syntax.AB.Assembly.Turbo :cal SetSyn("tasm")<CR>
-an 50.10.440 &Syntax.AB.Assembly.VAX\ Macro\ Assembly :cal SetSyn("vmasm")<CR>
-an 50.10.450 &Syntax.AB.Assembly.Z-80 :cal SetSyn("z8a")<CR>
-an 50.10.460 &Syntax.AB.Assembly.xa\ 6502\ cross\ assember :cal SetSyn("a65")<CR>
-an 50.10.470 &Syntax.AB.ASN\.1 :cal SetSyn("asn")<CR>
-an 50.10.480 &Syntax.AB.Asterisk\ config :cal SetSyn("asterisk")<CR>
-an 50.10.490 &Syntax.AB.Asterisk\ voicemail\ config :cal SetSyn("asteriskvm")<CR>
-an 50.10.500 &Syntax.AB.Atlas :cal SetSyn("atlas")<CR>
-an 50.10.510 &Syntax.AB.AutoHotKey :cal SetSyn("autohotkey")<CR>
-an 50.10.520 &Syntax.AB.AutoIt :cal SetSyn("autoit")<CR>
-an 50.10.530 &Syntax.AB.Automake :cal SetSyn("automake")<CR>
-an 50.10.540 &Syntax.AB.Avenue :cal SetSyn("ave")<CR>
-an 50.10.550 &Syntax.AB.Awk :cal SetSyn("awk")<CR>
-an 50.10.560 &Syntax.AB.AYacc :cal SetSyn("ayacc")<CR>
-an 50.10.580 &Syntax.AB.B :cal SetSyn("b")<CR>
-an 50.10.590 &Syntax.AB.Baan :cal SetSyn("baan")<CR>
-an 50.10.600 &Syntax.AB.Basic.FreeBasic :cal SetSyn("freebasic")<CR>
-an 50.10.610 &Syntax.AB.Basic.IBasic :cal SetSyn("ibasic")<CR>
-an 50.10.620 &Syntax.AB.Basic.QBasic :cal SetSyn("basic")<CR>
-an 50.10.630 &Syntax.AB.Basic.Visual\ Basic :cal SetSyn("vb")<CR>
-an 50.10.640 &Syntax.AB.Bazaar\ commit\ file :cal SetSyn("bzr")<CR>
-an 50.10.650 &Syntax.AB.BC\ calculator :cal SetSyn("bc")<CR>
-an 50.10.660 &Syntax.AB.BDF\ font :cal SetSyn("bdf")<CR>
-an 50.10.670 &Syntax.AB.BibTeX.Bibliography\ database :cal SetSyn("bib")<CR>
-an 50.10.680 &Syntax.AB.BibTeX.Bibliography\ Style :cal SetSyn("bst")<CR>
-an 50.10.690 &Syntax.AB.BIND.BIND\ config :cal SetSyn("named")<CR>
-an 50.10.700 &Syntax.AB.BIND.BIND\ zone :cal SetSyn("bindzone")<CR>
-an 50.10.710 &Syntax.AB.Blank :cal SetSyn("blank")<CR>
+an 50.10.310 &Syntax.AB.Arduino :cal SetSyn("arduino")<CR>
+an 50.10.320 &Syntax.AB.ART :cal SetSyn("art")<CR>
+an 50.10.330 &Syntax.AB.Ascii\ Doc :cal SetSyn("asciidoc")<CR>
+an 50.10.340 &Syntax.AB.ASP\ with\ VBScript :cal SetSyn("aspvbs")<CR>
+an 50.10.350 &Syntax.AB.ASP\ with\ Perl :cal SetSyn("aspperl")<CR>
+an 50.10.360 &Syntax.AB.Assembly.680x0 :cal SetSyn("asm68k")<CR>
+an 50.10.370 &Syntax.AB.Assembly.AVR :cal SetSyn("avra")<CR>
+an 50.10.380 &Syntax.AB.Assembly.Flat :cal SetSyn("fasm")<CR>
+an 50.10.390 &Syntax.AB.Assembly.GNU :cal SetSyn("asm")<CR>
+an 50.10.400 &Syntax.AB.Assembly.GNU\ H-8300 :cal SetSyn("asmh8300")<CR>
+an 50.10.410 &Syntax.AB.Assembly.Intel\ IA-64 :cal SetSyn("ia64")<CR>
+an 50.10.420 &Syntax.AB.Assembly.Microsoft :cal SetSyn("masm")<CR>
+an 50.10.430 &Syntax.AB.Assembly.Netwide :cal SetSyn("nasm")<CR>
+an 50.10.440 &Syntax.AB.Assembly.PIC :cal SetSyn("pic")<CR>
+an 50.10.450 &Syntax.AB.Assembly.Turbo :cal SetSyn("tasm")<CR>
+an 50.10.460 &Syntax.AB.Assembly.VAX\ Macro\ Assembly :cal SetSyn("vmasm")<CR>
+an 50.10.470 &Syntax.AB.Assembly.Z-80 :cal SetSyn("z8a")<CR>
+an 50.10.480 &Syntax.AB.Assembly.xa\ 6502\ cross\ assember :cal SetSyn("a65")<CR>
+an 50.10.490 &Syntax.AB.ASN\.1 :cal SetSyn("asn")<CR>
+an 50.10.500 &Syntax.AB.Asterisk\ config :cal SetSyn("asterisk")<CR>
+an 50.10.510 &Syntax.AB.Asterisk\ voicemail\ config :cal SetSyn("asteriskvm")<CR>
+an 50.10.520 &Syntax.AB.Atlas :cal SetSyn("atlas")<CR>
+an 50.10.530 &Syntax.AB.Autodoc :cal SetSyn("autodoc")<CR>
+an 50.10.540 &Syntax.AB.AutoHotKey :cal SetSyn("autohotkey")<CR>
+an 50.10.550 &Syntax.AB.AutoIt :cal SetSyn("autoit")<CR>
+an 50.10.560 &Syntax.AB.Automake :cal SetSyn("automake")<CR>
+an 50.10.570 &Syntax.AB.Avenue :cal SetSyn("ave")<CR>
+an 50.10.580 &Syntax.AB.Awk :cal SetSyn("awk")<CR>
+an 50.10.590 &Syntax.AB.AYacc :cal SetSyn("ayacc")<CR>
+an 50.10.610 &Syntax.AB.B :cal SetSyn("b")<CR>
+an 50.10.620 &Syntax.AB.Baan :cal SetSyn("baan")<CR>
+an 50.10.630 &Syntax.AB.Basic.FreeBasic :cal SetSyn("freebasic")<CR>
+an 50.10.640 &Syntax.AB.Basic.IBasic :cal SetSyn("ibasic")<CR>
+an 50.10.650 &Syntax.AB.Basic.QBasic :cal SetSyn("basic")<CR>
+an 50.10.660 &Syntax.AB.Basic.Visual\ Basic :cal SetSyn("vb")<CR>
+an 50.10.670 &Syntax.AB.Bazaar\ commit\ file :cal SetSyn("bzr")<CR>
+an 50.10.680 &Syntax.AB.Bazel :cal SetSyn("bzl")<CR>
+an 50.10.690 &Syntax.AB.BC\ calculator :cal SetSyn("bc")<CR>
+an 50.10.700 &Syntax.AB.BDF\ font :cal SetSyn("bdf")<CR>
+an 50.10.710 &Syntax.AB.BibTeX.Bibliography\ database :cal SetSyn("bib")<CR>
+an 50.10.720 &Syntax.AB.BibTeX.Bibliography\ Style :cal SetSyn("bst")<CR>
+an 50.10.730 &Syntax.AB.BIND.BIND\ config :cal SetSyn("named")<CR>
+an 50.10.740 &Syntax.AB.BIND.BIND\ zone :cal SetSyn("bindzone")<CR>
+an 50.10.750 &Syntax.AB.Blank :cal SetSyn("blank")<CR>
an 50.20.100 &Syntax.C.C :cal SetSyn("c")<CR>
an 50.20.110 &Syntax.C.C++ :cal SetSyn("cpp")<CR>
an 50.20.120 &Syntax.C.C# :cal SetSyn("cs")<CR>
@@ -117,75 +121,81 @@ an 50.20.270 &Syntax.C.Clever :cal SetSyn("cl")<CR>
an 50.20.280 &Syntax.C.Clipper :cal SetSyn("clipper")<CR>
an 50.20.290 &Syntax.C.Clojure :cal SetSyn("clojure")<CR>
an 50.20.300 &Syntax.C.Cmake :cal SetSyn("cmake")<CR>
-an 50.20.310 &Syntax.C.Cmusrc :cal SetSyn("cmusrc")<CR>
-an 50.20.320 &Syntax.C.Cobol :cal SetSyn("cobol")<CR>
-an 50.20.330 &Syntax.C.Coco/R :cal SetSyn("coco")<CR>
-an 50.20.340 &Syntax.C.Cold\ Fusion :cal SetSyn("cf")<CR>
-an 50.20.350 &Syntax.C.Conary\ Recipe :cal SetSyn("conaryrecipe")<CR>
-an 50.20.360 &Syntax.C.Config.Cfg\ Config\ file :cal SetSyn("cfg")<CR>
-an 50.20.370 &Syntax.C.Config.Configure\.in :cal SetSyn("config")<CR>
-an 50.20.380 &Syntax.C.Config.Generic\ Config\ file :cal SetSyn("conf")<CR>
-an 50.20.390 &Syntax.C.CRM114 :cal SetSyn("crm")<CR>
-an 50.20.400 &Syntax.C.Crontab :cal SetSyn("crontab")<CR>
-an 50.20.410 &Syntax.C.CSDL :cal SetSyn("csdl")<CR>
-an 50.20.420 &Syntax.C.CSP :cal SetSyn("csp")<CR>
-an 50.20.430 &Syntax.C.Ctrl-H :cal SetSyn("ctrlh")<CR>
-an 50.20.440 &Syntax.C.Cucumber :cal SetSyn("cucumber")<CR>
-an 50.20.450 &Syntax.C.CUDA :cal SetSyn("cuda")<CR>
-an 50.20.460 &Syntax.C.CUPL.CUPL :cal SetSyn("cupl")<CR>
-an 50.20.470 &Syntax.C.CUPL.Simulation :cal SetSyn("cuplsim")<CR>
-an 50.20.480 &Syntax.C.CVS.commit\ file :cal SetSyn("cvs")<CR>
-an 50.20.490 &Syntax.C.CVS.cvsrc :cal SetSyn("cvsrc")<CR>
-an 50.20.500 &Syntax.C.Cyn++ :cal SetSyn("cynpp")<CR>
-an 50.20.510 &Syntax.C.Cynlib :cal SetSyn("cynlib")<CR>
+an 50.20.310 &Syntax.C.Cmod :cal SetSyn("cmod")<CR>
+an 50.20.320 &Syntax.C.Cmusrc :cal SetSyn("cmusrc")<CR>
+an 50.20.330 &Syntax.C.Cobol :cal SetSyn("cobol")<CR>
+an 50.20.340 &Syntax.C.Coco/R :cal SetSyn("coco")<CR>
+an 50.20.350 &Syntax.C.Cold\ Fusion :cal SetSyn("cf")<CR>
+an 50.20.360 &Syntax.C.Conary\ Recipe :cal SetSyn("conaryrecipe")<CR>
+an 50.20.370 &Syntax.C.Config.Cfg\ Config\ file :cal SetSyn("cfg")<CR>
+an 50.20.380 &Syntax.C.Config.Configure\.in :cal SetSyn("config")<CR>
+an 50.20.390 &Syntax.C.Config.Generic\ Config\ file :cal SetSyn("conf")<CR>
+an 50.20.400 &Syntax.C.CRM114 :cal SetSyn("crm")<CR>
+an 50.20.410 &Syntax.C.Crontab :cal SetSyn("crontab")<CR>
+an 50.20.420 &Syntax.C.CSDL :cal SetSyn("csdl")<CR>
+an 50.20.430 &Syntax.C.CSP :cal SetSyn("csp")<CR>
+an 50.20.440 &Syntax.C.Ctrl-H :cal SetSyn("ctrlh")<CR>
+an 50.20.450 &Syntax.C.Cucumber :cal SetSyn("cucumber")<CR>
+an 50.20.460 &Syntax.C.CUDA :cal SetSyn("cuda")<CR>
+an 50.20.470 &Syntax.C.CUPL.CUPL :cal SetSyn("cupl")<CR>
+an 50.20.480 &Syntax.C.CUPL.Simulation :cal SetSyn("cuplsim")<CR>
+an 50.20.490 &Syntax.C.CVS.commit\ file :cal SetSyn("cvs")<CR>
+an 50.20.500 &Syntax.C.CVS.cvsrc :cal SetSyn("cvsrc")<CR>
+an 50.20.510 &Syntax.C.Cyn++ :cal SetSyn("cynpp")<CR>
+an 50.20.520 &Syntax.C.Cynlib :cal SetSyn("cynlib")<CR>
an 50.30.100 &Syntax.DE.D :cal SetSyn("d")<CR>
an 50.30.110 &Syntax.DE.Datascript :cal SetSyn("datascript")<CR>
an 50.30.120 &Syntax.DE.Debian.Debian\ ChangeLog :cal SetSyn("debchangelog")<CR>
an 50.30.130 &Syntax.DE.Debian.Debian\ Control :cal SetSyn("debcontrol")<CR>
-an 50.30.140 &Syntax.DE.Debian.Debian\ Sources\.list :cal SetSyn("debsources")<CR>
-an 50.30.150 &Syntax.DE.Denyhosts :cal SetSyn("denyhosts")<CR>
-an 50.30.160 &Syntax.DE.Desktop :cal SetSyn("desktop")<CR>
-an 50.30.170 &Syntax.DE.Dict\ config :cal SetSyn("dictconf")<CR>
-an 50.30.180 &Syntax.DE.Dictd\ config :cal SetSyn("dictdconf")<CR>
-an 50.30.190 &Syntax.DE.Diff :cal SetSyn("diff")<CR>
-an 50.30.200 &Syntax.DE.Digital\ Command\ Lang :cal SetSyn("dcl")<CR>
-an 50.30.210 &Syntax.DE.Dircolors :cal SetSyn("dircolors")<CR>
-an 50.30.220 &Syntax.DE.Django\ template :cal SetSyn("django")<CR>
-an 50.30.230 &Syntax.DE.DNS/BIND\ zone :cal SetSyn("bindzone")<CR>
-an 50.30.240 &Syntax.DE.Dnsmasq\ config :cal SetSyn("dnsmasq")<CR>
-an 50.30.250 &Syntax.DE.DocBook.auto-detect :cal SetSyn("docbk")<CR>
-an 50.30.260 &Syntax.DE.DocBook.SGML :cal SetSyn("docbksgml")<CR>
-an 50.30.270 &Syntax.DE.DocBook.XML :cal SetSyn("docbkxml")<CR>
-an 50.30.280 &Syntax.DE.Dot :cal SetSyn("dot")<CR>
-an 50.30.290 &Syntax.DE.Doxygen.C\ with\ doxygen :cal SetSyn("c.doxygen")<CR>
-an 50.30.300 &Syntax.DE.Doxygen.C++\ with\ doxygen :cal SetSyn("cpp.doxygen")<CR>
-an 50.30.310 &Syntax.DE.Doxygen.IDL\ with\ doxygen :cal SetSyn("idl.doxygen")<CR>
-an 50.30.320 &Syntax.DE.Doxygen.Java\ with\ doxygen :cal SetSyn("java.doxygen")<CR>
-an 50.30.330 &Syntax.DE.Doxygen.DataScript\ with\ doxygen :cal SetSyn("datascript.doxygen")<CR>
-an 50.30.340 &Syntax.DE.Dracula :cal SetSyn("dracula")<CR>
-an 50.30.350 &Syntax.DE.DSSSL :cal SetSyn("dsl")<CR>
-an 50.30.360 &Syntax.DE.DTD :cal SetSyn("dtd")<CR>
-an 50.30.370 &Syntax.DE.DTML\ (Zope) :cal SetSyn("dtml")<CR>
-an 50.30.380 &Syntax.DE.DTrace :cal SetSyn("dtrace")<CR>
-an 50.30.390 &Syntax.DE.Dts/dtsi :cal SetSyn("dts")<CR>
-an 50.30.400 &Syntax.DE.Dylan.Dylan :cal SetSyn("dylan")<CR>
-an 50.30.410 &Syntax.DE.Dylan.Dylan\ interface :cal SetSyn("dylanintr")<CR>
-an 50.30.420 &Syntax.DE.Dylan.Dylan\ lid :cal SetSyn("dylanlid")<CR>
-an 50.30.440 &Syntax.DE.EDIF :cal SetSyn("edif")<CR>
-an 50.30.450 &Syntax.DE.Eiffel :cal SetSyn("eiffel")<CR>
-an 50.30.460 &Syntax.DE.Elinks\ config :cal SetSyn("elinks")<CR>
-an 50.30.470 &Syntax.DE.Elm\ filter\ rules :cal SetSyn("elmfilt")<CR>
-an 50.30.480 &Syntax.DE.Embedix\ Component\ Description :cal SetSyn("ecd")<CR>
-an 50.30.490 &Syntax.DE.ERicsson\ LANGuage :cal SetSyn("erlang")<CR>
-an 50.30.500 &Syntax.DE.ESMTP\ rc :cal SetSyn("esmtprc")<CR>
-an 50.30.510 &Syntax.DE.ESQL-C :cal SetSyn("esqlc")<CR>
-an 50.30.520 &Syntax.DE.Essbase\ script :cal SetSyn("csc")<CR>
-an 50.30.530 &Syntax.DE.Esterel :cal SetSyn("esterel")<CR>
-an 50.30.540 &Syntax.DE.Eterm\ config :cal SetSyn("eterm")<CR>
-an 50.30.550 &Syntax.DE.Eviews :cal SetSyn("eviews")<CR>
-an 50.30.560 &Syntax.DE.Exim\ conf :cal SetSyn("exim")<CR>
-an 50.30.570 &Syntax.DE.Expect :cal SetSyn("expect")<CR>
-an 50.30.580 &Syntax.DE.Exports :cal SetSyn("exports")<CR>
+an 50.30.140 &Syntax.DE.Debian.Debian\ Copyright :cal SetSyn("debcopyright")<CR>
+an 50.30.150 &Syntax.DE.Debian.Debian\ Sources\.list :cal SetSyn("debsources")<CR>
+an 50.30.160 &Syntax.DE.Denyhosts :cal SetSyn("denyhosts")<CR>
+an 50.30.170 &Syntax.DE.Desktop :cal SetSyn("desktop")<CR>
+an 50.30.180 &Syntax.DE.Dict\ config :cal SetSyn("dictconf")<CR>
+an 50.30.190 &Syntax.DE.Dictd\ config :cal SetSyn("dictdconf")<CR>
+an 50.30.200 &Syntax.DE.Diff :cal SetSyn("diff")<CR>
+an 50.30.210 &Syntax.DE.Digital\ Command\ Lang :cal SetSyn("dcl")<CR>
+an 50.30.220 &Syntax.DE.Dircolors :cal SetSyn("dircolors")<CR>
+an 50.30.230 &Syntax.DE.Dirpager :cal SetSyn("dirpager")<CR>
+an 50.30.240 &Syntax.DE.Django\ template :cal SetSyn("django")<CR>
+an 50.30.250 &Syntax.DE.DNS/BIND\ zone :cal SetSyn("bindzone")<CR>
+an 50.30.260 &Syntax.DE.Dnsmasq\ config :cal SetSyn("dnsmasq")<CR>
+an 50.30.270 &Syntax.DE.DocBook.auto-detect :cal SetSyn("docbk")<CR>
+an 50.30.280 &Syntax.DE.DocBook.SGML :cal SetSyn("docbksgml")<CR>
+an 50.30.290 &Syntax.DE.DocBook.XML :cal SetSyn("docbkxml")<CR>
+an 50.30.300 &Syntax.DE.Dockerfile :cal SetSyn("dockerfile")<CR>
+an 50.30.310 &Syntax.DE.Dot :cal SetSyn("dot")<CR>
+an 50.30.320 &Syntax.DE.Doxygen.C\ with\ doxygen :cal SetSyn("c.doxygen")<CR>
+an 50.30.330 &Syntax.DE.Doxygen.C++\ with\ doxygen :cal SetSyn("cpp.doxygen")<CR>
+an 50.30.340 &Syntax.DE.Doxygen.IDL\ with\ doxygen :cal SetSyn("idl.doxygen")<CR>
+an 50.30.350 &Syntax.DE.Doxygen.Java\ with\ doxygen :cal SetSyn("java.doxygen")<CR>
+an 50.30.360 &Syntax.DE.Doxygen.DataScript\ with\ doxygen :cal SetSyn("datascript.doxygen")<CR>
+an 50.30.370 &Syntax.DE.Dracula :cal SetSyn("dracula")<CR>
+an 50.30.380 &Syntax.DE.DSSSL :cal SetSyn("dsl")<CR>
+an 50.30.390 &Syntax.DE.DTD :cal SetSyn("dtd")<CR>
+an 50.30.400 &Syntax.DE.DTML\ (Zope) :cal SetSyn("dtml")<CR>
+an 50.30.410 &Syntax.DE.DTrace :cal SetSyn("dtrace")<CR>
+an 50.30.420 &Syntax.DE.Dts/dtsi :cal SetSyn("dts")<CR>
+an 50.30.430 &Syntax.DE.Dylan.Dylan :cal SetSyn("dylan")<CR>
+an 50.30.440 &Syntax.DE.Dylan.Dylan\ interface :cal SetSyn("dylanintr")<CR>
+an 50.30.450 &Syntax.DE.Dylan.Dylan\ lid :cal SetSyn("dylanlid")<CR>
+an 50.30.470 &Syntax.DE.EDIF :cal SetSyn("edif")<CR>
+an 50.30.480 &Syntax.DE.Eiffel :cal SetSyn("eiffel")<CR>
+an 50.30.490 &Syntax.DE.Elinks\ config :cal SetSyn("elinks")<CR>
+an 50.30.500 &Syntax.DE.Elm\ filter\ rules :cal SetSyn("elmfilt")<CR>
+an 50.30.510 &Syntax.DE.Embedix\ Component\ Description :cal SetSyn("ecd")<CR>
+an 50.30.520 &Syntax.DE.ERicsson\ LANGuage :cal SetSyn("erlang")<CR>
+an 50.30.530 &Syntax.DE.ESMTP\ rc :cal SetSyn("esmtprc")<CR>
+an 50.30.540 &Syntax.DE.ESQL-C :cal SetSyn("esqlc")<CR>
+an 50.30.550 &Syntax.DE.Essbase\ script :cal SetSyn("csc")<CR>
+an 50.30.560 &Syntax.DE.Esterel :cal SetSyn("esterel")<CR>
+an 50.30.570 &Syntax.DE.Eterm\ config :cal SetSyn("eterm")<CR>
+an 50.30.580 &Syntax.DE.Euphoria\ 3 :cal SetSyn("euphoria3")<CR>
+an 50.30.590 &Syntax.DE.Euphoria\ 4 :cal SetSyn("euphoria4")<CR>
+an 50.30.600 &Syntax.DE.Eviews :cal SetSyn("eviews")<CR>
+an 50.30.610 &Syntax.DE.Exim\ conf :cal SetSyn("exim")<CR>
+an 50.30.620 &Syntax.DE.Expect :cal SetSyn("expect")<CR>
+an 50.30.630 &Syntax.DE.Exports :cal SetSyn("exports")<CR>
an 50.40.100 &Syntax.FG.Falcon :cal SetSyn("falcon")<CR>
an 50.40.110 &Syntax.FG.Fantom :cal SetSyn("fan")<CR>
an 50.40.120 &Syntax.FG.Fetchmail :cal SetSyn("fetchmail")<CR>
@@ -212,18 +222,20 @@ an 50.40.330 &Syntax.FG.Git.Send\ Email :cal SetSyn("gitsendemail")<CR>
an 50.40.340 &Syntax.FG.Gitolite :cal SetSyn("gitolite")<CR>
an 50.40.350 &Syntax.FG.Gkrellmrc :cal SetSyn("gkrellmrc")<CR>
an 50.40.360 &Syntax.FG.Gnash :cal SetSyn("gnash")<CR>
-an 50.40.370 &Syntax.FG.GP :cal SetSyn("gp")<CR>
-an 50.40.380 &Syntax.FG.GPG :cal SetSyn("gpg")<CR>
-an 50.40.390 &Syntax.FG.Grof :cal SetSyn("gprof")<CR>
-an 50.40.400 &Syntax.FG.Group\ file :cal SetSyn("group")<CR>
-an 50.40.410 &Syntax.FG.Grub :cal SetSyn("grub")<CR>
-an 50.40.420 &Syntax.FG.GNU\ Server\ Pages :cal SetSyn("gsp")<CR>
-an 50.40.430 &Syntax.FG.GNUplot :cal SetSyn("gnuplot")<CR>
-an 50.40.440 &Syntax.FG.GrADS\ scripts :cal SetSyn("grads")<CR>
-an 50.40.450 &Syntax.FG.Gretl :cal SetSyn("gretl")<CR>
-an 50.40.460 &Syntax.FG.Groff :cal SetSyn("groff")<CR>
-an 50.40.470 &Syntax.FG.Groovy :cal SetSyn("groovy")<CR>
-an 50.40.480 &Syntax.FG.GTKrc :cal SetSyn("gtkrc")<CR>
+an 50.40.370 &Syntax.FG.Go :cal SetSyn("go")<CR>
+an 50.40.380 &Syntax.FG.Godoc :cal SetSyn("godoc")<CR>
+an 50.40.390 &Syntax.FG.GP :cal SetSyn("gp")<CR>
+an 50.40.400 &Syntax.FG.GPG :cal SetSyn("gpg")<CR>
+an 50.40.410 &Syntax.FG.Grof :cal SetSyn("gprof")<CR>
+an 50.40.420 &Syntax.FG.Group\ file :cal SetSyn("group")<CR>
+an 50.40.430 &Syntax.FG.Grub :cal SetSyn("grub")<CR>
+an 50.40.440 &Syntax.FG.GNU\ Server\ Pages :cal SetSyn("gsp")<CR>
+an 50.40.450 &Syntax.FG.GNUplot :cal SetSyn("gnuplot")<CR>
+an 50.40.460 &Syntax.FG.GrADS\ scripts :cal SetSyn("grads")<CR>
+an 50.40.470 &Syntax.FG.Gretl :cal SetSyn("gretl")<CR>
+an 50.40.480 &Syntax.FG.Groff :cal SetSyn("groff")<CR>
+an 50.40.490 &Syntax.FG.Groovy :cal SetSyn("groovy")<CR>
+an 50.40.500 &Syntax.FG.GTKrc :cal SetSyn("gtkrc")<CR>
an 50.50.100 &Syntax.HIJK.Haml :cal SetSyn("haml")<CR>
an 50.50.110 &Syntax.HIJK.Hamster :cal SetSyn("hamster")<CR>
an 50.50.120 &Syntax.HIJK.Haskell.Haskell :cal SetSyn("haskell")<CR>
@@ -257,55 +269,60 @@ an 50.50.400 &Syntax.HIJK.Inittab :cal SetSyn("inittab")<CR>
an 50.50.410 &Syntax.HIJK.Inno\ setup :cal SetSyn("iss")<CR>
an 50.50.420 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ dat :cal SetSyn("upstreamdat")<CR>
an 50.50.430 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ log :cal SetSyn("upstreamlog")<CR>
-an 50.50.440 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ Install\ log :cal SetSyn("upstreaminstalllog")<CR>
-an 50.50.450 &Syntax.HIJK.Innovation\ Data\ Processing.Usserver\ log :cal SetSyn("usserverlog")<CR>
-an 50.50.460 &Syntax.HIJK.Innovation\ Data\ Processing.USW2KAgt\ log :cal SetSyn("usw2kagtlog")<CR>
-an 50.50.470 &Syntax.HIJK.InstallShield\ script :cal SetSyn("ishd")<CR>
-an 50.50.480 &Syntax.HIJK.Interactive\ Data\ Lang :cal SetSyn("idlang")<CR>
-an 50.50.490 &Syntax.HIJK.IPfilter :cal SetSyn("ipfilter")<CR>
-an 50.50.510 &Syntax.HIJK.JAL :cal SetSyn("jal")<CR>
-an 50.50.520 &Syntax.HIJK.JAM :cal SetSyn("jam")<CR>
-an 50.50.530 &Syntax.HIJK.Jargon :cal SetSyn("jargon")<CR>
-an 50.50.540 &Syntax.HIJK.Java.Java :cal SetSyn("java")<CR>
-an 50.50.550 &Syntax.HIJK.Java.JavaCC :cal SetSyn("javacc")<CR>
-an 50.50.560 &Syntax.HIJK.Java.Java\ Server\ Pages :cal SetSyn("jsp")<CR>
-an 50.50.570 &Syntax.HIJK.Java.Java\ Properties :cal SetSyn("jproperties")<CR>
-an 50.50.580 &Syntax.HIJK.JavaScript :cal SetSyn("javascript")<CR>
-an 50.50.590 &Syntax.HIJK.Jess :cal SetSyn("jess")<CR>
-an 50.50.600 &Syntax.HIJK.Jgraph :cal SetSyn("jgraph")<CR>
-an 50.50.610 &Syntax.HIJK.Jovial :cal SetSyn("jovial")<CR>
-an 50.50.630 &Syntax.HIJK.Kconfig :cal SetSyn("kconfig")<CR>
-an 50.50.640 &Syntax.HIJK.KDE\ script :cal SetSyn("kscript")<CR>
-an 50.50.650 &Syntax.HIJK.Kimwitu++ :cal SetSyn("kwt")<CR>
-an 50.50.660 &Syntax.HIJK.KixTart :cal SetSyn("kix")<CR>
+an 50.50.440 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ rpt :cal SetSyn("upstreamrpt")<CR>
+an 50.50.450 &Syntax.HIJK.Innovation\ Data\ Processing.Upstream\ Install\ log :cal SetSyn("upstreaminstalllog")<CR>
+an 50.50.460 &Syntax.HIJK.Innovation\ Data\ Processing.Usserver\ log :cal SetSyn("usserverlog")<CR>
+an 50.50.470 &Syntax.HIJK.Innovation\ Data\ Processing.USW2KAgt\ log :cal SetSyn("usw2kagtlog")<CR>
+an 50.50.480 &Syntax.HIJK.InstallShield\ script :cal SetSyn("ishd")<CR>
+an 50.50.490 &Syntax.HIJK.Interactive\ Data\ Lang :cal SetSyn("idlang")<CR>
+an 50.50.500 &Syntax.HIJK.IPfilter :cal SetSyn("ipfilter")<CR>
+an 50.50.520 &Syntax.HIJK.J :cal SetSyn("j")<CR>
+an 50.50.530 &Syntax.HIJK.JAL :cal SetSyn("jal")<CR>
+an 50.50.540 &Syntax.HIJK.JAM :cal SetSyn("jam")<CR>
+an 50.50.550 &Syntax.HIJK.Jargon :cal SetSyn("jargon")<CR>
+an 50.50.560 &Syntax.HIJK.Java.Java :cal SetSyn("java")<CR>
+an 50.50.570 &Syntax.HIJK.Java.JavaCC :cal SetSyn("javacc")<CR>
+an 50.50.580 &Syntax.HIJK.Java.Java\ Server\ Pages :cal SetSyn("jsp")<CR>
+an 50.50.590 &Syntax.HIJK.Java.Java\ Properties :cal SetSyn("jproperties")<CR>
+an 50.50.600 &Syntax.HIJK.JavaScript :cal SetSyn("javascript")<CR>
+an 50.50.610 &Syntax.HIJK.Jess :cal SetSyn("jess")<CR>
+an 50.50.620 &Syntax.HIJK.Jgraph :cal SetSyn("jgraph")<CR>
+an 50.50.630 &Syntax.HIJK.Jovial :cal SetSyn("jovial")<CR>
+an 50.50.640 &Syntax.HIJK.JSON :cal SetSyn("json")<CR>
+an 50.50.660 &Syntax.HIJK.Kconfig :cal SetSyn("kconfig")<CR>
+an 50.50.670 &Syntax.HIJK.KDE\ script :cal SetSyn("kscript")<CR>
+an 50.50.680 &Syntax.HIJK.Kimwitu++ :cal SetSyn("kwt")<CR>
+an 50.50.690 &Syntax.HIJK.Kivy :cal SetSyn("kivy")<CR>
+an 50.50.700 &Syntax.HIJK.KixTart :cal SetSyn("kix")<CR>
an 50.60.100 &Syntax.L.Lace :cal SetSyn("lace")<CR>
an 50.60.110 &Syntax.L.LamdaProlog :cal SetSyn("lprolog")<CR>
an 50.60.120 &Syntax.L.Latte :cal SetSyn("latte")<CR>
an 50.60.130 &Syntax.L.Ld\ script :cal SetSyn("ld")<CR>
an 50.60.140 &Syntax.L.LDAP.LDIF :cal SetSyn("ldif")<CR>
an 50.60.150 &Syntax.L.LDAP.Configuration :cal SetSyn("ldapconf")<CR>
-an 50.60.160 &Syntax.L.Lex :cal SetSyn("lex")<CR>
-an 50.60.170 &Syntax.L.LFTP\ config :cal SetSyn("lftp")<CR>
-an 50.60.180 &Syntax.L.Libao :cal SetSyn("libao")<CR>
-an 50.60.190 &Syntax.L.LifeLines\ script :cal SetSyn("lifelines")<CR>
-an 50.60.200 &Syntax.L.Lilo :cal SetSyn("lilo")<CR>
-an 50.60.210 &Syntax.L.Limits\ config :cal SetSyn("limits")<CR>
-an 50.60.220 &Syntax.L.Linden\ scripting :cal SetSyn("lsl")<CR>
-an 50.60.230 &Syntax.L.Liquid :cal SetSyn("liquid")<CR>
-an 50.60.240 &Syntax.L.Lisp :cal SetSyn("lisp")<CR>
-an 50.60.250 &Syntax.L.Lite :cal SetSyn("lite")<CR>
-an 50.60.260 &Syntax.L.LiteStep\ RC :cal SetSyn("litestep")<CR>
-an 50.60.270 &Syntax.L.Locale\ Input :cal SetSyn("fdcc")<CR>
-an 50.60.280 &Syntax.L.Login\.access :cal SetSyn("loginaccess")<CR>
-an 50.60.290 &Syntax.L.Login\.defs :cal SetSyn("logindefs")<CR>
-an 50.60.300 &Syntax.L.Logtalk :cal SetSyn("logtalk")<CR>
-an 50.60.310 &Syntax.L.LOTOS :cal SetSyn("lotos")<CR>
-an 50.60.320 &Syntax.L.LotusScript :cal SetSyn("lscript")<CR>
-an 50.60.330 &Syntax.L.Lout :cal SetSyn("lout")<CR>
-an 50.60.340 &Syntax.L.LPC :cal SetSyn("lpc")<CR>
-an 50.60.350 &Syntax.L.Lua :cal SetSyn("lua")<CR>
-an 50.60.360 &Syntax.L.Lynx\ Style :cal SetSyn("lss")<CR>
-an 50.60.370 &Syntax.L.Lynx\ config :cal SetSyn("lynx")<CR>
+an 50.60.160 &Syntax.L.Less :cal SetSyn("less")<CR>
+an 50.60.170 &Syntax.L.Lex :cal SetSyn("lex")<CR>
+an 50.60.180 &Syntax.L.LFTP\ config :cal SetSyn("lftp")<CR>
+an 50.60.190 &Syntax.L.Libao :cal SetSyn("libao")<CR>
+an 50.60.200 &Syntax.L.LifeLines\ script :cal SetSyn("lifelines")<CR>
+an 50.60.210 &Syntax.L.Lilo :cal SetSyn("lilo")<CR>
+an 50.60.220 &Syntax.L.Limits\ config :cal SetSyn("limits")<CR>
+an 50.60.230 &Syntax.L.Linden\ scripting :cal SetSyn("lsl")<CR>
+an 50.60.240 &Syntax.L.Liquid :cal SetSyn("liquid")<CR>
+an 50.60.250 &Syntax.L.Lisp :cal SetSyn("lisp")<CR>
+an 50.60.260 &Syntax.L.Lite :cal SetSyn("lite")<CR>
+an 50.60.270 &Syntax.L.LiteStep\ RC :cal SetSyn("litestep")<CR>
+an 50.60.280 &Syntax.L.Locale\ Input :cal SetSyn("fdcc")<CR>
+an 50.60.290 &Syntax.L.Login\.access :cal SetSyn("loginaccess")<CR>
+an 50.60.300 &Syntax.L.Login\.defs :cal SetSyn("logindefs")<CR>
+an 50.60.310 &Syntax.L.Logtalk :cal SetSyn("logtalk")<CR>
+an 50.60.320 &Syntax.L.LOTOS :cal SetSyn("lotos")<CR>
+an 50.60.330 &Syntax.L.LotusScript :cal SetSyn("lscript")<CR>
+an 50.60.340 &Syntax.L.Lout :cal SetSyn("lout")<CR>
+an 50.60.350 &Syntax.L.LPC :cal SetSyn("lpc")<CR>
+an 50.60.360 &Syntax.L.Lua :cal SetSyn("lua")<CR>
+an 50.60.370 &Syntax.L.Lynx\ Style :cal SetSyn("lss")<CR>
+an 50.60.380 &Syntax.L.Lynx\ config :cal SetSyn("lynx")<CR>
an 50.70.100 &Syntax.M.M4 :cal SetSyn("m4")<CR>
an 50.70.110 &Syntax.M.MaGic\ Point :cal SetSyn("mgp")<CR>
an 50.70.120 &Syntax.M.Mail :cal SetSyn("mail")<CR>
@@ -318,55 +335,60 @@ an 50.70.180 &Syntax.M.Man\ page :cal SetSyn("man")<CR>
an 50.70.190 &Syntax.M.Man\.conf :cal SetSyn("manconf")<CR>
an 50.70.200 &Syntax.M.Maple\ V :cal SetSyn("maple")<CR>
an 50.70.210 &Syntax.M.Markdown :cal SetSyn("markdown")<CR>
-an 50.70.220 &Syntax.M.Mason :cal SetSyn("mason")<CR>
-an 50.70.230 &Syntax.M.Mathematica :cal SetSyn("mma")<CR>
-an 50.70.240 &Syntax.M.Matlab :cal SetSyn("matlab")<CR>
-an 50.70.250 &Syntax.M.Maxima :cal SetSyn("maxima")<CR>
-an 50.70.260 &Syntax.M.MEL\ (for\ Maya) :cal SetSyn("mel")<CR>
-an 50.70.270 &Syntax.M.Messages\ (/var/log) :cal SetSyn("messages")<CR>
-an 50.70.280 &Syntax.M.Metafont :cal SetSyn("mf")<CR>
-an 50.70.290 &Syntax.M.MetaPost :cal SetSyn("mp")<CR>
-an 50.70.300 &Syntax.M.MGL :cal SetSyn("mgl")<CR>
-an 50.70.310 &Syntax.M.MMIX :cal SetSyn("mmix")<CR>
-an 50.70.320 &Syntax.M.Modconf :cal SetSyn("modconf")<CR>
-an 50.70.330 &Syntax.M.Model :cal SetSyn("model")<CR>
-an 50.70.340 &Syntax.M.Modsim\ III :cal SetSyn("modsim3")<CR>
-an 50.70.350 &Syntax.M.Modula\ 2 :cal SetSyn("modula2")<CR>
-an 50.70.360 &Syntax.M.Modula\ 3 :cal SetSyn("modula3")<CR>
-an 50.70.370 &Syntax.M.Monk :cal SetSyn("monk")<CR>
-an 50.70.380 &Syntax.M.Mplayer\ config :cal SetSyn("mplayerconf")<CR>
-an 50.70.390 &Syntax.M.MOO :cal SetSyn("moo")<CR>
-an 50.70.400 &Syntax.M.Mrxvtrc :cal SetSyn("mrxvtrc")<CR>
-an 50.70.410 &Syntax.M.MS-DOS/Windows.4DOS\ \.bat\ file :cal SetSyn("btm")<CR>
-an 50.70.420 &Syntax.M.MS-DOS/Windows.\.bat\/\.cmd\ file :cal SetSyn("dosbatch")<CR>
-an 50.70.430 &Syntax.M.MS-DOS/Windows.\.ini\ file :cal SetSyn("dosini")<CR>
-an 50.70.440 &Syntax.M.MS-DOS/Windows.Message\ text :cal SetSyn("msmessages")<CR>
-an 50.70.450 &Syntax.M.MS-DOS/Windows.Module\ Definition :cal SetSyn("def")<CR>
-an 50.70.460 &Syntax.M.MS-DOS/Windows.Registry :cal SetSyn("registry")<CR>
-an 50.70.470 &Syntax.M.MS-DOS/Windows.Resource\ file :cal SetSyn("rc")<CR>
-an 50.70.480 &Syntax.M.Msql :cal SetSyn("msql")<CR>
-an 50.70.490 &Syntax.M.MuPAD :cal SetSyn("mupad")<CR>
-an 50.70.500 &Syntax.M.MUSHcode :cal SetSyn("mush")<CR>
-an 50.70.510 &Syntax.M.Muttrc :cal SetSyn("muttrc")<CR>
-an 50.80.100 &Syntax.NO.Nanorc :cal SetSyn("nanorc")<CR>
-an 50.80.110 &Syntax.NO.Nastran\ input/DMAP :cal SetSyn("nastran")<CR>
-an 50.80.120 &Syntax.NO.Natural :cal SetSyn("natural")<CR>
-an 50.80.130 &Syntax.NO.Neomuttrc :cal SetSyn("neomuttrc")<CR>
-an 50.80.140 &Syntax.NO.Netrc :cal SetSyn("netrc")<CR>
-an 50.80.150 &Syntax.NO.Ninja :cal SetSyn("ninja")<CR>
-an 50.80.160 &Syntax.NO.Novell\ NCF\ batch :cal SetSyn("ncf")<CR>
-an 50.80.170 &Syntax.NO.Not\ Quite\ C\ (LEGO) :cal SetSyn("nqc")<CR>
-an 50.80.180 &Syntax.NO.Nroff :cal SetSyn("nroff")<CR>
-an 50.80.190 &Syntax.NO.NSIS\ script :cal SetSyn("nsis")<CR>
-an 50.80.200 &Syntax.NO.Obj\ 3D\ wavefront :cal SetSyn("obj")<CR>
-an 50.80.210 &Syntax.NO.Objective\ C :cal SetSyn("objc")<CR>
-an 50.80.220 &Syntax.NO.Objective\ C++ :cal SetSyn("objcpp")<CR>
-an 50.80.230 &Syntax.NO.OCAML :cal SetSyn("ocaml")<CR>
-an 50.80.240 &Syntax.NO.Occam :cal SetSyn("occam")<CR>
-an 50.80.250 &Syntax.NO.Omnimark :cal SetSyn("omnimark")<CR>
-an 50.80.260 &Syntax.NO.OpenROAD :cal SetSyn("openroad")<CR>
-an 50.80.270 &Syntax.NO.Open\ Psion\ Lang :cal SetSyn("opl")<CR>
-an 50.80.280 &Syntax.NO.Oracle\ config :cal SetSyn("ora")<CR>
+an 50.70.220 &Syntax.M.Markdown\ with\ R\ statements :cal SetSyn("rmd")<CR>
+an 50.70.230 &Syntax.M.Mason :cal SetSyn("mason")<CR>
+an 50.70.240 &Syntax.M.Mathematica :cal SetSyn("mma")<CR>
+an 50.70.250 &Syntax.M.Matlab :cal SetSyn("matlab")<CR>
+an 50.70.260 &Syntax.M.Maxima :cal SetSyn("maxima")<CR>
+an 50.70.270 &Syntax.M.MEL\ (for\ Maya) :cal SetSyn("mel")<CR>
+an 50.70.280 &Syntax.M.Messages\ (/var/log) :cal SetSyn("messages")<CR>
+an 50.70.290 &Syntax.M.Metafont :cal SetSyn("mf")<CR>
+an 50.70.300 &Syntax.M.MetaPost :cal SetSyn("mp")<CR>
+an 50.70.310 &Syntax.M.MGL :cal SetSyn("mgl")<CR>
+an 50.70.320 &Syntax.M.MIX :cal SetSyn("mix")<CR>
+an 50.70.330 &Syntax.M.MMIX :cal SetSyn("mmix")<CR>
+an 50.70.340 &Syntax.M.Modconf :cal SetSyn("modconf")<CR>
+an 50.70.350 &Syntax.M.Model :cal SetSyn("model")<CR>
+an 50.70.360 &Syntax.M.Modsim\ III :cal SetSyn("modsim3")<CR>
+an 50.70.370 &Syntax.M.Modula\ 2 :cal SetSyn("modula2")<CR>
+an 50.70.380 &Syntax.M.Modula\ 3 :cal SetSyn("modula3")<CR>
+an 50.70.390 &Syntax.M.Monk :cal SetSyn("monk")<CR>
+an 50.70.400 &Syntax.M.Motorola\ S-Record :cal SetSyn("srec")<CR>
+an 50.70.410 &Syntax.M.Mplayer\ config :cal SetSyn("mplayerconf")<CR>
+an 50.70.420 &Syntax.M.MOO :cal SetSyn("moo")<CR>
+an 50.70.430 &Syntax.M.Mrxvtrc :cal SetSyn("mrxvtrc")<CR>
+an 50.70.440 &Syntax.M.MS-DOS/Windows.4DOS\ \.bat\ file :cal SetSyn("btm")<CR>
+an 50.70.450 &Syntax.M.MS-DOS/Windows.\.bat\/\.cmd\ file :cal SetSyn("dosbatch")<CR>
+an 50.70.460 &Syntax.M.MS-DOS/Windows.\.ini\ file :cal SetSyn("dosini")<CR>
+an 50.70.470 &Syntax.M.MS-DOS/Windows.Message\ text :cal SetSyn("msmessages")<CR>
+an 50.70.480 &Syntax.M.MS-DOS/Windows.Module\ Definition :cal SetSyn("def")<CR>
+an 50.70.490 &Syntax.M.MS-DOS/Windows.Registry :cal SetSyn("registry")<CR>
+an 50.70.500 &Syntax.M.MS-DOS/Windows.Resource\ file :cal SetSyn("rc")<CR>
+an 50.70.510 &Syntax.M.Msql :cal SetSyn("msql")<CR>
+an 50.70.520 &Syntax.M.MuPAD :cal SetSyn("mupad")<CR>
+an 50.70.530 &Syntax.M.Murphi :cal SetSyn("murphi")<CR>
+an 50.70.540 &Syntax.M.MUSHcode :cal SetSyn("mush")<CR>
+an 50.70.550 &Syntax.M.Muttrc :cal SetSyn("muttrc")<CR>
+an 50.80.100 &Syntax.NO.N1QL :cal SetSyn("n1ql")<CR>
+an 50.80.110 &Syntax.NO.Nanorc :cal SetSyn("nanorc")<CR>
+an 50.80.120 &Syntax.NO.Nastran\ input/DMAP :cal SetSyn("nastran")<CR>
+an 50.80.130 &Syntax.NO.Natural :cal SetSyn("natural")<CR>
+an 50.80.140 &Syntax.NO.NeoMutt\ setup\ files :cal SetSyn("neomuttrc")<CR>
+an 50.80.150 &Syntax.NO.Netrc :cal SetSyn("netrc")<CR>
+an 50.80.160 &Syntax.NO.Ninja :cal SetSyn("ninja")<CR>
+an 50.80.170 &Syntax.NO.Novell\ NCF\ batch :cal SetSyn("ncf")<CR>
+an 50.80.180 &Syntax.NO.Not\ Quite\ C\ (LEGO) :cal SetSyn("nqc")<CR>
+an 50.80.190 &Syntax.NO.Nroff :cal SetSyn("nroff")<CR>
+an 50.80.200 &Syntax.NO.NSIS\ script :cal SetSyn("nsis")<CR>
+an 50.80.220 &Syntax.NO.Obj\ 3D\ wavefront :cal SetSyn("obj")<CR>
+an 50.80.230 &Syntax.NO.Objective\ C :cal SetSyn("objc")<CR>
+an 50.80.240 &Syntax.NO.Objective\ C++ :cal SetSyn("objcpp")<CR>
+an 50.80.250 &Syntax.NO.OCAML :cal SetSyn("ocaml")<CR>
+an 50.80.260 &Syntax.NO.Occam :cal SetSyn("occam")<CR>
+an 50.80.270 &Syntax.NO.Omnimark :cal SetSyn("omnimark")<CR>
+an 50.80.280 &Syntax.NO.OpenROAD :cal SetSyn("openroad")<CR>
+an 50.80.290 &Syntax.NO.Open\ Psion\ Lang :cal SetSyn("opl")<CR>
+an 50.80.300 &Syntax.NO.Oracle\ config :cal SetSyn("ora")<CR>
an 50.90.100 &Syntax.PQ.Packet\ filter\ conf :cal SetSyn("pf")<CR>
an 50.90.110 &Syntax.PQ.Palm\ resource\ compiler :cal SetSyn("pilrc")<CR>
an 50.90.120 &Syntax.PQ.Pam\ config :cal SetSyn("pamconf")<CR>
@@ -437,168 +459,178 @@ an 50.100.300 &Syntax.R.RockLinux\ package\ desc\. :cal SetSyn("desc")<CR>
an 50.100.310 &Syntax.R.Rpcgen :cal SetSyn("rpcgen")<CR>
an 50.100.320 &Syntax.R.RPL/2 :cal SetSyn("rpl")<CR>
an 50.100.330 &Syntax.R.ReStructuredText :cal SetSyn("rst")<CR>
-an 50.100.340 &Syntax.R.RTF :cal SetSyn("rtf")<CR>
-an 50.100.350 &Syntax.R.Ruby :cal SetSyn("ruby")<CR>
-an 50.110.100 &Syntax.S-Sm.S-Lang :cal SetSyn("slang")<CR>
-an 50.110.110 &Syntax.S-Sm.Samba\ config :cal SetSyn("samba")<CR>
-an 50.110.120 &Syntax.S-Sm.SAS :cal SetSyn("sas")<CR>
-an 50.110.130 &Syntax.S-Sm.Sass :cal SetSyn("sass")<CR>
-an 50.110.140 &Syntax.S-Sm.Sather :cal SetSyn("sather")<CR>
-an 50.110.150 &Syntax.S-Sm.Scheme :cal SetSyn("scheme")<CR>
-an 50.110.160 &Syntax.S-Sm.Scilab :cal SetSyn("scilab")<CR>
-an 50.110.170 &Syntax.S-Sm.Screen\ RC :cal SetSyn("screen")<CR>
-an 50.110.180 &Syntax.S-Sm.SCSS :cal SetSyn("scss")<CR>
-an 50.110.190 &Syntax.S-Sm.SDC\ Synopsys\ Design\ Constraints :cal SetSyn("sdc")<CR>
-an 50.110.200 &Syntax.S-Sm.SDL :cal SetSyn("sdl")<CR>
-an 50.110.210 &Syntax.S-Sm.Sed :cal SetSyn("sed")<CR>
-an 50.110.220 &Syntax.S-Sm.Sendmail\.cf :cal SetSyn("sm")<CR>
-an 50.110.230 &Syntax.S-Sm.Send-pr :cal SetSyn("sendpr")<CR>
-an 50.110.240 &Syntax.S-Sm.Sensors\.conf :cal SetSyn("sensors")<CR>
-an 50.110.250 &Syntax.S-Sm.Service\ Location\ config :cal SetSyn("slpconf")<CR>
-an 50.110.260 &Syntax.S-Sm.Service\ Location\ registration :cal SetSyn("slpreg")<CR>
-an 50.110.270 &Syntax.S-Sm.Service\ Location\ SPI :cal SetSyn("slpspi")<CR>
-an 50.110.280 &Syntax.S-Sm.Services :cal SetSyn("services")<CR>
-an 50.110.290 &Syntax.S-Sm.Setserial\ config :cal SetSyn("setserial")<CR>
-an 50.110.300 &Syntax.S-Sm.SGML.SGML\ catalog :cal SetSyn("catalog")<CR>
-an 50.110.310 &Syntax.S-Sm.SGML.SGML\ DTD :cal SetSyn("sgml")<CR>
-an 50.110.320 &Syntax.S-Sm.SGML.SGML\ Declaration :cal SetSyn("sgmldecl")<CR>
-an 50.110.330 &Syntax.S-Sm.SGML.SGML-linuxdoc :cal SetSyn("sgmllnx")<CR>
-an 50.110.340 &Syntax.S-Sm.Shell\ script.sh\ and\ ksh :cal SetSyn("sh")<CR>
-an 50.110.350 &Syntax.S-Sm.Shell\ script.csh :cal SetSyn("csh")<CR>
-an 50.110.360 &Syntax.S-Sm.Shell\ script.tcsh :cal SetSyn("tcsh")<CR>
-an 50.110.370 &Syntax.S-Sm.Shell\ script.zsh :cal SetSyn("zsh")<CR>
-an 50.110.380 &Syntax.S-Sm.SiCAD :cal SetSyn("sicad")<CR>
-an 50.110.390 &Syntax.S-Sm.Sieve :cal SetSyn("sieve")<CR>
-an 50.110.400 &Syntax.S-Sm.Simula :cal SetSyn("simula")<CR>
-an 50.110.410 &Syntax.S-Sm.Sinda.Sinda\ compare :cal SetSyn("sindacmp")<CR>
-an 50.110.420 &Syntax.S-Sm.Sinda.Sinda\ input :cal SetSyn("sinda")<CR>
-an 50.110.430 &Syntax.S-Sm.Sinda.Sinda\ output :cal SetSyn("sindaout")<CR>
-an 50.110.440 &Syntax.S-Sm.SiSU :cal SetSyn("sisu")<CR>
-an 50.110.450 &Syntax.S-Sm.SKILL.SKILL :cal SetSyn("skill")<CR>
-an 50.110.460 &Syntax.S-Sm.SKILL.SKILL\ for\ Diva :cal SetSyn("diva")<CR>
-an 50.110.470 &Syntax.S-Sm.Slice :cal SetSyn("slice")<CR>
-an 50.110.480 &Syntax.S-Sm.SLRN.Slrn\ rc :cal SetSyn("slrnrc")<CR>
-an 50.110.490 &Syntax.S-Sm.SLRN.Slrn\ score :cal SetSyn("slrnsc")<CR>
-an 50.110.500 &Syntax.S-Sm.SmallTalk :cal SetSyn("st")<CR>
-an 50.110.510 &Syntax.S-Sm.Smarty\ Templates :cal SetSyn("smarty")<CR>
-an 50.110.520 &Syntax.S-Sm.SMIL :cal SetSyn("smil")<CR>
-an 50.110.530 &Syntax.S-Sm.SMITH :cal SetSyn("smith")<CR>
-an 50.120.100 &Syntax.Sn-Sy.SNMP\ MIB :cal SetSyn("mib")<CR>
-an 50.120.110 &Syntax.Sn-Sy.SNNS.SNNS\ network :cal SetSyn("snnsnet")<CR>
-an 50.120.120 &Syntax.Sn-Sy.SNNS.SNNS\ pattern :cal SetSyn("snnspat")<CR>
-an 50.120.130 &Syntax.Sn-Sy.SNNS.SNNS\ result :cal SetSyn("snnsres")<CR>
-an 50.120.140 &Syntax.Sn-Sy.Snobol4 :cal SetSyn("snobol4")<CR>
-an 50.120.150 &Syntax.Sn-Sy.Snort\ Configuration :cal SetSyn("hog")<CR>
-an 50.120.160 &Syntax.Sn-Sy.SPEC\ (Linux\ RPM) :cal SetSyn("spec")<CR>
-an 50.120.170 &Syntax.Sn-Sy.Specman :cal SetSyn("specman")<CR>
-an 50.120.180 &Syntax.Sn-Sy.Spice :cal SetSyn("spice")<CR>
-an 50.120.190 &Syntax.Sn-Sy.Spyce :cal SetSyn("spyce")<CR>
-an 50.120.200 &Syntax.Sn-Sy.Speedup :cal SetSyn("spup")<CR>
-an 50.120.210 &Syntax.Sn-Sy.Splint :cal SetSyn("splint")<CR>
-an 50.120.220 &Syntax.Sn-Sy.Squid\ config :cal SetSyn("squid")<CR>
-an 50.120.230 &Syntax.Sn-Sy.SQL.SAP\ HANA :cal SetSyn("sqlhana")<CR>
-an 50.120.240 &Syntax.Sn-Sy.SQL.ESQL-C :cal SetSyn("esqlc")<CR>
-an 50.120.250 &Syntax.Sn-Sy.SQL.MySQL :cal SetSyn("mysql")<CR>
-an 50.120.260 &Syntax.Sn-Sy.SQL.PL/SQL :cal SetSyn("plsql")<CR>
-an 50.120.270 &Syntax.Sn-Sy.SQL.SQL\ Anywhere :cal SetSyn("sqlanywhere")<CR>
-an 50.120.280 &Syntax.Sn-Sy.SQL.SQL\ (automatic) :cal SetSyn("sql")<CR>
-an 50.120.290 &Syntax.Sn-Sy.SQL.SQL\ (Oracle) :cal SetSyn("sqloracle")<CR>
-an 50.120.300 &Syntax.Sn-Sy.SQL.SQL\ Forms :cal SetSyn("sqlforms")<CR>
-an 50.120.310 &Syntax.Sn-Sy.SQL.SQLJ :cal SetSyn("sqlj")<CR>
-an 50.120.320 &Syntax.Sn-Sy.SQL.SQL-Informix :cal SetSyn("sqlinformix")<CR>
-an 50.120.330 &Syntax.Sn-Sy.SQR :cal SetSyn("sqr")<CR>
-an 50.120.340 &Syntax.Sn-Sy.Ssh.ssh_config :cal SetSyn("sshconfig")<CR>
-an 50.120.350 &Syntax.Sn-Sy.Ssh.sshd_config :cal SetSyn("sshdconfig")<CR>
-an 50.120.360 &Syntax.Sn-Sy.Standard\ ML :cal SetSyn("sml")<CR>
-an 50.120.370 &Syntax.Sn-Sy.Stata.SMCL :cal SetSyn("smcl")<CR>
-an 50.120.380 &Syntax.Sn-Sy.Stata.Stata :cal SetSyn("stata")<CR>
-an 50.120.390 &Syntax.Sn-Sy.Stored\ Procedures :cal SetSyn("stp")<CR>
-an 50.120.400 &Syntax.Sn-Sy.Strace :cal SetSyn("strace")<CR>
-an 50.120.410 &Syntax.Sn-Sy.Streaming\ descriptor\ file :cal SetSyn("sd")<CR>
-an 50.120.420 &Syntax.Sn-Sy.Subversion\ commit :cal SetSyn("svn")<CR>
-an 50.120.430 &Syntax.Sn-Sy.Sudoers :cal SetSyn("sudoers")<CR>
-an 50.120.440 &Syntax.Sn-Sy.SVG :cal SetSyn("svg")<CR>
-an 50.120.450 &Syntax.Sn-Sy.Symbian\ meta-makefile :cal SetSyn("mmp")<CR>
-an 50.120.460 &Syntax.Sn-Sy.Sysctl\.conf :cal SetSyn("sysctl")<CR>
-an 50.130.100 &Syntax.T.TADS :cal SetSyn("tads")<CR>
-an 50.130.110 &Syntax.T.Tags :cal SetSyn("tags")<CR>
-an 50.130.120 &Syntax.T.TAK.TAK\ compare :cal SetSyn("takcmp")<CR>
-an 50.130.130 &Syntax.T.TAK.TAK\ input :cal SetSyn("tak")<CR>
-an 50.130.140 &Syntax.T.TAK.TAK\ output :cal SetSyn("takout")<CR>
-an 50.130.150 &Syntax.T.Tar\ listing :cal SetSyn("tar")<CR>
-an 50.130.160 &Syntax.T.Task\ data :cal SetSyn("taskdata")<CR>
-an 50.130.170 &Syntax.T.Task\ 42\ edit :cal SetSyn("taskedit")<CR>
-an 50.130.180 &Syntax.T.Tcl/Tk :cal SetSyn("tcl")<CR>
-an 50.130.190 &Syntax.T.TealInfo :cal SetSyn("tli")<CR>
-an 50.130.200 &Syntax.T.Telix\ Salt :cal SetSyn("tsalt")<CR>
-an 50.130.210 &Syntax.T.Termcap/Printcap :cal SetSyn("ptcap")<CR>
-an 50.130.220 &Syntax.T.Terminfo :cal SetSyn("terminfo")<CR>
-an 50.130.230 &Syntax.T.TeX.TeX/LaTeX :cal SetSyn("tex")<CR>
-an 50.130.240 &Syntax.T.TeX.plain\ TeX :cal SetSyn("plaintex")<CR>
-an 50.130.250 &Syntax.T.TeX.Initex :cal SetSyn("initex")<CR>
-an 50.130.260 &Syntax.T.TeX.ConTeXt :cal SetSyn("context")<CR>
-an 50.130.270 &Syntax.T.TeX.TeX\ configuration :cal SetSyn("texmf")<CR>
-an 50.130.280 &Syntax.T.TeX.Texinfo :cal SetSyn("texinfo")<CR>
-an 50.130.290 &Syntax.T.TF\ mud\ client :cal SetSyn("tf")<CR>
-an 50.130.300 &Syntax.T.Tidy\ configuration :cal SetSyn("tidy")<CR>
-an 50.130.310 &Syntax.T.Tilde :cal SetSyn("tilde")<CR>
-an 50.130.320 &Syntax.T.TPP :cal SetSyn("tpp")<CR>
-an 50.130.330 &Syntax.T.Trasys\ input :cal SetSyn("trasys")<CR>
-an 50.130.340 &Syntax.T.Treetop :cal SetSyn("treetop")<CR>
-an 50.130.350 &Syntax.T.Trustees :cal SetSyn("trustees")<CR>
-an 50.130.360 &Syntax.T.TSS.Command\ Line :cal SetSyn("tsscl")<CR>
-an 50.130.370 &Syntax.T.TSS.Geometry :cal SetSyn("tssgm")<CR>
-an 50.130.380 &Syntax.T.TSS.Optics :cal SetSyn("tssop")<CR>
-an 50.140.100 &Syntax.UV.Udev\ config :cal SetSyn("udevconf")<CR>
-an 50.140.110 &Syntax.UV.Udev\ permissions :cal SetSyn("udevperm")<CR>
-an 50.140.120 &Syntax.UV.Udev\ rules :cal SetSyn("udevrules")<CR>
-an 50.140.130 &Syntax.UV.UIT/UIL :cal SetSyn("uil")<CR>
-an 50.140.140 &Syntax.UV.UnrealScript :cal SetSyn("uc")<CR>
-an 50.140.150 &Syntax.UV.Updatedb\.conf :cal SetSyn("updatedb")<CR>
-an 50.140.160 &Syntax.UV.Upstart :cal SetSyn("upstart")<CR>
-an 50.140.180 &Syntax.UV.Valgrind :cal SetSyn("valgrind")<CR>
-an 50.140.190 &Syntax.UV.Vera :cal SetSyn("vera")<CR>
-an 50.140.200 &Syntax.UV.Verilog-AMS\ HDL :cal SetSyn("verilogams")<CR>
-an 50.140.210 &Syntax.UV.Verilog\ HDL :cal SetSyn("verilog")<CR>
-an 50.140.220 &Syntax.UV.Vgrindefs :cal SetSyn("vgrindefs")<CR>
-an 50.140.230 &Syntax.UV.VHDL :cal SetSyn("vhdl")<CR>
-an 50.140.240 &Syntax.UV.Vim.Vim\ help\ file :cal SetSyn("help")<CR>
-an 50.140.250 &Syntax.UV.Vim.Vim\ script :cal SetSyn("vim")<CR>
-an 50.140.260 &Syntax.UV.Vim.Viminfo\ file :cal SetSyn("viminfo")<CR>
-an 50.140.270 &Syntax.UV.Virata\ config :cal SetSyn("virata")<CR>
-an 50.140.280 &Syntax.UV.Visual\ Basic :cal SetSyn("vb")<CR>
-an 50.140.290 &Syntax.UV.VOS\ CM\ macro :cal SetSyn("voscm")<CR>
-an 50.140.300 &Syntax.UV.VRML :cal SetSyn("vrml")<CR>
-an 50.140.310 &Syntax.UV.VSE\ JCL :cal SetSyn("vsejcl")<CR>
-an 50.150.100 &Syntax.WXYZ.WEB.CWEB :cal SetSyn("cweb")<CR>
-an 50.150.110 &Syntax.WXYZ.WEB.WEB :cal SetSyn("web")<CR>
-an 50.150.120 &Syntax.WXYZ.WEB.WEB\ Changes :cal SetSyn("change")<CR>
-an 50.150.130 &Syntax.WXYZ.Webmacro :cal SetSyn("webmacro")<CR>
-an 50.150.140 &Syntax.WXYZ.Website\ MetaLanguage :cal SetSyn("wml")<CR>
-an 50.150.160 &Syntax.WXYZ.wDiff :cal SetSyn("wdiff")<CR>
-an 50.150.180 &Syntax.WXYZ.Wget\ config :cal SetSyn("wget")<CR>
-an 50.150.190 &Syntax.WXYZ.Whitespace\ (add) :cal SetSyn("whitespace")<CR>
-an 50.150.200 &Syntax.WXYZ.WildPackets\ EtherPeek\ Decoder :cal SetSyn("dcd")<CR>
-an 50.150.210 &Syntax.WXYZ.WinBatch/Webbatch :cal SetSyn("winbatch")<CR>
-an 50.150.220 &Syntax.WXYZ.Windows\ Scripting\ Host :cal SetSyn("wsh")<CR>
-an 50.150.230 &Syntax.WXYZ.WSML :cal SetSyn("wsml")<CR>
-an 50.150.240 &Syntax.WXYZ.WvDial :cal SetSyn("wvdial")<CR>
-an 50.150.260 &Syntax.WXYZ.X\ Keyboard\ Extension :cal SetSyn("xkb")<CR>
-an 50.150.270 &Syntax.WXYZ.X\ Pixmap :cal SetSyn("xpm")<CR>
-an 50.150.280 &Syntax.WXYZ.X\ Pixmap\ (2) :cal SetSyn("xpm2")<CR>
-an 50.150.290 &Syntax.WXYZ.X\ resources :cal SetSyn("xdefaults")<CR>
-an 50.150.300 &Syntax.WXYZ.XBL :cal SetSyn("xbl")<CR>
-an 50.150.310 &Syntax.WXYZ.Xinetd\.conf :cal SetSyn("xinetd")<CR>
-an 50.150.320 &Syntax.WXYZ.Xmodmap :cal SetSyn("xmodmap")<CR>
-an 50.150.330 &Syntax.WXYZ.Xmath :cal SetSyn("xmath")<CR>
-an 50.150.340 &Syntax.WXYZ.XML :cal SetSyn("xml")<CR>
-an 50.150.350 &Syntax.WXYZ.XML\ Schema\ (XSD) :cal SetSyn("xsd")<CR>
-an 50.150.360 &Syntax.WXYZ.XQuery :cal SetSyn("xquery")<CR>
-an 50.150.370 &Syntax.WXYZ.Xslt :cal SetSyn("xslt")<CR>
-an 50.150.380 &Syntax.WXYZ.XFree86\ Config :cal SetSyn("xf86conf")<CR>
-an 50.150.400 &Syntax.WXYZ.YAML :cal SetSyn("yaml")<CR>
-an 50.150.410 &Syntax.WXYZ.Yacc :cal SetSyn("yacc")<CR>
-an 50.150.430 &Syntax.WXYZ.Zimbu :cal SetSyn("zimbu")<CR>
+an 50.110.100 &Syntax.M.ReStructuredText\ with\ R\ statements :cal SetSyn("rrst")<CR>
+an 50.120.100 &Syntax.R.RTF :cal SetSyn("rtf")<CR>
+an 50.120.110 &Syntax.R.Ruby :cal SetSyn("ruby")<CR>
+an 50.120.120 &Syntax.R.Rust :cal SetSyn("rust")<CR>
+an 50.130.100 &Syntax.S-Sm.S-Lang :cal SetSyn("slang")<CR>
+an 50.130.110 &Syntax.S-Sm.Samba\ config :cal SetSyn("samba")<CR>
+an 50.130.120 &Syntax.S-Sm.SAS :cal SetSyn("sas")<CR>
+an 50.130.130 &Syntax.S-Sm.Sass :cal SetSyn("sass")<CR>
+an 50.130.140 &Syntax.S-Sm.Sather :cal SetSyn("sather")<CR>
+an 50.130.150 &Syntax.S-Sm.Sbt :cal SetSyn("sbt")<CR>
+an 50.130.160 &Syntax.S-Sm.Scala :cal SetSyn("scala")<CR>
+an 50.130.170 &Syntax.S-Sm.Scheme :cal SetSyn("scheme")<CR>
+an 50.130.180 &Syntax.S-Sm.Scilab :cal SetSyn("scilab")<CR>
+an 50.130.190 &Syntax.S-Sm.Screen\ RC :cal SetSyn("screen")<CR>
+an 50.130.200 &Syntax.S-Sm.SCSS :cal SetSyn("scss")<CR>
+an 50.130.210 &Syntax.S-Sm.SDC\ Synopsys\ Design\ Constraints :cal SetSyn("sdc")<CR>
+an 50.130.220 &Syntax.S-Sm.SDL :cal SetSyn("sdl")<CR>
+an 50.130.230 &Syntax.S-Sm.Sed :cal SetSyn("sed")<CR>
+an 50.130.240 &Syntax.S-Sm.Sendmail\.cf :cal SetSyn("sm")<CR>
+an 50.130.250 &Syntax.S-Sm.Send-pr :cal SetSyn("sendpr")<CR>
+an 50.130.260 &Syntax.S-Sm.Sensors\.conf :cal SetSyn("sensors")<CR>
+an 50.130.270 &Syntax.S-Sm.Service\ Location\ config :cal SetSyn("slpconf")<CR>
+an 50.130.280 &Syntax.S-Sm.Service\ Location\ registration :cal SetSyn("slpreg")<CR>
+an 50.130.290 &Syntax.S-Sm.Service\ Location\ SPI :cal SetSyn("slpspi")<CR>
+an 50.130.300 &Syntax.S-Sm.Services :cal SetSyn("services")<CR>
+an 50.130.310 &Syntax.S-Sm.Setserial\ config :cal SetSyn("setserial")<CR>
+an 50.130.320 &Syntax.S-Sm.SGML.SGML\ catalog :cal SetSyn("catalog")<CR>
+an 50.130.330 &Syntax.S-Sm.SGML.SGML\ DTD :cal SetSyn("sgml")<CR>
+an 50.130.340 &Syntax.S-Sm.SGML.SGML\ Declaration :cal SetSyn("sgmldecl")<CR>
+an 50.130.350 &Syntax.S-Sm.SGML.SGML-linuxdoc :cal SetSyn("sgmllnx")<CR>
+an 50.130.360 &Syntax.S-Sm.Shell\ script.sh\ and\ ksh :cal SetSyn("sh")<CR>
+an 50.130.370 &Syntax.S-Sm.Shell\ script.csh :cal SetSyn("csh")<CR>
+an 50.130.380 &Syntax.S-Sm.Shell\ script.tcsh :cal SetSyn("tcsh")<CR>
+an 50.130.390 &Syntax.S-Sm.Shell\ script.zsh :cal SetSyn("zsh")<CR>
+an 50.130.400 &Syntax.S-Sm.SiCAD :cal SetSyn("sicad")<CR>
+an 50.130.410 &Syntax.S-Sm.Sieve :cal SetSyn("sieve")<CR>
+an 50.130.420 &Syntax.S-Sm.Simula :cal SetSyn("simula")<CR>
+an 50.130.430 &Syntax.S-Sm.Sinda.Sinda\ compare :cal SetSyn("sindacmp")<CR>
+an 50.130.440 &Syntax.S-Sm.Sinda.Sinda\ input :cal SetSyn("sinda")<CR>
+an 50.130.450 &Syntax.S-Sm.Sinda.Sinda\ output :cal SetSyn("sindaout")<CR>
+an 50.130.460 &Syntax.S-Sm.SiSU :cal SetSyn("sisu")<CR>
+an 50.130.470 &Syntax.S-Sm.SKILL.SKILL :cal SetSyn("skill")<CR>
+an 50.130.480 &Syntax.S-Sm.SKILL.SKILL\ for\ Diva :cal SetSyn("diva")<CR>
+an 50.130.490 &Syntax.S-Sm.Slice :cal SetSyn("slice")<CR>
+an 50.130.500 &Syntax.S-Sm.SLRN.Slrn\ rc :cal SetSyn("slrnrc")<CR>
+an 50.130.510 &Syntax.S-Sm.SLRN.Slrn\ score :cal SetSyn("slrnsc")<CR>
+an 50.130.520 &Syntax.S-Sm.SmallTalk :cal SetSyn("st")<CR>
+an 50.130.530 &Syntax.S-Sm.Smarty\ Templates :cal SetSyn("smarty")<CR>
+an 50.130.540 &Syntax.S-Sm.SMIL :cal SetSyn("smil")<CR>
+an 50.130.550 &Syntax.S-Sm.SMITH :cal SetSyn("smith")<CR>
+an 50.140.100 &Syntax.Sn-Sy.SNMP\ MIB :cal SetSyn("mib")<CR>
+an 50.140.110 &Syntax.Sn-Sy.SNNS.SNNS\ network :cal SetSyn("snnsnet")<CR>
+an 50.140.120 &Syntax.Sn-Sy.SNNS.SNNS\ pattern :cal SetSyn("snnspat")<CR>
+an 50.140.130 &Syntax.Sn-Sy.SNNS.SNNS\ result :cal SetSyn("snnsres")<CR>
+an 50.140.140 &Syntax.Sn-Sy.Snobol4 :cal SetSyn("snobol4")<CR>
+an 50.140.150 &Syntax.Sn-Sy.Snort\ Configuration :cal SetSyn("hog")<CR>
+an 50.140.160 &Syntax.Sn-Sy.SPEC\ (Linux\ RPM) :cal SetSyn("spec")<CR>
+an 50.140.170 &Syntax.Sn-Sy.Specman :cal SetSyn("specman")<CR>
+an 50.140.180 &Syntax.Sn-Sy.Spice :cal SetSyn("spice")<CR>
+an 50.140.190 &Syntax.Sn-Sy.Spyce :cal SetSyn("spyce")<CR>
+an 50.140.200 &Syntax.Sn-Sy.Speedup :cal SetSyn("spup")<CR>
+an 50.140.210 &Syntax.Sn-Sy.Splint :cal SetSyn("splint")<CR>
+an 50.140.220 &Syntax.Sn-Sy.Squid\ config :cal SetSyn("squid")<CR>
+an 50.140.230 &Syntax.Sn-Sy.SQL.SAP\ HANA :cal SetSyn("sqlhana")<CR>
+an 50.140.240 &Syntax.Sn-Sy.SQL.ESQL-C :cal SetSyn("esqlc")<CR>
+an 50.140.250 &Syntax.Sn-Sy.SQL.MySQL :cal SetSyn("mysql")<CR>
+an 50.140.260 &Syntax.Sn-Sy.SQL.PL/SQL :cal SetSyn("plsql")<CR>
+an 50.140.270 &Syntax.Sn-Sy.SQL.SQL\ Anywhere :cal SetSyn("sqlanywhere")<CR>
+an 50.140.280 &Syntax.Sn-Sy.SQL.SQL\ (automatic) :cal SetSyn("sql")<CR>
+an 50.140.290 &Syntax.Sn-Sy.SQL.SQL\ (Oracle) :cal SetSyn("sqloracle")<CR>
+an 50.140.300 &Syntax.Sn-Sy.SQL.SQL\ Forms :cal SetSyn("sqlforms")<CR>
+an 50.140.310 &Syntax.Sn-Sy.SQL.SQLJ :cal SetSyn("sqlj")<CR>
+an 50.140.320 &Syntax.Sn-Sy.SQL.SQL-Informix :cal SetSyn("sqlinformix")<CR>
+an 50.140.330 &Syntax.Sn-Sy.SQR :cal SetSyn("sqr")<CR>
+an 50.140.340 &Syntax.Sn-Sy.Ssh.ssh_config :cal SetSyn("sshconfig")<CR>
+an 50.140.350 &Syntax.Sn-Sy.Ssh.sshd_config :cal SetSyn("sshdconfig")<CR>
+an 50.140.360 &Syntax.Sn-Sy.Standard\ ML :cal SetSyn("sml")<CR>
+an 50.140.370 &Syntax.Sn-Sy.Stata.SMCL :cal SetSyn("smcl")<CR>
+an 50.140.380 &Syntax.Sn-Sy.Stata.Stata :cal SetSyn("stata")<CR>
+an 50.140.390 &Syntax.Sn-Sy.Stored\ Procedures :cal SetSyn("stp")<CR>
+an 50.140.400 &Syntax.Sn-Sy.Strace :cal SetSyn("strace")<CR>
+an 50.140.410 &Syntax.Sn-Sy.Streaming\ descriptor\ file :cal SetSyn("sd")<CR>
+an 50.140.420 &Syntax.Sn-Sy.Subversion\ commit :cal SetSyn("svn")<CR>
+an 50.140.430 &Syntax.Sn-Sy.Sudoers :cal SetSyn("sudoers")<CR>
+an 50.140.440 &Syntax.Sn-Sy.SVG :cal SetSyn("svg")<CR>
+an 50.140.450 &Syntax.Sn-Sy.Symbian\ meta-makefile :cal SetSyn("mmp")<CR>
+an 50.140.460 &Syntax.Sn-Sy.Sysctl\.conf :cal SetSyn("sysctl")<CR>
+an 50.140.470 &Syntax.Sn-Sy.Systemd :cal SetSyn("systemd")<CR>
+an 50.140.480 &Syntax.Sn-Sy.SystemVerilog :cal SetSyn("systemverilog")<CR>
+an 50.150.100 &Syntax.T.TADS :cal SetSyn("tads")<CR>
+an 50.150.110 &Syntax.T.Tags :cal SetSyn("tags")<CR>
+an 50.150.120 &Syntax.T.TAK.TAK\ compare :cal SetSyn("takcmp")<CR>
+an 50.150.130 &Syntax.T.TAK.TAK\ input :cal SetSyn("tak")<CR>
+an 50.150.140 &Syntax.T.TAK.TAK\ output :cal SetSyn("takout")<CR>
+an 50.150.150 &Syntax.T.Tar\ listing :cal SetSyn("tar")<CR>
+an 50.150.160 &Syntax.T.Task\ data :cal SetSyn("taskdata")<CR>
+an 50.150.170 &Syntax.T.Task\ 42\ edit :cal SetSyn("taskedit")<CR>
+an 50.150.180 &Syntax.T.Tcl/Tk :cal SetSyn("tcl")<CR>
+an 50.150.190 &Syntax.T.TealInfo :cal SetSyn("tli")<CR>
+an 50.150.200 &Syntax.T.Telix\ Salt :cal SetSyn("tsalt")<CR>
+an 50.150.210 &Syntax.T.Termcap/Printcap :cal SetSyn("ptcap")<CR>
+an 50.150.220 &Syntax.T.Terminfo :cal SetSyn("terminfo")<CR>
+an 50.150.230 &Syntax.T.Tera\ Term :cal SetSyn("teraterm")<CR>
+an 50.150.240 &Syntax.T.TeX.TeX/LaTeX :cal SetSyn("tex")<CR>
+an 50.150.250 &Syntax.T.TeX.plain\ TeX :cal SetSyn("plaintex")<CR>
+an 50.150.260 &Syntax.T.TeX.Initex :cal SetSyn("initex")<CR>
+an 50.150.270 &Syntax.T.TeX.ConTeXt :cal SetSyn("context")<CR>
+an 50.150.280 &Syntax.T.TeX.TeX\ configuration :cal SetSyn("texmf")<CR>
+an 50.150.290 &Syntax.T.TeX.Texinfo :cal SetSyn("texinfo")<CR>
+an 50.150.300 &Syntax.T.TF\ mud\ client :cal SetSyn("tf")<CR>
+an 50.150.310 &Syntax.T.Tidy\ configuration :cal SetSyn("tidy")<CR>
+an 50.150.320 &Syntax.T.Tilde :cal SetSyn("tilde")<CR>
+an 50.150.330 &Syntax.T.Tmux\ configuration :cal SetSyn("tmux")<CR>
+an 50.150.340 &Syntax.T.TPP :cal SetSyn("tpp")<CR>
+an 50.150.350 &Syntax.T.Trasys\ input :cal SetSyn("trasys")<CR>
+an 50.150.360 &Syntax.T.Treetop :cal SetSyn("treetop")<CR>
+an 50.150.370 &Syntax.T.Trustees :cal SetSyn("trustees")<CR>
+an 50.150.380 &Syntax.T.TSS.Command\ Line :cal SetSyn("tsscl")<CR>
+an 50.150.390 &Syntax.T.TSS.Geometry :cal SetSyn("tssgm")<CR>
+an 50.150.400 &Syntax.T.TSS.Optics :cal SetSyn("tssop")<CR>
+an 50.160.100 &Syntax.UV.Udev\ config :cal SetSyn("udevconf")<CR>
+an 50.160.110 &Syntax.UV.Udev\ permissions :cal SetSyn("udevperm")<CR>
+an 50.160.120 &Syntax.UV.Udev\ rules :cal SetSyn("udevrules")<CR>
+an 50.160.130 &Syntax.UV.UIT/UIL :cal SetSyn("uil")<CR>
+an 50.160.140 &Syntax.UV.UnrealScript :cal SetSyn("uc")<CR>
+an 50.160.150 &Syntax.UV.Updatedb\.conf :cal SetSyn("updatedb")<CR>
+an 50.160.160 &Syntax.UV.Upstart :cal SetSyn("upstart")<CR>
+an 50.160.180 &Syntax.UV.Valgrind :cal SetSyn("valgrind")<CR>
+an 50.160.190 &Syntax.UV.Vera :cal SetSyn("vera")<CR>
+an 50.160.200 &Syntax.UV.Verbose\ TAP\ Output :cal SetSyn("tap")<CR>
+an 50.160.210 &Syntax.UV.Verilog-AMS\ HDL :cal SetSyn("verilogams")<CR>
+an 50.160.220 &Syntax.UV.Verilog\ HDL :cal SetSyn("verilog")<CR>
+an 50.160.230 &Syntax.UV.Vgrindefs :cal SetSyn("vgrindefs")<CR>
+an 50.160.240 &Syntax.UV.VHDL :cal SetSyn("vhdl")<CR>
+an 50.160.250 &Syntax.UV.Vim.Vim\ help\ file :cal SetSyn("help")<CR>
+an 50.160.260 &Syntax.UV.Vim.Vim\ script :cal SetSyn("vim")<CR>
+an 50.160.270 &Syntax.UV.Vim.Viminfo\ file :cal SetSyn("viminfo")<CR>
+an 50.160.280 &Syntax.UV.Virata\ config :cal SetSyn("virata")<CR>
+an 50.160.290 &Syntax.UV.Visual\ Basic :cal SetSyn("vb")<CR>
+an 50.160.300 &Syntax.UV.VOS\ CM\ macro :cal SetSyn("voscm")<CR>
+an 50.160.310 &Syntax.UV.VRML :cal SetSyn("vrml")<CR>
+an 50.160.320 &Syntax.UV.Vroom :cal SetSyn("vroom")<CR>
+an 50.160.330 &Syntax.UV.VSE\ JCL :cal SetSyn("vsejcl")<CR>
+an 50.170.100 &Syntax.WXYZ.WEB.CWEB :cal SetSyn("cweb")<CR>
+an 50.170.110 &Syntax.WXYZ.WEB.WEB :cal SetSyn("web")<CR>
+an 50.170.120 &Syntax.WXYZ.WEB.WEB\ Changes :cal SetSyn("change")<CR>
+an 50.170.130 &Syntax.WXYZ.Webmacro :cal SetSyn("webmacro")<CR>
+an 50.170.140 &Syntax.WXYZ.Website\ MetaLanguage :cal SetSyn("wml")<CR>
+an 50.170.160 &Syntax.WXYZ.wDiff :cal SetSyn("wdiff")<CR>
+an 50.170.180 &Syntax.WXYZ.Wget\ config :cal SetSyn("wget")<CR>
+an 50.170.190 &Syntax.WXYZ.Whitespace\ (add) :cal SetSyn("whitespace")<CR>
+an 50.170.200 &Syntax.WXYZ.WildPackets\ EtherPeek\ Decoder :cal SetSyn("dcd")<CR>
+an 50.170.210 &Syntax.WXYZ.WinBatch/Webbatch :cal SetSyn("winbatch")<CR>
+an 50.170.220 &Syntax.WXYZ.Windows\ Scripting\ Host :cal SetSyn("wsh")<CR>
+an 50.170.230 &Syntax.WXYZ.WSML :cal SetSyn("wsml")<CR>
+an 50.170.240 &Syntax.WXYZ.WvDial :cal SetSyn("wvdial")<CR>
+an 50.170.260 &Syntax.WXYZ.X\ Keyboard\ Extension :cal SetSyn("xkb")<CR>
+an 50.170.270 &Syntax.WXYZ.X\ Pixmap :cal SetSyn("xpm")<CR>
+an 50.170.280 &Syntax.WXYZ.X\ Pixmap\ (2) :cal SetSyn("xpm2")<CR>
+an 50.170.290 &Syntax.WXYZ.X\ resources :cal SetSyn("xdefaults")<CR>
+an 50.170.300 &Syntax.WXYZ.XBL :cal SetSyn("xbl")<CR>
+an 50.170.310 &Syntax.WXYZ.Xinetd\.conf :cal SetSyn("xinetd")<CR>
+an 50.170.320 &Syntax.WXYZ.Xmodmap :cal SetSyn("xmodmap")<CR>
+an 50.170.330 &Syntax.WXYZ.Xmath :cal SetSyn("xmath")<CR>
+an 50.170.340 &Syntax.WXYZ.XML :cal SetSyn("xml")<CR>
+an 50.170.350 &Syntax.WXYZ.XML\ Schema\ (XSD) :cal SetSyn("xsd")<CR>
+an 50.170.360 &Syntax.WXYZ.XQuery :cal SetSyn("xquery")<CR>
+an 50.170.370 &Syntax.WXYZ.Xslt :cal SetSyn("xslt")<CR>
+an 50.170.380 &Syntax.WXYZ.XFree86\ Config :cal SetSyn("xf86conf")<CR>
+an 50.170.400 &Syntax.WXYZ.YAML :cal SetSyn("yaml")<CR>
+an 50.170.410 &Syntax.WXYZ.Yacc :cal SetSyn("yacc")<CR>
+an 50.170.430 &Syntax.WXYZ.Zimbu :cal SetSyn("zimbu")<CR>
" The End Of The Syntax Menu
diff --git a/runtime/syntax/upstreamrpt.vim b/runtime/syntax/upstreamrpt.vim
index 170fc8f509..21c25633a2 100644
--- a/runtime/syntax/upstreamrpt.vim
+++ b/runtime/syntax/upstreamrpt.vim
@@ -307,4 +307,4 @@ hi def link upstreamdat_Parameter Type
"hi def link upstreamdat_Filespec Underlined
hi def link upstreamdat_Comment Comment
-let b:current_syntax = "upstreamdat"
+let b:current_syntax = "upstreamrpt"
diff --git a/src/clint.py b/src/clint.py
index 719142d523..3994ffbb14 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -48,7 +48,6 @@ from __future__ import unicode_literals
import codecs
import copy
-import fileinput
import getopt
import math # for log
import os
@@ -566,6 +565,7 @@ class _CppLintState(object):
return
self.record_errors_file = open(fname, 'w')
+
_cpplint_state = _CppLintState()
@@ -2123,7 +2123,7 @@ def CheckExpressionAlignment(filename, clean_lines, linenum, error, startpos=0):
'Inner expression indentation should be 4')
else:
if (pos != level_starts[depth][0] + 1
- + (level_starts[depth][2] == '{')):
+ + (level_starts[depth][2] == '{')):
if depth not in ignore_error_levels:
error(filename, linenum, 'whitespace/alignment', 2,
('Inner expression should be aligned '
@@ -2296,7 +2296,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
line = clean_lines.elided[linenum] # get rid of comments and strings
# Don't try to do spacing checks for operator methods
- line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
+ line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', r'operator\(', line)
# We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
# Otherwise not. Note we only check for non-spaces on *both* sides;
@@ -2597,8 +2597,8 @@ def CheckBraces(filename, clean_lines, linenum, error):
if (not Search(r'[,;:}{(]\s*$', prevline) and
not Match(r'\s*#', prevline)):
error(filename, linenum, 'whitespace/braces', 4,
- '{ should almost always be at the end'
- ' of the previous line')
+ '{ should almost always be at the end'
+ ' of the previous line')
# Brace must appear after function signature, but on the *next* line
if Match(r'^(?:\w+(?: ?\*+)? )+\w+\(', line):
@@ -3178,8 +3178,8 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
if not Search(r'eval/typval\.[ch]$', filename):
match = Search(r'(?:\.|->)'
r'(?:lv_(?:first|last|refcount|len|watch|idx(?:_item)?'
- r'|copylist|lock)'
- r'|li_(?:next|prev|tv))\b', line)
+ r'|copylist|lock)'
+ r'|li_(?:next|prev|tv))\b', line)
if match:
error(filename, linenum, 'runtime/deprecated', 4,
'Accessing list_T internals directly is prohibited (hint: see commit d46e37cb4c71)')
diff --git a/src/nvim/README.md b/src/nvim/README.md
index 02464c2500..3c956cb2e9 100644
--- a/src/nvim/README.md
+++ b/src/nvim/README.md
@@ -60,9 +60,9 @@ Enable the sanitizer(s) via these environment variables:
# Change to detect_leaks=1 to detect memory leaks (slower).
export ASAN_OPTIONS="detect_leaks=0:log_path=$HOME/logs/asan"
- export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-5.0/bin/llvm-symbolizer
+ export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer
- export MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-5.0/bin/llvm-symbolizer
+ export MSAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer
export TSAN_OPTIONS="external_symbolizer_path=/usr/lib/llvm-5.0/bin/llvm-symbolizer log_path=${HOME}/logs/tsan"
Logs will be written to `${HOME}/logs/*san.PID`.
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index dbe3b66fd5..ed6a28bcda 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -21,6 +21,7 @@
#include "nvim/lua/executor.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
+#include "nvim/context.h"
#include "nvim/file_search.h"
#include "nvim/highlight.h"
#include "nvim/window.h"
@@ -1268,6 +1269,67 @@ Dictionary nvim_get_color_map(void)
return colors;
}
+/// Gets a map of the current editor state.
+///
+/// @param types Context types ("regs", "jumps", "buflist", "gvars", ...)
+/// to gather, or NIL for all.
+///
+/// @return map of global context
+Dictionary nvim_get_context(Array types)
+ FUNC_API_SINCE(6)
+{
+ int int_types = 0;
+ if (types.size == 1 && types.items[0].type == kObjectTypeNil) {
+ int_types = kCtxAll;
+ } else {
+ for (size_t i = 0; i < types.size; i++) {
+ if (types.items[i].type == kObjectTypeString) {
+ const char *const current = types.items[i].data.string.data;
+ if (strequal(current, "regs")) {
+ int_types |= kCtxRegs;
+ } else if (strequal(current, "jumps")) {
+ int_types |= kCtxJumps;
+ } else if (strequal(current, "buflist")) {
+ int_types |= kCtxBuflist;
+ } else if (strequal(current, "gvars")) {
+ int_types |= kCtxGVars;
+ } else if (strequal(current, "sfuncs")) {
+ int_types |= kCtxSFuncs;
+ } else if (strequal(current, "funcs")) {
+ int_types |= kCtxFuncs;
+ }
+ }
+ }
+ }
+
+ Context ctx = CONTEXT_INIT;
+ ctx_save(&ctx, int_types);
+ Dictionary dict = ctx_to_dict(&ctx);
+ ctx_free(&ctx);
+ return dict;
+}
+
+/// Sets the current editor state to that in given context dictionary.
+///
+/// @param ctx_dict Context dictionary.
+Object nvim_load_context(Dictionary dict)
+ FUNC_API_SINCE(6)
+{
+ Context ctx = CONTEXT_INIT;
+
+ int save_did_emsg = did_emsg;
+ did_emsg = false;
+
+ ctx_from_dict(dict, &ctx);
+ if (!did_emsg) {
+ ctx_restore(&ctx, kCtxAll);
+ }
+
+ ctx_free(&ctx);
+
+ did_emsg = save_did_emsg;
+ return (Object)OBJECT_INIT;
+}
/// Gets the current mode. |mode()|
/// "blocking" is true if Nvim is waiting for input.
diff --git a/src/nvim/context.c b/src/nvim/context.c
new file mode 100644
index 0000000000..b2a2fd3fd9
--- /dev/null
+++ b/src/nvim/context.c
@@ -0,0 +1,383 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// Context: snapshot of the entire editor state as one big object/map
+
+#include "nvim/context.h"
+#include "nvim/eval/encode.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/option.h"
+#include "nvim/shada.h"
+#include "nvim/api/vim.h"
+#include "nvim/api/private/helpers.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "context.c.generated.h"
+#endif
+
+int kCtxAll = (kCtxRegs | kCtxJumps | kCtxBuflist | kCtxGVars | kCtxSFuncs
+ | kCtxFuncs);
+
+static ContextVec ctx_stack = KV_INITIAL_VALUE;
+
+/// Clears and frees the context stack
+void ctx_free_all(void)
+{
+ for (size_t i = 0; i < kv_size(ctx_stack); i++) {
+ ctx_free(&kv_A(ctx_stack, i));
+ }
+ kv_destroy(ctx_stack);
+}
+
+/// Returns the size of the context stack.
+size_t ctx_size(void)
+{
+ return kv_size(ctx_stack);
+}
+
+/// Returns pointer to Context object with given zero-based index from the top
+/// of context stack or NULL if index is out of bounds.
+Context *ctx_get(size_t index)
+{
+ if (index < kv_size(ctx_stack)) {
+ return &kv_Z(ctx_stack, index);
+ }
+ return NULL;
+}
+
+/// Free resources used by Context object.
+///
+/// param[in] ctx pointer to Context object to free.
+void ctx_free(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (ctx->regs.data) {
+ msgpack_sbuffer_destroy(&ctx->regs);
+ }
+ if (ctx->jumps.data) {
+ msgpack_sbuffer_destroy(&ctx->jumps);
+ }
+ if (ctx->buflist.data) {
+ msgpack_sbuffer_destroy(&ctx->buflist);
+ }
+ if (ctx->gvars.data) {
+ msgpack_sbuffer_destroy(&ctx->gvars);
+ }
+ if (ctx->funcs.items) {
+ api_free_array(ctx->funcs);
+ }
+}
+
+/// Saves the editor state to a context.
+///
+/// If "context" is NULL, pushes context on context stack.
+/// Use "flags" to select particular types of context.
+///
+/// @param ctx Save to this context, or push on context stack if NULL.
+/// @param flags Flags, see ContextTypeFlags enum.
+void ctx_save(Context *ctx, const int flags)
+{
+ if (ctx == NULL) {
+ kv_push(ctx_stack, CONTEXT_INIT);
+ ctx = &kv_last(ctx_stack);
+ }
+
+ if (flags & kCtxRegs) {
+ ctx_save_regs(ctx);
+ }
+
+ if (flags & kCtxJumps) {
+ ctx_save_jumps(ctx);
+ }
+
+ if (flags & kCtxBuflist) {
+ ctx_save_buflist(ctx);
+ }
+
+ if (flags & kCtxGVars) {
+ ctx_save_gvars(ctx);
+ }
+
+ if (flags & kCtxFuncs) {
+ ctx_save_funcs(ctx, false);
+ } else if (flags & kCtxSFuncs) {
+ ctx_save_funcs(ctx, true);
+ }
+}
+
+/// Restores the editor state from a context.
+///
+/// If "context" is NULL, pops context from context stack.
+/// Use "flags" to select particular types of context.
+///
+/// @param ctx Restore from this context. Pop from context stack if NULL.
+/// @param flags Flags, see ContextTypeFlags enum.
+///
+/// @return true on success, false otherwise (i.e.: empty context stack).
+bool ctx_restore(Context *ctx, const int flags)
+{
+ bool free_ctx = false;
+ if (ctx == NULL) {
+ if (ctx_stack.size == 0) {
+ return false;
+ }
+ ctx = &kv_pop(ctx_stack);
+ free_ctx = true;
+ }
+
+ char_u *op_shada;
+ get_option_value((char_u *)"shada", NULL, &op_shada, OPT_GLOBAL);
+ set_option_value("shada", 0L, "!,'100,%", OPT_GLOBAL);
+
+ if (flags & kCtxRegs) {
+ ctx_restore_regs(ctx);
+ }
+
+ if (flags & kCtxJumps) {
+ ctx_restore_jumps(ctx);
+ }
+
+ if (flags & kCtxBuflist) {
+ ctx_restore_buflist(ctx);
+ }
+
+ if (flags & kCtxGVars) {
+ ctx_restore_gvars(ctx);
+ }
+
+ if (flags & kCtxFuncs) {
+ ctx_restore_funcs(ctx);
+ }
+
+ if (free_ctx) {
+ ctx_free(ctx);
+ }
+
+ set_option_value("shada", 0L, (char *)op_shada, OPT_GLOBAL);
+ xfree(op_shada);
+
+ return true;
+}
+
+/// Saves the global registers to a context.
+///
+/// @param ctx Save to this context.
+static inline void ctx_save_regs(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ msgpack_sbuffer_init(&ctx->regs);
+ shada_encode_regs(&ctx->regs);
+}
+
+/// Restores the global registers from a context.
+///
+/// @param ctx Restore from this context.
+static inline void ctx_restore_regs(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ shada_read_sbuf(&ctx->regs, kShaDaWantInfo | kShaDaForceit);
+}
+
+/// Saves the jumplist to a context.
+///
+/// @param ctx Save to this context.
+static inline void ctx_save_jumps(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ msgpack_sbuffer_init(&ctx->jumps);
+ shada_encode_jumps(&ctx->jumps);
+}
+
+/// Restores the jumplist from a context.
+///
+/// @param ctx Restore from this context.
+static inline void ctx_restore_jumps(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ shada_read_sbuf(&ctx->jumps, kShaDaWantInfo | kShaDaForceit);
+}
+
+/// Saves the buffer list to a context.
+///
+/// @param ctx Save to this context.
+static inline void ctx_save_buflist(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ msgpack_sbuffer_init(&ctx->buflist);
+ shada_encode_buflist(&ctx->buflist);
+}
+
+/// Restores the buffer list from a context.
+///
+/// @param ctx Restore from this context.
+static inline void ctx_restore_buflist(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ shada_read_sbuf(&ctx->buflist, kShaDaWantInfo | kShaDaForceit);
+}
+
+/// Saves global variables to a context.
+///
+/// @param ctx Save to this context.
+static inline void ctx_save_gvars(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ msgpack_sbuffer_init(&ctx->gvars);
+ shada_encode_gvars(&ctx->gvars);
+}
+
+/// Restores global variables from a context.
+///
+/// @param ctx Restore from this context.
+static inline void ctx_restore_gvars(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ shada_read_sbuf(&ctx->gvars, kShaDaWantInfo | kShaDaForceit);
+}
+
+/// Saves functions to a context.
+///
+/// @param ctx Save to this context.
+/// @param scriptonly Save script-local (s:) functions only.
+static inline void ctx_save_funcs(Context *ctx, bool scriptonly)
+ FUNC_ATTR_NONNULL_ALL
+{
+ ctx->funcs = (Array)ARRAY_DICT_INIT;
+ Error err = ERROR_INIT;
+
+ HASHTAB_ITER(&func_hashtab, hi, {
+ const char_u *const name = hi->hi_key;
+ bool islambda = (STRNCMP(name, "<lambda>", 8) == 0);
+ bool isscript = (name[0] == K_SPECIAL);
+
+ if (!islambda && (!scriptonly || isscript)) {
+ size_t cmd_len = sizeof("func! ") + STRLEN(name);
+ char *cmd = xmalloc(cmd_len);
+ snprintf(cmd, cmd_len, "func! %s", name);
+ String func_body = nvim_command_output(cstr_as_string(cmd), &err);
+ xfree(cmd);
+ if (!ERROR_SET(&err)) {
+ ADD(ctx->funcs, STRING_OBJ(func_body));
+ }
+ api_clear_error(&err);
+ }
+ });
+}
+
+/// Restores functions from a context.
+///
+/// @param ctx Restore from this context.
+static inline void ctx_restore_funcs(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ for (size_t i = 0; i < ctx->funcs.size; i++) {
+ do_cmdline_cmd(ctx->funcs.items[i].data.string.data);
+ }
+}
+
+/// Convert msgpack_sbuffer to readfile()-style array.
+///
+/// @param[in] sbuf msgpack_sbuffer to convert.
+///
+/// @return readfile()-style array representation of "sbuf".
+static inline Array sbuf_to_array(msgpack_sbuffer sbuf)
+{
+ list_T *const list = tv_list_alloc(kListLenMayKnow);
+ tv_list_append_string(list, "", 0);
+ if (sbuf.size > 0) {
+ encode_list_write(list, sbuf.data, sbuf.size);
+ }
+
+ typval_T list_tv = (typval_T) {
+ .v_lock = VAR_UNLOCKED,
+ .v_type = VAR_LIST,
+ .vval.v_list = list
+ };
+
+ Array array = vim_to_object(&list_tv).data.array;
+ tv_clear(&list_tv);
+ return array;
+}
+
+/// Convert readfile()-style array to msgpack_sbuffer.
+///
+/// @param[in] array readfile()-style array to convert.
+///
+/// @return msgpack_sbuffer with conversion result.
+static inline msgpack_sbuffer array_to_sbuf(Array array)
+{
+ msgpack_sbuffer sbuf;
+ msgpack_sbuffer_init(&sbuf);
+
+ typval_T list_tv;
+ Error err = ERROR_INIT;
+ object_to_vim(ARRAY_OBJ(array), &list_tv, &err);
+
+ if (!encode_vim_list_to_buf(list_tv.vval.v_list, &sbuf.size, &sbuf.data)) {
+ EMSG(_("E474: Failed to convert list to msgpack string buffer"));
+ }
+ sbuf.alloc = sbuf.size;
+
+ tv_clear(&list_tv);
+ api_clear_error(&err);
+ return sbuf;
+}
+
+/// Converts Context to Dictionary representation.
+///
+/// @param[in] ctx Context to convert.
+///
+/// @return Dictionary representing "ctx".
+Dictionary ctx_to_dict(Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(ctx != NULL);
+
+ Dictionary rv = ARRAY_DICT_INIT;
+
+ PUT(rv, "regs", ARRAY_OBJ(sbuf_to_array(ctx->regs)));
+ PUT(rv, "jumps", ARRAY_OBJ(sbuf_to_array(ctx->jumps)));
+ PUT(rv, "buflist", ARRAY_OBJ(sbuf_to_array(ctx->buflist)));
+ PUT(rv, "gvars", ARRAY_OBJ(sbuf_to_array(ctx->gvars)));
+ PUT(rv, "funcs", ARRAY_OBJ(copy_array(ctx->funcs)));
+
+ return rv;
+}
+
+/// Converts Dictionary representation of Context back to Context object.
+///
+/// @param[in] dict Context Dictionary representation.
+/// @param[out] ctx Context object to store conversion result into.
+///
+/// @return types of included context items.
+int ctx_from_dict(Dictionary dict, Context *ctx)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(ctx != NULL);
+
+ int types = 0;
+ for (size_t i = 0; i < dict.size; i++) {
+ KeyValuePair item = dict.items[i];
+ if (item.value.type != kObjectTypeArray) {
+ continue;
+ }
+ if (strequal(item.key.data, "regs")) {
+ types |= kCtxRegs;
+ ctx->regs = array_to_sbuf(item.value.data.array);
+ } else if (strequal(item.key.data, "jumps")) {
+ types |= kCtxJumps;
+ ctx->jumps = array_to_sbuf(item.value.data.array);
+ } else if (strequal(item.key.data, "buflist")) {
+ types |= kCtxBuflist;
+ ctx->buflist = array_to_sbuf(item.value.data.array);
+ } else if (strequal(item.key.data, "gvars")) {
+ types |= kCtxGVars;
+ ctx->gvars = array_to_sbuf(item.value.data.array);
+ } else if (strequal(item.key.data, "funcs")) {
+ types |= kCtxFuncs;
+ ctx->funcs = copy_object(item.value).data.array;
+ }
+ }
+
+ return types;
+}
diff --git a/src/nvim/context.h b/src/nvim/context.h
new file mode 100644
index 0000000000..328e12c6a6
--- /dev/null
+++ b/src/nvim/context.h
@@ -0,0 +1,46 @@
+#ifndef NVIM_CONTEXT_H
+#define NVIM_CONTEXT_H
+
+#include <msgpack.h>
+#include "nvim/api/private/defs.h"
+#include "nvim/lib/kvec.h"
+
+typedef struct {
+ msgpack_sbuffer regs; ///< Registers.
+ msgpack_sbuffer jumps; ///< Jumplist.
+ msgpack_sbuffer buflist; ///< Buffer list.
+ msgpack_sbuffer gvars; ///< Global variables.
+ Array funcs; ///< Functions.
+} Context;
+typedef kvec_t(Context) ContextVec;
+
+#define MSGPACK_SBUFFER_INIT (msgpack_sbuffer) { \
+ .size = 0, \
+ .data = NULL, \
+ .alloc = 0, \
+}
+
+#define CONTEXT_INIT (Context) { \
+ .regs = MSGPACK_SBUFFER_INIT, \
+ .jumps = MSGPACK_SBUFFER_INIT, \
+ .buflist = MSGPACK_SBUFFER_INIT, \
+ .gvars = MSGPACK_SBUFFER_INIT, \
+ .funcs = ARRAY_DICT_INIT, \
+}
+
+typedef enum {
+ kCtxRegs = 1, ///< Registers
+ kCtxJumps = 2, ///< Jumplist
+ kCtxBuflist = 4, ///< Buffer list
+ kCtxGVars = 8, ///< Global variables
+ kCtxSFuncs = 16, ///< Script functions
+ kCtxFuncs = 32, ///< Functions
+} ContextTypeFlags;
+
+extern int kCtxAll;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "context.h.generated.h"
+#endif
+
+#endif // NVIM_CONTEXT_H
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index f2b3abb526..4176769f85 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -2190,7 +2190,7 @@ int diffopt_changed(void)
}
diff_flags = diff_flags_new;
- diff_context = diff_context_new;
+ diff_context = diff_context_new == 0 ? 1 : diff_context_new;
diff_foldcolumn = diff_foldcolumn_new;
diff_algorithm = diff_algorithm_new;
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 3305d281bd..5a9549cc89 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -2580,10 +2580,35 @@ static bool pum_enough_matches(void)
return i >= 2;
}
-/*
- * Show the popup menu for the list of matches.
- * Also adjusts "compl_shown_match" to an entry that is actually displayed.
- */
+static void trigger_complete_changed_event(int cur)
+{
+ static bool recursive = false;
+
+ if (recursive) {
+ return;
+ }
+
+ dict_T *v_event = get_vim_var_dict(VV_EVENT);
+ if (cur < 0) {
+ tv_dict_add_dict(v_event, S_LEN("completed_item"), tv_dict_alloc());
+ } else {
+ dict_T *item = ins_compl_dict_alloc(compl_curr_match);
+ tv_dict_add_dict(v_event, S_LEN("completed_item"), item);
+ }
+ pum_set_event_info(v_event);
+ tv_dict_set_keys_readonly(v_event);
+
+ recursive = true;
+ textlock++;
+ apply_autocmds(EVENT_COMPLETECHANGED, NULL, NULL, false, curbuf);
+ textlock--;
+ recursive = false;
+
+ tv_dict_clear(v_event);
+}
+
+/// Show the popup menu for the list of matches.
+/// Also adjusts "compl_shown_match" to an entry that is actually displayed.
void ins_compl_show_pum(void)
{
compl_T *compl;
@@ -2715,22 +2740,9 @@ void ins_compl_show_pum(void)
pum_display(compl_match_array, compl_match_arraysize, cur, array_changed, 0);
curwin->w_cursor.col = col;
- if (!has_event(EVENT_COMPLETECHANGED)) {
- return;
+ if (has_event(EVENT_COMPLETECHANGED)) {
+ trigger_complete_changed_event(cur);
}
- dict_T *dict = get_vim_var_dict(VV_EVENT);
- if (cur < 0) {
- tv_dict_add_dict(dict, S_LEN("completed_item"), tv_dict_alloc());
- } else {
- dict_T *item = ins_compl_dict_alloc(compl_curr_match);
- tv_dict_add_dict(dict, S_LEN("completed_item"), item);
- }
- pum_set_boundings(dict);
- tv_dict_set_keys_readonly(dict);
- textlock++;
- apply_autocmds(EVENT_COMPLETECHANGED, NULL, NULL, false, curbuf);
- textlock--;
- tv_dict_clear(dict);
}
#define DICT_FIRST (1) /* use just first element in "dict" */
@@ -3110,6 +3122,7 @@ void get_complete_info(list_T *what_list, dict_T *retdict)
? compl_curr_match->cp_number - 1 : -1);
}
+ (void)ret;
// TODO(vim):
// if (ret == OK && (what_flag & CI_WHAT_INSERTED))
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index f91552bc1c..cefd351dd7 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -26,6 +26,7 @@
#include "nvim/buffer.h"
#include "nvim/channel.h"
#include "nvim/charset.h"
+#include "nvim/context.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
#include "nvim/edit.h"
@@ -303,15 +304,6 @@ typedef struct {
list_T *fi_list; /* list being used */
} forinfo_T;
-/*
- * enum used by var_flavour()
- */
-typedef enum {
- VAR_FLAVOUR_DEFAULT, /* doesn't start with uppercase */
- VAR_FLAVOUR_SESSION, /* starts with uppercase, some lower */
- VAR_FLAVOUR_SHADA /* all uppercase */
-} var_flavour_T;
-
/* values for vv_flags: */
#define VV_COMPAT 1 /* compatible, also used without "v:" */
#define VV_RO 2 /* read-only */
@@ -534,6 +526,35 @@ const list_T *eval_msgpack_type_lists[] = {
[kMPExt] = NULL,
};
+// Return "n1" divided by "n2", taking care of dividing by zero.
+varnumber_T num_divide(varnumber_T n1, varnumber_T n2)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ varnumber_T result;
+
+ if (n2 == 0) { // give an error message?
+ if (n1 == 0) {
+ result = VARNUMBER_MIN; // similar to NaN
+ } else if (n1 < 0) {
+ result = -VARNUMBER_MAX;
+ } else {
+ result = VARNUMBER_MAX;
+ }
+ } else {
+ result = n1 / n2;
+ }
+
+ return result;
+}
+
+// Return "n1" modulus "n2", taking care of dividing by zero.
+varnumber_T num_modulus(varnumber_T n1, varnumber_T n2)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ // Give an error when n2 is 0?
+ return (n2 == 0) ? 0 : (n1 % n2);
+}
+
/*
* Initialize the global and v: variables.
*/
@@ -2019,8 +2040,8 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
case '+': n = numval + n; break;
case '-': n = numval - n; break;
case '*': n = numval * n; break;
- case '/': n = numval / n; break;
- case '%': n = numval % n; break;
+ case '/': n = num_divide(numval, n); break;
+ case '%': n = num_modulus(numval, n); break;
}
} else if (opt_type == 0 && stringval != NULL) { // string
char *const oldstringval = stringval;
@@ -4150,22 +4171,9 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
if (op == '*') {
n1 = n1 * n2;
} else if (op == '/') {
- if (n2 == 0) { // give an error message?
- if (n1 == 0) {
- n1 = VARNUMBER_MIN; // similar to NaN
- } else if (n1 < 0) {
- n1 = -VARNUMBER_MAX;
- } else {
- n1 = VARNUMBER_MAX;
- }
- } else {
- n1 = n1 / n2;
- }
+ n1 = num_divide(n1, n2);
} else {
- if (n2 == 0) /* give an error message? */
- n1 = 0;
- else
- n1 = n1 % n2;
+ n1 = num_modulus(n1, n2);
}
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = n1;
@@ -5225,7 +5233,7 @@ bool garbage_collect(bool testing)
yankreg_T reg;
char name = NUL;
bool is_unnamed = false;
- reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
+ reg_iter = op_global_reg_iter(reg_iter, &name, &reg, &is_unnamed);
if (name != NUL) {
ABORTING(set_ref_dict)(reg.additional_data, copyID);
}
@@ -7987,6 +7995,116 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr)
(char_u *)prepend);
}
+/// "ctxget([{index}])" function
+static void f_ctxget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ size_t index = 0;
+ if (argvars[0].v_type == VAR_NUMBER) {
+ index = argvars[0].vval.v_number;
+ } else if (argvars[0].v_type != VAR_UNKNOWN) {
+ EMSG2(_(e_invarg2), "expected nothing or a Number as an argument");
+ return;
+ }
+
+ Context *ctx = ctx_get(index);
+ if (ctx == NULL) {
+ EMSG3(_(e_invargNval), "index", "out of bounds");
+ return;
+ }
+
+ Dictionary ctx_dict = ctx_to_dict(ctx);
+ Error err = ERROR_INIT;
+ object_to_vim(DICTIONARY_OBJ(ctx_dict), rettv, &err);
+ api_free_dictionary(ctx_dict);
+ api_clear_error(&err);
+}
+
+/// "ctxpop()" function
+static void f_ctxpop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ if (!ctx_restore(NULL, kCtxAll)) {
+ EMSG(_("Context stack is empty"));
+ }
+}
+
+/// "ctxpush([{types}])" function
+static void f_ctxpush(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ int types = kCtxAll;
+ if (argvars[0].v_type == VAR_LIST) {
+ types = 0;
+ TV_LIST_ITER(argvars[0].vval.v_list, li, {
+ typval_T *tv_li = TV_LIST_ITEM_TV(li);
+ if (tv_li->v_type == VAR_STRING) {
+ if (strequal((char *)tv_li->vval.v_string, "regs")) {
+ types |= kCtxRegs;
+ } else if (strequal((char *)tv_li->vval.v_string, "jumps")) {
+ types |= kCtxJumps;
+ } else if (strequal((char *)tv_li->vval.v_string, "buflist")) {
+ types |= kCtxBuflist;
+ } else if (strequal((char *)tv_li->vval.v_string, "gvars")) {
+ types |= kCtxGVars;
+ } else if (strequal((char *)tv_li->vval.v_string, "sfuncs")) {
+ types |= kCtxSFuncs;
+ } else if (strequal((char *)tv_li->vval.v_string, "funcs")) {
+ types |= kCtxFuncs;
+ }
+ }
+ });
+ } else if (argvars[0].v_type != VAR_UNKNOWN) {
+ EMSG2(_(e_invarg2), "expected nothing or a List as an argument");
+ return;
+ }
+ ctx_save(NULL, types);
+}
+
+/// "ctxset({context}[, {index}])" function
+static void f_ctxset(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_DICT) {
+ EMSG2(_(e_invarg2), "expected dictionary as first argument");
+ return;
+ }
+
+ size_t index = 0;
+ if (argvars[1].v_type == VAR_NUMBER) {
+ index = argvars[1].vval.v_number;
+ } else if (argvars[1].v_type != VAR_UNKNOWN) {
+ EMSG2(_(e_invarg2), "expected nothing or a Number as second argument");
+ return;
+ }
+
+ Context *ctx = ctx_get(index);
+ if (ctx == NULL) {
+ EMSG3(_(e_invargNval), "index", "out of bounds");
+ return;
+ }
+
+ int save_did_emsg = did_emsg;
+ did_emsg = false;
+
+ Dictionary dict = vim_to_object(&argvars[0]).data.dictionary;
+ Context tmp = CONTEXT_INIT;
+ ctx_from_dict(dict, &tmp);
+
+ if (did_emsg) {
+ ctx_free(&tmp);
+ } else {
+ ctx_free(ctx);
+ *ctx = tmp;
+ }
+
+ api_free_dictionary(dict);
+ did_emsg = save_did_emsg;
+}
+
+/// "ctxsize()" function
+static void f_ctxsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = ctx_size();
+}
+
/// "cursor(lnum, col)" function, or
/// "cursor(list)"
///
@@ -9462,6 +9580,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
dictitem_T *di;
dict_T *d;
typval_T *tv = NULL;
+ bool what_is_dict = false;
if (argvars[0].v_type == VAR_LIST) {
if ((l = argvars[0].vval.v_list) != NULL) {
@@ -9503,7 +9622,10 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
func_ref(rettv->vval.v_string);
}
} else if (strcmp(what, "dict") == 0) {
- tv_dict_set_ret(rettv, pt->pt_dict);
+ what_is_dict = true;
+ if (pt->pt_dict != NULL) {
+ tv_dict_set_ret(rettv, pt->pt_dict);
+ }
} else if (strcmp(what, "args") == 0) {
rettv->v_type = VAR_LIST;
if (tv_list_alloc_ret(rettv, pt->pt_argc) != NULL) {
@@ -9514,7 +9636,12 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
EMSG2(_(e_invarg2), what);
}
- return;
+
+ // When {what} == "dict" and pt->pt_dict == NULL, evaluate the
+ // third argument
+ if (!what_is_dict) {
+ return;
+ }
}
} else {
EMSG2(_(e_listdictarg), "get()");
@@ -15037,15 +15164,15 @@ static void set_buffer_lines(buf_T *buf, linenr_T lnum, typval_T *lines,
}
rettv->vval.v_number = 1; // FAIL
- if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) {
+ if (line == NULL || lnum > curbuf->b_ml.ml_line_count + 1) {
break;
}
- /* When coming here from Insert mode, sync undo, so that this can be
- * undone separately from what was previously inserted. */
+ // When coming here from Insert mode, sync undo, so that this can be
+ // undone separately from what was previously inserted.
if (u_sync_once == 2) {
- u_sync_once = 1; /* notify that u_sync() was called */
- u_sync(TRUE);
+ u_sync_once = 1; // notify that u_sync() was called
+ u_sync(true);
}
if (lnum <= curbuf->b_ml.ml_line_count) {
@@ -15582,7 +15709,7 @@ free_lstval:
if (set_unnamed) {
// Discard the result. We already handle the error case.
- if (op_register_set_previous(regname)) { }
+ if (op_reg_set_previous(regname)) { }
}
}
@@ -15869,10 +15996,12 @@ static void f_sign_getplaced(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
if ((di = tv_dict_find(dict, "lnum", -1)) != NULL) {
// get signs placed at this line
- lnum = tv_get_lnum(&di->di_tv);
- if (lnum <= 0) {
+ lnum = (linenr_T)tv_get_number_chk(&di->di_tv, &notanum);
+ if (notanum) {
return;
}
+ (void)lnum;
+ lnum = tv_get_lnum(&di->di_tv);
}
if ((di = tv_dict_find(dict, "id", -1)) != NULL) {
// get sign placed with this identifier
@@ -15926,9 +16055,6 @@ static void f_sign_jump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
sign_group = NULL; // global sign group
} else {
sign_group = xstrdup(sign_group_chk);
- if (sign_group == NULL) {
- return;
- }
}
// Buffer to place the sign
@@ -15977,9 +16103,6 @@ static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
group = NULL; // global sign group
} else {
group = vim_strsave((const char_u *)group_chk);
- if (group == NULL) {
- return;
- }
}
// Sign name
@@ -16007,6 +16130,7 @@ static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (notanum) {
goto cleanup;
}
+ (void)lnum;
lnum = tv_get_lnum(&di->di_tv);
}
if ((di = tv_dict_find(dict, "priority", -1)) != NULL) {
@@ -16072,9 +16196,6 @@ static void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr)
group = NULL; // global sign group
} else {
group = vim_strsave((const char_u *)group_chk);
- if (group == NULL) {
- return;
- }
}
if (argvars[1].v_type != VAR_UNKNOWN) {
@@ -20847,7 +20968,7 @@ void ex_function(exarg_T *eap)
continue;
}
if (!func_name_refcount(fp->uf_name)) {
- list_func_head(fp, false);
+ list_func_head(fp, false, false);
}
}
}
@@ -20878,7 +20999,7 @@ void ex_function(exarg_T *eap)
fp = HI2UF(hi);
if (!isdigit(*fp->uf_name)
&& vim_regexec(&regmatch, fp->uf_name, 0))
- list_func_head(fp, FALSE);
+ list_func_head(fp, false, false);
}
}
vim_regfree(regmatch.regprog);
@@ -20928,9 +21049,12 @@ void ex_function(exarg_T *eap)
saved_did_emsg = did_emsg;
did_emsg = FALSE;
- /*
- * ":function func" with only function name: list function.
- */
+ //
+ // ":function func" with only function name: list function.
+ // If bang is given:
+ // - include "!" in function head
+ // - exclude line numbers from function body
+ //
if (!paren) {
if (!ends_excmd(*skipwhite(p))) {
EMSG(_(e_trailing));
@@ -20942,17 +21066,20 @@ void ex_function(exarg_T *eap)
if (!eap->skip && !got_int) {
fp = find_func(name);
if (fp != NULL) {
- list_func_head(fp, TRUE);
- for (int j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) {
- if (FUNCLINE(fp, j) == NULL)
+ list_func_head(fp, !eap->forceit, eap->forceit);
+ for (int j = 0; j < fp->uf_lines.ga_len && !got_int; j++) {
+ if (FUNCLINE(fp, j) == NULL) {
continue;
- msg_putchar('\n');
- msg_outnum((long)j + 1);
- if (j < 9) {
- msg_putchar(' ');
}
- if (j < 99) {
- msg_putchar(' ');
+ msg_putchar('\n');
+ if (!eap->forceit) {
+ msg_outnum((long)j + 1);
+ if (j < 9) {
+ msg_putchar(' ');
+ }
+ if (j < 99) {
+ msg_putchar(' ');
+ }
}
msg_prt_line(FUNCLINE(fp, j), false);
ui_flush(); // show a line at a time
@@ -20960,7 +21087,7 @@ void ex_function(exarg_T *eap)
}
if (!got_int) {
msg_putchar('\n');
- msg_puts(" endfunction");
+ msg_puts(eap->forceit ? "endfunction" : " endfunction");
}
} else
emsg_funcname(N_("E123: Undefined function: %s"), name);
@@ -21650,15 +21777,17 @@ static inline bool eval_fname_sid(const char *const name)
return *name == 's' || TOUPPER_ASC(name[2]) == 'I';
}
-/*
- * List the head of the function: "name(arg1, arg2)".
- */
-static void list_func_head(ufunc_T *fp, int indent)
+/// List the head of the function: "name(arg1, arg2)".
+///
+/// @param[in] fp Function pointer.
+/// @param[in] indent Indent line.
+/// @param[in] force Include bang "!" (i.e.: "function!").
+static void list_func_head(ufunc_T *fp, int indent, bool force)
{
msg_start();
if (indent)
MSG_PUTS(" ");
- MSG_PUTS("function ");
+ MSG_PUTS(force ? "function! " : "function ");
if (fp->uf_name[0] == K_SPECIAL) {
MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
msg_puts((const char *)fp->uf_name + 3);
@@ -23242,7 +23371,7 @@ dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
/// @return Pointer that needs to be passed to next `var_shada_iter` invocation
/// or NULL to indicate that iteration is over.
const void *var_shada_iter(const void *const iter, const char **const name,
- typval_T *rettv)
+ typval_T *rettv, var_flavour_T flavour)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2, 3)
{
const hashitem_T *hi;
@@ -23253,7 +23382,7 @@ const void *var_shada_iter(const void *const iter, const char **const name,
hi = globvarht.ht_array;
while ((size_t) (hi - hifirst) < hinum
&& (HASHITEM_EMPTY(hi)
- || var_flavour(hi->hi_key) != VAR_FLAVOUR_SHADA)) {
+ || !(var_flavour(hi->hi_key) & flavour))) {
hi++;
}
if ((size_t) (hi - hifirst) == hinum) {
@@ -23265,7 +23394,7 @@ const void *var_shada_iter(const void *const iter, const char **const name,
*name = (char *)TV_DICT_HI2DI(hi)->di_key;
tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv);
while ((size_t)(++hi - hifirst) < hinum) {
- if (!HASHITEM_EMPTY(hi) && var_flavour(hi->hi_key) == VAR_FLAVOUR_SHADA) {
+ if (!HASHITEM_EMPTY(hi) && (var_flavour(hi->hi_key) & flavour)) {
return hi;
}
}
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 149dae688e..abe032a96e 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -24,6 +24,13 @@ EXTERN ufunc_T dumuf;
#define HIKEY2UF(p) ((ufunc_T *)(p - offsetof(ufunc_T, uf_name)))
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
+/// enum used by var_flavour()
+typedef enum {
+ VAR_FLAVOUR_DEFAULT = 1, // doesn't start with uppercase
+ VAR_FLAVOUR_SESSION = 2, // starts with uppercase, some lower
+ VAR_FLAVOUR_SHADA = 4 // all uppercase
+} var_flavour_T;
+
/// Defines for Vim variables
typedef enum {
VV_COUNT,
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 089b08d5d1..0b77a24f7a 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -74,6 +74,11 @@ return {
cosh={args=1, func="float_op_wrapper", data="&cosh"},
count={args={2, 4}},
cscope_connection={args={0, 3}},
+ ctxget={args={0, 1}},
+ ctxpop={},
+ ctxpush={args={0, 1}},
+ ctxset={args={1, 2}},
+ ctxsize={},
cursor={args={1, 3}},
deepcopy={args={1, 2}},
delete={args={1,2}},
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index e972c506dd..8cd21f8d62 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -74,8 +74,8 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
case '+': n += tv_get_number(tv2); break;
case '-': n -= tv_get_number(tv2); break;
case '*': n *= tv_get_number(tv2); break;
- case '/': n /= tv_get_number(tv2); break;
- case '%': n %= tv_get_number(tv2); break;
+ case '/': n = num_divide(n, tv_get_number(tv2)); break;
+ case '%': n = num_modulus(n, tv_get_number(tv2)); break;
}
tv_clear(tv1);
tv1->v_type = VAR_NUMBER;
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index cd0b05c6c9..73e6f85627 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -1793,17 +1793,14 @@ void ex_args(exarg_T *eap)
// ":args": list arguments.
if (ARGCOUNT > 0) {
char_u **items = xmalloc(sizeof(char_u *) * (size_t)ARGCOUNT);
-
- if (items != NULL) {
- // Overwrite the command, for a short list there is no scrolling
- // required and no wait_return().
- gotocmdline(true);
- for (int i = 0; i < ARGCOUNT; i++) {
- items[i] = alist_name(&ARGLIST[i]);
- }
- list_in_columns(items, ARGCOUNT, curwin->w_arg_idx);
- xfree(items);
+ // Overwrite the command, for a short list there is no scrolling
+ // required and no wait_return().
+ gotocmdline(true);
+ for (int i = 0; i < ARGCOUNT; i++) {
+ items[i] = alist_name(&ARGLIST[i]);
}
+ list_in_columns(items, ARGCOUNT, curwin->w_arg_idx);
+ xfree(items);
}
} else if (eap->cmdidx == CMD_arglocal) {
garray_T *gap = &curwin->w_alist->al_ga;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index c8edf7173e..5365270e0b 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -7520,7 +7520,7 @@ static void ex_operators(exarg_T *eap)
case CMD_yank:
oa.op_type = OP_YANK;
- (void)op_yank(&oa, true);
+ (void)op_yank(&oa, true, false);
break;
default: /* CMD_rshift or CMD_lshift */
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index ec9f978416..38432a34db 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -4946,7 +4946,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
{
char_u *pat;
int i;
- char_u *path;
+ char_u *path = NULL;
garray_T ga;
char_u *buf = xmalloc(MAXPATHL);
size_t l;
@@ -4965,15 +4965,14 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
bool mustfree = false; // Track memory allocation for *path.
- // For an absolute name we don't use $PATH.
- if (path_is_absolute(pat)) {
- path = (char_u *)" ";
- } else if (pat[0] == '.' && (vim_ispathsep(pat[1])
- || (pat[1] == '.'
- && vim_ispathsep(pat[2])))) {
+ if (pat[0] == '.' && (vim_ispathsep(pat[1])
+ || (pat[1] == '.' && vim_ispathsep(pat[2])))) {
path = (char_u *)".";
} else {
- path = (char_u *)vim_getenv("PATH");
+ // For an absolute name we don't use $PATH.
+ if (!path_is_absolute(pat)) {
+ path = (char_u *)vim_getenv("PATH");
+ }
if (path == NULL) {
path = (char_u *)"";
} else {
@@ -4987,6 +4986,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
* current directory, to find "subdir/cmd".
*/
ga_init(&ga, (int)sizeof(char *), 10);
+ hashtab_T found_ht;
+ hash_init(&found_ht);
for (s = path; ; s = e) {
if (*s == NUL) {
if (did_curdir) {
@@ -4998,13 +4999,10 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
did_curdir = true;
}
- if (*s == ' ') {
- s++; // Skip space used for absolute path name.
- }
-
- e = vim_strchr(s, ':');
- if (e == NULL)
+ e = vim_strchr(s, ENV_SEPCHAR);
+ if (e == NULL) {
e = s + STRLEN(s);
+ }
l = (size_t)(e - s);
if (l > MAXPATHL - 5) {
@@ -5020,14 +5018,24 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
if (ret == OK) {
ga_grow(&ga, *num_file);
{
- for (i = 0; i < *num_file; ++i) {
- s = (*file)[i];
- if (STRLEN(s) > l) {
- /* Remove the path again. */
- STRMOVE(s, s + l);
- ((char_u **)ga.ga_data)[ga.ga_len++] = s;
- } else
- xfree(s);
+ for (i = 0; i < *num_file; i++) {
+ char_u *name = (*file)[i];
+
+ if (STRLEN(name) > l) {
+ // Check if this name was already found.
+ hash_T hash = hash_hash(name + l);
+ hashitem_T *hi =
+ hash_lookup(&found_ht, (const char *)(name + l),
+ STRLEN(name + l), hash);
+ if (HASHITEM_EMPTY(hi)) {
+ // Remove the path that was prepended.
+ STRMOVE(name, name + l);
+ ((char_u **)ga.ga_data)[ga.ga_len++] = name;
+ hash_add_item(&found_ht, hi, name, hash);
+ name = NULL;
+ }
+ }
+ xfree(name);
}
xfree(*file);
}
@@ -5043,6 +5051,7 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
if (mustfree) {
xfree(path);
}
+ hash_clear(&found_ht);
}
/// Call "user_expand_func()" to invoke a user defined Vim script function and
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 387475c9e2..907e6c978a 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -4248,15 +4248,13 @@ void shorten_buf_fname(buf_T *buf, char_u *dirname, int force)
buf->b_sfname = vim_strsave(p);
buf->b_fname = buf->b_sfname;
}
- if (p == NULL || buf->b_fname == NULL) {
+ if (p == NULL) {
buf->b_fname = buf->b_ffname;
}
}
}
-/*
- * Shorten filenames for all buffers.
- */
+/// Shorten filenames for all buffers.
void shorten_fnames(int force)
{
char_u dirname[MAXPATHL];
@@ -4265,8 +4263,8 @@ void shorten_fnames(int force)
FOR_ALL_BUFFERS(buf) {
shorten_buf_fname(buf, dirname, force);
- /* Always make the swap file name a full path, a "nofile" buffer may
- * also have a swap file. */
+ // Always make the swap file name a full path, a "nofile" buffer may
+ // also have a swap file.
mf_fullname(buf->b_ml.ml_mfp);
}
status_redraw_all();
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 28d37f3581..7d8342c4dd 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -3288,29 +3288,36 @@ char *map_mode_to_chars(int mode)
ga_init(&mapmode, 1, 7);
- if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
- ga_append(&mapmode, '!'); /* :map! */
- else if (mode & INSERT)
- ga_append(&mapmode, 'i'); /* :imap */
- else if (mode & LANGMAP)
- ga_append(&mapmode, 'l'); /* :lmap */
- else if (mode & CMDLINE)
- ga_append(&mapmode, 'c'); /* :cmap */
- else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
- == NORMAL + VISUAL + SELECTMODE + OP_PENDING)
- ga_append(&mapmode, ' '); /* :map */
- else {
- if (mode & NORMAL)
- ga_append(&mapmode, 'n'); /* :nmap */
- if (mode & OP_PENDING)
- ga_append(&mapmode, 'o'); /* :omap */
- if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE)
- ga_append(&mapmode, 'v'); /* :vmap */
- else {
- if (mode & VISUAL)
- ga_append(&mapmode, 'x'); /* :xmap */
- if (mode & SELECTMODE)
- ga_append(&mapmode, 's'); /* :smap */
+ if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE) {
+ ga_append(&mapmode, '!'); // :map!
+ } else if (mode & INSERT) {
+ ga_append(&mapmode, 'i'); // :imap
+ } else if (mode & LANGMAP) {
+ ga_append(&mapmode, 'l'); // :lmap
+ } else if (mode & CMDLINE) {
+ ga_append(&mapmode, 'c'); // :cmap
+ } else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING))
+ == NORMAL + VISUAL + SELECTMODE + OP_PENDING) {
+ ga_append(&mapmode, ' '); // :map
+ } else {
+ if (mode & NORMAL) {
+ ga_append(&mapmode, 'n'); // :nmap
+ }
+ if (mode & OP_PENDING) {
+ ga_append(&mapmode, 'o'); // :omap
+ }
+ if (mode & TERM_FOCUS) {
+ ga_append(&mapmode, 't'); // :tmap
+ }
+ if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE) {
+ ga_append(&mapmode, 'v'); // :vmap
+ } else {
+ if (mode & VISUAL) {
+ ga_append(&mapmode, 'x'); // :xmap
+ }
+ if (mode & SELECTMODE) {
+ ga_append(&mapmode, 's'); // :smap
+ }
}
}
@@ -3441,7 +3448,7 @@ int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
{
mapblock_T *mp;
int hash;
- bool expand_buffer = false;
+ bool exp_buffer = false;
validate_maphash();
@@ -3452,12 +3459,12 @@ int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
if (hash > 0) { // There is only one abbr list.
break;
}
- if (expand_buffer) {
+ if (exp_buffer) {
mp = curbuf->b_first_abbr;
} else {
mp = first_abbr;
}
- } else if (expand_buffer) {
+ } else if (exp_buffer) {
mp = curbuf->b_maphash[hash];
} else {
mp = maphash[hash];
@@ -3469,10 +3476,10 @@ int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
}
}
}
- if (expand_buffer) {
+ if (exp_buffer) {
break;
}
- expand_buffer = true;
+ exp_buffer = true;
}
return false;
@@ -3947,10 +3954,10 @@ void vim_unescape_csi(char_u *p)
* Write map commands for the current mappings to an .exrc file.
* Return FAIL on error, OK otherwise.
*/
-int
-makemap (
+int
+makemap(
FILE *fd,
- buf_T *buf /* buffer for local mappings or NULL */
+ buf_T *buf // buffer for local mappings or NULL
)
{
mapblock_T *mp;
@@ -3963,50 +3970,56 @@ makemap (
validate_maphash();
- /*
- * Do the loop twice: Once for mappings, once for abbreviations.
- * Then loop over all map hash lists.
- */
- for (abbr = 0; abbr < 2; ++abbr)
- for (hash = 0; hash < 256; ++hash) {
+ // Do the loop twice: Once for mappings, once for abbreviations.
+ // Then loop over all map hash lists.
+ for (abbr = 0; abbr < 2; abbr++) {
+ for (hash = 0; hash < 256; hash++) {
if (abbr) {
- if (hash > 0) /* there is only one abbr list */
+ if (hash > 0) { // there is only one abbr list
break;
- if (buf != NULL)
+ }
+ if (buf != NULL) {
mp = buf->b_first_abbr;
- else
+ } else {
mp = first_abbr;
+ }
} else {
- if (buf != NULL)
+ if (buf != NULL) {
mp = buf->b_maphash[hash];
- else
+ } else {
mp = maphash[hash];
+ }
}
for (; mp; mp = mp->m_next) {
- /* skip script-local mappings */
- if (mp->m_noremap == REMAP_SCRIPT)
+ // skip script-local mappings
+ if (mp->m_noremap == REMAP_SCRIPT) {
continue;
+ }
- /* skip mappings that contain a <SNR> (script-local thing),
- * they probably don't work when loaded again */
- for (p = mp->m_str; *p != NUL; ++p)
+ // skip mappings that contain a <SNR> (script-local thing),
+ // they probably don't work when loaded again
+ for (p = mp->m_str; *p != NUL; p++) {
if (p[0] == K_SPECIAL && p[1] == KS_EXTRA
- && p[2] == (int)KE_SNR)
+ && p[2] == (int)KE_SNR) {
break;
- if (*p != NUL)
+ }
+ }
+ if (*p != NUL) {
continue;
+ }
- /* It's possible to create a mapping and then ":unmap" certain
- * modes. We recreate this here by mapping the individual
- * modes, which requires up to three of them. */
+ // It's possible to create a mapping and then ":unmap" certain
+ // modes. We recreate this here by mapping the individual
+ // modes, which requires up to three of them.
c1 = NUL;
c2 = NUL;
c3 = NUL;
- if (abbr)
+ if (abbr) {
cmd = "abbr";
- else
+ } else {
cmd = "map";
+ }
switch (mp->m_mode) {
case NORMAL + VISUAL + SELECTMODE + OP_PENDING:
break;
@@ -4064,8 +4077,9 @@ makemap (
c2 = 'o';
break;
case CMDLINE + INSERT:
- if (!abbr)
+ if (!abbr) {
cmd = "map!";
+ }
break;
case CMDLINE:
c1 = 'c';
@@ -4083,9 +4097,10 @@ makemap (
IEMSG(_("E228: makemap: Illegal mode"));
return FAIL;
}
- do { /* do this twice if c2 is set, 3 times with c3 */
- /* When outputting <> form, need to make sure that 'cpo'
- * is set to the Vim default. */
+ do {
+ // do this twice if c2 is set, 3 times with c3 */
+ // When outputting <> form, need to make sure that 'cpo'
+ // is set to the Vim default.
if (!did_cpo) {
if (*mp->m_str == NUL) { // Will use <Nop>.
did_cpo = true;
@@ -4100,63 +4115,69 @@ makemap (
if (fprintf(fd, "let s:cpo_save=&cpo") < 0
|| put_eol(fd) < 0
|| fprintf(fd, "set cpo&vim") < 0
- || put_eol(fd) < 0)
+ || put_eol(fd) < 0) {
return FAIL;
+ }
}
}
- if (c1 && putc(c1, fd) < 0)
- return FAIL;
- if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
+ if (c1 && putc(c1, fd) < 0) {
return FAIL;
- if (fputs(cmd, fd) < 0)
+ }
+ if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0) {
return FAIL;
- if (buf != NULL && fputs(" <buffer>", fd) < 0)
+ }
+ if (fputs(cmd, fd) < 0) {
return FAIL;
- if (mp->m_nowait && fputs(" <nowait>", fd) < 0)
+ }
+ if (buf != NULL && fputs(" <buffer>", fd) < 0) {
return FAIL;
- if (mp->m_silent && fputs(" <silent>", fd) < 0)
+ }
+ if (mp->m_nowait && fputs(" <nowait>", fd) < 0) {
return FAIL;
- if (mp->m_noremap == REMAP_SCRIPT
- && fputs("<script>", fd) < 0)
+ }
+ if (mp->m_silent && fputs(" <silent>", fd) < 0) {
return FAIL;
- if (mp->m_expr && fputs(" <expr>", fd) < 0)
+ }
+ if (mp->m_expr && fputs(" <expr>", fd) < 0) {
return FAIL;
+ }
- if ( putc(' ', fd) < 0
- || put_escstr(fd, mp->m_keys, 0) == FAIL
- || putc(' ', fd) < 0
- || put_escstr(fd, mp->m_str, 1) == FAIL
- || put_eol(fd) < 0)
+ if (putc(' ', fd) < 0
+ || put_escstr(fd, mp->m_keys, 0) == FAIL
+ || putc(' ', fd) < 0
+ || put_escstr(fd, mp->m_str, 1) == FAIL
+ || put_eol(fd) < 0) {
return FAIL;
+ }
c1 = c2;
c2 = c3;
c3 = NUL;
} while (c1 != NUL);
}
}
-
- if (did_cpo)
+ }
+ if (did_cpo) {
if (fprintf(fd, "let &cpo=s:cpo_save") < 0
|| put_eol(fd) < 0
|| fprintf(fd, "unlet s:cpo_save") < 0
- || put_eol(fd) < 0)
+ || put_eol(fd) < 0) {
return FAIL;
+ }
+ }
return OK;
}
-/*
- * write escape string to file
- * "what": 0 for :map lhs, 1 for :map rhs, 2 for :set
- *
- * return FAIL for failure, OK otherwise
- */
+// write escape string to file
+// "what": 0 for :map lhs, 1 for :map rhs, 2 for :set
+//
+// return FAIL for failure, OK otherwise
int put_escstr(FILE *fd, char_u *strstart, int what)
{
char_u *str = strstart;
int c;
int modifiers;
- /* :map xx <Nop> */
+ // :map xx <Nop>
if (*str == NUL && what == 1) {
if (fprintf(fd, "<Nop>") < 0)
return FAIL;
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index c758e000a9..f2ba91335d 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -163,7 +163,8 @@
# define NVIM_HAS_ATTRIBUTE __has_attribute
#endif
-#if NVIM_HAS_ATTRIBUTE(fallthrough)
+#if NVIM_HAS_ATTRIBUTE(fallthrough) \
+ && (!defined(__apple_build_version__) || __apple_build_version__ >= 7000000)
# define FALLTHROUGH __attribute__((fallthrough))
#else
# define FALLTHROUGH
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 3736004527..9f357575d0 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1213,8 +1213,8 @@ void cleanup_jumplist(win_T *wp, bool loadfiles)
// When pointer is below last jump, remove the jump if it matches the current
// line. This avoids useless/phantom jumps. #9805
- if (wp->w_jumplistlen
- && wp->w_jumplistidx == wp->w_jumplistlen) {
+ if (loadfiles // otherwise (i.e.: Shada), last entry should be kept
+ && wp->w_jumplistlen && wp->w_jumplistidx == wp->w_jumplistlen) {
const xfmark_T *fm_last = &wp->w_jumplist[wp->w_jumplistlen - 1];
if (fm_last->fmark.fnum == curbuf->b_fnum
&& fm_last->fmark.mark.lnum == wp->w_cursor.lnum) {
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 1384aa177b..64aae71433 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -9,6 +9,7 @@
#include <stdbool.h>
#include "nvim/vim.h"
+#include "nvim/context.h"
#include "nvim/eval.h"
#include "nvim/highlight.h"
#include "nvim/memfile.h"
@@ -671,6 +672,7 @@ void free_all_mem(void)
eval_clear();
api_vim_free_all_mem();
+ ctx_free_all();
// Free all buffers. Reset 'autochdir' to avoid accessing things that
// were freed already.
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 286159ac0f..c3b4f4e376 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1817,7 +1817,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
}
} else {
curwin->w_p_lbr = lbr_saved;
- (void)op_yank(oap, !gui_yank);
+ (void)op_yank(oap, !gui_yank, false);
}
check_cursor_col();
break;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 40c96eb333..6709e52679 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -1400,9 +1400,11 @@ int op_delete(oparg_T *oap)
*/
if (oap->regname != '_') {
yankreg_T *reg = NULL;
+ int did_yank = false;
if (oap->regname != 0) {
- //yank without message
- if (!op_yank(oap, false)) {
+ // yank without message
+ did_yank = op_yank(oap, false, true);
+ if (!did_yank) {
// op_yank failed, don't do anything
return OK;
}
@@ -1423,6 +1425,7 @@ int op_delete(oparg_T *oap)
y_regs[1].y_array = NULL; // set register "1 to empty
reg = &y_regs[1];
op_yank_reg(oap, false, reg, false);
+ did_yank = true;
}
/* Yank into small delete register when no named register specified
@@ -1431,13 +1434,14 @@ int op_delete(oparg_T *oap)
&& oap->line_count == 1) {
reg = get_yank_register('-', YREG_YANK);
op_yank_reg(oap, false, reg, false);
+ did_yank = true;
}
- if (oap->regname == 0) {
+ if (did_yank || oap->regname == 0) {
if (reg == NULL) {
abort();
}
- set_clipboard(0, reg);
+ set_clipboard(oap->regname, reg);
do_autocmd_textyankpost(oap, reg);
}
@@ -2376,8 +2380,9 @@ void free_register(yankreg_T *reg)
///
/// @param oap operator arguments
/// @param message show message when more than `&report` lines are yanked.
+/// @param deleting whether the function was called from a delete operation.
/// @returns whether the operation register was writable.
-bool op_yank(oparg_T *oap, bool message)
+bool op_yank(oparg_T *oap, bool message, int deleting)
FUNC_ATTR_NONNULL_ALL
{
// check for read-only register
@@ -2391,8 +2396,11 @@ bool op_yank(oparg_T *oap, bool message)
yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK);
op_yank_reg(oap, message, reg, is_append_register(oap->regname));
- set_clipboard(oap->regname, reg);
- do_autocmd_textyankpost(oap, reg);
+ // op_delete will set_clipboard and do_autocmd
+ if (!deleting) {
+ set_clipboard(oap->regname, reg);
+ do_autocmd_textyankpost(oap, reg);
+ }
return true;
}
@@ -3439,7 +3447,7 @@ void ex_display(exarg_T *eap)
MSG_PUTS_ATTR("^J", attr);
n -= 2;
}
- for (p = yb->y_array[j]; *p && (n -= ptr2cells(p)) >= 0; p++) { // -V1019
+ for (p = yb->y_array[j]; *p && (n -= ptr2cells(p)) >= 0; p++) { // -V1019 NOLINT(whitespace/line_length)
clen = (*mb_ptr2len)(p);
msg_outtrans_len(p, clen);
p += clen - 1;
@@ -3516,8 +3524,8 @@ void ex_display(exarg_T *eap)
* display a string for do_dis()
* truncate at end of screen line
*/
-static void
-dis_msg (
+static void
+dis_msg(
char_u *p,
int skip_esc /* if TRUE, ignore trailing ESC */
)
@@ -3857,8 +3865,8 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in
/*
* Implementation of the format operator 'gq'.
*/
-void
-op_format (
+void
+op_format(
oparg_T *oap,
int keep_cursor /* keep cursor on same text char */
)
@@ -3937,8 +3945,8 @@ void op_formatexpr(oparg_T *oap)
op_format(oap, FALSE);
}
-int
-fex_format (
+int
+fex_format(
linenr_T lnum,
long count,
int c /* character to be inserted */
@@ -3980,8 +3988,8 @@ fex_format (
* Lines after the cursor line are saved for undo, caller must have saved the
* first line.
*/
-void
-format_lines (
+void
+format_lines(
linenr_T line_count,
int avoid_fex /* don't use 'formatexpr' */
)
@@ -5892,33 +5900,45 @@ static inline bool reg_empty(const yankreg_T *const reg)
&& *(reg->y_array[0]) == NUL));
}
-/// Iterate over registerrs
+/// Iterate over global registers.
+///
+/// @see op_register_iter
+const void *op_global_reg_iter(const void *const iter, char *const name,
+ yankreg_T *const reg, bool *is_unnamed)
+ FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return op_reg_iter(iter, y_regs, name, reg, is_unnamed);
+}
+
+/// Iterate over registers `regs`.
///
/// @param[in] iter Iterator. Pass NULL to start iteration.
+/// @param[in] regs Registers list to be iterated.
/// @param[out] name Register name.
/// @param[out] reg Register contents.
///
-/// @return Pointer that needs to be passed to next `op_register_iter` call or
+/// @return Pointer that must be passed to next `op_register_iter` call or
/// NULL if iteration is over.
-const void *op_register_iter(const void *const iter, char *const name,
- yankreg_T *const reg, bool *is_unnamed)
- FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
+const void *op_reg_iter(const void *const iter, const yankreg_T *const regs,
+ char *const name, yankreg_T *const reg,
+ bool *is_unnamed)
+ FUNC_ATTR_NONNULL_ARG(3, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
const yankreg_T *iter_reg = (iter == NULL
- ? &(y_regs[0])
- : (const yankreg_T *const) iter);
- while (iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS && reg_empty(iter_reg)) {
+ ? &(regs[0])
+ : (const yankreg_T *const)iter);
+ while (iter_reg - &(regs[0]) < NUM_SAVED_REGISTERS && reg_empty(iter_reg)) {
iter_reg++;
}
- if (iter_reg - &(y_regs[0]) == NUM_SAVED_REGISTERS || reg_empty(iter_reg)) {
+ if (iter_reg - &(regs[0]) == NUM_SAVED_REGISTERS || reg_empty(iter_reg)) {
return NULL;
}
- int iter_off = (int)(iter_reg - &(y_regs[0]));
+ int iter_off = (int)(iter_reg - &(regs[0]));
*name = (char)get_register_name(iter_off);
*reg = *iter_reg;
*is_unnamed = (iter_reg == y_previous);
- while (++iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS) {
+ while (++iter_reg - &(regs[0]) < NUM_SAVED_REGISTERS) {
if (!reg_empty(iter_reg)) {
return (void *) iter_reg;
}
@@ -5927,7 +5947,7 @@ const void *op_register_iter(const void *const iter, char *const name,
}
/// Get a number of non-empty registers
-size_t op_register_amount(void)
+size_t op_reg_amount(void)
FUNC_ATTR_WARN_UNUSED_RESULT
{
size_t ret = 0;
@@ -5946,7 +5966,7 @@ size_t op_register_amount(void)
/// @param[in] is_unnamed Whether to set the unnamed regiseter to reg
///
/// @return true on success, false on failure.
-bool op_register_set(const char name, const yankreg_T reg, bool is_unnamed)
+bool op_reg_set(const char name, const yankreg_T reg, bool is_unnamed)
{
int i = op_reg_index(name);
if (i == -1) {
@@ -5966,7 +5986,7 @@ bool op_register_set(const char name, const yankreg_T reg, bool is_unnamed)
/// @param[in] name Register name.
///
/// @return Pointer to the register contents or NULL.
-const yankreg_T *op_register_get(const char name)
+const yankreg_T *op_reg_get(const char name)
{
int i = op_reg_index(name);
if (i == -1) {
@@ -5980,7 +6000,7 @@ const yankreg_T *op_register_get(const char name)
/// @param[in] name Register name.
///
/// @return true on success, false on failure.
-bool op_register_set_previous(const char name)
+bool op_reg_set_previous(const char name)
FUNC_ATTR_WARN_UNUSED_RESULT
{
int i = op_reg_index(name);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 35151ab81c..40c1358fa5 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3508,7 +3508,9 @@ static char_u *set_chars_option(win_T *wp, char_u **varp)
{
int round, i, len, entries;
char_u *p, *s;
- int c1 = 0, c2 = 0, c3 = 0;
+ int c1;
+ int c2 = 0;
+ int c3 = 0;
struct chars_tab {
int *cp; ///< char value
@@ -3575,7 +3577,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp)
if (STRNCMP(p, tab[i].name, len) == 0
&& p[len] == ':'
&& p[len + 1] != NUL) {
- c1 = c2 = c3 = 0;
+ c2 = c3 = 0;
s = p + len + 1;
// TODO(bfredl): use schar_T representation and utfc_ptr2len
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index ef4330003f..ce40bc15e0 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -855,7 +855,8 @@ int pum_get_height(void)
return pum_height;
}
-void pum_set_boundings(dict_T *dict)
+/// Add size information about the pum to "dict".
+void pum_set_event_info(dict_T *dict)
{
if (!pum_visible()) {
return;
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index cc4a2a90b9..1eb616bca7 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1326,7 +1326,7 @@ static int qf_parse_multiline_pfx(qf_info_T *qi, int qf_idx, int idx,
if (qfprev == NULL) {
return QF_FAIL;
}
- if (*fields->errmsg && !qfl->qf_multiignore) {
+ if (*fields->errmsg) {
size_t textlen = strlen((char *)qfprev->qf_text);
size_t errlen = strlen((char *)fields->errmsg);
qfprev->qf_text = xrealloc(qfprev->qf_text, textlen + errlen + 2);
@@ -2056,7 +2056,7 @@ static int qf_jump_to_usable_window(int qf_fnum, int *opened_window)
win_T *usable_win_ptr = NULL;
int usable_win;
int flags;
- win_T *win = NULL;
+ win_T *win;
win_T *altwin;
usable_win = 0;
@@ -2079,7 +2079,6 @@ static int qf_jump_to_usable_window(int qf_fnum, int *opened_window)
// Locate a window showing a normal buffer
FOR_ALL_WINDOWS_IN_TAB(win2, curtab) {
if (win2->w_buffer->b_p_bt[0] == NUL) {
- win = win2;
usable_win = 1;
break;
}
@@ -2212,7 +2211,6 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit,
oldwin == curwin ? curwin : NULL);
}
} else {
- int old_qf_curlist = qi->qf_curlist;
unsigned save_qfid = qi->qf_lists[qi->qf_curlist].qf_id;
retval = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
@@ -2229,8 +2227,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit,
EMSG(_(e_loc_list_changed));
*abort = true;
}
- } else if (old_qf_curlist != qi->qf_curlist
- || !is_qf_entry_present(qi, qf_ptr)) {
+ } else if (!is_qf_entry_present(qi, qf_ptr)) {
if (IS_QF_STACK(qi)) {
EMSG(_("E925: Current quickfix was changed"));
} else {
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 414472a8f3..06b99d0b75 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -4323,8 +4323,10 @@ static int regmatch(
/* Still at same position as last time, fail. */
status = RA_NOMATCH;
- if (status != RA_FAIL && status != RA_NOMATCH)
+ assert(status != RA_FAIL);
+ if (status != RA_NOMATCH) {
reg_save(&bp[i].bp_pos, &backpos);
+ }
}
break;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 877bd2db21..06f886d411 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -3143,7 +3143,6 @@ win_line (
c = '>';
mb_c = c;
mb_l = 1;
- mb_utf8 = false;
multi_attr = win_hl_attr(wp, HLF_AT);
// put the pointer back to output the double-width
diff --git a/src/nvim/search.c b/src/nvim/search.c
index c1770fd80d..85de7f26de 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -864,13 +864,11 @@ int searchit(
}
at_first_line = FALSE;
- /*
- * Stop the search if wrapscan isn't set, "stop_lnum" is
- * specified, after an interrupt, after a match and after looping
- * twice.
- */
+ // Stop the search if wrapscan isn't set, "stop_lnum" is
+ // specified, after an interrupt, after a match and after looping
+ // twice.
if (!p_ws || stop_lnum != 0 || got_int || called_emsg
- || (timed_out != NULL && timed_out)
+ || (timed_out != NULL && *timed_out)
|| break_loop
|| found || loop) {
break;
@@ -1139,7 +1137,7 @@ int do_search(
// Get the offset, so we know how long it is.
if (spats[0].off.line || spats[0].off.end || spats[0].off.off) {
- p = off_buf;
+ p = off_buf; // -V507
*p++ = dirc;
if (spats[0].off.end) {
*p++ = 'e';
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 4aafc669dc..3ebe75b980 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -151,15 +151,6 @@ KHASH_SET_INIT_STR(strset)
/// Callback function for add_search_pattern
typedef void (*SearchPatternGetter)(SearchPattern *);
-/// Flags for shada_read_file and children
-typedef enum {
- kShaDaWantInfo = 1, ///< Load non-mark information
- kShaDaWantMarks = 2, ///< Load local file marks and change list
- kShaDaForceit = 4, ///< Overwrite info already read
- kShaDaGetOldfiles = 8, ///< Load v:oldfiles.
- kShaDaMissingError = 16, ///< Error out when os_open returns -ENOENT.
-} ShaDaReadFileFlags;
-
/// Possible ShaDa entry types
///
/// @warning Enum values are part of the API and must not be altered.
@@ -283,7 +274,7 @@ typedef struct {
char sep;
list_T *additional_elements;
} history_item;
- struct reg {
+ struct reg { // yankreg_T
char name;
MotionType type;
char **contents;
@@ -1328,13 +1319,13 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
break;
}
if (!force) {
- const yankreg_T *const reg = op_register_get(cur_entry.data.reg.name);
+ const yankreg_T *const reg = op_reg_get(cur_entry.data.reg.name);
if (reg == NULL || reg->timestamp >= cur_entry.timestamp) {
shada_free_shada_entry(&cur_entry);
break;
}
}
- if (!op_register_set(cur_entry.data.reg.name, (yankreg_T) {
+ if (!op_reg_set(cur_entry.data.reg.name, (yankreg_T) {
.y_array = (char_u **)cur_entry.data.reg.contents,
.y_size = cur_entry.data.reg.contents_size,
.y_type = cur_entry.data.reg.type,
@@ -2496,7 +2487,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms,
yankreg_T reg;
char name = NUL;
bool is_unnamed = false;
- reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
+ reg_iter = op_global_reg_iter(reg_iter, &name, &reg, &is_unnamed);
if (name == NUL) {
break;
}
@@ -2552,6 +2543,19 @@ static inline void replace_numbered_mark(WriteMergerState *const wms,
wms->numbered_marks[idx].data.data.filemark.name = (char)('0' + (int)idx);
}
+/// Find buffers ignored due to their location.
+///
+/// @param[out] removable_bufs Cache of buffers ignored due to their location.
+static inline void find_removable_bufs(khash_t(bufset) *removable_bufs)
+{
+ FOR_ALL_BUFFERS(buf) {
+ if (buf->b_ffname != NULL && shada_removable((char *)buf->b_ffname)) {
+ int kh_ret;
+ (void)kh_put(bufset, removable_bufs, (uintptr_t)buf, &kh_ret);
+ }
+ }
+}
+
/// Write ShaDa file
///
/// @param[in] sd_writer Structure containing file writer definition.
@@ -2621,12 +2625,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
set_last_cursor(wp);
}
- FOR_ALL_BUFFERS(buf) {
- if (buf->b_ffname != NULL && shada_removable((char *) buf->b_ffname)) {
- int kh_ret;
- (void) kh_put(bufset, &removable_bufs, (uintptr_t) buf, &kh_ret);
- }
- }
+ find_removable_bufs(&removable_bufs);
// Write header
if (shada_pack_entry(packer, (ShadaEntry) {
@@ -2673,7 +2672,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
do {
typval_T vartv;
const char *name = NULL;
- var_iter = var_shada_iter(var_iter, &name, &vartv);
+ var_iter = var_shada_iter(var_iter, &name, &vartv, VAR_FLAVOUR_SHADA);
if (name == NULL) {
break;
}
@@ -2737,49 +2736,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
// Initialize jump list
- const void *jump_iter = NULL;
- cleanup_jumplist(curwin, false);
- setpcmark();
- do {
- xfmark_T fm;
- jump_iter = mark_jumplist_iter(jump_iter, curwin, &fm);
-
- if (fm.fmark.mark.lnum == 0) {
- iemsgf("ShaDa: mark lnum zero (ji:%p, js:%p, len:%i)",
- (void *)jump_iter, (void *)&curwin->w_jumplist[0],
- curwin->w_jumplistlen);
- continue;
- }
- const buf_T *const buf = (fm.fmark.fnum == 0
- ? NULL
- : buflist_findnr(fm.fmark.fnum));
- if (buf != NULL
- ? in_bufset(&removable_bufs, buf)
- : fm.fmark.fnum != 0) {
- continue;
- }
- const char *const fname = (char *) (fm.fmark.fnum == 0
- ? (fm.fname == NULL ? NULL : fm.fname)
- : buf->b_ffname);
- if (fname == NULL) {
- continue;
- }
- wms->jumps[wms->jumps_size++] = (PossiblyFreedShadaEntry) {
- .can_free_entry = false,
- .data = {
- .type = kSDItemJump,
- .timestamp = fm.fmark.timestamp,
- .data = {
- .filemark = {
- .name = NUL,
- .mark = fm.fmark.mark,
- .fname = (char *) fname,
- .additional_data = fm.fmark.additional_data,
- }
- }
- }
- };
- } while (jump_iter != NULL);
+ wms->jumps_size = shada_init_jumps(wms->jumps, &removable_bufs);
// Initialize global marks
if (dump_global_marks) {
@@ -4117,3 +4074,236 @@ static bool shada_removable(const char *name)
xfree(new_name);
return retval;
}
+
+/// Initialize ShaDa jumplist entries.
+///
+/// @param[in,out] jumps Array of ShaDa entries to set.
+/// @param[in] removable_bufs Cache of buffers ignored due to their
+/// location.
+///
+/// @return number of jumplist entries
+static inline size_t shada_init_jumps(
+ PossiblyFreedShadaEntry *jumps, khash_t(bufset) *const removable_bufs)
+{
+ // Initialize jump list
+ size_t jumps_size = 0;
+ const void *jump_iter = NULL;
+ setpcmark();
+ cleanup_jumplist(curwin, false);
+ do {
+ xfmark_T fm;
+ jump_iter = mark_jumplist_iter(jump_iter, curwin, &fm);
+
+ if (fm.fmark.mark.lnum == 0) {
+ iemsgf("ShaDa: mark lnum zero (ji:%p, js:%p, len:%i)",
+ (void *)jump_iter, (void *)&curwin->w_jumplist[0],
+ curwin->w_jumplistlen);
+ continue;
+ }
+ const buf_T *const buf = (fm.fmark.fnum == 0
+ ? NULL
+ : buflist_findnr(fm.fmark.fnum));
+ if (buf != NULL
+ ? in_bufset(removable_bufs, buf)
+ : fm.fmark.fnum != 0) {
+ continue;
+ }
+ const char *const fname = (char *) (fm.fmark.fnum == 0
+ ? (fm.fname == NULL ? NULL : fm.fname)
+ : buf->b_ffname);
+ if (fname == NULL) {
+ continue;
+ }
+ jumps[jumps_size++] = (PossiblyFreedShadaEntry) {
+ .can_free_entry = false,
+ .data = {
+ .type = kSDItemJump,
+ .timestamp = fm.fmark.timestamp,
+ .data = {
+ .filemark = {
+ .name = NUL,
+ .mark = fm.fmark.mark,
+ .fname = (char *) fname,
+ .additional_data = fm.fmark.additional_data,
+ }
+ }
+ }
+ };
+ } while (jump_iter != NULL);
+ return jumps_size;
+}
+
+/// Write registers ShaDa entries in given msgpack_sbuffer.
+///
+/// @param[in] sbuf target msgpack_sbuffer to write to.
+void shada_encode_regs(msgpack_sbuffer *const sbuf)
+ FUNC_ATTR_NONNULL_ALL
+{
+ WriteMergerState *const wms = xcalloc(1, sizeof(*wms));
+ shada_initialize_registers(wms, -1);
+ msgpack_packer packer;
+ msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write);
+ for (size_t i = 0; i < ARRAY_SIZE(wms->registers); i++) {
+ if (wms->registers[i].data.type == kSDItemRegister) {
+ if (kSDWriteFailed
+ == shada_pack_pfreed_entry(&packer, wms->registers[i], 0)) {
+ abort();
+ }
+ }
+ }
+ xfree(wms);
+}
+
+/// Write jumplist ShaDa entries in given msgpack_sbuffer.
+///
+/// @param[in] sbuf target msgpack_sbuffer to write to.
+void shada_encode_jumps(msgpack_sbuffer *const sbuf)
+ FUNC_ATTR_NONNULL_ALL
+{
+ khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
+ find_removable_bufs(&removable_bufs);
+ PossiblyFreedShadaEntry jumps[JUMPLISTSIZE];
+ size_t jumps_size = shada_init_jumps(jumps, &removable_bufs);
+ msgpack_packer packer;
+ msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write);
+ for (size_t i = 0; i < jumps_size; i++) {
+ if (kSDWriteFailed == shada_pack_pfreed_entry(&packer, jumps[i], 0)) {
+ abort();
+ }
+ }
+}
+
+/// Write buffer list ShaDa entry in given msgpack_sbuffer.
+///
+/// @param[in] sbuf target msgpack_sbuffer to write to.
+void shada_encode_buflist(msgpack_sbuffer *const sbuf)
+ FUNC_ATTR_NONNULL_ALL
+{
+ khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
+ find_removable_bufs(&removable_bufs);
+ ShadaEntry buflist_entry = shada_get_buflist(&removable_bufs);
+ msgpack_packer packer;
+ msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write);
+ if (kSDWriteFailed == shada_pack_entry(&packer, buflist_entry, 0)) {
+ abort();
+ }
+ xfree(buflist_entry.data.buffer_list.buffers);
+}
+
+/// Write global variables ShaDa entries in given msgpack_sbuffer.
+///
+/// @param[in] sbuf target msgpack_sbuffer to write to.
+void shada_encode_gvars(msgpack_sbuffer *const sbuf)
+ FUNC_ATTR_NONNULL_ALL
+{
+ msgpack_packer packer;
+ msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write);
+ const void *var_iter = NULL;
+ const Timestamp cur_timestamp = os_time();
+ do {
+ typval_T vartv;
+ const char *name = NULL;
+ var_iter = var_shada_iter(
+ var_iter, &name, &vartv,
+ VAR_FLAVOUR_DEFAULT | VAR_FLAVOUR_SESSION | VAR_FLAVOUR_SHADA);
+ if (name == NULL) {
+ break;
+ }
+ if (vartv.v_type != VAR_FUNC && vartv.v_type != VAR_PARTIAL) {
+ typval_T tgttv;
+ tv_copy(&vartv, &tgttv);
+ ShaDaWriteResult r = shada_pack_entry(&packer, (ShadaEntry) {
+ .type = kSDItemVariable,
+ .timestamp = cur_timestamp,
+ .data = {
+ .global_var = {
+ .name = (char *)name,
+ .value = tgttv,
+ .additional_elements = NULL,
+ }
+ }
+ }, 0);
+ if (kSDWriteFailed == r) {
+ abort();
+ }
+ tv_clear(&tgttv);
+ }
+ tv_clear(&vartv);
+ } while (var_iter != NULL);
+}
+
+/// Wrapper for reading from msgpack_sbuffer.
+///
+/// @return number of bytes read.
+static ptrdiff_t read_sbuf(ShaDaReadDef *const sd_reader, void *const dest,
+ const size_t size)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie;
+ const uintmax_t bytes_read = MIN(size, sbuf->size - sd_reader->fpos);
+ if (bytes_read < size) {
+ sd_reader->eof = true;
+ }
+ memcpy(dest, sbuf->data + sd_reader->fpos, (size_t)bytes_read);
+ sd_reader->fpos += bytes_read;
+ return (ptrdiff_t)bytes_read;
+}
+
+/// Wrapper for read that ignores bytes read from msgpack_sbuffer.
+///
+/// Used for skipping.
+///
+/// @param[in,out] sd_reader ShaDaReadDef with msgpack_sbuffer.
+/// @param[in] offset Amount of bytes to skip.
+///
+/// @return FAIL in case of failure, OK in case of success. May set
+/// sd_reader->eof.
+static int sd_sbuf_reader_skip_read(ShaDaReadDef *const sd_reader,
+ const size_t offset)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ msgpack_sbuffer *sbuf = (msgpack_sbuffer *)sd_reader->cookie;
+ assert(sbuf->size >= sd_reader->fpos);
+ const uintmax_t skip_bytes = MIN(offset, sbuf->size - sd_reader->fpos);
+ if (skip_bytes < offset) {
+ sd_reader->eof = true;
+ return FAIL;
+ }
+ sd_reader->fpos += offset;
+ return OK;
+}
+
+/// Prepare ShaDaReadDef with msgpack_sbuffer for reading.
+///
+/// @param[in] sbuf msgpack_sbuffer to read from.
+/// @param[out] sd_reader Location where reader structure will be saved.
+static void open_shada_sbuf_for_reading(const msgpack_sbuffer *const sbuf,
+ ShaDaReadDef *sd_reader)
+ FUNC_ATTR_NONNULL_ALL
+{
+ *sd_reader = (ShaDaReadDef) {
+ .read = &read_sbuf,
+ .close = NULL,
+ .skip = &sd_sbuf_reader_skip_read,
+ .error = NULL,
+ .eof = false,
+ .fpos = 0,
+ .cookie = (void *)sbuf,
+ };
+}
+
+/// Read ShaDa from msgpack_sbuffer.
+///
+/// @param[in] file msgpack_sbuffer to read from.
+/// @param[in] flags Flags, see ShaDaReadFileFlags enum.
+void shada_read_sbuf(msgpack_sbuffer *const sbuf, const int flags)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(sbuf != NULL);
+ if (sbuf->data == NULL) {
+ return;
+ }
+ ShaDaReadDef sd_reader;
+ open_shada_sbuf_for_reading(sbuf, &sd_reader);
+ shada_read(&sd_reader, flags);
+}
diff --git a/src/nvim/shada.h b/src/nvim/shada.h
index 49986ac1c1..2a945a06bc 100644
--- a/src/nvim/shada.h
+++ b/src/nvim/shada.h
@@ -1,6 +1,17 @@
#ifndef NVIM_SHADA_H
#define NVIM_SHADA_H
+#include <msgpack.h>
+
+/// Flags for shada_read_file and children
+typedef enum {
+ kShaDaWantInfo = 1, ///< Load non-mark information
+ kShaDaWantMarks = 2, ///< Load local file marks and change list
+ kShaDaForceit = 4, ///< Overwrite info already read
+ kShaDaGetOldfiles = 8, ///< Load v:oldfiles.
+ kShaDaMissingError = 16, ///< Error out when os_open returns -ENOENT.
+} ShaDaReadFileFlags;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "shada.h.generated.h"
#endif
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 0f399d9922..16ab00a52b 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -253,11 +253,7 @@ char_u * sign_typenr2name(int typenr)
/// Return information about a sign in a Dict
dict_T * sign_get_info(signlist_T *sign)
{
- dict_T *d;
-
- if ((d = tv_dict_alloc()) == NULL) {
- return NULL;
- }
+ dict_T *d = tv_dict_alloc();
tv_dict_add_nr(d, S_LEN("id"), sign->id);
tv_dict_add_str(d, S_LEN("group"), ((sign->group == NULL)
? (char *)""
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 893a13b9f0..cc214616f4 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -4500,7 +4500,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp->ts_state = STATE_SWAP3;
break;
}
- if (c2 != NUL && TRY_DEEPER(su, stack, depth, SCORE_SWAP)) {
+ if (TRY_DEEPER(su, stack, depth, SCORE_SWAP)) {
go_deeper(stack, depth, SCORE_SWAP);
#ifdef DEBUG_TRIEWALK
snprintf(changename[depth], sizeof(changename[0]),
diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim
index 8139e7a239..fbe4fcc50f 100644
--- a/src/nvim/testdir/test_arglist.vim
+++ b/src/nvim/testdir/test_arglist.vim
@@ -150,6 +150,25 @@ func Test_argument()
let &hidden = save_hidden
+ let save_columns = &columns
+ let &columns = 79
+ exe 'args ' .. join(range(1, 81))
+ call assert_equal(join([
+ \ '',
+ \ '[1] 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 ',
+ \ '2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 ',
+ \ '3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 ',
+ \ '4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 ',
+ \ '5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ',
+ \ ], "\n"),
+ \ execute('args'))
+
+ " No trailing newline with one item per row.
+ let long_arg = repeat('X', 81)
+ exe 'args ' .. long_arg
+ call assert_equal("\n[".long_arg.']', execute('args'))
+ let &columns = save_columns
+
" Setting argument list should fail when the current buffer has unsaved
" changes
%argd
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index e0d4df48a9..eb18284b4a 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -232,6 +232,15 @@ func Test_getcompletion()
let l = getcompletion('not', 'mapclear')
call assert_equal([], l)
+ let l = getcompletion('.', 'shellcmd')
+ call assert_equal(['./', '../'], l[0:1])
+ call assert_equal(-1, match(l[2:], '^\.\.\?/$'))
+ let root = has('win32') ? 'C:\\' : '/'
+ let l = getcompletion(root, 'shellcmd')
+ let expected = map(filter(glob(root . '*', 0, 1),
+ \ 'isdirectory(v:val) || executable(v:val)'), 'isdirectory(v:val) ? v:val . ''/'' : v:val')
+ call assert_equal(expected, l)
+
if has('cscope')
let l = getcompletion('', 'cscope')
let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
@@ -273,8 +282,7 @@ func Test_getcompletion()
call assert_equal([], l)
" For others test if the name is recognized.
- let names = ['buffer', 'environment', 'file_in_path',
- \ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user']
+ let names = ['buffer', 'environment', 'file_in_path', 'mapping', 'tag', 'tag_listfiles', 'user']
if has('cmdline_hist')
call add(names, 'history')
endif
diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim
index d6b6b69aa8..3b61d68ebc 100644
--- a/src/nvim/testdir/test_getvar.vim
+++ b/src/nvim/testdir/test_getvar.vim
@@ -1,4 +1,5 @@
-" Tests for getwinvar(), gettabvar() and gettabwinvar().
+" Tests for getwinvar(), gettabvar(), gettabwinvar() and get().
+
func Test_var()
" Use strings to test for memory leaks. First, check that in an empty
" window, gettabvar() returns the correct value
@@ -102,3 +103,44 @@ func Test_gettabvar_in_tabline()
close
redrawstatus!
endfunc
+
+" Test get() function using default value.
+
+" get({dict}, {key} [, {default}])
+func Test_get_dict()
+ let d = {'foo': 42}
+ call assert_equal(42, get(d, 'foo', 99))
+ call assert_equal(999, get(d, 'bar', 999))
+endfunc
+
+" get({list}, {idx} [, {default}])
+func Test_get_list()
+ let l = [1,2,3]
+ call assert_equal(1, get(l, 0, 999))
+ call assert_equal(3, get(l, -1, 999))
+ call assert_equal(999, get(l, 3, 999))
+endfunc
+
+" get({blob}, {idx} [, {default}]) - in test_blob.vim
+
+" get({lambda}, {what} [, {default}])
+func Test_get_lambda()
+ let l:L = {-> 42}
+ call assert_match('^<lambda>', get(l:L, 'name'))
+ call assert_equal(l:L, get(l:L, 'func'))
+ call assert_equal({'lambda has': 'no dict'}, get(l:L, 'dict', {'lambda has': 'no dict'}))
+ call assert_equal(0, get(l:L, 'dict'))
+ call assert_equal([], get(l:L, 'args'))
+endfunc
+
+" get({func}, {what} [, {default}])
+func Test_get_func()
+ let l:F = function('tr')
+ call assert_equal('tr', get(l:F, 'name'))
+ call assert_equal(l:F, get(l:F, 'func'))
+ call assert_equal({'func has': 'no dict'}, get(l:F, 'dict', {'func has': 'no dict'}))
+ call assert_equal(0, get(l:F, 'dict'))
+ call assert_equal([], get(l:F, 'args'))
+endfunc
+
+" get({partial}, {what} [, {default}]) - in test_partial.vim
diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim
index 0fb878b04a..ee16a22398 100644
--- a/src/nvim/testdir/test_maparg.vim
+++ b/src/nvim/testdir/test_maparg.vim
@@ -27,6 +27,10 @@ function Test_maparg()
call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ',
\ 'nowait': 1, 'expr': 0, 'sid': sid, 'rhs': 'bar', 'buffer': 1},
\ maparg('foo', '', 0, 1))
+ tmap baz foo
+ call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'baz', 'mode': 't',
+ \ 'nowait': 0, 'expr': 0, 'sid': sid, 'rhs': 'foo', 'buffer': 0},
+ \ maparg('baz', 't', 0, 1))
map abc x<char-114>x
call assert_equal("xrx", maparg('abc'))
diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim
index de5c26c2dd..590e18e024 100644
--- a/src/nvim/testdir/test_partial.vim
+++ b/src/nvim/testdir/test_partial.vim
@@ -285,6 +285,11 @@ func Test_get_partial_items()
call assert_equal('MyDictFunc', get(Func, 'name'))
call assert_equal([], get(Func, 'args'))
call assert_true(empty( get(Func, 'dict')))
+
+ let P = function('substitute', ['hello there', 'there'])
+ let dict = {'partial has': 'no dict'}
+ call assert_equal(dict, get(P, 'dict', dict))
+ call assert_equal(0, get(l:P, 'dict'))
endfunc
func Test_compare_partials()
diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim
index 557f60751c..98e9de9ffb 100644
--- a/src/nvim/testdir/test_popup.vim
+++ b/src/nvim/testdir/test_popup.vim
@@ -841,4 +841,38 @@ func Test_popup_complete_info_02()
bwipe!
endfunc
+func Test_CompleteChanged()
+ new
+ call setline(1, ['foo', 'bar', 'foobar', ''])
+ set complete=. completeopt=noinsert,noselect,menuone
+ function! OnPumChange()
+ let g:event = copy(v:event)
+ let g:item = get(v:event, 'completed_item', {})
+ let g:word = get(g:item, 'word', v:null)
+ endfunction
+ augroup AAAAA_Group
+ au!
+ autocmd CompleteChanged * :call OnPumChange()
+ augroup END
+ call cursor(4, 1)
+
+ call feedkeys("Sf\<C-N>", 'tx')
+ call assert_equal({'completed_item': {}, 'width': 15,
+ \ 'height': 2, 'size': 2,
+ \ 'col': 0, 'row': 4, 'scrollbar': v:false}, g:event)
+ call feedkeys("a\<C-N>\<C-N>\<C-E>", 'tx')
+ call assert_equal('foo', g:word)
+ call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-E>", 'tx')
+ call assert_equal('foobar', g:word)
+ call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-E>", 'tx')
+ call assert_equal(v:null, g:word)
+ call feedkeys("a\<C-N>\<C-N>\<C-N>\<C-N>\<C-P>", 'tx')
+ call assert_equal('foobar', g:word)
+
+ autocmd! AAAAA_Group
+ set complete& completeopt&
+ delfunc! OnPumchange
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index f3e40e1210..f39e53d6dd 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -21,7 +21,7 @@ com! -nargs=1 Xout call Xout(<args>)
"
" Create a script that consists of the body of the function a:funcname.
" Replace any ":return" by a ":finish", any argument variable by a global
-" variable, and and every ":call" by a ":source" for the next following argument
+" variable, and every ":call" by a ":source" for the next following argument
" in the variable argument list. This function is useful if similar tests are
" to be made for a ":return" from a function call or a ":finish" in a script
" file.
@@ -1310,6 +1310,43 @@ func Test_compound_assignment_operators()
let x .= 'n'
call assert_equal('2n', x)
+ " Test special cases: division or modulus with 0.
+ let x = 1
+ let x /= 0
+ if has('num64')
+ call assert_equal(0x7FFFFFFFFFFFFFFF, x)
+ else
+ call assert_equal(0x7fffffff, x)
+ endif
+
+ let x = -1
+ let x /= 0
+ if has('num64')
+ call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
+ else
+ call assert_equal(-0x7fffffff, x)
+ endif
+
+ let x = 0
+ let x /= 0
+ if has('num64')
+ call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
+ else
+ call assert_equal(-0x7FFFFFFF - 1, x)
+ endif
+
+ let x = 1
+ let x %= 0
+ call assert_equal(0, x)
+
+ let x = -1
+ let x %= 0
+ call assert_equal(0, x)
+
+ let x = 0
+ let x %= 0
+ call assert_equal(0, x)
+
" Test for string
let x = 'str'
let x .= 'ing'
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
index d0b21ae591..2cb3cf7ee7 100644
--- a/src/nvim/ui_compositor.c
+++ b/src/nvim/ui_compositor.c
@@ -359,7 +359,7 @@ static void compose_line(Integer row, Integer startcol, Integer endcol,
attrbuf[i+1], &thru);
}
if (thru) {
- memcpy(linebuf[i], bg_line[i], (size_t)width * sizeof(linebuf[i]));
+ memcpy(linebuf + i, bg_line + i, (size_t)width * sizeof(linebuf[i]));
}
}
}
diff --git a/src/nvim/version.c b/src/nvim/version.c
index baa0df84f4..33b2a05cbb 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -2038,6 +2038,9 @@ static void version_msg(char *s)
static void list_features(void)
{
list_in_columns((char_u **)features, -1, -1);
+ if (msg_col > 0) {
+ msg_putchar('\n');
+ }
MSG_PUTS("See \":help feature-compile\"\n\n");
}
@@ -2065,7 +2068,7 @@ void list_in_columns(char_u **items, int size, int current)
// Not enough screen columns - show one per line
for (i = 0; i < item_count; i++) {
version_msg_wrap(items[i], i == current);
- if (msg_col > 0) {
+ if (msg_col > 0 && i < item_count - 1) {
msg_putchar('\n');
}
}
@@ -2100,6 +2103,14 @@ void list_in_columns(char_u **items, int size, int current)
msg_putchar(' ');
}
}
+ } else {
+ // this row is out of items, thus at the end of the row
+ if (msg_col > 0) {
+ if (cur_row < nrow) {
+ msg_putchar('\n');
+ }
+ cur_row++;
+ }
}
}
}
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index dcc64db8a0..b4a0f57e99 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -2330,7 +2330,7 @@ viml_pexpr_parse_invalid_comma:
break;
} else if (eastnode_type == kExprNodeSubscript) {
is_subscript = true;
- can_be_ternary = false;
+ // can_be_ternary = false;
assert(!is_ternary);
break;
} else if (eastnode_type == kExprNodeColon) {
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
index b3f6bb7895..73c55a342c 100644
--- a/test/functional/api/keymap_spec.lua
+++ b/test/functional/api/keymap_spec.lua
@@ -346,11 +346,6 @@ describe('nvim_set_keymap, nvim_del_keymap', function()
to_return.sid = not opts.sid and 0 or opts.sid
to_return.buffer = not opts.buffer and 0 or opts.buffer
- -- mode 't' doesn't print when calling maparg
- if mode == 't' then
- to_return.mode = ''
- end
-
return to_return
end
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index a3d57662b3..110b3a4b16 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -11,6 +11,7 @@ local meth_pcall = helpers.meth_pcall
local meths = helpers.meths
local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
local os_name = helpers.os_name
+local parse_context = helpers.parse_context
local request = helpers.request
local source = helpers.source
local next_msg = helpers.next_msg
@@ -680,6 +681,65 @@ describe('API', function()
end)
end)
+ describe('nvim_get_context', function()
+ it('returns context dictionary of current editor state', function()
+ local ctx_items = {'regs', 'jumps', 'buflist', 'gvars'}
+ eq({}, parse_context(nvim('get_context', ctx_items)))
+
+ feed('i1<cr>2<cr>3<c-[>ddddddqahjklquuu')
+ feed('gg')
+ feed('G')
+ command('edit! BUF1')
+ command('edit BUF2')
+ nvim('set_var', 'one', 1)
+ nvim('set_var', 'Two', 2)
+ nvim('set_var', 'THREE', 3)
+
+ local expected_ctx = {
+ ['regs'] = {
+ {['rt'] = 1, ['rc'] = {'1'}, ['n'] = 49, ['ru'] = true},
+ {['rt'] = 1, ['rc'] = {'2'}, ['n'] = 50},
+ {['rt'] = 1, ['rc'] = {'3'}, ['n'] = 51},
+ {['rc'] = {'hjkl'}, ['n'] = 97},
+ },
+
+ ['jumps'] = eval(([[
+ filter(map(add(
+ getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }),
+ 'filter(
+ { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
+ { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
+ ]]):gsub('\n', '')),
+
+ ['buflist'] = eval([[
+ filter(map(getbufinfo(), '{ "f": v:val.name }'), '!empty(v:val.f)')
+ ]]),
+
+ ['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}},
+ }
+
+ eq(expected_ctx, parse_context(nvim('get_context', ctx_items)))
+ end)
+ end)
+
+ describe('nvim_load_context', function()
+ it('sets current editor state to given context dictionary', function()
+ local ctx_items = {'regs', 'jumps', 'buflist', 'gvars'}
+ eq({}, parse_context(nvim('get_context', ctx_items)))
+
+ nvim('set_var', 'one', 1)
+ nvim('set_var', 'Two', 2)
+ nvim('set_var', 'THREE', 3)
+ local ctx = nvim('get_context', ctx_items)
+ nvim('set_var', 'one', 'a')
+ nvim('set_var', 'Two', 'b')
+ nvim('set_var', 'THREE', 'c')
+ eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
+ nvim('load_context', ctx)
+ eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
+ end)
+ end)
+
describe('nvim_replace_termcodes', function()
it('escapes K_SPECIAL as K_SPECIAL KS_SPECIAL KE_FILLER', function()
eq('\128\254X', helpers.nvim('replace_termcodes', '\128', true, true, true))
diff --git a/test/functional/autocmd/textyankpost_spec.lua b/test/functional/autocmd/textyankpost_spec.lua
index 5849679dd2..8c23b72cff 100644
--- a/test/functional/autocmd/textyankpost_spec.lua
+++ b/test/functional/autocmd/textyankpost_spec.lua
@@ -229,4 +229,9 @@ describe('TextYankPost', function()
eq(4, eval('g:count'))
end)
+ it('updates numbered registers correctly #10225', function()
+ command('autocmd TextYankPost * let g:reg = getreg("1")')
+ feed('"adj')
+ eq('foo\nbar\nbaz text\n', eval('g:reg'))
+ end)
end)
diff --git a/test/functional/eval/ctx_functions_spec.lua b/test/functional/eval/ctx_functions_spec.lua
new file mode 100644
index 0000000000..35133e2341
--- /dev/null
+++ b/test/functional/eval/ctx_functions_spec.lua
@@ -0,0 +1,408 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local call = helpers.call
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local eval = helpers.eval
+local expect_err = helpers.expect_err
+local feed = helpers.feed
+local map = helpers.map
+local nvim = helpers.nvim
+local parse_context = helpers.parse_context
+local redir_exec = helpers.redir_exec
+local source = helpers.source
+local trim = helpers.trim
+local write_file = helpers.write_file
+
+describe('context functions', function()
+ local fname1 = 'Xtest-functional-eval-ctx1'
+ local fname2 = 'Xtest-functional-eval-ctx2'
+ local outofbounds =
+ 'Vim:E475: Invalid value for argument index: out of bounds'
+
+ before_each(function()
+ clear()
+ write_file(fname1, "1\n2\n3")
+ write_file(fname2, "a\nb\nc")
+ end)
+
+ after_each(function()
+ os.remove(fname1)
+ os.remove(fname2)
+ end)
+
+ describe('ctxpush/ctxpop', function()
+ it('saves and restores registers properly', function()
+ local regs = {'1', '2', '3', 'a'}
+ local vals = {'1', '2', '3', 'hjkl'}
+ feed('i1<cr>2<cr>3<c-[>ddddddqahjklq')
+ eq(vals, map(function(r) return trim(call('getreg', r)) end, regs))
+ call('ctxpush')
+ call('ctxpush', {'regs'})
+
+ map(function(r) call('setreg', r, {}) end, regs)
+ eq({'', '', '', ''},
+ map(function(r) return trim(call('getreg', r)) end, regs))
+
+ call('ctxpop')
+ eq(vals, map(function(r) return trim(call('getreg', r)) end, regs))
+
+ map(function(r) call('setreg', r, {}) end, regs)
+ eq({'', '', '', ''},
+ map(function(r) return trim(call('getreg', r)) end, regs))
+
+ call('ctxpop')
+ eq(vals, map(function(r) return trim(call('getreg', r)) end, regs))
+ end)
+
+ it('saves and restores jumplist properly', function()
+ command('edit '..fname1)
+ feed('G')
+ feed('gg')
+ command('edit '..fname2)
+ local jumplist = call('getjumplist')
+ call('ctxpush')
+ call('ctxpush', {'jumps'})
+
+ command('clearjumps')
+ eq({{}, 0}, call('getjumplist'))
+
+ call('ctxpop')
+ eq(jumplist, call('getjumplist'))
+
+ command('clearjumps')
+ eq({{}, 0}, call('getjumplist'))
+
+ call('ctxpop')
+ eq(jumplist, call('getjumplist'))
+ end)
+
+ it('saves and restores buffer list properly', function()
+ command('edit '..fname1)
+ command('edit '..fname2)
+ command('edit TEST')
+ local buflist = call('map', call('getbufinfo'), 'v:val.name')
+ call('ctxpush')
+ call('ctxpush', {'buflist'})
+
+ command('%bwipeout')
+ eq({''}, call('map', call('getbufinfo'), 'v:val.name'))
+
+ call('ctxpop')
+ eq({'', unpack(buflist)}, call('map', call('getbufinfo'), 'v:val.name'))
+
+ command('%bwipeout')
+ eq({''}, call('map', call('getbufinfo'), 'v:val.name'))
+
+ call('ctxpop')
+ eq({'', unpack(buflist)}, call('map', call('getbufinfo'), 'v:val.name'))
+ end)
+
+ it('saves and restores global variables properly', function()
+ nvim('set_var', 'one', 1)
+ nvim('set_var', 'Two', 2)
+ nvim('set_var', 'THREE', 3)
+ eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
+ call('ctxpush')
+ call('ctxpush', {'gvars'})
+
+ nvim('del_var', 'one')
+ nvim('del_var', 'Two')
+ nvim('del_var', 'THREE')
+ expect_err('E121: Undefined variable: g:one', eval, 'g:one')
+ expect_err('E121: Undefined variable: g:Two', eval, 'g:Two')
+ expect_err('E121: Undefined variable: g:THREE', eval, 'g:THREE')
+
+ call('ctxpop')
+ eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
+
+ nvim('del_var', 'one')
+ nvim('del_var', 'Two')
+ nvim('del_var', 'THREE')
+ expect_err('E121: Undefined variable: g:one', eval, 'g:one')
+ expect_err('E121: Undefined variable: g:Two', eval, 'g:Two')
+ expect_err('E121: Undefined variable: g:THREE', eval, 'g:THREE')
+
+ call('ctxpop')
+ eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
+ end)
+
+ it('saves and restores script functions properly', function()
+ source([[
+ function s:greet(name)
+ echom 'Hello, '.a:name.'!'
+ endfunction
+
+ function s:greet_all(name, ...)
+ echom 'Hello, '.a:name.'!'
+ for more in a:000
+ echom 'Hello, '.more.'!'
+ endfor
+ endfunction
+
+ function Greet(name)
+ call call('s:greet', [a:name])
+ endfunction
+
+ function GreetAll(name, ...)
+ call call('s:greet_all', extend([a:name], a:000))
+ endfunction
+
+ function SaveSFuncs()
+ call ctxpush(['sfuncs'])
+ endfunction
+
+ function DeleteSFuncs()
+ delfunction s:greet
+ delfunction s:greet_all
+ endfunction
+
+ function RestoreFuncs()
+ call ctxpop()
+ endfunction
+ ]])
+
+ eq('\nHello, World!', redir_exec([[call Greet('World')]]))
+ eq('\nHello, World!'..
+ '\nHello, One!'..
+ '\nHello, Two!'..
+ '\nHello, Three!',
+ redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
+
+ call('SaveSFuncs')
+ call('DeleteSFuncs')
+
+ eq('\nError detected while processing function Greet:'..
+ '\nline 1:'..
+ '\nE117: Unknown function: s:greet',
+ redir_exec([[call Greet('World')]]))
+ eq('\nError detected while processing function GreetAll:'..
+ '\nline 1:'..
+ '\nE117: Unknown function: s:greet_all',
+ redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
+
+ call('RestoreFuncs')
+
+ eq('\nHello, World!', redir_exec([[call Greet('World')]]))
+ eq('\nHello, World!'..
+ '\nHello, One!'..
+ '\nHello, Two!'..
+ '\nHello, Three!',
+ redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
+ end)
+
+ it('saves and restores functions properly', function()
+ source([[
+ function Greet(name)
+ echom 'Hello, '.a:name.'!'
+ endfunction
+
+ function GreetAll(name, ...)
+ echom 'Hello, '.a:name.'!'
+ for more in a:000
+ echom 'Hello, '.more.'!'
+ endfor
+ endfunction
+ ]])
+
+ eq('\nHello, World!', redir_exec([[call Greet('World')]]))
+ eq('\nHello, World!'..
+ '\nHello, One!'..
+ '\nHello, Two!'..
+ '\nHello, Three!',
+ redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
+
+ call('ctxpush', {'funcs'})
+ command('delfunction Greet')
+ command('delfunction GreetAll')
+
+ expect_err('Vim:E117: Unknown function: Greet', call, 'Greet', 'World')
+ expect_err('Vim:E117: Unknown function: Greet', call, 'GreetAll',
+ 'World', 'One', 'Two', 'Three')
+
+ call('ctxpop')
+
+ eq('\nHello, World!', redir_exec([[call Greet('World')]]))
+ eq('\nHello, World!'..
+ '\nHello, One!'..
+ '\nHello, Two!'..
+ '\nHello, Three!',
+ redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
+ end)
+
+ it('errors out when context stack is empty', function()
+ local err = 'Vim:Context stack is empty'
+ expect_err(err, call, 'ctxpop')
+ expect_err(err, call, 'ctxpop')
+ call('ctxpush')
+ call('ctxpush')
+ call('ctxpop')
+ call('ctxpop')
+ expect_err(err, call, 'ctxpop')
+ end)
+ end)
+
+ describe('ctxsize()', function()
+ it('returns context stack size', function()
+ eq(0, call('ctxsize'))
+ call('ctxpush')
+ eq(1, call('ctxsize'))
+ call('ctxpush')
+ eq(2, call('ctxsize'))
+ call('ctxpush')
+ eq(3, call('ctxsize'))
+ call('ctxpop')
+ eq(2, call('ctxsize'))
+ call('ctxpop')
+ eq(1, call('ctxsize'))
+ call('ctxpop')
+ eq(0, call('ctxsize'))
+ end)
+ end)
+
+ describe('ctxget()', function()
+ it('errors out when index is out of bounds', function()
+ expect_err(outofbounds, call, 'ctxget')
+ call('ctxpush')
+ expect_err(outofbounds, call, 'ctxget', 1)
+ call('ctxpop')
+ expect_err(outofbounds, call, 'ctxget', 0)
+ end)
+
+ it('returns context dictionary at index in context stack', function()
+ feed('i1<cr>2<cr>3<c-[>ddddddqahjklq')
+ command('edit! '..fname1)
+ feed('G')
+ feed('gg')
+ command('edit '..fname2)
+ nvim('set_var', 'one', 1)
+ nvim('set_var', 'Two', 2)
+ nvim('set_var', 'THREE', 3)
+
+ local with_regs = {
+ ['regs'] = {
+ {['rt'] = 1, ['rc'] = {'1'}, ['n'] = 49, ['ru'] = true},
+ {['rt'] = 1, ['rc'] = {'2'}, ['n'] = 50},
+ {['rt'] = 1, ['rc'] = {'3'}, ['n'] = 51},
+ {['rc'] = {'hjkl'}, ['n'] = 97},
+ }
+ }
+
+ local with_jumps = {
+ ['jumps'] = eval(([[
+ filter(map(add(
+ getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }),
+ 'filter(
+ { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
+ { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
+ ]]):gsub('\n', ''))
+ }
+
+ local with_buflist = {
+ ['buflist'] = eval([[
+ filter(map(getbufinfo(), '{ "f": v:val.name }'), '!empty(v:val.f)')
+ ]])
+ }
+
+ local with_gvars = {
+ ['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}}
+ }
+
+ local with_all = {
+ ['regs'] = with_regs['regs'],
+ ['jumps'] = with_jumps['jumps'],
+ ['buflist'] = with_buflist['buflist'],
+ ['gvars'] = with_gvars['gvars'],
+ }
+
+ call('ctxpush')
+ eq(with_all, parse_context(call('ctxget')))
+ eq(with_all, parse_context(call('ctxget', 0)))
+
+ call('ctxpush', {'gvars'})
+ eq(with_gvars, parse_context(call('ctxget')))
+ eq(with_gvars, parse_context(call('ctxget', 0)))
+ eq(with_all, parse_context(call('ctxget', 1)))
+
+ call('ctxpush', {'buflist'})
+ eq(with_buflist, parse_context(call('ctxget')))
+ eq(with_buflist, parse_context(call('ctxget', 0)))
+ eq(with_gvars, parse_context(call('ctxget', 1)))
+ eq(with_all, parse_context(call('ctxget', 2)))
+
+ call('ctxpush', {'jumps'})
+ eq(with_jumps, parse_context(call('ctxget')))
+ eq(with_jumps, parse_context(call('ctxget', 0)))
+ eq(with_buflist, parse_context(call('ctxget', 1)))
+ eq(with_gvars, parse_context(call('ctxget', 2)))
+ eq(with_all, parse_context(call('ctxget', 3)))
+
+ call('ctxpush', {'regs'})
+ eq(with_regs, parse_context(call('ctxget')))
+ eq(with_regs, parse_context(call('ctxget', 0)))
+ eq(with_jumps, parse_context(call('ctxget', 1)))
+ eq(with_buflist, parse_context(call('ctxget', 2)))
+ eq(with_gvars, parse_context(call('ctxget', 3)))
+ eq(with_all, parse_context(call('ctxget', 4)))
+
+ call('ctxpop')
+ eq(with_jumps, parse_context(call('ctxget')))
+ eq(with_jumps, parse_context(call('ctxget', 0)))
+ eq(with_buflist, parse_context(call('ctxget', 1)))
+ eq(with_gvars, parse_context(call('ctxget', 2)))
+ eq(with_all, parse_context(call('ctxget', 3)))
+
+ call('ctxpop')
+ eq(with_buflist, parse_context(call('ctxget')))
+ eq(with_buflist, parse_context(call('ctxget', 0)))
+ eq(with_gvars, parse_context(call('ctxget', 1)))
+ eq(with_all, parse_context(call('ctxget', 2)))
+
+ call('ctxpop')
+ eq(with_gvars, parse_context(call('ctxget')))
+ eq(with_gvars, parse_context(call('ctxget', 0)))
+ eq(with_all, parse_context(call('ctxget', 1)))
+
+ call('ctxpop')
+ eq(with_all, parse_context(call('ctxget')))
+ eq(with_all, parse_context(call('ctxget', 0)))
+ end)
+ end)
+
+ describe('ctxset()', function()
+ it('errors out when index is out of bounds', function()
+ expect_err(outofbounds, call, 'ctxset', {dummy = 1})
+ call('ctxpush')
+ expect_err(outofbounds, call, 'ctxset', {dummy = 1}, 1)
+ call('ctxpop')
+ expect_err(outofbounds, call, 'ctxset', {dummy = 1}, 0)
+ end)
+
+ it('sets context dictionary at index in context stack', function()
+ nvim('set_var', 'one', 1)
+ nvim('set_var', 'Two', 2)
+ nvim('set_var', 'THREE', 3)
+ call('ctxpush')
+ local ctx1 = call('ctxget')
+ nvim('set_var', 'one', 'a')
+ nvim('set_var', 'Two', 'b')
+ nvim('set_var', 'THREE', 'c')
+ call('ctxpush')
+ call('ctxpush')
+ local ctx2 = call('ctxget')
+
+ eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
+ call('ctxset', ctx1)
+ call('ctxset', ctx2, 2)
+ call('ctxpop')
+ eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
+ call('ctxpop')
+ eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
+ nvim('set_var', 'one', 1.5)
+ eq({1.5, 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
+ call('ctxpop')
+ eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
+ end)
+ end)
+end)
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index ce7d348747..8223290760 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -13,6 +13,8 @@ local check_cores = global_helpers.check_cores
local check_logs = global_helpers.check_logs
local dedent = global_helpers.dedent
local eq = global_helpers.eq
+local filter = global_helpers.filter
+local map = global_helpers.map
local ok = global_helpers.ok
local sleep = global_helpers.sleep
local tbl_contains = global_helpers.tbl_contains
@@ -763,6 +765,22 @@ local function load_adjust(num)
return math.ceil(num * load_factor)
end
+local function parse_context(ctx)
+ local parsed = {}
+ for _, item in ipairs({'regs', 'jumps', 'buflist', 'gvars'}) do
+ parsed[item] = filter(function(v)
+ return type(v) == 'table'
+ end, nvim_call('msgpackparse', ctx[item]))
+ end
+ parsed['buflist'] = parsed['buflist'][1]
+ return map(function(v)
+ if #v == 0 then
+ return nil
+ end
+ return v
+ end, parsed)
+end
+
local module = {
NIL = mpack.NIL,
alter_slashes = alter_slashes,
@@ -810,6 +828,7 @@ local module = {
nvim_prog_abs = nvim_prog_abs,
nvim_set = nvim_set,
os_name = os_name,
+ parse_context = parse_context,
pathroot = pathroot,
pending_win32 = pending_win32,
prepend_argv = prepend_argv,
diff --git a/test/includes/pre/uv.h b/test/includes/pre/uv.h
deleted file mode 100644
index da7818cd07..0000000000
--- a/test/includes/pre/uv.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <uv.h>
-
-static const int kUV_ENOENT = UV_ENOENT;
-static const int kUV_EEXIST = UV_EEXIST;
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index f1ec94ae87..526a09e845 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -27,7 +27,7 @@ cimport('./src/nvim/fileio.h')
local fs = cimport('./src/nvim/os/os.h', './src/nvim/path.h')
cppimport('sys/stat.h')
cppimport('fcntl.h')
-cppimport('uv.h')
+cimport('uv.h')
local s = ''
for i = 0, 255 do
@@ -540,7 +540,7 @@ describe('fs.c', function()
itp('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function()
assert_file_exists(existing_file)
- eq(ffi.C.kUV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
+ eq(ffi.C.UV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
end)
itp('sets `rwx` permissions for O_CREAT 700 which then can be closed', function()