aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/autocmd.txt42
-rw-r--r--runtime/doc/change.txt6
-rw-r--r--runtime/doc/diagnostic.txt24
-rw-r--r--runtime/doc/editing.txt36
-rw-r--r--runtime/doc/eval.txt25
-rw-r--r--runtime/doc/options.txt4
-rw-r--r--runtime/doc/pattern.txt2
-rw-r--r--runtime/doc/usr_22.txt24
-rw-r--r--runtime/doc/usr_41.txt3
-rw-r--r--runtime/doc/various.txt2
-rw-r--r--runtime/doc/vim_diff.txt5
-rw-r--r--runtime/filetype.vim7
-rw-r--r--runtime/ftplugin/context.vim67
-rw-r--r--runtime/ftplugin/csh.vim49
-rw-r--r--runtime/ftplugin/tcsh.vim21
-rw-r--r--runtime/ftplugin/tmux.vim3
-rw-r--r--runtime/ftplugin/toml.vim23
-rw-r--r--runtime/indent/hamster.vim21
-rw-r--r--runtime/indent/sqlanywhere.vim22
-rw-r--r--runtime/indent/tcsh.vim13
-rw-r--r--runtime/lua/vim/diagnostic.lua80
-rw-r--r--runtime/lua/vim/uri.lua11
-rw-r--r--runtime/syntax/css.vim27
-rw-r--r--runtime/syntax/tcsh.vim66
-rw-r--r--runtime/syntax/tmux.vim103
-rw-r--r--runtime/syntax/toml.vim81
-rw-r--r--src/nvim/api/keysets.lua3
-rw-r--r--src/nvim/api/vim.c24
-rw-r--r--src/nvim/buffer.c33
-rw-r--r--src/nvim/buffer_defs.h5
-rw-r--r--src/nvim/eval.c6
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c94
-rw-r--r--src/nvim/eval/userfunc.c96
-rw-r--r--src/nvim/ex_cmds.c150
-rw-r--r--src/nvim/ex_cmds2.c80
-rw-r--r--src/nvim/ex_cmds2.h25
-rw-r--r--src/nvim/ex_docmd.c237
-rw-r--r--src/nvim/ex_eval.c120
-rw-r--r--src/nvim/ex_getln.c20
-rw-r--r--src/nvim/ex_session.c2
-rw-r--r--src/nvim/file_search.c45
-rw-r--r--src/nvim/fileio.c122
-rw-r--r--src/nvim/fold.c127
-rw-r--r--src/nvim/generators/c_grammar.lua2
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua2
-rwxr-xr-xsrc/nvim/generators/gen_declarations.lua13
-rw-r--r--src/nvim/globals.h16
-rw-r--r--src/nvim/lua/executor.c6
-rw-r--r--src/nvim/lua/vim.lua37
-rw-r--r--src/nvim/main.c6
-rw-r--r--src/nvim/mark.c33
-rw-r--r--src/nvim/marktree.c4
-rw-r--r--src/nvim/mbyte.c30
-rw-r--r--src/nvim/memline.c52
-rw-r--r--src/nvim/menu.c8
-rw-r--r--src/nvim/normal.c91
-rw-r--r--src/nvim/ops.c79
-rw-r--r--src/nvim/option.c44
-rw-r--r--src/nvim/regexp.c12
-rw-r--r--src/nvim/regexp_nfa.c79
-rw-r--r--src/nvim/runtime.c115
-rw-r--r--src/nvim/runtime.h1
-rw-r--r--src/nvim/screen.c8
-rw-r--r--src/nvim/search.c87
-rw-r--r--src/nvim/spellfile.c2
-rw-r--r--src/nvim/syntax.c121
-rw-r--r--src/nvim/tag.c73
-rw-r--r--src/nvim/testdir/test_autochdir.vim10
-rw-r--r--src/nvim/testdir/test_autocmd.vim73
-rw-r--r--src/nvim/testdir/test_cd.vim138
-rw-r--r--src/nvim/testdir/test_filetype.vim6
-rw-r--r--src/nvim/testdir/test_find_complete.vim8
-rw-r--r--src/nvim/testdir/test_findfile.vim4
-rw-r--r--src/nvim/testdir/test_getcwd.vim2
-rw-r--r--src/nvim/undo.c76
-rw-r--r--src/nvim/window.c175
-rw-r--r--test/functional/api/vim_spec.lua45
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua120
-rw-r--r--test/functional/core/startup_spec.lua9
-rw-r--r--test/functional/ex_cmds/source_spec.lua20
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua1
-rw-r--r--test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua2
-rw-r--r--test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua3
-rw-r--r--test/functional/lua/diagnostic_spec.lua72
-rw-r--r--test/functional/lua/ffi_spec.lua62
-rw-r--r--test/functional/lua/uri_spec.lua17
-rw-r--r--test/functional/lua/vim_spec.lua11
-rw-r--r--test/functional/plugin/health_spec.lua4
92 files changed, 2406 insertions, 1333 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index de74ee891e..6c41dd3b10 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -519,11 +519,17 @@ DiffUpdated After diffs have been updated. Depending on
change or when doing |:diffupdate|.
*DirChanged*
DirChanged After the |current-directory| was changed.
+ The pattern can be:
+ "window" to trigger on `:lcd`
+ "tabpage" to trigger on `:tcd`
+ "global" to trigger on `:cd`
+ "auto" to trigger on 'autochdir'.
Sets these |v:event| keys:
cwd: current working directory
scope: "global", "tab", "window"
changed_window: v:true if we fired the event
switching window (or tab)
+ <afile> is set to the new directory name.
Non-recursive (event cannot trigger itself).
*FileAppendCmd*
FileAppendCmd Before appending to a file. Should do the
@@ -630,7 +636,7 @@ FilterReadPre Before reading a file from a filter command.
*FilterWritePost*
FilterWritePost After writing a file for a filter command or
making a diff with an external diff (see
- DiffUpdated for internal diff).
+ |DiffUpdated| for internal diff).
Vim checks the pattern against the name of
the current buffer as with FilterWritePre.
Not triggered when 'shelltemp' is off.
@@ -683,23 +689,6 @@ InsertCharPre When a character is typed in Insert mode,
Cannot change the text. |textlock|
Not triggered when 'paste' is set.
- *TextYankPost*
-TextYankPost Just after a |yank| or |deleting| command, but not
- if the black hole register |quote_| is used nor
- for |setreg()|. Pattern must be *.
- Sets these |v:event| keys:
- inclusive
- operator
- regcontents
- regname
- regtype
- visual
- The `inclusive` flag combined with the |'[|
- and |']| marks can be used to calculate the
- precise region of the operation.
-
- Non-recursive (event cannot trigger itself).
- Cannot change the text. |textlock|
*InsertEnter*
InsertEnter Just before starting Insert mode. Also for
Replace mode and Virtual Replace mode. The
@@ -948,6 +937,23 @@ TextChangedP After a change was made to the text in the
current buffer in Insert mode, only when the
popup menu is visible. Otherwise the same as
TextChanged.
+ *TextYankPost*
+TextYankPost Just after a |yank| or |deleting| command, but not
+ if the black hole register |quote_| is used nor
+ for |setreg()|. Pattern must be *.
+ Sets these |v:event| keys:
+ inclusive
+ operator
+ regcontents
+ regname
+ regtype
+ visual
+ The `inclusive` flag combined with the |'[|
+ and |']| marks can be used to calculate the
+ precise region of the operation.
+
+ Non-recursive (event cannot trigger itself).
+ Cannot change the text. |textlock|
*User*
User Not executed automatically. Use |:doautocmd|
to trigger this, typically for "custom events"
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index 2b799e3e27..ffdd8427f9 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1129,9 +1129,6 @@ a register, a paste on a visual selected area will paste that single line on
each of the selected lines (thus replacing the blockwise selected region by a
block of the pasted line).
-Use |zP|/|zp| to paste a blockwise yanked register without appending trailing
-spaces.
-
*blockwise-register*
If you use a blockwise Visual mode command to get the text into the register,
the block of text will be inserted before ("P") or after ("p") the cursor
@@ -1142,6 +1139,9 @@ this happen. However, if the width of the block is not a multiple of a <Tab>
width and the text after the inserted block contains <Tab>s, that text may be
misaligned.
+Use |zP|/|zp| to paste a blockwise yanked register without appending trailing
+spaces.
+
Note that after a charwise yank command, Vim leaves the cursor on the first
yanked character that is closest to the start of the buffer. This means that
"yl" doesn't move the cursor, but "yh" moves the cursor one character left.
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index 75c8a2ad6f..17d317522b 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -254,12 +254,31 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
Configure diagnostic options globally or for a specific
diagnostic namespace.
+ Configuration can be specified globally, per-namespace, or
+ ephemerally (i.e. only for a single call to
+ |vim.diagnostic.set()| or |vim.diagnostic.show()|). Ephemeral
+ configuration has highest priority, followed by namespace
+ configuration, and finally global configuration.
+
+ For example, if a user enables virtual text globally with >
+
+ vim.diagnostic.config({virt_text = true})
+<
+
+ and a diagnostic producer sets diagnostics with >
+
+ vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
+<
+
+ then virtual text will not be enabled for those diagnostics.
+
Note:
Each of the configuration options below accepts one of the
following:
• `false` : Disable this feature
• `true` : Enable this feature, use default settings.
- • `table` : Enable this feature with overrides.
+ • `table` : Enable this feature with overrides. Use an
+ empty table to use default values.
• `function` : Function with signature (namespace, bufnr)
that returns any of the above.
@@ -460,8 +479,9 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
For example, consider a line of output from a linter: >
WARNING filename:27:3: Variable 'foo' does not exist
+<
- < This can be parsed into a diagnostic |diagnostic-structure|
+ This can be parsed into a diagnostic |diagnostic-structure|
with: >
local s = "WARNING filename:27:3: Variable 'foo' does not exist"
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index 0e7e461a61..efba9020f9 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -1275,10 +1275,12 @@ exist, the next-higher scope in the hierarchy applies.
*:chd* *:chdir*
:chd[ir][!] [path] Same as |:cd|.
- *:tc* *:tcd* *E5000* *E5001* *E5002*
-:tc[d][!] {path} Like |:cd|, but set the current directory for the
- current tab and window. The current directory for
- other tabs and windows is not changed.
+ *:tc* *:tcd*
+:tc[d][!] {path} Like |:cd|, but only set the directory for the current
+ tab. The current window will also use this directory.
+ The current directory is not changed for windows in
+ other tabs and for windows in the current tab that
+ have their own window-local directory.
*:tcd-*
:tc[d][!] - Change to the previous current directory (before the
@@ -1302,15 +1304,30 @@ exist, the next-higher scope in the hierarchy applies.
*:pw* *:pwd* *E187*
:pw[d] Print the current directory name.
Also see |getcwd()|.
+ *:pwd-verbose*
+ When 'verbose' is non-zero, |:pwd| will also display
+ what scope the current directory was set. Example: >
-So long as no |:tcd| or |:lcd| command has been used, all windows share the
-same "current directory". Using a command to jump to another window doesn't
+ " Set by :cd
+ :verbose pwd
+ [global] /path/to/current
+
+ " Set by :lcd
+ :verbose pwd
+ [window] /path/to/current
+
+ " Set by :tcd
+ :verbose pwd
+ [tabpage] /path/to/current
+
+So long as no |:lcd| or |:tcd| command has been used, all windows share the
+same current directory. Using a command to jump to another window doesn't
change anything for the current directory.
When |:lcd| has been used for a window, the specified directory becomes the
current directory for that window. Windows where the |:lcd| command has not
been used stick to the global or tab-local directory. When jumping to another
-window the current directory will become the last specified local current
+window the current directory is changed to the last specified local current
directory. If none was specified, the global or tab-local directory is used.
When changing tabs the same behaviour applies. If the current tab has no
@@ -1467,6 +1484,11 @@ It is also possible that you modified the file yourself, from another edit
session or with another command (e.g., a filter command). Then you will know
which version of the file you want to keep.
+The accuracy of the time check depends on the filesystem. On Unix it is
+usually sub-second. With old file sytems and on MS-Windows it is normally one
+second. Use has('nanotime') check if sub-second time stamp checks are
+available.
+
There is one situation where you get the message while there is nothing wrong:
On a Win32 system on the day daylight saving time starts. There is something
in the Win32 libraries that confuses Vim about the hour time difference. The
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index e956ccaa77..4467afaa16 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2316,6 +2316,7 @@ chansend({id}, {data}) Number Writes {data} to channel
char2nr({expr}[, {utf8}]) Number ASCII/UTF-8 value of first char in {expr}
charidx({string}, {idx} [, {countcc}])
Number char index of byte {idx} in {string}
+chdir({dir}) String change current working directory
cindent({lnum}) Number C indent for line {lnum}
clearmatches([{win}]) none clear all matches
col({expr}) Number column nr of cursor or mark
@@ -2461,6 +2462,7 @@ has({feature}) Number |TRUE| if feature {feature} supported
has_key({dict}, {key}) Number |TRUE| if {dict} has entry {key}
haslocaldir([{winnr} [, {tabnr}]])
Number |TRUE| if current window executed |:lcd|
+ or |:tcd|
hasmapto({what} [, {mode} [, {abbr}]])
Number |TRUE| if mapping to {what} exists
histadd({history}, {item}) String add an item to a history
@@ -3280,6 +3282,27 @@ charidx({string}, {idx} [, {countcc}])
echo charidx('áb́ć', 6, 1) returns 4
echo charidx('áb́ć', 16) returns -1
+chdir({dir}) *chdir()*
+ Change the current working directory to {dir}. The scope of
+ the directory change depends on the directory of the current
+ window:
+ - If the current window has a window-local directory
+ (|:lcd|), then changes the window local directory.
+ - Otherwise, if the current tabpage has a local
+ directory (|:tcd|) then changes the tabpage local
+ directory.
+ - Otherwise, changes the global directory.
+ If successful, returns the previous working directory. Pass
+ this to another chdir() to restore the directory.
+ On failure, returns an empty string.
+
+ Example: >
+ let save_dir = chdir(newdir)
+ if save_dir
+ " ... do some work
+ call chdir(save_dir)
+ endif
+<
cindent({lnum}) *cindent()*
Get the amount of indent for line {lnum} according the C
indenting rules, as with 'cindent'.
@@ -4987,6 +5010,8 @@ getcwd([{winnr}[, {tabnr}]]) *getcwd()*
getcwd(0, 0)
< If {winnr} is -1 it is ignored, only the tab is resolved.
{winnr} can be the window number or the |window-ID|.
+ If both {winnr} and {tabnr} are -1 the global working
+ directory is returned.
Can also be used as a |method|: >
GetWinnr()->getcwd()
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 981bdd09fc..3520d40591 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5981,13 +5981,13 @@ A jump table for the options with a short description can be found at |Q_op|.
return value of expr contains % items they will get expanded.
The expression can contain the } character, the end of
expression is denoted by %}.
- The For example: >
+ For example: >
func! Stl_filename() abort
return "%t"
endfunc
< `stl=%{Stl_filename()}` results in `"%t"`
`stl=%{%Stl_filename()%}` results in `"Name of current file"`
- } - End of `{%` expression
+ %} - End of `{%` expression
( - Start of item group. Can be used for setting the width and
alignment of a section. Must be followed by %) somewhere.
) - End of item group. No width fields allowed.
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index c49cc6d540..dfed39dba6 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -977,7 +977,7 @@ $ At end of pattern or in front of "\|", "\)" or "\n" ('magic' on):
/.*\%17v
< Column 17 is highlighted by 'hlsearch' because there is another match
where ".*" matches zero characters.
-<
+
Character classes:
\i identifier character (see 'isident' option) */\i*
diff --git a/runtime/doc/usr_22.txt b/runtime/doc/usr_22.txt
index 56fe5ada2b..f53d578456 100644
--- a/runtime/doc/usr_22.txt
+++ b/runtime/doc/usr_22.txt
@@ -202,14 +202,28 @@ the other window. This is called a local directory. >
:pwd
/home/Bram/VeryLongFileName
-So long as no ":lcd" command has been used, all windows share the same current
-directory. Doing a ":cd" command in one window will also change the current
+So long as no `:lcd` command has been used, all windows share the same current
+directory. Doing a `:cd` command in one window will also change the current
directory of the other window.
- For a window where ":lcd" has been used a different current directory is
-remembered. Using ":cd" or ":lcd" in other windows will not change it.
- When using a ":cd" command in a window that uses a different current
+ For a window where `:lcd` has been used a different current directory is
+remembered. Using `:cd` or `:lcd` in other windows will not change it.
+ When using a `:cd` command in a window that uses a different current
directory, it will go back to using the shared directory.
+
+TAB LOCAL DIRECTORY
+
+When you open a new tab page, it uses the directory of the window in the
+previous tab page from which the new tab page was opened. You can change the
+directory of the current tab page using the `:tcd` command. All the windows in
+a tab page share this directory except for windows with a window-local
+directory. Any new windows opened in this tab page will use this directory as
+the current working directory. Using a `:cd` command in a tab page will not
+change the working directory of tab pages which have a tab local directory.
+When the global working directory is changed using the ":cd" command in a tab
+page, it will also change the current tab page working directory.
+
+
==============================================================================
*22.3* Finding a file
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index c575dd9fd8..6a9284dac9 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -785,9 +785,10 @@ System functions and manipulation of files:
isdirectory() check if a directory exists
getfsize() get the size of a file
getcwd() get the current working directory
- haslocaldir() check if current window used |:lcd|
+ haslocaldir() check if current window used |:lcd| or |:tcd|
tempname() get the name of a temporary file
mkdir() create a new directory
+ chdir() change current working directory
delete() delete a file
rename() rename a file
system() get the result of a shell command as a string
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index b06fa7518c..5484e27797 100644
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -168,7 +168,7 @@ g8 Print the hex values of the bytes used in the
*:z!*
:[range]z![+-^.=][count]
- Like ":z:", but when [count] is not specified, it
+ Like ":z", but when [count] is not specified, it
defaults to the Vim window height minus one.
:[range]z[!]#[+-^.=][count] *:z#*
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 64824b2e3f..7e7bb7d62f 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -180,6 +180,7 @@ Commands:
|:match| can be invoked before highlight group is defined
Events:
+ |DirChanged| can be triggered when switching to another window
|Signal|
|TabNewEntered|
|TermClose|
@@ -196,6 +197,10 @@ Functions:
|stdpath()|
|system()|, |systemlist()| can run {cmd} directly (without 'shell')
|matchadd()| can be called before highlight group is defined
+ |getcwd()| and |haslocaldir()| may throw errors. *E5000* *E5001* *E5002*
+ |haslocaldir()|'s only possible return values are 0 and 1, it never returns 2.
+ `getcwd(-1)` is equivalent to `getcwd(-1, 0)` instead of returning the global
+ working directory. Use `getcwd(-1, -1)` to get the global working directory.
Highlight groups:
|highlight-blend| controls blend level for a highlight group
diff --git a/runtime/filetype.vim b/runtime/filetype.vim
index c86ca9646b..75354968e9 100644
--- a/runtime/filetype.vim
+++ b/runtime/filetype.vim
@@ -703,6 +703,7 @@ au BufNewFile,BufRead *.gpi setf gnuplot
" Go (Google)
au BufNewFile,BufRead *.go setf go
+au BufNewFile,BufRead Gopkg.lock setf toml
" GrADS scripts
au BufNewFile,BufRead *.gs setf grads
@@ -1283,7 +1284,7 @@ au BufNewFile,BufRead *.rcp setf pilrc
au BufNewFile,BufRead .pinerc,pinerc,.pinercex,pinercex setf pine
" Pipenv Pipfiles
-au BufNewFile,BufRead Pipfile setf config
+au BufNewFile,BufRead Pipfile setf toml
au BufNewFile,BufRead Pipfile.lock setf json
" PL/1, PL/I
@@ -1517,6 +1518,7 @@ au BufNewFile,BufRead [rR]antfile,*.rant,[rR]akefile,*.rake setf ruby
" Rust
au BufNewFile,BufRead *.rs setf rust
+au BufNewFile,BufRead Cargo.lock,*/.cargo/config,*/.cargo/credentials setf toml
" S-lang (or shader language, or SmallLisp)
au BufNewFile,BufRead *.sl setf slang
@@ -2301,6 +2303,9 @@ au BufNewFile,BufRead .tcshrc* call dist#ft#SetFileTypeShell("tcsh")
" csh scripts ending in a star
au BufNewFile,BufRead .login*,.cshrc* call dist#ft#CSH()
+" tmux configuration with arbitrary extension
+au BufNewFile,BufRead {.,}tmux*.conf* setf tmux
+
" VHDL
au BufNewFile,BufRead *.vhdl_[0-9]* call s:StarSetf('vhdl')
diff --git a/runtime/ftplugin/context.vim b/runtime/ftplugin/context.vim
index 10f1ae1648..37f7240d7b 100644
--- a/runtime/ftplugin/context.vim
+++ b/runtime/ftplugin/context.vim
@@ -2,7 +2,7 @@
" Language: ConTeXt typesetting engine
" Maintainer: Nicola Vitacolonna <nvitacolonna@gmail.com>
" Former Maintainers: Nikolai Weibull <now@bitwi.se>
-" Latest Revision: 2016 Oct 30
+" Latest Revision: 2021 Oct 15
if exists("b:did_ftplugin")
finish
@@ -17,7 +17,6 @@ if !exists('current_compiler')
endif
let b:undo_ftplugin = "setl com< cms< def< inc< sua< fo< ofu<"
- \ . "| unlet! b:match_ignorecase b:match_words b:match_skip"
setlocal comments=b:%D,b:%C,b:%M,:% commentstring=%\ %s formatoptions+=tjcroql2
if get(b:, 'context_metapost', get(g:, 'context_metapost', 1))
@@ -35,11 +34,12 @@ let &l:include = '^\s*\\\%(input\|component\|product\|project\|environment\)'
setlocal suffixesadd=.tex
-if exists("loaded_matchit")
+if exists("loaded_matchit") && !exists("b:match_words")
let b:match_ignorecase = 0
let b:match_skip = 'r:\\\@<!\%(\\\\\)*%'
let b:match_words = '(:),\[:],{:},\\(:\\),\\\[:\\],' .
\ '\\start\(\a\+\):\\stop\1'
+ let b:undo_ftplugin .= " | unlet! b:match_ignorecase b:match_words b:match_skip"
endif
let s:context_regex = {
@@ -57,19 +57,28 @@ function! s:move_around(count, what, flags, visual)
call map(range(2, a:count), 'search(s:context_regex[a:what], a:flags)')
endfunction
-" Move around macros.
-nnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:false) <CR>
-vnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:true) <CR>
-nnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:false) <CR>
-vnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:true) <CR>
-nnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:false) <CR>
-vnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:true) <CR>
-nnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:false) <CR>
-vnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:true) <CR>
-nnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:false) <CR>
-vnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:true) <CR>
-nnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:false) <CR>
-vnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:true) <CR>
+if !exists("no_plugin_maps") && !exists("no_context_maps")
+ " Move around macros.
+ nnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:false) <CR>
+ vnoremap <silent><buffer> [[ :<C-U>call <SID>move_around(v:count1, "beginsection", "bW", v:true) <CR>
+ nnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:false) <CR>
+ vnoremap <silent><buffer> ]] :<C-U>call <SID>move_around(v:count1, "beginsection", "W", v:true) <CR>
+ nnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:false) <CR>
+ vnoremap <silent><buffer> [] :<C-U>call <SID>move_around(v:count1, "endsection", "bW", v:true) <CR>
+ nnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:false) <CR>
+ vnoremap <silent><buffer> ][ :<C-U>call <SID>move_around(v:count1, "endsection", "W", v:true) <CR>
+ nnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:false) <CR>
+ vnoremap <silent><buffer> [{ :<C-U>call <SID>move_around(v:count1, "beginblock", "bW", v:true) <CR>
+ nnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:false) <CR>
+ vnoremap <silent><buffer> ]} :<C-U>call <SID>move_around(v:count1, "endblock", "W", v:true) <CR>
+
+ let b:undo_ftplugin .= " | sil! exe 'nunmap <buffer> [[' | sil! exe 'vunmap <buffer> [['" .
+ \ " | sil! exe 'nunmap <buffer> ]]' | sil! exe 'vunmap <buffer> ]]'" .
+ \ " | sil! exe 'nunmap <buffer> []' | sil! exe 'vunmap <buffer> []'" .
+ \ " | sil! exe 'nunmap <buffer> ][' | sil! exe 'vunmap <buffer> ]['" .
+ \ " | sil! exe 'nunmap <buffer> [{' | sil! exe 'vunmap <buffer> [{'" .
+ \ " | sil! exe 'nunmap <buffer> ]}' | sil! exe 'vunmap <buffer> ]}'"
+end
" Other useful mappings
if get(g:, 'context_mappings', 1)
@@ -81,16 +90,22 @@ if get(g:, 'context_mappings', 1)
call cursor(search(s:tp_regex, 'W') - 1, 1)
endf
- " Reflow paragraphs with commands like gqtp ("gq TeX paragraph")
- onoremap <silent><buffer> tp :<c-u>call <sid>tp()<cr>
- " Select TeX paragraph
- vnoremap <silent><buffer> tp <esc>:<c-u>call <sid>tp()<cr>
-
- " $...$ text object
- onoremap <silent><buffer> i$ :<c-u>normal! T$vt$<cr>
- onoremap <silent><buffer> a$ :<c-u>normal! F$vf$<cr>
- vnoremap <buffer> i$ T$ot$
- vnoremap <buffer> a$ F$of$
+ if !exists("no_plugin_maps") && !exists("no_context_maps")
+ " Reflow paragraphs with commands like gqtp ("gq TeX paragraph")
+ onoremap <silent><buffer> tp :<c-u>call <sid>tp()<cr>
+ " Select TeX paragraph
+ vnoremap <silent><buffer> tp <esc>:<c-u>call <sid>tp()<cr>
+
+ " $...$ text object
+ onoremap <silent><buffer> i$ :<c-u>normal! T$vt$<cr>
+ onoremap <silent><buffer> a$ :<c-u>normal! F$vf$<cr>
+ vnoremap <buffer> i$ T$ot$
+ vnoremap <buffer> a$ F$of$
+
+ let b:undo_ftplugin .= " | sil! exe 'ounmap <buffer> tp' | sil! exe 'vunmap <buffer> tp'" .
+ \ " | sil! exe 'ounmap <buffer> i$' | sil! exe 'vunmap <buffer> i$'" .
+ \ " | sil! exe 'ounmap <buffer> a$' | sil! exe 'vunmap <buffer> a$'"
+ endif
endif
" Commands for asynchronous typesetting
diff --git a/runtime/ftplugin/csh.vim b/runtime/ftplugin/csh.vim
index 4ae09f91be..929823219c 100644
--- a/runtime/ftplugin/csh.vim
+++ b/runtime/ftplugin/csh.vim
@@ -1,21 +1,23 @@
" Vim filetype plugin file
-" Language: csh
-" Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
-" Last Changed: 20 Jan 2009
-" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
+" Language: csh
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
+" Contributor: Johannes Zellner <johannes@zellner.org>
+" Last Change: 2021 Oct 15
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
-" Make sure the continuation lines below do not cause problems in
-" compatibility mode.
let s:save_cpo = &cpo
set cpo-=C
+setlocal comments=:#
setlocal commentstring=#%s
setlocal formatoptions-=t
setlocal formatoptions+=crql
+let b:undo_ftplugin = "setlocal com< cms< fo<"
+
" Csh: thanks to Johannes Zellner
" - Both foreach and end must appear alone on separate lines.
" - The words else and endif must appear at the beginning of input lines;
@@ -23,26 +25,27 @@ setlocal formatoptions+=crql
" - Each case label and the default label must appear at the start of a
" line.
" - while and end must appear alone on their input lines.
-if exists("loaded_matchit")
- let b:match_words =
- \ '^\s*\<if\>.*(.*).*\<then\>:'.
- \ '^\s*\<else\>\s\+\<if\>.*(.*).*\<then\>:^\s*\<else\>:'.
- \ '^\s*\<endif\>,'.
- \ '\%(^\s*\<foreach\>\s\+\S\+\|^s*\<while\>\).*(.*):'.
- \ '\<break\>:\<continue\>:^\s*\<end\>,'.
- \ '^\s*\<switch\>.*(.*):^\s*\<case\>\s\+:^\s*\<default\>:^\s*\<endsw\>'
+if exists("loaded_matchit") && !exists("b:match_words")
+ let s:line_start = '\%(^\s*\)\@<='
+ let b:match_words =
+ \ s:line_start .. 'if\s*(.*)\s*then\>:' ..
+ \ s:line_start .. 'else\s\+if\s*(.*)\s*then\>:' .. s:line_start .. 'else\>:' ..
+ \ s:line_start .. 'endif\>,' ..
+ \ s:line_start .. '\%(\<foreach\s\+\h\w*\|while\)\s*(:' ..
+ \ '\<break\>:\<continue\>:' ..
+ \ s:line_start .. 'end\>,' ..
+ \ s:line_start .. 'switch\s*(:' ..
+ \ s:line_start .. 'case\s\+:' .. s:line_start .. 'default\>:\<breaksw\>:' ..
+ \ s:line_start .. 'endsw\>'
+ unlet s:line_start
+ let b:undo_ftplugin ..= " | unlet b:match_words"
endif
-" Change the :browse e filter to primarily show csh-related files.
-if has("gui_win32")
- let b:browsefilter="csh Scripts (*.csh)\t*.csh\n" .
- \ "All Files (*.*)\t*.*\n"
+if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
+ let b:browsefilter="csh Scripts (*.csh)\t*.csh\n" ..
+ \ "All Files (*.*)\t*.*\n"
+ let b:undo_ftplugin ..= " | unlet b:browsefilter"
endif
-" Undo the stuff we changed.
-let b:undo_ftplugin = "setlocal commentstring< formatoptions<" .
- \ " | unlet! b:match_words b:browsefilter"
-
-" Restore the saved compatibility options.
let &cpo = s:save_cpo
unlet s:save_cpo
diff --git a/runtime/ftplugin/tcsh.vim b/runtime/ftplugin/tcsh.vim
index 7e2d959932..33f1aabf68 100644
--- a/runtime/ftplugin/tcsh.vim
+++ b/runtime/ftplugin/tcsh.vim
@@ -1,19 +1,17 @@
" Vim filetype plugin file
-" Language: tcsh
-" Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
-" Last Changed: 20 Jan 2009
-" URL: http://dwsharp.users.sourceforge.net/vim/ftplugin
+" Language: tcsh
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Dan Sharp <dwsharp at users dot sourceforge dot net>
+" Last Change: 2021 Oct 15
if exists("b:did_ftplugin") | finish | endif
-" Make sure the continuation lines below do not cause problems in
-" compatibility mode.
let s:save_cpo = &cpo
set cpo-=C
" Define some defaults in case the included ftplugins don't set them.
let s:undo_ftplugin = ""
-let s:browsefilter = "csh Files (*.csh)\t*.csh\n" .
+let s:browsefilter = "csh Files (*.csh)\t*.csh\n" ..
\ "All Files (*.*)\t*.*\n"
runtime! ftplugin/csh.vim ftplugin/csh_*.vim ftplugin/csh/*.vim
@@ -27,14 +25,11 @@ if exists("b:browsefilter")
let s:browsefilter = b:browsefilter
endif
-" Change the :browse e filter to primarily show tcsh-related files.
-if has("gui_win32")
- let b:browsefilter="tcsh Scripts (*.tcsh)\t*.tcsh\n" . s:browsefilter
+if (has("gui_win32") || has("gui_gtk"))
+ let b:browsefilter="tcsh Scripts (*.tcsh)\t*.tcsh\n" .. s:browsefilter
endif
-" Undo the stuff we changed.
-let b:undo_ftplugin = "unlet! b:browsefilter | " . s:undo_ftplugin
+let b:undo_ftplugin = "unlet! b:browsefilter | " .. s:undo_ftplugin
-" Restore the saved compatibility options.
let &cpo = s:save_cpo
unlet s:save_cpo
diff --git a/runtime/ftplugin/tmux.vim b/runtime/ftplugin/tmux.vim
index ed9154924b..5c3461fefb 100644
--- a/runtime/ftplugin/tmux.vim
+++ b/runtime/ftplugin/tmux.vim
@@ -9,4 +9,7 @@ if exists("b:did_ftplugin")
endif
let b:did_ftplugin = 1
+let b:undo_ftplugin = "setlocal comments< commentstring<"
+
+setlocal comments=:#
setlocal commentstring=#\ %s
diff --git a/runtime/ftplugin/toml.vim b/runtime/ftplugin/toml.vim
new file mode 100644
index 0000000000..1ef09a16e3
--- /dev/null
+++ b/runtime/ftplugin/toml.vim
@@ -0,0 +1,23 @@
+" Vim filetype plugin
+" Language: TOML
+" Homepage: https://github.com/cespare/vim-toml
+" Maintainer: Aman Verma
+" Author: Kevin Ballard <kevin@sb.org>
+" Last Change: Sep 21, 2021
+
+if exists('b:did_ftplugin')
+ finish
+endif
+let b:did_ftplugin = 1
+
+let s:save_cpo = &cpo
+set cpo&vim
+let b:undo_ftplugin = 'setlocal commentstring< comments<'
+
+setlocal commentstring=#\ %s
+setlocal comments=:#
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim: et sw=2 sts=2
diff --git a/runtime/indent/hamster.vim b/runtime/indent/hamster.vim
index b27a173924..ae5c3fdedd 100644
--- a/runtime/indent/hamster.vim
+++ b/runtime/indent/hamster.vim
@@ -1,8 +1,14 @@
" Vim indent file
" Language: Hamster Script
-" Version: 2.0.6.0
-" Last Change: Wed Nov 08 2006 12:02:42 PM
-" Maintainer: David Fishburn <fishburn@ianywhere.com>
+" Version: 2.0.6.1
+" Last Change: 2021 Oct 11
+" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
+" Download: https://www.vim.org/scripts/script.php?script_id=1099
+"
+" 2.0.6.1 (Oct 2021)
+" Added b:undo_indent
+" Added cpo check
+"
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -14,12 +20,17 @@ setlocal indentkeys+==~if,=~else,=~endif,=~endfor,=~endwhile
setlocal indentkeys+==~do,=~until,=~while,=~repeat,=~for,=~loop
setlocal indentkeys+==~sub,=~endsub
+let b:undo_indent = "setl indentkeys<"
+
" Define the appropriate indent function but only once
setlocal indentexpr=HamGetFreeIndent()
if exists("*HamGetFreeIndent")
finish
endif
+let s:keepcpo = &cpo
+set cpo&vim
+
function HamGetIndent(lnum)
let ind = indent(a:lnum)
let prevline=getline(a:lnum)
@@ -52,4 +63,8 @@ function HamGetFreeIndent()
return ind
endfunction
+" Restore:
+let &cpo = s:keepcpo
+unlet s:keepcpo
+
" vim:sw=2 tw=80
diff --git a/runtime/indent/sqlanywhere.vim b/runtime/indent/sqlanywhere.vim
index d39fa3240e..4772b5951b 100644
--- a/runtime/indent/sqlanywhere.vim
+++ b/runtime/indent/sqlanywhere.vim
@@ -1,9 +1,8 @@
" Vim indent file
" Language: SQL
" Maintainer: David Fishburn <dfishburn dot vim at gmail dot com>
-" Last Change By Maintainer: 2017 Jun 13
-" Last Change: by Stephen Wall, #5578, 2020 Jun 07
-" Version: 3.0
+" Last Change: 2021 Oct 11
+" Version: 4.0
" Download: http://vim.sourceforge.net/script.php?script_id=495
" Notes:
@@ -21,6 +20,9 @@
" it, this can leave the indent hanging to the right one too many.
"
" History:
+" 4.0 (Oct 2021)
+" Added b:undo_indent
+"
" 3.0 (Dec 2012)
" Added cpo check
"
@@ -56,10 +58,13 @@ setlocal indentkeys+==~end,=~else,=~elseif,=~elsif,0=~when,0=)
" in the indentkeys is typed
setlocal indentexpr=GetSQLIndent()
+let b:undo_indent = "setl indentexpr< indentkeys<"
+
" Only define the functions once.
if exists("*GetSQLIndent")
finish
endif
+
let s:keepcpo= &cpo
set cpo&vim
@@ -68,14 +73,9 @@ set cpo&vim
" IS is excluded, since it is difficult to determine when the
" ending block is (especially for procedures/functions).
let s:SQLBlockStart = '^\s*\%('.
- \ 'if\>.*\<then\|'.
- \ 'then\|else\>\|'.
- \ 'elseif\>.*\<then\|'.
- \ 'elsif\>.(\<then\|'.
- \ 'while\>.*\<loop\|'.
- \ 'for\>.*\<loop\|'.
- \ 'foreach\>.*\<loop\|'.
- \ 'loop\|do\|declare\|begin\|'.
+ \ 'if\|else\|elseif\|elsif\|'.
+ \ 'while\|loop\|do\|for\|'.
+ \ 'begin\|'.
\ 'case\|when\|merge\|exception'.
\ '\)\>'
let s:SQLBlockEnd = '^\s*\(end\)\>'
diff --git a/runtime/indent/tcsh.vim b/runtime/indent/tcsh.vim
index 025d9c805d..93d96e7789 100644
--- a/runtime/indent/tcsh.vim
+++ b/runtime/indent/tcsh.vim
@@ -1,7 +1,8 @@
" Vim indent file
" Language: C-shell (tcsh)
-" Maintainer: Doug Kearns <a@b.com> where a=dougkearns, b=gmail
-" Last Modified: Sun 26 Sep 2021 12:38:38 PM EDT
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail (Original Author)
+" Last Change: 2021 Oct 15
" Only load this indent file when no other was loaded.
if exists("b:did_indent")
@@ -11,7 +12,9 @@ endif
let b:did_indent = 1
setlocal indentexpr=TcshGetIndent()
-setlocal indentkeys+=e,0=end,0=endsw indentkeys-=0{,0},0),:,0#
+setlocal indentkeys+=e,0=end
+setlocal indentkeys-=0{,0},0),:,0#
+
let b:undo_indent = "setl inde< indk<"
" Only define the function once.
@@ -40,9 +43,9 @@ function TcshGetIndent()
let ind = ind - shiftwidth()
endif
- " Subtract indent if current line has on end, endif, case commands
+ " Subtract indent if current line has on end, endif, endsw, case commands
let line = getline(v:lnum)
- if line =~ '\v^\s*%(else|end|endif)\s*$'
+ if line =~ '\v^\s*%(else|end|endif|endsw)\s*$'
let ind = ind - shiftwidth()
endif
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index e8aba6b7a3..326932d982 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -93,28 +93,6 @@ local function reformat_diagnostics(format, diagnostics)
return formatted
end
----@private
-local function resolve_optional_value(option, namespace, bufnr)
- local enabled_val = {}
-
- if not option then
- return false
- elseif option == true then
- return enabled_val
- elseif type(option) == 'function' then
- local val = option(namespace, bufnr)
- if val == true then
- return enabled_val
- else
- return val
- end
- elseif type(option) == 'table' then
- return option
- else
- error("Unexpected option type: " .. vim.inspect(option))
- end
-end
-
local all_namespaces = {}
---@private
@@ -140,12 +118,46 @@ local function get_namespace(ns)
end
---@private
+local function enabled_value(option, namespace)
+ local ns = get_namespace(namespace)
+ if type(ns.opts[option]) == "table" then
+ return ns.opts[option]
+ end
+
+ if type(global_diagnostic_options[option]) == "table" then
+ return global_diagnostic_options[option]
+ end
+
+ return {}
+end
+
+---@private
+local function resolve_optional_value(option, value, namespace, bufnr)
+ if not value then
+ return false
+ elseif value == true then
+ return enabled_value(option, namespace)
+ elseif type(value) == 'function' then
+ local val = value(namespace, bufnr)
+ if val == true then
+ return enabled_value(option, namespace)
+ else
+ return val
+ end
+ elseif type(value) == 'table' then
+ return value
+ else
+ error("Unexpected option type: " .. vim.inspect(value))
+ end
+end
+
+---@private
local function get_resolved_options(opts, namespace, bufnr)
local ns = get_namespace(namespace)
local resolved = vim.tbl_extend('keep', opts or {}, ns.opts, global_diagnostic_options)
for k in pairs(global_diagnostic_options) do
if resolved[k] ~= nil then
- resolved[k] = resolve_optional_value(resolved[k], namespace, bufnr)
+ resolved[k] = resolve_optional_value(k, resolved[k], namespace, bufnr)
end
end
return resolved
@@ -542,10 +554,27 @@ end
--- Configure diagnostic options globally or for a specific diagnostic
--- namespace.
---
+--- Configuration can be specified globally, per-namespace, or ephemerally
+--- (i.e. only for a single call to |vim.diagnostic.set()| or
+--- |vim.diagnostic.show()|). Ephemeral configuration has highest priority,
+--- followed by namespace configuration, and finally global configuration.
+---
+--- For example, if a user enables virtual text globally with
+--- <pre>
+--- vim.diagnostic.config({virt_text = true})
+--- </pre>
+---
+--- and a diagnostic producer sets diagnostics with
+--- <pre>
+--- vim.diagnostic.set(ns, 0, diagnostics, {virt_text = false})
+--- </pre>
+---
+--- then virtual text will not be enabled for those diagnostics.
+---
---@note Each of the configuration options below accepts one of the following:
--- - `false`: Disable this feature
--- - `true`: Enable this feature, use default settings.
---- - `table`: Enable this feature with overrides.
+--- - `table`: Enable this feature with overrides. Use an empty table to use default values.
--- - `function`: Function with signature (namespace, bufnr) that returns any of the above.
---
---@param opts table Configuration table with the following keys:
@@ -653,8 +682,6 @@ function M.set(namespace, bufnr, diagnostics, opts)
if vim.api.nvim_buf_is_loaded(bufnr) then
M.show(namespace, bufnr, diagnostics, opts)
- elseif opts then
- M.config(opts, namespace)
end
vim.api.nvim_command("doautocmd <nomodeline> User DiagnosticsChanged")
@@ -1277,6 +1304,7 @@ end
--- <pre>
--- WARNING filename:27:3: Variable 'foo' does not exist
--- </pre>
+---
--- This can be parsed into a diagnostic |diagnostic-structure|
--- with:
--- <pre>
diff --git a/runtime/lua/vim/uri.lua b/runtime/lua/vim/uri.lua
index a3e79a0f2b..5d8d4fa169 100644
--- a/runtime/lua/vim/uri.lua
+++ b/runtime/lua/vim/uri.lua
@@ -75,13 +75,22 @@ local function uri_from_fname(path)
end
local URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*):.*'
+local WINDOWS_URI_SCHEME_PATTERN = '^([a-zA-Z]+[a-zA-Z0-9+-.]*):[a-zA-Z]:.*'
--- Get a URI from a bufnr
---@param bufnr (number): Buffer number
---@return URI
local function uri_from_bufnr(bufnr)
local fname = vim.api.nvim_buf_get_name(bufnr)
- local scheme = fname:match(URI_SCHEME_PATTERN)
+ local volume_path = fname:match("^([a-zA-Z]:).*")
+ local is_windows = volume_path ~= nil
+ local scheme
+ if is_windows then
+ fname = fname:gsub("\\", "/")
+ scheme = fname:match(WINDOWS_URI_SCHEME_PATTERN)
+ else
+ scheme = fname:match(URI_SCHEME_PATTERN)
+ end
if scheme then
return fname
else
diff --git a/runtime/syntax/css.vim b/runtime/syntax/css.vim
index 19326d01e4..67ad1ea335 100644
--- a/runtime/syntax/css.vim
+++ b/runtime/syntax/css.vim
@@ -2,12 +2,12 @@
" Language: Cascading Style Sheets
" Previous Contributor List:
" Jules Wang <w.jq0722@gmail.com>
-" Claudio Fleiner <claudio@fleiner.com> (Maintainer)
+" Claudio Fleiner <claudio@fleiner.com>
" Yeti (Add full CSS2, HTML4 support)
" Nikolai Weibull (Add CSS2 support)
-" URL: https://github.com/jsit/css.vim
+" URL: https://github.com/vim-language-dept/css-syntax.vim
" Maintainer: Jay Sitter <jay@jaysitter.com>
-" Last Change: 2019 Jul. 29
+" Last Change: 2021 Oct 15
" quit when a syntax file was already loaded
if !exists("main_syntax")
@@ -23,6 +23,8 @@ let s:cpo_save = &cpo
set cpo&vim
syn case ignore
+" Add dash to allowed keyword characters.
+syn iskeyword @,48-57,_,192-255,-
" HTML4 tags
syn keyword cssTagName abbr address area a b base
@@ -32,7 +34,7 @@ syn keyword cssTagName dfn div dl dt em fieldset form
syn keyword cssTagName h1 h2 h3 h4 h5 h6 head hr html img i
syn keyword cssTagName iframe input ins isindex kbd label legend li
syn keyword cssTagName link map menu meta noscript ol optgroup
-syn keyword cssTagName option p param pre q s samp script small
+syn keyword cssTagName option p param picture pre q s samp script small
syn keyword cssTagName span strong sub sup tbody td
syn keyword cssTagName textarea tfoot th thead title tr ul u var
syn keyword cssTagName object svg
@@ -127,7 +129,7 @@ syn region cssURL contained matchgroup=cssFunctionName start="\<\(uri\|url\|loca
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(var\|calc\)\s*(" end=")" contains=cssCustomProp,cssValue.*,cssFunction,cssColor,cssStringQ,cssStringQQ oneline
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgb\|clip\|attr\|counter\|rect\|cubic-bezier\|steps\)\s*(" end=")" oneline contains=cssValueInteger,cssValueNumber,cssValueLength,cssFunctionComma
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgba\|hsl\|hsla\|color-stop\|from\|to\)\s*(" end=")" oneline contains=cssColor,cssValueInteger,cssValueNumber,cssValueLength,cssFunctionComma,cssFunction
-syn region cssFunction contained matchgroup=cssFunctionName start="\<\(linear-\|radial-\)\=\gradient\s*(" end=")" oneline contains=cssColor,cssValueInteger,cssValueNumber,cssValueLength,cssFunction,cssGradientAttr,cssFunctionComma
+syn region cssFunction contained matchgroup=cssFunctionName start="\<\(linear-\|radial-\|conic-\)\=\gradient\s*(" end=")" oneline contains=cssColor,cssValueInteger,cssValueNumber,cssValueLength,cssFunction,cssGradientAttr,cssFunctionComma
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(matrix\(3d\)\=\|scale\(3d\|X\|Y\|Z\)\=\|translate\(3d\|X\|Y\|Z\)\=\|skew\(X\|Y\)\=\|rotate\(3d\|X\|Y\|Z\)\=\|perspective\)\s*(" end=")" oneline contains=cssValueInteger,cssValueNumber,cssValueLength,cssValueAngle,cssFunctionComma
syn region cssFunction contained matchgroup=cssFunctionName start="\<\(blur\|brightness\|contrast\|drop-shadow\|grayscale\|hue-rotate\|invert\|opacity\|saturate\|sepia\)\s*(" end=")" oneline contains=cssValueInteger,cssValueNumber,cssValueLength,cssValueAngle,cssFunctionComma
syn keyword cssGradientAttr contained top bottom left right cover center middle ellipse at
@@ -220,7 +222,7 @@ syn keyword cssFlexibleBoxProp contained order
syn match cssFlexibleBoxAttr contained "\<\(row\|column\|wrap\)\(-reverse\)\=\>"
syn keyword cssFlexibleBoxAttr contained nowrap stretch baseline center
syn match cssFlexibleBoxAttr contained "\<flex\(-\(start\|end\)\)\=\>"
-syn match cssFlexibleBoxAttr contained "\<space\(-\(between\|around\)\)\=\>"
+syn match cssFlexibleBoxAttr contained "\<space\(-\(between\|around\|evenly\)\)\=\>"
" CSS Fonts Module Level 3
" http://www.w3.org/TR/css-fonts-3/
@@ -234,9 +236,7 @@ syn keyword cssFontAttr contained larger smaller
syn match cssFontAttr contained "\<\(x\{1,2\}-\)\=\(large\|small\)\>"
syn match cssFontAttr contained "\<small-\(caps\|caption\)\>"
" font-family attributes
-syn match cssFontAttr contained "\<\(sans-\)\=serif\>"
-syn keyword cssFontAttr contained Antiqua Arial Black Book Charcoal Comic Courier Dingbats Gadget Geneva Georgia Grande Helvetica Impact Linotype Lucida MS Monaco Neue New Palatino Roboto Roman Symbol Tahoma Times Trebuchet Verdana Webdings Wingdings York Zapf
-syn keyword cssFontAttr contained cursive fantasy monospace
+syn keyword cssFontAttr contained sans-serif serif cursive fantasy monospace
" font-feature-settings attributes
syn keyword cssFontAttr contained on off
" font-stretch attributes
@@ -283,6 +283,7 @@ syn match cssGridProp contained "\<grid\>"
syn match cssGridProp contained "\<grid-template\(-\(columns\|rows\|areas\)\)\=\>"
syn match cssGridProp contained "\<grid-\(column\|row\)\(-\(start\|end\|gap\)\)\=\>"
syn match cssGridProp contained "\<grid-\(area\|gap\)\>"
+syn match cssGridProp contained "\<gap\>"
syn match cssGridProp contained "\<grid-auto-\(flow\|rows\|columns\)\>"
syn match cssHyerlinkProp contained "\<target\(-\(name\|new\|position\)\)\=\>"
@@ -294,6 +295,10 @@ syn match cssListAttr contained "\<\(decimal\(-leading-zero\)\=\|cjk-ideographic
syn keyword cssListAttr contained disc circle square hebrew armenian georgian
syn keyword cssListAttr contained inside outside
+" object-fit https://www.w3.org/TR/css-images-3/#the-object-fit
+syn match cssObjectProp contained "\<object-\(fit\|position\)\>"
+syn keyword cssObjectAttr contained fill contain cover scale-down
+
syn keyword cssPositioningProp contained bottom clear clip display float left
syn keyword cssPositioningProp contained position right top visibility
syn match cssPositioningProp contained "\<z-index\>"
@@ -303,7 +308,7 @@ syn keyword cssPositioningAttr contained left right both
syn match cssPositioningAttr contained "\<list-item\>"
syn match cssPositioningAttr contained "\<inline\(-\(block\|box\|table\|grid\|flex\)\)\=\>"
syn match cssPositioningAttr contained "\<flow\(-root\)\=\>"
-syn keyword cssPositioningAttr contained static relative absolute fixed subgrid
+syn keyword cssPositioningAttr contained static relative absolute fixed subgrid sticky
syn keyword cssPrintAttr contained landscape portrait crop cross always
@@ -548,6 +553,7 @@ hi def link cssMarqueeProp cssProp
hi def link cssMultiColumnProp cssProp
hi def link cssPagedMediaProp cssProp
hi def link cssPositioningProp cssProp
+hi def link cssObjectProp cssProp
hi def link cssPrintProp cssProp
hi def link cssRubyProp cssProp
hi def link cssSpeechProp cssProp
@@ -581,6 +587,7 @@ hi def link cssMultiColumnAttr cssAttr
hi def link cssPaddingAttr cssAttr
hi def link cssPagedMediaAttr cssAttr
hi def link cssPositioningAttr cssAttr
+hi def link cssObjectAttr cssAttr
hi def link cssGradientAttr cssAttr
hi def link cssPrintAttr cssAttr
hi def link cssRubyAttr cssAttr
diff --git a/runtime/syntax/tcsh.vim b/runtime/syntax/tcsh.vim
index 27c6417fd0..6837125129 100644
--- a/runtime/syntax/tcsh.vim
+++ b/runtime/syntax/tcsh.vim
@@ -1,8 +1,9 @@
-" tcsh.vim: Vim syntax file for tcsh scripts
-" Maintainer: Doug Kearns <dougkearns@NoSpam.com> where NoSpam=gmail
-" Author: Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail
-" Modified: Sun 26 Sep 2021 12:40:55 PM EDT
-"
+" Vim syntax file
+" Language: tcsh scripts
+" Maintainer: Doug Kearns <dougkearns@gmail.com>
+" Previous Maintainer: Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail (Original Author)
+" Last Change: 2021 Oct 15
+
" Description: We break up each statement into a "command" and an "end" part.
" All groups are either a "command" or part of the "end" of a statement (ie
" everything after the "command"). This is because blindly highlighting tcsh
@@ -20,36 +21,36 @@ endif
let s:oldcpo = &cpo
set cpo&vim " Line continuation is used
-setlocal iskeyword+=-
+syn iskeyword @,48-57,_,192-255,-
syn case match
-" ----- Clusters -----
+" ----- Clusters ----- {{{1
syn cluster tcshModifiers contains=tcshModifier,tcshModifierError
syn cluster tcshQuoteList contains=tcshDQuote,tcshSQuote,tcshBQuote
-syn cluster tcshStatementEnds contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshRedir,tcshMeta,tcshHereDoc,tcshSpecial,tcshArguement
+syn cluster tcshStatementEnds contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshRedir,tcshMeta,tcshHereDoc,tcshSpecial,tcshArgument
syn cluster tcshStatements contains=tcshBuiltin,tcshCommands,tcshIf,tcshWhile
syn cluster tcshVarList contains=tcshUsrVar,tcshArgv,tcshSubst
syn cluster tcshConditions contains=tcshCmdSubst,tcshParenExpr,tcshOperator,tcshNumber,@tcshVarList
-" ----- Errors -----
+" ----- Errors ----- {{{1
" Define first, so can be easily overridden.
syn match tcshError contained '\v\S.+'
-" ----- Statements -----
+" ----- Statements ----- {{{1
" Tcsh commands: Any filename / modifiable variable (must be first!)
syn match tcshCommands '\v[a-zA-Z0-9\\./_$:-]+' contains=tcshSpecial,tcshUsrVar,tcshArgv,tcshVarError nextgroup=tcshStatementEnd
" Builtin commands except those treated specially. Currently (un)set(env),
" (un)alias, if, while, else, bindkey
-syn keyword tcshBuiltin nextgroup=tcshStatementEnd alloc bg break breaksw builtins bye case cd chdir complete continue default dirs echo echotc end endif endsw eval exec exit fg filetest foreach getspath getxvers glob goto hashstat history hup inlib jobs kill limit log login logout ls ls-F migrate newgrp nice nohup notify onintr popd printenv pushd rehash repeat rootnode sched setpath setspath settc setty setxvers shift source stop suspend switch telltc time umask uncomplete unhash universe unlimit ver wait warp watchlog where which
+syn keyword tcshBuiltin nextgroup=tcshStatementEnd alloc bg break breaksw builtins bye case cd chdir complete continue default dirs echo echotc end endif endsw eval exec exit fg filetest foreach getspath getxvers glob goto hashstat history hup inlib jobs kill limit log login logout ls ls-F migrate newgrp nice nohup notify onintr popd printenv pushd rehash repeat rootnode sched setpath setspath settc setty setxvers shift source stop suspend switch telltc termname time umask uncomplete unhash universe unlimit ver wait warp watchlog where which
" StatementEnd is anything after a built-in / command till the lexical end of a
" statement (;, |, ||, |&, && or end of line)
syn region tcshStatementEnd transparent contained matchgroup=tcshBuiltin start='' end='\v\\@<!(;|\|[|&]?|\&\&|$)' contains=@tcshStatementEnds
" set expressions (Contains shell variables)
-syn keyword tcshShellVar contained afsuser ampm argv autocorrect autoexpand autolist autologout backslash_quote catalog cdpath color colorcat command complete continue continue_args correct cwd dextract dirsfile dirstack dspmbyte dunique echo echo_style edit ellipsis fignore filec gid group histchars histdup histfile histlit history home ignoreeof implicitcd inputmode killdup killring listflags listjobs listlinks listmax listmaxrows loginsh logout mail matchbeep nobeep noclobber noding noglob nokanji nonomatch nostat notify oid owd path printexitvalue prompt prompt2 prompt3 promptchars pushdtohome pushdsilent recexact recognize_only_executables rmstar rprompt savedirs savehist sched shell shlvl status symlinks tcsh term time tperiod tty uid user verbose version visiblebell watch who wordchars
+syn keyword tcshShellVar contained addsuffix afsuser ampm anyerror argv autocorrect autoexpand autolist autologout autorehash backslash_quote catalog cdpath cdtohome color colorcat command compat_expr complete continue continue_args correct csubstnonl cwd dextract dirsfile dirstack dspmbyte dunique echo echo_style edit editors ellipsis euid euser fignore filec gid globdot globstar group highlight histchars histdup histfile histlit history home ignoreeof implicitcd inputmode killdup killring listflags listjobs listlinks listmax listmaxrows loginsh logout mail matchbeep nobeep noclobber noding noglob nokanji nonomatch nostat notify oid owd padhour parseoctal path printexitvalue prompt prompt2 prompt3 promptchars pushdtohome pushdsilent recexact recognize_only_executables rmstar rprompt savedirs savehist sched shell shlvl status symlinks tcsh term time tperiod tty uid user verbose version vimode visiblebell watch who wordchars
syn keyword tcshBuiltin nextgroup=tcshSetEnd set unset
syn region tcshSetEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$\|;' contains=tcshShellVar,@tcshStatementEnds
@@ -96,14 +97,15 @@ syn keyword tcshBindkeyFuncs contained backward-char backward-delete-char
\ history-search-forward insert-last-word i-search-fwd
\ i-search-back keyboard-quit kill-line kill-region
\ kill-whole-line list-choices list-choices-raw list-glob
- \ list-or-eof load-average magic-space newline normalize-path
- \ normalize-command overwrite-mode prefix-meta quoted-insert
- \ redisplay run-fg-editor run-help self-insert-command
- \ sequence-lead-in set-mark-command spell-word spell-line
- \ stuff-char toggle-literal-history transpose-chars
- \ transpose-gosling tty-dsusp tty-flush-output tty-sigintr
- \ tty-sigquit tty-sigtsusp tty-start-output tty-stop-output
- \ undefined-key universal-argument up-history upcase-word
+ \ list-or-eof load-average magic-space newline newline-and-hold
+ \ newline-and-down-history normalize-path normalize-command
+ \ overwrite-mode prefix-meta quoted-insert redisplay
+ \ run-fg-editor run-help self-insert-command sequence-lead-in
+ \ set-mark-command spell-word spell-line stuff-char
+ \ toggle-literal-history transpose-chars transpose-gosling
+ \ tty-dsusp tty-flush-output tty-sigintr tty-sigquit tty-sigtsusp
+ \ tty-start-output tty-stop-output undefined-key
+ \ universal-argument up-history upcase-word
\ vi-beginning-of-next-word vi-add vi-add-at-eol vi-chg-case
\ vi-chg-meta vi-chg-to-eol vi-cmd-mode vi-cmd-mode-complete
\ vi-delprev vi-delmeta vi-endword vi-eword vi-char-back
@@ -116,7 +118,7 @@ syn keyword tcshBindkeyFuncs contained backward-char backward-delete-char
\ e_paste_from_clipboard e_dosify_next e_dosify_prev e_page_up
\ e_page_down
syn keyword tcshBuiltin nextgroup=tcshBindkeyEnd bindkey
-syn region tcshBindkeyEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$' contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshMeta,tcshSpecial,tcshArguement,tcshBindkeyFuncs
+syn region tcshBindkeyEnd contained transparent matchgroup=tcshBuiltin start='' skip='\\$' end='$' contains=@tcshQuoteList,tcshComment,@tcshVarList,tcshMeta,tcshSpecial,tcshArgument,tcshBindkeyFuncs
" Expressions start with @.
syn match tcshExprStart '\v\@\s+' nextgroup=tcshExprVar
@@ -126,20 +128,20 @@ syn match tcshExprOp contained '\v\s*\=' nextgroup=tcshExprEnd
syn match tcshExprEnd contained '\v.*$'hs=e+1 contains=@tcshConditions
syn match tcshExprEnd contained '\v.{-};'hs=e contains=@tcshConditions
-" ----- Comments: -----
+" ----- Comments: ----- {{{1
syn match tcshComment '#\s.*' contains=tcshTodo,tcshCommentTi,@Spell
syn match tcshComment '\v#($|\S.*)' contains=tcshTodo,tcshCommentTi
syn match tcshSharpBang '^#! .*$'
syn match tcshCommentTi contained '\v#\s*\u\w*(\s+\u\w*)*:'hs=s+1 contains=tcshTodo
syn match tcshTodo contained '\v\c<todo>'
-" ----- Strings -----
+" ----- Strings ----- {{{1
" Tcsh does not allow \" in strings unless the "backslash_quote" shell
" variable is set. Set the vim variable "tcsh_backslash_quote" to 0 if you
" want VIM to assume that no backslash quote constructs exist.
" Backquotes are treated as commands, and are not contained in anything
-if(exists('tcsh_backslash_quote') && tcsh_backslash_quote == 0)
+if exists('tcsh_backslash_quote') && tcsh_backslash_quote == 0
syn region tcshSQuote keepend contained start="\v\\@<!'" end="'"
syn region tcshDQuote keepend contained start='\v\\@<!"' end='"' contains=@tcshVarList,tcshSpecial,@Spell
syn region tcshBQuote keepend start='\v\\@<!`' end='`' contains=@tcshStatements
@@ -149,7 +151,7 @@ else
syn region tcshBQuote keepend matchgroup=tcshBQuoteGrp start='\v\\@<!`' skip='\v\\\\|\\`' end='`' contains=@tcshStatements
endif
-" ----- Variables -----
+" ----- Variables ----- {{{1
" Variable Errors. Must come first! \$ constructs will be flagged by
" tcshSpecial, so we don't consider them here.
syn match tcshVarError '\v\$\S*' contained
@@ -171,7 +173,7 @@ syn match tcshSubst contained '\v\$\{[%#?]%(\h\w*|\d+)%(:\S*)?\}' contains=tcshM
syn match tcshModifierError contained '\v:\S*'
syn match tcshModifier contained '\v:[ag]?[htreuls&qx]' nextgroup=@tcshModifiers
-" ----- Operators / Specials -----
+" ----- Operators / Specials ----- {{{1
" Standard redirects (except <<) [<, >, >>, >>&, >>!, >>&!]
syn match tcshRedir contained '\v\<|\>\>?\&?!?'
@@ -190,13 +192,13 @@ syn match tcshOperator contained '&&\|!\~\|!=\|<<\|<=\|==\|=\~\|>=\|>>\|\*\|\^\|
syn match tcshNumber contained '\v<-?\d+>'
" Arguments
-syn match tcshArguement contained '\v\s@<=-(\w|-)*'
+syn match tcshArgument contained '\v\s@<=-(\w|-)*'
" Special characters. \xxx, or backslashed characters.
"syn match tcshSpecial contained '\v\\@<!\\(\d{3}|.)'
syn match tcshSpecial contained '\v\\%([0-7]{3}|.)'
-" ----- Synchronising -----
+" ----- Synchronising ----- {{{1
if exists('tcsh_minlines')
if tcsh_minlines == 'fromstart'
syn sync fromstart
@@ -207,6 +209,7 @@ else
syn sync minlines=100 " Some completions can be quite long
endif
+" ----- Highlighting ----- {{{1
" Define highlighting of syntax groups
hi def link tcshError Error
hi def link tcshBuiltin Statement
@@ -233,17 +236,20 @@ hi def link tcshVarError Error
hi def link tcshUsrVar Type
hi def link tcshArgv tcshUsrVar
hi def link tcshSubst tcshUsrVar
-hi def link tcshModifier tcshArguement
+hi def link tcshModifier tcshArgument
hi def link tcshModifierError tcshVarError
hi def link tcshMeta tcshSubst
hi def link tcshRedir tcshOperator
hi def link tcshHereDoc tcshSQuote
hi def link tcshOperator Operator
hi def link tcshNumber Number
-hi def link tcshArguement Special
+hi def link tcshArgument Special
hi def link tcshSpecial SpecialChar
+" }}}
let &cpo = s:oldcpo
unlet s:oldcpo
let b:current_syntax = 'tcsh'
+
+" vim: nowrap sw=2 sts=2 ts=8 noet fdm=marker:
diff --git a/runtime/syntax/tmux.vim b/runtime/syntax/tmux.vim
index 4f435ab923..867c033cb5 100644
--- a/runtime/syntax/tmux.vim
+++ b/runtime/syntax/tmux.vim
@@ -1,5 +1,5 @@
" Language: tmux(1) configuration file
-" Version: 3.0 (git-48cbbb87)
+" Version: 3.2a (git-44ada9cd)
" URL: https://github.com/ericpruitt/tmux.vim/
" Maintainer: Eric Pruitt <eric.pruitt@gmail.com>
" License: 2-Clause BSD (http://opensource.org/licenses/BSD-2-Clause)
@@ -30,14 +30,14 @@ syn match tmuxVariable /\w\+=/ display
syn match tmuxVariableExpansion /\${\=\w\+}\=/ display
syn match tmuxControl /%\(if\|elif\|else\|endif\)/
-syn region tmuxComment start=/#/ skip=/\\\@<!\\$/ end=/$/ contains=tmuxTodo
+syn region tmuxComment start=/#/ skip=/\\\@<!\\$/ end=/$/ contains=tmuxTodo,@Spell
-syn region tmuxString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=tmuxFormatString
-syn region tmuxString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end='$' contains=tmuxFormatString
+syn region tmuxString start=+"+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=tmuxFormatString,@Spell
+syn region tmuxString start=+'+ skip=+\\\\\|\\'\|\\$+ excludenl end=+'+ end='$' contains=tmuxFormatString,@Spell
" TODO: Figure out how escaping works inside of #(...) and #{...} blocks.
syn region tmuxFormatString start=/#[#DFhHIPSTW]/ end=// contained keepend
-syn region tmuxFormatString start=/#{/ skip=/#{.\{-}}/ end=/}/ contained keepend
+syn region tmuxFormatString start=/#{/ skip=/#{.\{-}}/ end=/}/ keepend
syn region tmuxFormatString start=/#(/ skip=/#(.\{-})/ end=/)/ contained keepend
hi def link tmuxFormatString Identifier
@@ -55,62 +55,69 @@ hi def link tmuxTodo Todo
hi def link tmuxVariable Identifier
hi def link tmuxVariableExpansion Identifier
-" Make the foreground of colourXXX keywords match the color they represent.
+" Make the foreground of colourXXX keywords match the color they represent
+" when g:tmux_syntax_colors is unset or set to a non-zero value.
" Darker colors have their background set to white.
-for s:i in range(0, 255)
- let s:bg = (!s:i || s:i == 16 || (s:i > 231 && s:i < 235)) ? 15 : "none"
- exec "syn match tmuxColour" . s:i . " /\\<colour" . s:i . "\\>/ display"
-\ " | highlight tmuxColour" . s:i . " ctermfg=" . s:i . " ctermbg=" . s:bg
-endfor
+if get(g:, "tmux_syntax_colors", 1)
+ for s:i in range(0, 255)
+ let s:bg = (!s:i || s:i == 16 || (s:i > 231 && s:i < 235)) ? 15 : "none"
+ exec "syn match tmuxColour" . s:i . " /\\<colour" . s:i . "\\>/ display"
+\ " | highlight tmuxColour" . s:i . " ctermfg=" . s:i . " ctermbg=" . s:bg
+ endfor
+endif
syn keyword tmuxOptions
-\ backspace buffer-limit command-alias default-terminal escape-time
-\ exit-empty activity-action assume-paste-time base-index bell-action
-\ default-command default-shell default-size destroy-unattached
+\ backspace buffer-limit command-alias copy-command default-terminal editor
+\ escape-time exit-empty activity-action assume-paste-time base-index
+\ bell-action default-command default-shell default-size destroy-unattached
\ detach-on-destroy display-panes-active-colour display-panes-colour
-\ display-panes-time display-time exit-unattached focus-events history-file
-\ history-limit key-table lock-after-time lock-command message-command-style
-\ message-limit message-style aggressive-resize allow-rename
-\ alternate-screen automatic-rename automatic-rename-format
-\ clock-mode-colour clock-mode-style main-pane-height main-pane-width
-\ mode-keys mode-style monitor-activity monitor-bell monitor-silence mouse
-\ other-pane-height other-pane-width pane-active-border-style
-\ pane-base-index pane-border-format pane-border-status pane-border-style
-\ prefix prefix2 remain-on-exit renumber-windows repeat-time set-clipboard
-\ set-titles set-titles-string silence-action status status-bg status-fg
-\ status-format status-interval status-justify status-keys status-left
-\ status-left-length status-left-style status-position status-right
-\ status-right-length status-right-style status-style synchronize-panes
-\ terminal-overrides update-environment user-keys visual-activity
-\ visual-bell visual-silence window-active-style window-size
-\ window-status-activity-style window-status-bell-style
+\ display-panes-time display-time exit-unattached extended-keys focus-events
+\ history-file history-limit key-table lock-after-time lock-command
+\ message-command-style message-limit message-style aggressive-resize
+\ allow-rename alternate-screen automatic-rename automatic-rename-format
+\ clock-mode-colour clock-mode-style copy-mode-current-match-style
+\ copy-mode-mark-style copy-mode-match-style main-pane-height
+\ main-pane-width mode-keys mode-style monitor-activity monitor-bell
+\ monitor-silence mouse other-pane-height other-pane-width
+\ pane-active-border-style pane-base-index pane-border-format
+\ pane-border-lines pane-border-status pane-border-style pane-colours prefix
+\ prefix2 prompt-history-limit remain-on-exit renumber-windows repeat-time
+\ set-clipboard set-titles set-titles-string silence-action status status-bg
+\ status-fg status-format status-interval status-justify status-keys
+\ status-left status-left-length status-left-style status-position
+\ status-right status-right-length status-right-style status-style
+\ synchronize-panes terminal-features terminal-overrides update-environment
+\ user-keys visual-activity visual-bell visual-silence window-active-style
+\ window-size window-status-activity-style window-status-bell-style
\ window-status-current-format window-status-current-style
\ window-status-format window-status-last-style window-status-separator
-\ window-status-style window-style word-separators wrap-search xterm-keys
+\ window-status-style window-style word-separators wrap-search
syn keyword tmuxCommands
\ attach attach-session bind bind-key break-pane breakp capture-pane
\ capturep choose-buffer choose-client choose-tree clear-history clearhist
-\ clock-mode command-prompt confirm confirm-before copy-mode detach
-\ detach-client display display-menu display-message display-panes displayp
-\ find-window findw if if-shell join-pane joinp kill-pane kill-server
-\ kill-session kill-window killp has-session has killw link-window linkw
-\ list-buffers list-clients list-commands list-keys list-panes list-sessions
-\ list-windows load-buffer loadb lock lock-client lock-server lock-session
-\ lockc last-pane lastp locks ls last-window last lsb lsc delete-buffer
-\ deleteb lscm lsk lsp lsw menu move-pane move-window movep movew new
-\ new-session new-window neww next next-layout next-window nextl
-\ paste-buffer pasteb pipe-pane pipep prev previous-layout previous-window
-\ prevl refresh refresh-client rename rename-session rename-window renamew
-\ resize-pane resize-window resizep resizew respawn-pane respawn-window
-\ respawnp respawnw rotate-window rotatew run run-shell save-buffer saveb
+\ clock-mode command-prompt confirm confirm-before copy-mode customize-mode
+\ detach detach-client display display-menu display-message display-panes
+\ display-popup displayp find-window findw if if-shell join-pane joinp
+\ kill-pane kill-server kill-session kill-window killp has has-session killw
+\ link-window linkw list-buffers list-clients list-commands list-keys
+\ list-panes list-sessions list-windows load-buffer loadb lock lock-client
+\ lock-server lock-session lockc last-pane lastp locks ls last last-window
+\ lsb delete-buffer deleteb lsc lscm lsk lsp lsw menu move-pane move-window
+\ clear-prompt-history clearphist movep movew new new-session new-window
+\ neww next next-layout next-window nextl paste-buffer pasteb pipe-pane
+\ pipep popup prev previous-layout previous-window prevl refresh
+\ refresh-client rename rename-session rename-window renamew resize-pane
+\ resize-window resizep resizew respawn-pane respawn-window respawnp
+\ respawnw rotate-window rotatew run run-shell save-buffer saveb
\ select-layout select-pane select-window selectl selectp selectw send
\ send-keys send-prefix set set-buffer set-environment set-hook set-option
\ set-window-option setb setenv setw show show-buffer show-environment
-\ show-hooks show-messages show-options show-window-options showb showenv
-\ showmsgs showw source source-file split-window splitw start start-server
-\ suspend-client suspendc swap-pane swap-window swapp swapw switch-client
-\ switchc unbind unbind-key unlink-window unlinkw wait wait-for
+\ show-hooks show-messages show-options show-prompt-history
+\ show-window-options showb showenv showmsgs showphist showw source
+\ source-file split-window splitw start start-server suspend-client suspendc
+\ swap-pane swap-window swapp swapw switch-client switchc unbind unbind-key
+\ unlink-window unlinkw wait wait-for
let &cpo = s:original_cpo
unlet! s:original_cpo s:bg s:i
diff --git a/runtime/syntax/toml.vim b/runtime/syntax/toml.vim
new file mode 100644
index 0000000000..bcb1b0b9c9
--- /dev/null
+++ b/runtime/syntax/toml.vim
@@ -0,0 +1,81 @@
+" Vim syntax file
+" Language: TOML
+" Homepage: https://github.com/cespare/vim-toml
+" Maintainer: Aman Verma
+" Previous Maintainer: Caleb Spare <cespare@gmail.com>
+" Last Change: Oct 8, 2021
+
+if exists('b:current_syntax')
+ finish
+endif
+
+syn match tomlEscape /\\[btnfr"/\\]/ display contained
+syn match tomlEscape /\\u\x\{4}/ contained
+syn match tomlEscape /\\U\x\{8}/ contained
+syn match tomlLineEscape /\\$/ contained
+
+" Basic strings
+syn region tomlString oneline start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=tomlEscape
+" Multi-line basic strings
+syn region tomlString start=/"""/ end=/"""/ contains=tomlEscape,tomlLineEscape
+" Literal strings
+syn region tomlString oneline start=/'/ end=/'/
+" Multi-line literal strings
+syn region tomlString start=/'''/ end=/'''/
+
+syn match tomlInteger /[+-]\=\<[1-9]\(_\=\d\)*\>/ display
+syn match tomlInteger /[+-]\=\<0\>/ display
+syn match tomlInteger /[+-]\=\<0x[[:xdigit:]]\(_\=[[:xdigit:]]\)*\>/ display
+syn match tomlInteger /[+-]\=\<0o[0-7]\(_\=[0-7]\)*\>/ display
+syn match tomlInteger /[+-]\=\<0b[01]\(_\=[01]\)*\>/ display
+syn match tomlInteger /[+-]\=\<\(inf\|nan\)\>/ display
+
+syn match tomlFloat /[+-]\=\<\d\(_\=\d\)*\.\d\+\>/ display
+syn match tomlFloat /[+-]\=\<\d\(_\=\d\)*\(\.\d\(_\=\d\)*\)\=[eE][+-]\=\d\(_\=\d\)*\>/ display
+
+syn match tomlBoolean /\<\%(true\|false\)\>/ display
+
+" https://tools.ietf.org/html/rfc3339
+syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}/ display
+syn match tomlDate /\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?/ display
+syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}[T ]\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?\%(Z\|[+-]\d\{2\}:\d\{2\}\)\?/ display
+
+syn match tomlDotInKey /\v[^.]+\zs\./ contained display
+syn match tomlKey /\v(^|[{,])\s*\zs[[:alnum:]._-]+\ze\s*\=/ contains=tomlDotInKey display
+syn region tomlKeyDq oneline start=/\v(^|[{,])\s*\zs"/ end=/"\ze\s*=/ contains=tomlEscape
+syn region tomlKeySq oneline start=/\v(^|[{,])\s*\zs'/ end=/'\ze\s*=/
+
+syn region tomlTable oneline start=/^\s*\[[^\[]/ end=/\]/ contains=tomlKey,tomlKeyDq,tomlKeySq,tomlDotInKey
+
+syn region tomlTableArray oneline start=/^\s*\[\[/ end=/\]\]/ contains=tomlKey,tomlKeyDq,tomlKeySq,tomlDotInKey
+
+syn region tomlKeyValueArray start=/=\s*\[\zs/ end=/\]/ contains=@tomlValue
+
+syn region tomlArray start=/\[/ end=/\]/ contains=@tomlValue contained
+
+syn cluster tomlValue contains=tomlArray,tomlString,tomlInteger,tomlFloat,tomlBoolean,tomlDate,tomlComment
+
+syn keyword tomlTodo TODO FIXME XXX BUG contained
+
+syn match tomlComment /#.*/ contains=@Spell,tomlTodo
+
+hi def link tomlComment Comment
+hi def link tomlTodo Todo
+hi def link tomlTableArray Title
+hi def link tomlTable Title
+hi def link tomlDotInKey Normal
+hi def link tomlKeySq Identifier
+hi def link tomlKeyDq Identifier
+hi def link tomlKey Identifier
+hi def link tomlDate Constant
+hi def link tomlBoolean Boolean
+hi def link tomlFloat Float
+hi def link tomlInteger Number
+hi def link tomlString String
+hi def link tomlLineEscape SpecialChar
+hi def link tomlEscape SpecialChar
+
+syn sync minlines=500
+let b:current_syntax = 'toml'
+
+" vim: et sw=2 sts=2
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index 76ce9e15ea..a430d56168 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -48,5 +48,8 @@ return {
"style";
"noautocmd";
};
+ runtime = {
+ "is_lua";
+ };
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 44552bcb26..847e142939 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -756,6 +756,11 @@ ArrayOf(String) nvim_list_runtime_paths(Error *err)
return nvim_get_runtime_file(NULL_STRING, true, err);
}
+Array nvim__runtime_inspect(void)
+{
+ return runtime_inspect();
+}
+
/// Find files in runtime directories
///
/// 'name' can contain wildcards. For example
@@ -794,6 +799,25 @@ String nvim__get_lib_dir(void)
return cstr_as_string(get_lib_dir());
}
+/// Find files in runtime directories
+///
+/// @param pat pattern of files to search for
+/// @param all whether to return all matches or only the first
+/// @param options
+/// is_lua: only search lua subdirs
+/// @return list of absolute paths to the found files
+ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, Error *err)
+ FUNC_API_SINCE(8)
+ FUNC_API_FAST
+{
+ bool is_lua = api_object_to_bool(opts->is_lua, "is_lua", false, err);
+ if (ERROR_SET(err)) {
+ return (Array)ARRAY_DICT_INIT;
+ }
+ return runtime_get_named(is_lua, pat, all);
+}
+
+
/// Changes the global working directory.
///
/// @param dir Directory path
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 37cc854959..826a197454 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -526,8 +526,8 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
diff_buf_delete(buf); // Clear 'diff' for hidden buffer.
}
- /* Return when a window is displaying the buffer or when it's not
- * unloaded. */
+ // Return when a window is displaying the buffer or when it's not
+ // unloaded.
if (buf->b_nwindows > 0 || !unload_buf) {
return false;
}
@@ -593,9 +593,6 @@ bool close_buffer(win_T *win, buf_T *buf, int action, bool abort_if_last)
buf->b_nwindows--;
}
- // Change directories when the 'acd' option is set.
- do_autochdir();
-
// Disable buffer-updates for the current buffer.
// No need to check `unload_buf`: in that case the function returned above.
buf_updates_unload(buf, false);
@@ -1591,8 +1588,8 @@ void enter_buffer(buf_T *buf)
apply_autocmds(EVENT_BUFWINENTER, NULL, NULL, false, curbuf);
}
- /* If autocommands did not change the cursor position, restore cursor lnum
- * and possibly cursor col. */
+ // If autocommands did not change the cursor position, restore cursor lnum
+ // and possibly cursor col.
if (curwin->w_cursor.lnum == 1 && inindent(0)) {
buflist_getfpos();
}
@@ -1628,7 +1625,7 @@ void do_autochdir(void)
if (p_acd) {
if (starting == 0
&& curbuf->b_ffname != NULL
- && vim_chdirfile(curbuf->b_ffname) == OK) {
+ && vim_chdirfile(curbuf->b_ffname, kCdCauseAuto) == OK) {
post_chdir(kCdScopeGlobal, false);
shorten_fnames(true);
}
@@ -1754,8 +1751,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl
if ((flags & BLN_CURBUF) && curbuf_reusable()) {
assert(curbuf != NULL);
buf = curbuf;
- /* It's like this buffer is deleted. Watch out for autocommands that
- * change curbuf! If that happens, allocate a new buffer anyway. */
+ // It's like this buffer is deleted. Watch out for autocommands that
+ // change curbuf! If that happens, allocate a new buffer anyway.
if (curbuf->b_p_bl) {
apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf);
}
@@ -2257,8 +2254,8 @@ int buflist_findpat(const char_u *pattern, const char_u *pattern_end, bool unlis
}
}
- /* Only search for unlisted buffers if there was no match with
- * a listed buffer. */
+ // Only search for unlisted buffers if there was no match with
+ // a listed buffer.
if (!unlisted || !find_listed || match != -1) {
break;
}
@@ -2893,8 +2890,8 @@ void buf_set_name(int fnum, char_u *name)
xfree(buf->b_ffname);
buf->b_ffname = vim_strsave(name);
buf->b_sfname = NULL;
- /* Allocate ffname and expand into full path. Also resolves .lnk
- * files on Win32. */
+ // Allocate ffname and expand into full path. Also resolves .lnk
+ // files on Win32.
fname_expand(buf, &buf->b_ffname, &buf->b_sfname);
buf->b_fname = buf->b_sfname;
}
@@ -3166,8 +3163,8 @@ void fileinfo(int fullname, int shorthelp, int dont_truncate)
(void)append_arg_number(curwin, buffer, IOSIZE, !shortmess(SHM_FILE));
if (dont_truncate) {
- /* Temporarily set msg_scroll to avoid the message being truncated.
- * First call msg_start() to get the message in the right place. */
+ // Temporarily set msg_scroll to avoid the message being truncated.
+ // First call msg_start() to get the message in the right place.
msg_start();
n = msg_scroll;
msg_scroll = true;
@@ -5233,8 +5230,8 @@ void do_modelines(int flags)
return;
}
- /* Disallow recursive entry here. Can happen when executing a modeline
- * triggers an autocommand, which reloads modelines with a ":do". */
+ // Disallow recursive entry here. Can happen when executing a modeline
+ // triggers an autocommand, which reloads modelines with a ":do".
if (entered) {
return;
}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 2c411553b8..19b0a3c5c6 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -953,6 +953,7 @@ struct tabpage_S {
ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
dict_T *tp_vars; ///< Internal variables, local to tab page.
char_u *tp_localdir; ///< Absolute path of local cwd or NULL.
+ char_u *tp_prevdir; ///< Previous directory.
};
/*
@@ -1381,8 +1382,8 @@ struct window_S {
// out of range!)
int w_arg_idx_invalid; // editing another file than w_arg_idx
- char_u *w_localdir; /* absolute path of local directory or
- NULL */
+ char_u *w_localdir; // absolute path of local directory or NULL
+ char_u *w_prevdir; // previous directory
// Options local to a window.
// They are local because they influence the layout of the window or
// depend on the window layout.
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index b19ea36bd5..e6a3901dcf 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -9191,8 +9191,12 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, cons
} else if (*name == 'l' && funccal != NULL) { // local variable
*d = &funccal->l_vars;
} else if (*name == 's' // script variable
- && current_sctx.sc_sid > 0
+ && (current_sctx.sc_sid > 0 || current_sctx.sc_sid == SID_STR)
&& current_sctx.sc_sid <= ga_scripts.ga_len) {
+ // For anonymous scripts without a script item, create one now so script vars can be used
+ if (current_sctx.sc_sid == SID_STR) {
+ new_script_item(NULL, &current_sctx.sc_sid);
+ }
*d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict;
}
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 70aa2bb1f8..dfc51d80af 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -72,6 +72,7 @@ return {
chansend={args=2},
char2nr={args={1, 2}, base=1},
charidx={args={2, 3}},
+ chdir={args=1, base=1},
cindent={args=1, base=1},
clearmatches={args={0, 1}, base=1},
col={args=1, base=1},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index da129c1170..5c22bf0f8f 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -28,6 +28,7 @@
#include "nvim/file_search.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/globals.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
@@ -1062,6 +1063,45 @@ static void f_charidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
rettv->vval.v_number = len > 0 ? len - 1 : 0;
}
+// "chdir(dir)" function
+static void f_chdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char_u *cwd;
+ CdScope scope = kCdScopeGlobal;
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ if (argvars[0].v_type != VAR_STRING) {
+ // Returning an empty string means it failed.
+ // No error message, for historic reasons.
+ return;
+ }
+
+ // Return the current directory
+ cwd = xmalloc(MAXPATHL);
+ if (cwd != NULL) {
+ if (os_dirname(cwd, MAXPATHL) != FAIL) {
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust(cwd);
+#endif
+ rettv->vval.v_string = vim_strsave(cwd);
+ }
+ xfree(cwd);
+ }
+
+ if (curwin->w_localdir != NULL) {
+ scope = kCdScopeWindow;
+ } else if (curtab->tp_localdir != NULL) {
+ scope = kCdScopeTabpage;
+ }
+
+ if (!changedir_func(argvars[0].vval.v_string, scope)) {
+ // Directory change failed
+ XFREE_CLEAR(rettv->vval.v_string);
+ }
+}
+
/*
* "cindent(lnum)" function
*/
@@ -3405,8 +3445,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Numbers of the scope objects (window, tab) we want the working directory
// of. A `-1` means to skip this scope, a `0` means the current object.
int scope_number[] = {
- [kCdScopeWindow] = 0, // Number of window to look at.
- [kCdScopeTab ] = 0, // Number of tab to look at.
+ [kCdScopeWindow ] = 0, // Number of window to look at.
+ [kCdScopeTabpage] = 0, // Number of tab to look at.
};
char_u *cwd = NULL; // Current working directory to print
@@ -3449,8 +3489,8 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Find the tabpage by number
- if (scope_number[kCdScopeTab] > 0) {
- tp = find_tabpage(scope_number[kCdScopeTab]);
+ if (scope_number[kCdScopeTabpage] > 0) {
+ tp = find_tabpage(scope_number[kCdScopeTabpage]);
if (!tp) {
EMSG(_("E5000: Cannot find tab number."));
return;
@@ -3459,7 +3499,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Find the window in `tp` by number, `NULL` if none.
if (scope_number[kCdScopeWindow] >= 0) {
- if (scope_number[kCdScopeTab] < 0) {
+ if (scope_number[kCdScopeTabpage] < 0) {
EMSG(_("E5001: Higher scope cannot be -1 if lower scope is >= 0."));
return;
}
@@ -3483,7 +3523,7 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
FALLTHROUGH;
- case kCdScopeTab:
+ case kCdScopeTabpage:
assert(tp);
from = tp->tp_localdir;
if (from) {
@@ -4612,8 +4652,8 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Numbers of the scope objects (window, tab) we want the working directory
// of. A `-1` means to skip this scope, a `0` means the current object.
int scope_number[] = {
- [kCdScopeWindow] = 0, // Number of window to look at.
- [kCdScopeTab ] = 0, // Number of tab to look at.
+ [kCdScopeWindow ] = 0, // Number of window to look at.
+ [kCdScopeTabpage] = 0, // Number of tab to look at.
};
tabpage_T *tp = curtab; // The tabpage to look at.
@@ -4651,8 +4691,8 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
// Find the tabpage by number
- if (scope_number[kCdScopeTab] > 0) {
- tp = find_tabpage(scope_number[kCdScopeTab]);
+ if (scope_number[kCdScopeTabpage] > 0) {
+ tp = find_tabpage(scope_number[kCdScopeTabpage]);
if (!tp) {
EMSG(_("E5000: Cannot find tab number."));
return;
@@ -4661,7 +4701,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// Find the window in `tp` by number, `NULL` if none.
if (scope_number[kCdScopeWindow] >= 0) {
- if (scope_number[kCdScopeTab] < 0) {
+ if (scope_number[kCdScopeTabpage] < 0) {
EMSG(_("E5001: Higher scope cannot be -1 if lower scope is >= 0."));
return;
}
@@ -4680,7 +4720,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
assert(win);
rettv->vval.v_number = win->w_localdir ? 1 : 0;
break;
- case kCdScopeTab:
+ case kCdScopeTabpage:
assert(tp);
rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
break;
@@ -8480,20 +8520,22 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_list_append_number(rettv->vval.v_list, (varnumber_T)col);
}
-/*
- * Search for a start/middle/end thing.
- * Used by searchpair(), see its documentation for the details.
- * Returns 0 or -1 for no match,
- */
-long do_searchpair(const char *spat, // start pattern
- const char *mpat, // middle pattern
- const char *epat, // end pattern
- int dir, // BACKWARD or FORWARD
- const typval_T *skip, // skip expression
- int flags, // SP_SETPCMARK and other SP_ values
- pos_T *match_pos, linenr_T lnum_stop, // stop at this line if not zero
- long time_limit // stop after this many msec
- )
+/// Search for a start/middle/end thing.
+/// Used by searchpair(), see its documentation for the details.
+///
+/// @param spat start pattern
+/// @param mpat middle pattern
+/// @param epat end pattern
+/// @param dir BACKWARD or FORWARD
+/// @param skip skip expression
+/// @param flags SP_SETPCMARK and other SP_ values
+/// @param lnum_stop stop at this line if not zero
+/// @param time_limit stop after this many msec
+///
+/// @returns 0 or -1 for no match,
+long do_searchpair(const char *spat, const char *mpat, const char *epat, int dir,
+ const typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop,
+ long time_limit)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
{
char_u *save_cpo;
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 657777d7db..f4393a79dc 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -402,15 +402,15 @@ void emsg_funcname(char *ermsg, const char_u *name)
}
}
-/*
- * Allocate a variable for the result of a function.
- * Return OK or FAIL.
- */
-int get_func_tv(const char_u *name, // name of the function
- int len, // length of "name" or -1 to use strlen()
- typval_T *rettv, char_u **arg, // argument, pointing to the '('
- funcexe_T *funcexe // various values
- )
+/// Allocate a variable for the result of a function.
+///
+/// @param name name of the function
+/// @param len length of "name" or -1 to use strlen()
+/// @param arg argument, pointing to the '('
+/// @param funcexe various values
+///
+/// @return OK or FAIL.
+int get_func_tv(const char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe)
{
char_u *argp;
int ret = OK;
@@ -1436,17 +1436,18 @@ static void argv_add_base(typval_T *const basetv, typval_T **const argvars, int
/// Call a function with its resolved parameters
///
+/// @param funcname name of the function
+/// @param len length of "name" or -1 to use strlen()
+/// @param rettv [out] value goes here
+/// @param argcount_in number of "argvars"
+/// @param argvars_in vars for arguments, must have "argcount" PLUS ONE elements!
+/// @param funcexe more arguments
+///
/// @return FAIL if function cannot be called, else OK (even if an error
/// occurred while executing the function! Set `msg_list` to capture
/// the error, see do_cmdline()).
-int call_func(const char_u *funcname, // name of the function
- int len, // length of "name" or -1 to use strlen()
- typval_T *rettv, // [out] value goes here
- int argcount_in, // number of "argvars"
- typval_T *argvars_in, // vars for arguments, must have "argcount"
- // PLUS ONE elements!
- funcexe_T *funcexe // more arguments
- )
+int call_func(const char_u *funcname, int len, typval_T *rettv, int argcount_in,
+ typval_T *argvars_in, funcexe_T *funcexe)
FUNC_ATTR_NONNULL_ARG(1, 3, 5, 6)
{
int ret = FAIL;
@@ -1690,11 +1691,12 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
/// TFN_NO_DEREF: do not dereference a Funcref
/// Advances "pp" to just after the function name (if no error).
///
+/// @param skip only find the end, don't evaluate
+/// @param fdp return: info about dictionary used
+/// @param partial return: partial of a FuncRef
+///
/// @return the function name in allocated memory, or NULL for failure.
-char_u *trans_function_name(char_u **pp, bool skip, // only find the end, don't evaluate
- int flags, funcdict_T *fdp, // return: info about dictionary used
- partial_T **partial // return: partial of a FuncRef
- )
+char_u *trans_function_name(char_u **pp, bool skip, int flags, funcdict_T *fdp, partial_T **partial)
FUNC_ATTR_NONNULL_ARG(1)
{
char_u *name = NULL;
@@ -1709,8 +1711,8 @@ char_u *trans_function_name(char_u **pp, bool skip, // only
}
start = *pp;
- /* Check for hard coded <SNR>: already translated function ID (from a user
- * command). */
+ // Check for hard coded <SNR>: already translated function ID (from a user
+ // command).
if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
&& (*pp)[2] == (int)KE_SNR) {
*pp += 3;
@@ -2032,8 +2034,8 @@ void ex_function(exarg_T *eap)
}
}
- /* An error in a function call during evaluation of an expression in magic
- * braces should not cause the function not to be defined. */
+ // An error in a function call during evaluation of an expression in magic
+ // braces should not cause the function not to be defined.
saved_did_emsg = did_emsg;
did_emsg = FALSE;
@@ -2105,8 +2107,8 @@ void ex_function(exarg_T *eap)
ga_init(&newlines, (int)sizeof(char_u *), 3);
if (!eap->skip) {
- /* Check the name of the function. Unless it's a dictionary function
- * (that we are overwriting). */
+ // Check the name of the function. Unless it's a dictionary function
+ // (that we are overwriting).
if (name != NULL) {
arg = name;
} else {
@@ -2164,8 +2166,8 @@ void ex_function(exarg_T *eap)
}
}
- /* When there is a line break use what follows for the function body.
- * Makes 'exe "func Test()\n...\nendfunc"' work. */
+ // When there is a line break use what follows for the function body.
+ // Makes 'exe "func Test()\n...\nendfunc"' work.
if (*p == '\n') {
line_arg = p + 1;
} else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) {
@@ -2176,9 +2178,9 @@ void ex_function(exarg_T *eap)
* Read the body of the function, until ":endfunction" is found.
*/
if (KeyTyped) {
- /* Check if the function already exists, don't let the user type the
- * whole function before telling him it doesn't work! For a script we
- * need to skip the body to be able to find what follows. */
+ // Check if the function already exists, don't let the user type the
+ // whole function before telling him it doesn't work! For a script we
+ // need to skip the body to be able to find what follows.
if (!eap->skip && !eap->forceit) {
if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) {
EMSG(_(e_funcdict));
@@ -2305,8 +2307,8 @@ void ex_function(exarg_T *eap)
break;
}
- /* Increase indent inside "if", "while", "for" and "try", decrease
- * at "end". */
+ // Increase indent inside "if", "while", "for" and "try", decrease
+ // at "end".
if (indent > 2 && STRNCMP(p, "end", 3) == 0) {
indent -= 2;
} else if (STRNCMP(p, "if", 2) == 0
@@ -2421,8 +2423,8 @@ void ex_function(exarg_T *eap)
}
}
- /* Don't define the function when skipping commands or when an error was
- * detected. */
+ // Don't define the function when skipping commands or when an error was
+ // detected.
if (eap->skip || did_emsg) {
goto erret;
}
@@ -2640,8 +2642,8 @@ bool function_exists(const char *const name, bool no_deref)
NULL);
nm = skipwhite(nm);
- /* Only accept "funcname", "funcname ", "funcname (..." and
- * "funcname(...", not "funcname!...". */
+ // Only accept "funcname", "funcname ", "funcname (..." and
+ // "funcname(...", not "funcname!...".
if (p != NULL && (*nm == NUL || *nm == '(')) {
n = translated_function_exists(p);
}
@@ -2903,9 +2905,9 @@ void ex_return(exarg_T *eap)
}
}
- /* When skipping or the return gets pending, advance to the next command
- * in this line (!returning). Otherwise, ignore the rest of the line.
- * Following lines will be ignored by get_func_line(). */
+ // When skipping or the return gets pending, advance to the next command
+ // in this line (!returning). Otherwise, ignore the rest of the line.
+ // Following lines will be ignored by get_func_line().
if (returning) {
eap->nextcmd = NULL;
} else if (eap->nextcmd == NULL) { // no argument
@@ -3098,9 +3100,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
}
if (reanimate) {
- /* The pending return value could be overwritten by a ":return"
- * without argument in a finally clause; reset the default
- * return value. */
+ // The pending return value could be overwritten by a ":return"
+ // without argument in a finally clause; reset the default
+ // return value.
current_funccal->rettv->v_type = VAR_NUMBER;
current_funccal->rettv->vval.v_number = 0;
}
@@ -3109,9 +3111,9 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
} else {
current_funccal->returned = TRUE;
- /* If the return is carried out now, store the return value. For
- * a return immediately after reanimation, the value is already
- * there. */
+ // If the return is carried out now, store the return value. For
+ // a return immediately after reanimation, the value is already
+ // there.
if (!reanimate && rettv != NULL) {
tv_clear(current_funccal->rettv);
*current_funccal->rettv = *(typval_T *)rettv;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 5d43a14168..4a23f284cc 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -361,8 +361,8 @@ static int linelen(int *has_tab)
return len;
}
-/* Buffer for two lines used during sorting. They are allocated to
- * contain the longest line being sorted. */
+// Buffer for two lines used during sorting. They are allocated to
+// contain the longest line being sorted.
static char_u *sortbuf1;
static char_u *sortbuf2;
@@ -404,9 +404,9 @@ static int sort_compare(const void *s1, const void *s2)
sorti_T l2 = *(sorti_T *)s2;
int result = 0;
- /* If the user interrupts, there's no way to stop qsort() immediately, but
- * if we return 0 every time, qsort will assume it's done sorting and
- * exit. */
+ // If the user interrupts, there's no way to stop qsort() immediately, but
+ // if we return 0 every time, qsort will assume it's done sorting and
+ // exit.
if (sort_abort) {
return 0;
}
@@ -1733,8 +1733,8 @@ int rename_buffer(char_u *new_fname)
*/
void ex_file(exarg_T *eap)
{
- /* ":0file" removes the file name. Check for illegal uses ":3file",
- * "0file name", etc. */
+ // ":0file" removes the file name. Check for illegal uses ":3file",
+ // "0file name", etc.
if (eap->addr_count > 0
&& (*eap->arg != NUL
|| eap->line2 > 0
@@ -1888,11 +1888,11 @@ int do_write(exarg_T *eap)
retval = FAIL;
goto theend;
}
- /* Exchange the file names for the current and the alternate
- * buffer. This makes it look like we are now editing the buffer
- * under the new name. Must be done before buf_write(), because
- * if there is no file name and 'cpo' contains 'F', it will set
- * the file name. */
+ // Exchange the file names for the current and the alternate
+ // buffer. This makes it look like we are now editing the buffer
+ // under the new name. Must be done before buf_write(), because
+ // if there is no file name and 'cpo' contains 'F', it will set
+ // the file name.
fname = alt_buf->b_fname;
alt_buf->b_fname = curbuf->b_fname;
curbuf->b_fname = fname;
@@ -1923,8 +1923,8 @@ int do_write(exarg_T *eap)
do_modelines(0);
}
- /* Autocommands may have changed buffer names, esp. when
- * 'autochdir' is set. */
+ // Autocommands may have changed buffer names, esp. when
+ // 'autochdir' is set.
fname = curbuf->b_sfname;
}
@@ -2003,11 +2003,11 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int
char_u *p;
char_u *swapname;
- /* We only try the first entry in 'directory', without checking if
- * it's writable. If the "." directory is not writable the write
- * will probably fail anyway.
- * Use 'shortname' of the current buffer, since there is no buffer
- * for the written file. */
+ // We only try the first entry in 'directory', without checking if
+ // it's writable. If the "." directory is not writable the write
+ // will probably fail anyway.
+ // Use 'shortname' of the current buffer, since there is no buffer
+ // for the written file.
if (*p_dir == NUL) {
dir = xmalloc(5);
STRCPY(dir, ".");
@@ -2466,8 +2466,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
}
}
- /* May jump to last used line number for a loaded buffer or when asked
- * for explicitly */
+ // May jump to last used line number for a loaded buffer or when asked
+ // for explicitly
if ((oldbuf && newlnum == ECMD_LASTL) || newlnum == ECMD_LAST) {
pos = buflist_findfpos(buf);
newlnum = pos->lnum;
@@ -2577,10 +2577,10 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
}
}
- /* May get the window options from the last time this buffer
- * was in this window (or another window). If not used
- * before, reset the local window options to the global
- * values. Also restores old folding stuff. */
+ // May get the window options from the last time this buffer
+ // was in this window (or another window). If not used
+ // before, reset the local window options to the global
+ // values. Also restores old folding stuff.
get_winopts(curbuf);
did_get_winopts = true;
}
@@ -2621,10 +2621,10 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
goto theend;
}
- /* Since we are starting to edit a file, consider the filetype to be
- * unset. Helps for when an autocommand changes files and expects syntax
- * highlighting to work in the other file. */
- did_filetype = FALSE;
+ // Since we are starting to edit a file, consider the filetype to be
+ // unset. Helps for when an autocommand changes files and expects syntax
+ // highlighting to work in the other file.
+ did_filetype = false;
/*
* other_file oldbuf
@@ -2828,8 +2828,8 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new
&& !auto_buf) {
int msg_scroll_save = msg_scroll;
- /* Obey the 'O' flag in 'cpoptions': overwrite any previous file
- * message. */
+ // Obey the 'O' flag in 'cpoptions': overwrite any previous file
+ // message.
if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) {
msg_scroll = FALSE;
}
@@ -2953,8 +2953,8 @@ void ex_append(exarg_T *eap)
}
}
if (eap->getline == NULL) {
- /* No getline() function, use the lines that follow. This ends
- * when there is no more. */
+ // No getline() function, use the lines that follow. This ends
+ // when there is no more.
if (eap->nextcmd == NULL || *eap->nextcmd == NUL) {
break;
}
@@ -3750,8 +3750,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
sub_firstline = vim_strsave(ml_get(sub_firstlnum));
}
- /* Save the line number of the last change for the final
- * cursor position (just like Vi). */
+ // Save the line number of the last change for the final
+ // cursor position (just like Vi).
curwin->w_cursor.lnum = lnum;
do_again = FALSE;
@@ -3778,8 +3778,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
goto skip;
}
- /* Normally we continue searching for a match just after the
- * previous match. */
+ // Normally we continue searching for a match just after the
+ // previous match.
matchcol = regmatch.endpos[0].col;
prev_matchcol = matchcol;
@@ -3818,8 +3818,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
do_check_cursorbind();
}
- /* When 'cpoptions' contains "u" don't sync undo when
- * asking for confirmation. */
+ // When 'cpoptions' contains "u" don't sync undo when
+ // asking for confirmation.
if (vim_strchr(p_cpo, CPO_UNDO) != NULL) {
++no_u_sync;
}
@@ -3970,11 +3970,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
}
if (typed == 'n') {
- /* For a multi-line match, put matchcol at the NUL at
- * the end of the line and set nmatch to one, so that
- * we continue looking for a match on the next line.
- * Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc"
- * get stuck when pressing 'n'. */
+ // For a multi-line match, put matchcol at the NUL at
+ // the end of the line and set nmatch to one, so that
+ // we continue looking for a match on the next line.
+ // Avoids that ":%s/\nB\@=//gc" and ":%s/\n/,\r/gc"
+ // get stuck when pressing 'n'.
if (nmatch > 1) {
matchcol = (colnr_T)STRLEN(sub_firstline);
skip_match = true;
@@ -3986,8 +3986,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
}
}
- /* Move the cursor to the start of the match, so that we can
- * use "\=col("."). */
+ // Move the cursor to the start of the match, so that we can
+ // use "\=col(".").
curwin->w_cursor.col = regmatch.startpos[0].col;
// When the match included the "$" of the last line it may
@@ -4178,11 +4178,11 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
// strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g.
// But ":s/\n/#/" is OK.
skip:
- /* We already know that we did the last subst when we are at
- * the end of the line, except that a pattern like
- * "bar\|\nfoo" may match at the NUL. "lnum" can be below
- * "line2" when there is a \zs in the pattern after a line
- * break. */
+ // We already know that we did the last subst when we are at
+ // the end of the line, except that a pattern like
+ // "bar\|\nfoo" may match at the NUL. "lnum" can be below
+ // "line2" when there is a \zs in the pattern after a line
+ // break.
lastone = (skip_match
|| got_int
|| got_quit
@@ -4249,8 +4249,8 @@ skip:
nmatch_tl = 0;
}
- /* When asking, undo is saved each time, must also set
- * changed flag each time. */
+ // When asking, undo is saved each time, must also set
+ // changed flag each time.
if (subflags.do_ask) {
changed_bytes(lnum, 0);
} else {
@@ -4278,9 +4278,9 @@ skip:
* 5. break if there isn't another match in this line
*/
if (nmatch <= 0) {
- /* If the match found didn't start where we were
- * searching, do the next search in the line where we
- * found the match. */
+ // If the match found didn't start where we were
+ // searching, do the next search in the line where we
+ // found the match.
if (nmatch == -1) {
lnum -= regmatch.startpos[0].lnum;
}
@@ -4329,9 +4329,9 @@ skip:
curbuf->deleted_bytes2 = 0;
if (first_line != 0) {
- /* Need to subtract the number of added lines from "last_line" to get
- * the line number before the change (same as adding the number of
- * deleted lines). */
+ // Need to subtract the number of added lines from "last_line" to get
+ // the line number before the change (same as adding the number of
+ // deleted lines).
i = curbuf->b_ml.ml_line_count - old_line_count;
changed_lines(first_line, 0, last_line - i, i, false);
@@ -4842,9 +4842,9 @@ void ex_help(exarg_T *eap)
}
fclose(helpfd);
- /* Split off help window; put it at far top if no position
- * specified, the current window is vertically split and
- * narrow. */
+ // Split off help window; put it at far top if no position
+ // specified, the current window is vertically split and
+ // narrow.
n = WSP_HELP;
if (cmdmod.split == 0 && curwin->w_width != Columns
&& curwin->w_width < 80) {
@@ -4884,9 +4884,9 @@ void ex_help(exarg_T *eap)
do_tag(tag, DT_HELP, 1, FALSE, TRUE);
- /* Delete the empty buffer if we're not using it. Careful: autocommands
- * may have jumped to another window, check that the buffer is not in a
- * window. */
+ // Delete the empty buffer if we're not using it. Careful: autocommands
+ // may have jumped to another window, check that the buffer is not in a
+ // window.
if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) {
buf = buflist_findnr(empty_fnum);
if (buf != NULL && buf->b_nwindows == 0) {
@@ -5057,11 +5057,11 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool
}
if (i < 0) { // no match in table
- /* Replace "\S" with "/\\S", etc. Otherwise every tag is matched.
- * Also replace "\%^" and "\%(", they match every tag too.
- * Also "\zs", "\z1", etc.
- * Also "\@<", "\@=", "\@<=", etc.
- * And also "\_$" and "\_^". */
+ // Replace "\S" with "/\\S", etc. Otherwise every tag is matched.
+ // Also replace "\%^" and "\%(", they match every tag too.
+ // Also "\zs", "\z1", etc.
+ // Also "\@<", "\@=", "\@<=", etc.
+ // And also "\_$" and "\_^".
if (arg[0] == '\\'
&& ((arg[1] != NUL && arg[2] == NUL)
|| (vim_strchr((char_u *)"%_z@", arg[1]) != NULL
@@ -5158,8 +5158,8 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool
*d++ = '\\';
}
- /* "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
- * "CTRL-\_CTRL-N" */
+ // "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in
+ // "CTRL-\_CTRL-N"
if (STRNICMP(s, "CTRL-\\_", 7) == 0) {
STRCPY(d, "CTRL-\\\\");
d += 7;
@@ -5213,9 +5213,9 @@ int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, bool
}
if (find_tags(IObuff, num_matches, matches, flags, MAXCOL, NULL) == OK
&& *num_matches > 0) {
- /* Sort the matches found on the heuristic number that is after the
- * tag name. */
- qsort((void *)*matches, (size_t)*num_matches,
+ // Sort the matches found on the heuristic number that is after the
+ // tag name.
+ qsort((void *)(*matches), (size_t)(*num_matches),
sizeof(char_u *), help_compare);
// Delete more than TAG_MANY to reduce the size of the listing.
while (*num_matches > TAG_MANY) {
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 40a2960a85..5d40d7a16a 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -52,33 +52,7 @@
#include "nvim/version.h"
#include "nvim/window.h"
-
/// Growarray to store info about already sourced scripts.
-/// Also store the dev/ino, so that we don't have to stat() each
-/// script when going through the list.
-typedef struct scriptitem_S {
- char_u *sn_name;
- bool file_id_valid;
- FileID file_id;
- bool sn_prof_on; ///< true when script is/was profiled
- bool sn_pr_force; ///< forceit: profile functions in this script
- proftime_T sn_pr_child; ///< time set when going into first child
- int sn_pr_nest; ///< nesting for sn_pr_child
- // profiling the script as a whole
- int sn_pr_count; ///< nr of times sourced
- proftime_T sn_pr_total; ///< time spent in script + children
- proftime_T sn_pr_self; ///< time spent in script itself
- proftime_T sn_pr_start; ///< time at script start
- proftime_T sn_pr_children; ///< time in children after script start
- // profiling the script per line
- garray_T sn_prl_ga; ///< things stored for every line
- proftime_T sn_prl_start; ///< start time for current line
- proftime_T sn_prl_children; ///< time spent in children for this line
- proftime_T sn_prl_wait; ///< wait start time for current line
- linenr_T sn_prl_idx; ///< index of line being timed; -1 if none
- int sn_prl_execed; ///< line being timed was executed
-} scriptitem_T;
-
static garray_T script_items = { 0, 0, sizeof(scriptitem_T), 4, NULL };
#define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
@@ -1939,6 +1913,29 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat)
return ga.ga_data;
}
+/// Create a new script item and allocate script-local vars. @see new_script_vars
+///
+/// @param name File name of the script. NULL for anonymous :source.
+/// @param[out] sid_out SID of the new item.
+/// @return pointer to the created script item.
+scriptitem_T *new_script_item(char_u *const name, scid_T *const sid_out)
+{
+ static scid_T last_current_SID = 0;
+ const scid_T sid = ++last_current_SID;
+ if (sid_out != NULL) {
+ *sid_out = sid;
+ }
+ ga_grow(&script_items, (int)(sid - script_items.ga_len));
+ while (script_items.ga_len < sid) {
+ script_items.ga_len++;
+ SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
+ SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
+ }
+ SCRIPT_ITEM(sid).sn_name = name;
+ new_script_vars(sid); // Allocate the local script variables to use for this script.
+ return &SCRIPT_ITEM(sid);
+}
+
static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name)
{
char_u *save_sourcing_name = sourcing_name;
@@ -2036,7 +2033,6 @@ int do_source(char *fname, int check_other, int is_vimrc)
char_u *fname_exp;
char_u *firstline = NULL;
int retval = FAIL;
- static scid_T last_current_SID = 0;
static int last_current_SID_seq = 0;
int save_debug_break_level = debug_break_level;
scriptitem_T *si = NULL;
@@ -2183,15 +2179,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
}
}
if (current_sctx.sc_sid == 0) {
- current_sctx.sc_sid = ++last_current_SID;
- ga_grow(&script_items, (int)(current_sctx.sc_sid - script_items.ga_len));
- while (script_items.ga_len < current_sctx.sc_sid) {
- script_items.ga_len++;
- SCRIPT_ITEM(script_items.ga_len).sn_name = NULL;
- SCRIPT_ITEM(script_items.ga_len).sn_prof_on = false;
- }
- si = &SCRIPT_ITEM(current_sctx.sc_sid);
- si->sn_name = fname_exp;
+ si = new_script_item(fname_exp, &current_sctx.sc_sid);
fname_exp = vim_strsave(si->sn_name); // used for autocmd
if (file_id_ok) {
si->file_id_valid = true;
@@ -2199,9 +2187,6 @@ int do_source(char *fname, int check_other, int is_vimrc)
} else {
si->file_id_valid = false;
}
-
- // Allocate the local script variables to use for this script.
- new_script_vars(current_sctx.sc_sid);
}
if (l_do_profiling == PROF_YES) {
@@ -2375,16 +2360,21 @@ char_u *get_scriptname(LastSet last_set, bool *should_free)
case SID_LUA:
return (char_u *)_("Lua");
case SID_API_CLIENT:
- vim_snprintf((char *)IObuff, IOSIZE,
- _("API client (channel id %" PRIu64 ")"),
- last_set.channel_id);
+ snprintf((char *)IObuff, IOSIZE, _("API client (channel id %" PRIu64 ")"), last_set.channel_id);
return IObuff;
case SID_STR:
return (char_u *)_("anonymous :source");
- default:
+ default: {
+ char_u *const sname = SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name;
+ if (sname == NULL) {
+ snprintf((char *)IObuff, IOSIZE, _("anonymous :source (script id %d)"),
+ last_set.script_ctx.sc_sid);
+ return IObuff;
+ }
+
*should_free = true;
- return home_replace_save(NULL,
- SCRIPT_ITEM(last_set.script_ctx.sc_sid).sn_name);
+ return home_replace_save(NULL, sname);
+ }
}
}
diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h
index de4e1429b7..d426ff28f8 100644
--- a/src/nvim/ex_cmds2.h
+++ b/src/nvim/ex_cmds2.h
@@ -16,6 +16,31 @@
#define CCGD_ALLBUF 8 // may write all buffers
#define CCGD_EXCMD 16 // may suggest using !
+/// Also store the dev/ino, so that we don't have to stat() each
+/// script when going through the list.
+typedef struct scriptitem_S {
+ char_u *sn_name;
+ bool file_id_valid;
+ FileID file_id;
+ bool sn_prof_on; ///< true when script is/was profiled
+ bool sn_pr_force; ///< forceit: profile functions in this script
+ proftime_T sn_pr_child; ///< time set when going into first child
+ int sn_pr_nest; ///< nesting for sn_pr_child
+ // profiling the script as a whole
+ int sn_pr_count; ///< nr of times sourced
+ proftime_T sn_pr_total; ///< time spent in script + children
+ proftime_T sn_pr_self; ///< time spent in script itself
+ proftime_T sn_pr_start; ///< time at script start
+ proftime_T sn_pr_children; ///< time in children after script start
+ // profiling the script per line
+ garray_T sn_prl_ga; ///< things stored for every line
+ proftime_T sn_prl_start; ///< start time for current line
+ proftime_T sn_prl_children; ///< time spent in children for this line
+ proftime_T sn_prl_wait; ///< wait start time for current line
+ linenr_T sn_prl_idx; ///< index of line being timed; -1 if none
+ int sn_prl_execed; ///< line being timed was executed
+} scriptitem_T;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds2.h.generated.h"
#endif
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 16a9b78c6a..f649266b9f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -197,8 +197,8 @@ void do_exmode(void)
exmode_active = true;
State = NORMAL;
- /* When using ":global /pat/ visual" and then "Q" we return to continue
- * the :global command. */
+ // When using ":global /pat/ visual" and then "Q" we return to continue
+ // the :global command.
if (global_busy) {
return;
}
@@ -231,8 +231,8 @@ void do_exmode(void)
EMSG(_(e_emptybuf));
} else {
if (ex_pressedreturn) {
- /* go up one line, to overwrite the ":<CR>" line, so the
- * output doesn't contain empty lines. */
+ // go up one line, to overwrite the ":<CR>" line, so the
+ // output doesn't contain empty lines.
msg_row = prev_msg_row;
if (prev_msg_row == Rows - 1) {
msg_row--;
@@ -374,8 +374,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
++ex_nesting_level;
}
- /* Get the function or script name and the address where the next breakpoint
- * line and the debug tick for a function or script are stored. */
+ // Get the function or script name and the address where the next breakpoint
+ // line and the debug tick for a function or script are stored.
if (getline_is_func) {
fname = func_name(real_cookie);
breakpoint = func_breakpoint(real_cookie);
@@ -500,11 +500,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
}
if (cstack.cs_looplevel > 0) {
- /* Inside a while/for loop we need to store the lines and use them
- * again. Pass a different "fgetline" function to do_one_cmd()
- * below, so that it stores lines in or reads them from
- * "lines_ga". Makes it possible to define a function inside a
- * while/for loop. */
+ // Inside a while/for loop we need to store the lines and use them
+ // again. Pass a different "fgetline" function to do_one_cmd()
+ // below, so that it stores lines in or reads them from
+ // "lines_ga". Makes it possible to define a function inside a
+ // while/for loop.
cmd_getline = get_loop_line;
cmd_cookie = (void *)&cmd_loop_cookie;
cmd_loop_cookie.lines_gap = &lines_ga;
@@ -612,8 +612,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
}
if (cmd_cookie == (void *)&cmd_loop_cookie) {
- /* Use "current_line" from "cmd_loop_cookie", it may have been
- * incremented when defining a function. */
+ // Use "current_line" from "cmd_loop_cookie", it may have been
+ // incremented when defining a function.
current_line = cmd_loop_cookie.current_line;
}
@@ -671,8 +671,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
cstack.cs_lflags |= CSL_HAD_LOOP;
line_breakcheck(); // check if CTRL-C typed
- /* Check for the next breakpoint at or after the ":while"
- * or ":for". */
+ // Check for the next breakpoint at or after the ":while"
+ // or ":for".
if (breakpoint != NULL) {
*breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
fname,
@@ -724,8 +724,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY;
}
- /* Update global "trylevel" for recursive calls to do_cmdline() from
- * within this loop. */
+ // Update global "trylevel" for recursive calls to do_cmdline() from
+ // within this loop.
trylevel = initial_trylevel + cstack.cs_trylevel;
// If the outermost try conditional (across function calls and sourced
@@ -806,9 +806,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags)
trylevel = initial_trylevel;
}
- /* If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory
- * lack was reported above and the error message is to be converted to an
- * exception, do this now after rewinding the cstack. */
+ // If a missing ":endtry", ":endwhile", ":endfor", or ":endif" or a memory
+ // lack was reported above and the error message is to be converted to an
+ // exception, do this now after rewinding the cstack.
do_errthrow(&cstack, getline_equal(fgetline, cookie, get_func_line)
? (char_u *)"endfunction" : (char_u *)NULL);
@@ -1014,9 +1014,9 @@ int getline_equal(LineGetter fgetline, void *cookie, LineGetter func)
LineGetter gp;
struct loop_cookie *cp;
- /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
- * function that's originally used to obtain the lines. This may be
- * nested several levels. */
+ // When "fgetline" is "get_loop_line()" use the "cookie" to find the
+ // function that's originally used to obtain the lines. This may be
+ // nested several levels.
gp = fgetline;
cp = (struct loop_cookie *)cookie;
while (gp == get_loop_line) {
@@ -1035,9 +1035,9 @@ void *getline_cookie(LineGetter fgetline, void *cookie)
LineGetter gp;
struct loop_cookie *cp;
- /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
- * cookie that's originally used to obtain the lines. This may be nested
- * several levels. */
+ // When "fgetline" is "get_loop_line()" use the "cookie" to find the
+ // cookie that's originally used to obtain the lines. This may be nested
+ // several levels.
gp = fgetline;
cp = (struct loop_cookie *)cookie;
while (gp == get_loop_line) {
@@ -2625,9 +2625,9 @@ static char_u *find_command(exarg_T *eap, int *full)
}
len = (int)(p - eap->cmd);
if (*eap->cmd == 'd' && (p[-1] == 'l' || p[-1] == 'p')) {
- /* Check for ":dl", ":dell", etc. to ":deletel": that's
- * :delete with the 'l' flag. Same for 'p'. */
- for (i = 0; i < len; ++i) {
+ // Check for ":dl", ":dell", etc. to ":deletel": that's
+ // :delete with the 'l' flag. Same for 'p'.
+ for (i = 0; i < len; i++) {
if (eap->cmd[i] != ((char_u *)"delete")[i]) {
break;
}
@@ -4435,8 +4435,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
continue;
}
- /* Wildcards won't be expanded below, the replacement is taken
- * literally. But do expand "~/file", "~user/file" and "$HOME/file". */
+ // Wildcards won't be expanded below, the replacement is taken
+ // literally. But do expand "~/file", "~user/file" and "$HOME/file".
if (vim_strchr(repl, '$') != NULL || vim_strchr(repl, '~') != NULL) {
char_u *l = repl;
@@ -4463,8 +4463,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
&& !(eap->argt & EX_NOSPC)) {
char_u *l;
#ifdef BACKSLASH_IN_FILENAME
- /* Don't escape a backslash here, because rem_backslash() doesn't
- * remove it later. */
+ // Don't escape a backslash here, because rem_backslash() doesn't
+ // remove it later.
static char_u *nobslash = (char_u *)" \t\"|";
# define ESCAPE_CHARS nobslash
#else
@@ -7205,8 +7205,8 @@ void ex_splitview(exarg_T *eap)
}
} else if (win_split(eap->addr_count > 0 ? (int)eap->line2 : 0,
*eap->cmd == 'v' ? WSP_VERT : 0) != FAIL) {
- /* Reset 'scrollbind' when editing another file, but keep it when
- * doing ":split" without arguments. */
+ // Reset 'scrollbind' when editing another file, but keep it when
+ // doing ":split" without arguments.
if (*eap->arg != NUL
) {
RESET_BINDING(curwin);
@@ -7402,8 +7402,8 @@ static void ex_find(exarg_T *eap)
fname = find_file_in_path(eap->arg, STRLEN(eap->arg),
FNAME_MESS, TRUE, curbuf->b_ffname);
if (eap->addr_count > 0) {
- /* Repeat finding the file "count" times. This matters when it
- * appears several times in the path. */
+ // Repeat finding the file "count" times. This matters when it
+ // appears several times in the path.
count = eap->line2;
while (fname != NULL && --count > 0) {
xfree(fname);
@@ -7509,8 +7509,8 @@ void do_exedit(exarg_T *eap, win_T *old_curwin)
if (!need_hide || buf_hide(curbuf)) {
cleanup_T cs;
- /* Reset the error/interrupt/exception state here so that
- * aborting() returns FALSE when closing a window. */
+ // Reset the error/interrupt/exception state here so that
+ // aborting() returns FALSE when closing a window.
enter_cleanup(&cs);
win_close(curwin, !need_hide && !buf_hide(curbuf));
@@ -7675,8 +7675,8 @@ static void ex_read(exarg_T *eap)
}
} else {
if (empty && exmode_active) {
- /* Delete the empty line that remains. Historically ex does
- * this but vi doesn't. */
+ // Delete the empty line that remains. Historically ex does
+ // this but vi doesn't.
if (eap->line2 == 0) {
lnum = curbuf->b_ml.ml_line_count;
} else {
@@ -7707,6 +7707,21 @@ void free_cd_dir(void)
#endif
+// Get the previous directory for the given chdir scope.
+static char_u *get_prevdir(CdScope scope)
+{
+ switch (scope) {
+ case kCdScopeTabpage:
+ return curtab->tp_prevdir;
+ break;
+ case kCdScopeWindow:
+ return curwin->w_prevdir;
+ break;
+ default:
+ return prev_dir;
+ }
+}
+
/// Deal with the side effects of changing the current directory.
///
/// @param scope Scope of the function call (global, tab or window).
@@ -7716,14 +7731,15 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
XFREE_CLEAR(curwin->w_localdir);
// Overwrite the tab-local CWD for :cd, :tcd.
- if (scope >= kCdScopeTab) {
+ if (scope >= kCdScopeTabpage) {
XFREE_CLEAR(curtab->tp_localdir);
}
if (scope < kCdScopeGlobal) {
+ char_u *pdir = get_prevdir(scope);
// If still in global directory, set CWD as the global directory.
- if (globaldir == NULL && prev_dir != NULL) {
- globaldir = vim_strsave(prev_dir);
+ if (globaldir == NULL && pdir != NULL) {
+ globaldir = vim_strsave(pdir);
}
}
@@ -7736,7 +7752,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
// We are now in the global directory, no need to remember its name.
XFREE_CLEAR(globaldir);
break;
- case kCdScopeTab:
+ case kCdScopeTabpage:
curtab->tp_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeWindow:
@@ -7749,59 +7765,92 @@ void post_chdir(CdScope scope, bool trigger_dirchanged)
shorten_fnames(true);
if (trigger_dirchanged) {
- do_autocmd_dirchanged(cwd, scope, false);
+ do_autocmd_dirchanged(cwd, scope, kCdCauseManual);
}
}
-/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
-void ex_cd(exarg_T *eap)
+/// Change directory function used by :cd/:tcd/:lcd Ex commands and the chdir() function.
+/// @param new_dir The directory to change to.
+/// @param scope Scope of the function call (global, tab or window).
+/// @return true if the directory is successfully changed.
+bool changedir_func(char_u *new_dir, CdScope scope)
{
- char_u *new_dir;
char_u *tofree;
+ char_u *pdir = NULL;
+ bool retval = false;
- new_dir = eap->arg;
-#if !defined(UNIX)
- // for non-UNIX ":cd" means: print current directory
- if (*new_dir == NUL) {
- ex_pwd(NULL);
- } else
-#endif
- {
- if (allbuf_locked()) {
- return;
- }
+ if (new_dir == NULL || allbuf_locked()) {
+ return false;
+ }
- // ":cd -": Change to previous directory
- if (STRCMP(new_dir, "-") == 0) {
- if (prev_dir == NULL) {
- EMSG(_("E186: No previous directory"));
- return;
- }
- new_dir = prev_dir;
+ // ":cd -": Change to previous directory
+ if (STRCMP(new_dir, "-") == 0) {
+ pdir = get_prevdir(scope);
+ if (pdir == NULL) {
+ EMSG(_("E186: No previous directory"));
+ return false;
}
+ new_dir = pdir;
+ }
- // Save current directory for next ":cd -"
- tofree = prev_dir;
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- prev_dir = vim_strsave(NameBuff);
- } else {
- prev_dir = NULL;
- }
+ // Free the previous directory
+ tofree = get_prevdir(scope);
+
+ if (os_dirname(NameBuff, MAXPATHL) == OK) {
+ pdir = vim_strsave(NameBuff);
+ } else {
+ pdir = NULL;
+ }
+
+ switch (scope) {
+ case kCdScopeTabpage:
+ curtab->tp_prevdir = pdir;
+ break;
+ case kCdScopeWindow:
+ curwin->w_prevdir = pdir;
+ break;
+ default:
+ prev_dir = pdir;
+ }
#if defined(UNIX)
- // On Unix ":cd" means: go to home directory.
- if (*new_dir == NUL) {
- // Use NameBuff for home directory name.
- expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
- new_dir = NameBuff;
- }
+ // On Unix ":cd" means: go to home directory.
+ if (*new_dir == NUL) {
+ // Use NameBuff for home directory name.
+ expand_env((char_u *)"$HOME", NameBuff, MAXPATHL);
+ new_dir = NameBuff;
+ }
#endif
- CdScope scope = kCdScopeGlobal; // Depends on command invoked
+ if (vim_chdir(new_dir) == 0) {
+ bool dir_differs = pdir == NULL || pathcmp((char *)pdir, (char *)new_dir, -1) != 0;
+ post_chdir(scope, dir_differs);
+ retval = true;
+ } else {
+ EMSG(_(e_failed));
+ }
+ xfree(tofree);
+
+ return retval;
+}
+
+/// ":cd", ":tcd", ":lcd", ":chdir", "tchdir" and ":lchdir".
+void ex_cd(exarg_T *eap)
+{
+ char_u *new_dir;
+ new_dir = eap->arg;
+#if !defined(UNIX) && !defined(VMS)
+ // for non-UNIX ":cd" means: print current directory
+ if (*new_dir == NUL) {
+ ex_pwd(NULL);
+ } else
+#endif
+ {
+ CdScope scope = kCdScopeGlobal;
switch (eap->cmdidx) {
case CMD_tcd:
case CMD_tchdir:
- scope = kCdScopeTab;
+ scope = kCdScopeTabpage;
break;
case CMD_lcd:
case CMD_lchdir:
@@ -7810,18 +7859,12 @@ void ex_cd(exarg_T *eap)
default:
break;
}
-
- if (vim_chdir(new_dir)) {
- EMSG(_(e_failed));
- } else {
- post_chdir(scope, true);
+ if (changedir_func(new_dir, scope)) {
// Echo the new current directory if the command was typed.
if (KeyTyped || p_verbose >= 5) {
ex_pwd(eap);
}
}
-
- xfree(tofree);
}
}
@@ -7834,7 +7877,17 @@ static void ex_pwd(exarg_T *eap)
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(NameBuff);
#endif
- msg(NameBuff);
+ if (p_verbose > 0) {
+ char *context = "global";
+ if (curwin->w_localdir != NULL) {
+ context = "window";
+ } else if (curtab->tp_localdir != NULL) {
+ context = "tabpage";
+ }
+ smsg("[%s] %s", context, (char *)NameBuff);
+ } else {
+ msg(NameBuff);
+ }
} else {
EMSG(_("E187: Unknown"));
}
@@ -8298,8 +8351,8 @@ static void ex_redir(exarg_T *eap)
}
}
- /* Make sure redirection is not off. Can happen for cmdline completion
- * that indirectly invokes a command to catch its output. */
+ // Make sure redirection is not off. Can happen for cmdline completion
+ // that indirectly invokes a command to catch its output.
if (redir_fd != NULL
|| redir_reg || redir_vname) {
redir_off = false;
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 21ddf7399b..09a1350f17 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -135,8 +135,8 @@ int should_abort(int retcode)
*/
int aborted_in_try(void)
{
- /* This function is only called after an error. In this case, "force_abort"
- * determines whether searching for finally clauses is necessary. */
+ // This function is only called after an error. In this case, "force_abort"
+ // determines whether searching for finally clauses is necessary.
return force_abort;
}
@@ -321,8 +321,8 @@ void do_errthrow(cstack_T *cstack, char_u *cmdname)
force_abort = TRUE;
}
- /* If no exception is to be thrown or the conversion should be done after
- * returning to a previous invocation of do_one_cmd(), do nothing. */
+ // If no exception is to be thrown or the conversion should be done after
+ // returning to a previous invocation of do_one_cmd(), do nothing.
if (msg_list == NULL || *msg_list == NULL) {
return;
}
@@ -471,8 +471,8 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname)
excp = xmalloc(sizeof(except_T));
if (type == ET_ERROR) {
- /* Store the original message and prefix the exception value with
- * "Vim:" or, if a command name is given, "Vim(cmdname):". */
+ // Store the original message and prefix the exception value with
+ // "Vim:" or, if a command name is given, "Vim(cmdname):".
excp->messages = (struct msglist *)value;
}
@@ -940,11 +940,11 @@ void ex_else(exarg_T *eap)
if (eap->cmdidx == CMD_elseif) {
bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
- /* When throwing error exceptions, we want to throw always the first
- * of several errors in a row. This is what actually happens when
- * a conditional error was detected above and there is another failure
- * when parsing the expression. Since the skip flag is set in this
- * case, the parsing error will be ignored by emsg(). */
+ // When throwing error exceptions, we want to throw always the first
+ // of several errors in a row. This is what actually happens when
+ // a conditional error was detected above and there is another failure
+ // when parsing the expression. Since the skip flag is set in this
+ // case, the parsing error will be ignored by emsg().
if (!skip && !error) {
if (result) {
@@ -1000,8 +1000,8 @@ void ex_while(exarg_T *eap)
* ":for var in list-expr"
*/
if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) {
- /* Jumping here from a ":continue" or ":endfor": use the
- * previously evaluated list. */
+ // Jumping here from a ":continue" or ":endfor": use the
+ // previously evaluated list.
fi = cstack->cs_forinfo[cstack->cs_idx];
error = FALSE;
} else {
@@ -1033,10 +1033,10 @@ void ex_while(exarg_T *eap)
cstack->cs_lflags ^= CSL_HAD_LOOP;
} else {
cstack->cs_lflags &= ~CSL_HAD_LOOP;
- /* If the ":while" evaluates to FALSE or ":for" is past the end of
- * the list, show the debug prompt at the ":endwhile"/":endfor" as
- * if there was a ":break" in a ":while"/":for" evaluating to
- * TRUE. */
+ // If the ":while" evaluates to FALSE or ":for" is past the end of
+ // the list, show the debug prompt at the ":endwhile"/":endfor" as
+ // if there was a ":break" in a ":while"/":for" evaluating to
+ // TRUE.
if (!skip && !error) {
cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
}
@@ -1125,8 +1125,8 @@ void ex_endwhile(exarg_T *eap)
} else {
fl = cstack->cs_flags[cstack->cs_idx];
if (!(fl & csf)) {
- /* If we are in a ":while" or ":for" but used the wrong endloop
- * command, do not rewind to the next enclosing ":for"/":while". */
+ // If we are in a ":while" or ":for" but used the wrong endloop
+ // command, do not rewind to the next enclosing ":for"/":while".
if (fl & CSF_WHILE) {
eap->errmsg = (char_u *)_("E732: Using :endfor with :while");
} else if (fl & CSF_FOR) {
@@ -1143,8 +1143,8 @@ void ex_endwhile(exarg_T *eap)
for (idx = cstack->cs_idx; idx > 0; --idx) {
fl = cstack->cs_flags[idx];
if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) {
- /* Give up at a try conditional not in its finally clause.
- * Ignore the ":endwhile"/":endfor". */
+ // Give up at a try conditional not in its finally clause.
+ // Ignore the ":endwhile"/":endfor".
eap->errmsg = err;
return;
}
@@ -1258,9 +1258,9 @@ void do_throw(cstack_T *cstack)
if (cstack->cs_flags[idx] & CSF_ACTIVE) {
cstack->cs_flags[idx] |= CSF_THROWN;
} else {
- /* THROWN may have already been set for a catchable exception
- * that has been discarded. Ensure it is reset for the new
- * exception. */
+ // THROWN may have already been set for a catchable exception
+ // that has been discarded. Ensure it is reset for the new
+ // exception.
cstack->cs_flags[idx] &= ~CSF_THROWN;
}
}
@@ -1288,9 +1288,9 @@ void ex_try(exarg_T *eap)
skip = CHECK_SKIP;
if (!skip) {
- /* Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
- * commands should check for a match if an exception is thrown and
- * that the finally clause needs to be executed. */
+ // Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
+ // commands should check for a match if an exception is thrown and
+ // that the finally clause needs to be executed.
cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
/*
@@ -1343,8 +1343,8 @@ void ex_catch(exarg_T *eap)
give_up = TRUE;
} else {
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
- /* Report what's missing if the matching ":try" is not in its
- * finally clause. */
+ // Report what's missing if the matching ":try" is not in its
+ // finally clause.
eap->errmsg = get_end_emsg(cstack);
skip = TRUE;
}
@@ -1497,9 +1497,9 @@ void ex_finally(exarg_T *eap)
break;
}
}
- /* Make this error pending, so that the commands in the following
- * finally clause can be executed. This overrules also a pending
- * ":continue", ":break", ":return", or ":finish". */
+ // Make this error pending, so that the commands in the following
+ // finally clause can be executed. This overrules also a pending
+ // ":continue", ":break", ":return", or ":finish".
pending = CSTP_ERROR;
} else {
idx = cstack->cs_idx;
@@ -1524,14 +1524,14 @@ void ex_finally(exarg_T *eap)
skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
if (!skip) {
- /* When debugging or a breakpoint was encountered, display the
- * debug prompt (if not already done). The user then knows that the
- * finally clause is executed. */
+ // When debugging or a breakpoint was encountered, display the
+ // debug prompt (if not already done). The user then knows that the
+ // finally clause is executed.
if (dbg_check_skipped(eap)) {
- /* Handle a ">quit" debug command as if an interrupt had
- * occurred before the ":finally". That is, discard the
- * original exception and replace it by an interrupt
- * exception. */
+ // Handle a ">quit" debug command as if an interrupt had
+ // occurred before the ":finally". That is, discard the
+ // original exception and replace it by an interrupt
+ // exception.
(void)do_intthrow(cstack);
}
@@ -1732,13 +1732,13 @@ void ex_endtry(exarg_T *eap)
case CSTP_NONE:
break;
- /* Reactivate a pending ":continue", ":break", ":return",
- * ":finish" from the try block or a catch clause of this try
- * conditional. This is skipped, if there was an error in an
- * (unskipped) conditional command or an interrupt afterwards
- * or if the finally clause is present and executed a new error,
- * interrupt, throw, ":continue", ":break", ":return", or
- * ":finish". */
+ // Reactivate a pending ":continue", ":break", ":return",
+ // ":finish" from the try block or a catch clause of this try
+ // conditional. This is skipped, if there was an error in an
+ // (unskipped) conditional command or an interrupt afterwards
+ // or if the finally clause is present and executed a new error,
+ // interrupt, throw, ":continue", ":break", ":return", or
+ // ":finish".
case CSTP_CONTINUE:
ex_continue(eap);
break;
@@ -1866,10 +1866,10 @@ void leave_cleanup(cleanup_T *csp)
return;
}
- /* If there was an aborting error, an interrupt, or an uncaught exception
- * after the corresponding call to enter_cleanup(), discard what has been
- * made pending by it. Report this to the user if required by the
- * 'verbose' option or when debugging. */
+ // If there was an aborting error, an interrupt, or an uncaught exception
+ // after the corresponding call to enter_cleanup(), discard what has been
+ // made pending by it. Report this to the user if required by the
+ // 'verbose' option or when debugging.
if (aborting() || need_rethrow) {
if (pending & CSTP_THROW) {
// Cancel the pending exception (includes report).
@@ -1878,8 +1878,8 @@ void leave_cleanup(cleanup_T *csp)
report_discard_pending(pending, NULL);
}
- /* If an error was about to be converted to an exception when
- * enter_cleanup() was called, free the message list. */
+ // If an error was about to be converted to an exception when
+ // enter_cleanup() was called, free the message list.
if (msg_list != NULL) {
free_global_msglist();
}
@@ -1999,10 +1999,10 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
&& (cstack->cs_flags[idx] & CSF_CAUGHT)) {
finish_exception((except_T *)cstack->cs_exception[idx]);
}
- /* Stop at this try conditional - except the try block never
- * got active (because of an inactive surrounding conditional
- * or when the ":try" appeared after an error or interrupt or
- * throw). */
+ // Stop at this try conditional - except the try block never
+ // got active (because of an inactive surrounding conditional
+ // or when the ":try" appeared after an error or interrupt or
+ // throw).
if (cstack->cs_flags[idx] & CSF_TRUE) {
if (searched_cond == 0 && !inclusive) {
break;
@@ -2012,10 +2012,10 @@ int cleanup_conditionals(cstack_T *cstack, int searched_cond, int inclusive)
}
}
- /* Stop on the searched conditional type (even when the surrounding
- * conditional is not active or something has been made pending).
- * If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
- * check first whether "emsg_silent" needs to be restored. */
+ // Stop on the searched conditional type (even when the surrounding
+ // conditional is not active or something has been made pending).
+ // If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
+ // check first whether "emsg_silent" needs to be restored.
if (cstack->cs_flags[idx] & searched_cond) {
if (!inclusive) {
break;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 4c4d3e89e4..62a4d48645 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -2637,8 +2637,8 @@ static void realloc_cmdbuff(int len)
&& ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) {
int i = (int)(ccline.xpc->xp_pattern - p);
- /* If xp_pattern points inside the old cmdbuff it needs to be adjusted
- * to point into the newly allocated memory. */
+ // If xp_pattern points inside the old cmdbuff it needs to be adjusted
+ // to point into the newly allocated memory.
if (i >= 0 && i <= ccline.cmdlen) {
ccline.xpc->xp_pattern = ccline.cmdbuff + i;
}
@@ -3457,8 +3457,8 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
return FAIL;
}
- /* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
- * part of the word. */
+ // When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
+ // part of the word.
p = arg;
if (p_is && regname == Ctrl_W) {
char_u *w;
@@ -5976,8 +5976,8 @@ int set_cmdline_pos(int pos)
return 1;
}
- /* The position is not set directly but after CTRL-\ e or CTRL-R = has
- * changed the command line. */
+ // The position is not set directly but after CTRL-\ e or CTRL-R = has
+ // changed the command line.
if (pos < 0) {
new_cmdpos = 0;
} else {
@@ -6471,8 +6471,8 @@ static int open_cmdwin(void)
exmode_active = save_exmode;
- /* Safety check: The old window or buffer was deleted: It's a bug when
- * this happens! */
+ // Safety check: The old window or buffer was deleted: It's a bug when
+ // this happens!
if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) {
cmdwin_result = Ctrl_C;
EMSG(_("E199: Active window or buffer deleted"));
@@ -6498,8 +6498,8 @@ static int open_cmdwin(void)
stuffcharReadbuff(CAR);
}
} else if (cmdwin_result == Ctrl_C) {
- /* :q or :close, don't execute any command
- * and don't modify the cmd window. */
+ // :q or :close, don't execute any command
+ // and don't modify the cmd window.
ccline.cmdbuff = NULL;
} else {
ccline.cmdbuff = vim_strsave(get_cursor_line_ptr());
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c
index 1e1da6a9a3..0dfd7e1edd 100644
--- a/src/nvim/ex_session.c
+++ b/src/nvim/ex_session.c
@@ -963,7 +963,7 @@ void ex_mkrc(exarg_T *eap)
*dirnow = NUL;
}
if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) {
- if (vim_chdirfile((char_u *)fname) == OK) {
+ if (vim_chdirfile((char_u *)fname, kCdCauseOther) == OK) {
shorten_fnames(true);
}
} else if (*dirnow != NUL
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 5458d8acf2..9eab579243 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -54,6 +54,7 @@
#include "nvim/eval.h"
#include "nvim/file_search.h"
#include "nvim/fileio.h"
+#include "nvim/globals.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
@@ -1590,7 +1591,7 @@ theend:
return file_name;
}
-void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
+void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause)
{
static bool recursive = false;
@@ -1609,8 +1610,8 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
case kCdScopeGlobal:
snprintf(buf, sizeof(buf), "global");
break;
- case kCdScopeTab:
- snprintf(buf, sizeof(buf), "tab");
+ case kCdScopeTabpage:
+ snprintf(buf, sizeof(buf), "tabpage");
break;
case kCdScopeWindow:
snprintf(buf, sizeof(buf), "window");
@@ -1620,11 +1621,30 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
abort();
}
+#ifdef BACKSLASH_IN_FILENAME
+ char new_dir_buf[MAXPATHL];
+ STRCPY(new_dir_buf, new_dir);
+ slash_adjust(new_dir_buf);
+ new_dir = new_dir_buf;
+#endif
+
tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614
- tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
- tv_dict_add_bool(dict, S_LEN("changed_window"), changed_window);
+ tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
+ tv_dict_add_bool(dict, S_LEN("changed_window"), cause == kCdCauseWindow);
tv_dict_set_keys_readonly(dict);
+ switch (cause) {
+ case kCdCauseManual:
+ case kCdCauseWindow:
+ break;
+ case kCdCauseAuto:
+ snprintf(buf, sizeof(buf), "auto");
+ break;
+ case kCdCauseOther:
+ // Should never happen.
+ abort();
+ }
+
apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
curbuf);
@@ -1636,7 +1656,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window)
/// Change to a file's directory.
/// Caller must call shorten_fnames()!
/// @return OK or FAIL
-int vim_chdirfile(char_u *fname)
+int vim_chdirfile(char_u *fname, CdCause cause)
{
char dir[MAXPATHL];
@@ -1647,17 +1667,14 @@ int vim_chdirfile(char_u *fname)
NameBuff[0] = NUL;
}
- if (os_chdir(dir) != 0) {
+ if (os_chdir(dir) == 0) {
+ if (cause != kCdCauseOther && pathcmp(dir, (char *)NameBuff, -1) != 0) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow, cause);
+ }
+ } else {
return FAIL;
}
-#ifdef BACKSLASH_IN_FILENAME
- slash_adjust((char_u *)dir);
-#endif
- if (!strequal(dir, (char *)NameBuff)) {
- do_autocmd_dirchanged(dir, kCdScopeWindow, false);
- }
-
return OK;
}
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index f5a4efc371..bd78818ab2 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -269,10 +269,10 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
}
}
- /* Remember the initial values of curbuf, curbuf->b_ffname and
- * curbuf->b_fname to detect whether they are altered as a result of
- * executing nasty autocommands. Also check if "fname" and "sfname"
- * point to one of these values. */
+ // Remember the initial values of curbuf, curbuf->b_ffname and
+ // curbuf->b_fname to detect whether they are altered as a result of
+ // executing nasty autocommands. Also check if "fname" and "sfname"
+ // point to one of these values.
old_curbuf = curbuf;
old_b_ffname = curbuf->b_ffname;
old_b_fname = curbuf->b_fname;
@@ -429,8 +429,8 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
curbuf->b_orig_mode = 0;
}
- /* Reset the "new file" flag. It will be set again below when the
- * file doesn't exist. */
+ // Reset the "new file" flag. It will be set again below when the
+ // file doesn't exist.
curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
}
@@ -514,8 +514,8 @@ int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_ski
}
if (set_options) {
- /* Don't change 'eol' if reading from buffer as it will already be
- * correctly set when reading stdin. */
+ // Don't change 'eol' if reading from buffer as it will already be
+ // correctly set when reading stdin.
if (!read_buffer) {
curbuf->b_p_eol = TRUE;
curbuf->b_start_eol = TRUE;
@@ -816,8 +816,8 @@ retry:
fio_flags = 0;
converted = need_conversion(fenc);
if (converted) {
- /* "ucs-bom" means we need to check the first bytes of the file
- * for a BOM. */
+ // "ucs-bom" means we need to check the first bytes of the file
+ // for a BOM.
if (STRCMP(fenc, ENC_UCSBOM) == 0) {
fio_flags = FIO_UCSBOM;
} else {
@@ -949,16 +949,16 @@ retry:
ptr = buffer + linerest;
line_start = buffer;
- /* May need room to translate into.
- * For iconv() we don't really know the required space, use a
- * factor ICONV_MULT.
- * latin1 to utf-8: 1 byte becomes up to 2 bytes
- * utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
- * become up to 4 bytes, size must be multiple of 2
- * ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
- * multiple of 2
- * ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
- * multiple of 4 */
+ // May need room to translate into.
+ // For iconv() we don't really know the required space, use a
+ // factor ICONV_MULT.
+ // latin1 to utf-8: 1 byte becomes up to 2 bytes
+ // utf-16 to utf-8: 2 bytes become up to 3 bytes, 4 bytes
+ // become up to 4 bytes, size must be multiple of 2
+ // ucs-2 to utf-8: 2 bytes become up to 3 bytes, size must be
+ // multiple of 2
+ // ucs-4 to utf-8: 4 bytes become up to 6 bytes, size must be
+ // multiple of 4
real_size = (int)size;
#ifdef HAVE_ICONV
if (iconv_fd != (iconv_t)-1) {
@@ -1000,9 +1000,9 @@ retry:
p = ml_get(read_buf_lnum) + read_buf_col;
n = (int)STRLEN(p);
if ((int)tlen + n + 1 > size) {
- /* Filled up to "size", append partial line.
- * Change NL to NUL to reverse the effect done
- * below. */
+ // Filled up to "size", append partial line.
+ // Change NL to NUL to reverse the effect done
+ // below.
n = (int)(size - tlen);
for (ni = 0; ni < n; ++ni) {
if (p[ni] == NL) {
@@ -1026,8 +1026,8 @@ retry:
ptr[tlen++] = NL;
read_buf_col = 0;
if (++read_buf_lnum > from) {
- /* When the last line didn't have an
- * end-of-line don't add it now either. */
+ // When the last line didn't have an
+ // end-of-line don't add it now either.
if (!curbuf->b_p_eol) {
--tlen;
}
@@ -1279,8 +1279,8 @@ retry:
}
}
- /* If there is a trailing incomplete sequence move it to
- * conv_rest[]. */
+ // If there is a trailing incomplete sequence move it to
+ // conv_rest[].
if (tail != NULL) {
conv_restlen = (int)((ptr + size) - tail);
memmove(conv_rest, tail, conv_restlen);
@@ -1320,8 +1320,8 @@ retry:
}
}
- /* found second word of double-word, get the first
- * word and compute the resulting character */
+ // found second word of double-word, get the first
+ // word and compute the resulting character
if (fio_flags & FIO_ENDIAN_L) {
u16c = (*--p << 8);
u16c += *--p;
@@ -1369,9 +1369,9 @@ retry:
p -= len;
u8c = utf_ptr2char(p);
if (len == 0) {
- /* Not a valid UTF-8 character, retry with
- * another fenc when possible, otherwise just
- * report the error. */
+ // Not a valid UTF-8 character, retry with
+ // another fenc when possible, otherwise just
+ // report the error.
if (can_retry) {
goto rewind_retry;
}
@@ -1435,9 +1435,9 @@ retry:
}
}
if (l == 1 || l > todo) {
- /* Illegal byte. If we can try another encoding
- * do that, unless at EOF where a truncated
- * file is more likely than a conversion error. */
+ // Illegal byte. If we can try another encoding
+ // do that, unless at EOF where a truncated
+ // file is more likely than a conversion error.
if (can_retry && !incomplete_tail) {
break;
}
@@ -1909,8 +1909,8 @@ failed:
*/
curbuf->b_no_eol_lnum = read_no_eol_lnum;
- /* When reloading a buffer put the cursor at the first line that is
- * different. */
+ // When reloading a buffer put the cursor at the first line that is
+ // different.
if (flags & READ_KEEP_UNDO) {
u_find_first_changed();
}
@@ -1929,8 +1929,8 @@ failed:
int m = msg_scroll;
int n = msg_scrolled;
- /* Save the fileformat now, otherwise the buffer will be considered
- * modified if the format/encoding was automatically detected. */
+ // Save the fileformat now, otherwise the buffer will be considered
+ // modified if the format/encoding was automatically detected.
if (set_options) {
save_file_ff(curbuf);
}
@@ -4804,15 +4804,15 @@ int check_timestamps(int focus)
{
int didit = 0;
- /* Don't check timestamps while system() or another low-level function may
- * cause us to lose and gain focus. */
+ // Don't check timestamps while system() or another low-level function may
+ // cause us to lose and gain focus.
if (no_check_timestamps > 0) {
return FALSE;
}
- /* Avoid doing a check twice. The OK/Reload dialog can cause a focus
- * event and we would keep on checking if the file is steadily growing.
- * Do check again after typing something. */
+ // Avoid doing a check twice. The OK/Reload dialog can cause a focus
+ // event and we would keep on checking if the file is steadily growing.
+ // Do check again after typing something.
if (focus && did_check_timestamps) {
need_check_timestamps = TRUE;
return FALSE;
@@ -5025,8 +5025,8 @@ int buf_check_timestamp(buf_T *buf)
mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started");
mesg2 = _("See \":help W16\" for more info.");
} else {
- /* Only timestamp changed, store it to avoid a warning
- * in check_mtime() later. */
+ // Only timestamp changed, store it to avoid a warning
+ // in check_mtime() later.
buf->b_mtime_read = buf->b_mtime;
}
}
@@ -5623,12 +5623,11 @@ char_u *file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allo
}
#ifdef BACKSLASH_IN_FILENAME
if (!no_bslash) {
- /* translate:
- * "\x" to "\\x" e.g., "dir\file"
- * "\*" to "\\.*" e.g., "dir\*.c"
- * "\?" to "\\." e.g., "dir\??.c"
- * "\+" to "\+" e.g., "fileX\+.c"
- */
+ // translate:
+ // "\x" to "\\x" e.g., "dir\file"
+ // "\*" to "\\.*" e.g., "dir\*.c"
+ // "\?" to "\\." e.g., "dir\??.c"
+ // "\+" to "\+" e.g., "fileX\+.c"
if ((vim_isfilec(p[1]) || p[1] == '*' || p[1] == '?')
&& p[1] != '+') {
reg_pat[i++] = '[';
@@ -5642,16 +5641,15 @@ char_u *file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allo
}
}
#endif
- /* Undo escaping from ExpandEscape():
- * foo\?bar -> foo?bar
- * foo\%bar -> foo%bar
- * foo\,bar -> foo,bar
- * foo\ bar -> foo bar
- * Don't unescape \, * and others that are also special in a
- * regexp.
- * An escaped { must be unescaped since we use magic not
- * verymagic. Use "\\\{n,m\}"" to get "\{n,m}".
- */
+ // Undo escaping from ExpandEscape():
+ // foo\?bar -> foo?bar
+ // foo\%bar -> foo%bar
+ // foo\,bar -> foo,bar
+ // foo\ bar -> foo bar
+ // Don't unescape \, * and others that are also special in a
+ // regexp.
+ // An escaped { must be unescaped since we use magic not
+ // verymagic. Use "\\\{n,m\}"" to get "\{n,m}".
if (*++p == '?'
#ifdef BACKSLASH_IN_FILENAME
&& no_bslash
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 5a2ce74666..e141f9bb62 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -224,8 +224,8 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp
break;
}
- /* Fold found, but it's open: Check nested folds. Line number is
- * relative to containing fold. */
+ // Fold found, but it's open: Check nested folds. Line number is
+ // relative to containing fold.
gap = &fp->fd_nested;
lnum_rel -= fp->fd_top;
++level;
@@ -264,8 +264,8 @@ bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp
*/
int foldLevel(linenr_T lnum)
{
- /* While updating the folds lines between invalid_top and invalid_bot have
- * an undefined fold level. Otherwise update the folds first. */
+ // While updating the folds lines between invalid_top and invalid_bot have
+ // an undefined fold level. Otherwise update the folds first.
if (invalid_top == (linenr_T)0) {
checkupdate(curwin);
} else if (lnum == prev_lnum && prev_lnum_lvl >= 0) {
@@ -492,9 +492,9 @@ static void newFoldLevelWin(win_T *wp)
checkupdate(wp);
if (wp->w_fold_manual) {
- /* Set all flags for the first level of folds to FD_LEVEL. Following
- * manual open/close will then change the flags to FD_OPEN or
- * FD_CLOSED for those folds that don't use 'foldlevel'. */
+ // Set all flags for the first level of folds to FD_LEVEL. Following
+ // manual open/close will then change the flags to FD_OPEN or
+ // FD_CLOSED for those folds that don't use 'foldlevel'.
fp = (fold_T *)wp->w_folds.ga_data;
for (int i = 0; i < wp->w_folds.ga_len; ++i) {
fp[i].fd_flags = FD_LEVEL;
@@ -904,8 +904,8 @@ int foldMoveTo(const bool updown, const int dir, const long count)
break;
}
- /* When moving up, consider a fold above the cursor; when
- * moving down consider a fold below the cursor. */
+ // When moving up, consider a fold above the cursor; when
+ // moving down consider a fold below the cursor.
if (dir == FORWARD) {
if (fp - (fold_T *)gap->ga_data >= gap->ga_len) {
break;
@@ -1424,13 +1424,13 @@ void deleteFoldRecurse(buf_T *bp, garray_T *gap)
*/
void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
- /* If deleting marks from line1 to line2, but not deleting all those
- * lines, set line2 so that only deleted lines have their folds removed. */
+ // If deleting marks from line1 to line2, but not deleting all those
+ // lines, set line2 so that only deleted lines have their folds removed.
if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) {
line2 = line1 - amount_after - 1;
}
- /* If appending a line in Insert mode, it should be included in the fold
- * just above the line. */
+ // If appending a line in Insert mode, it should be included in the fold
+ // just above the line.
if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
line1--;
}
@@ -1449,8 +1449,8 @@ static void foldMarkAdjustRecurse(win_T *wp, garray_T *gap, linenr_T line1, line
return;
}
- /* In Insert mode an inserted line at the top of a fold is considered part
- * of the fold, otherwise it isn't. */
+ // In Insert mode an inserted line at the top of a fold is considered part
+ // of the fold, otherwise it isn't.
if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) {
top = line1 + 1;
} else {
@@ -1580,8 +1580,8 @@ static bool check_closed(win_T *const wp, fold_T *const fp, bool *const use_leve
{
bool closed = false;
- /* Check if this fold is closed. If the flag is FD_LEVEL this
- * fold and all folds it contains depend on 'foldlevel'. */
+ // Check if this fold is closed. If the flag is FD_LEVEL this
+ // fold and all folds it contains depend on 'foldlevel'.
if (*use_levelp || fp->fd_flags == FD_LEVEL) {
*use_levelp = true;
if (level >= wp->w_p_fdl) {
@@ -2035,8 +2035,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
// Init marker variables to speed up foldlevelMarker().
parseMarker(wp);
- /* Need to get the level of the line above top, it is used if there is
- * no marker at the top. */
+ // Need to get the level of the line above top, it is used if there is
+ // no marker at the top.
if (top > 1) {
// Get the fold level at top - 1.
const int level = foldLevelWin(wp, top - 1);
@@ -2046,9 +2046,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
fline.lvl = level;
getlevel(&fline);
- /* If a fold started here, we already had the level, if it stops
- * here, we need to use lvl_next. Could also start and end a fold
- * in the same line. */
+ // If a fold started here, we already had the level, if it stops
+ // here, we need to use lvl_next. Could also start and end a fold
+ // in the same line.
if (fline.lvl > level) {
fline.lvl = level - (fline.lvl - fline.lvl_next);
} else {
@@ -2061,8 +2061,8 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
fline.lnum = top;
if (foldmethodIsExpr(wp)) {
getlevel = foldlevelExpr;
- /* start one line back, because a "<1" may indicate the end of a
- * fold in the topline */
+ // start one line back, because a "<1" may indicate the end of a
+ // fold in the topline
if (top > 1) {
--fline.lnum;
}
@@ -2151,9 +2151,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
end = fp->fd_top + fp->fd_len - 1;
} else if (getlevel == foldlevelSyntax
&& foldLevelWin(wp, fline.lnum) != fline.lvl) {
- /* For "syntax" method: Compare the foldlevel that the syntax
- * tells us to the foldlevel from the existing folds. If they
- * don't match continue updating folds. */
+ // For "syntax" method: Compare the foldlevel that the syntax
+ // tells us to the foldlevel from the existing folds. If they
+ // don't match continue updating folds.
end = fline.lnum;
} else {
break;
@@ -2185,9 +2185,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
changed_window_setting_win(wp);
}
- /* If we updated folds past "bot", need to redraw more lines. Don't do
- * this in other situations, the changed lines will be redrawn anyway and
- * this method can cause the whole window to be updated. */
+ // If we updated folds past "bot", need to redraw more lines. Don't do
+ // this in other situations, the changed lines will be redrawn anyway and
+ // this method can cause the whole window to be updated.
if (end != bot) {
if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) {
wp->w_redraw_top = top;
@@ -2272,10 +2272,10 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
// Updating folds can be slow, check for CTRL-C.
line_breakcheck();
- /* Set "lvl" to the level of line "flp->lnum". When flp->start is set
- * and after the first line of the fold, set the level to zero to
- * force the fold to end. Do the same when had_end is set: Previous
- * line was marked as end of a fold. */
+ // Set "lvl" to the level of line "flp->lnum". When flp->start is set
+ // and after the first line of the fold, set the level to zero to
+ // force the fold to end. Do the same when had_end is set: Previous
+ // line was marked as end of a fold.
lvl = flp->lvl;
if (lvl > MAX_LEVEL) {
lvl = MAX_LEVEL;
@@ -2286,12 +2286,11 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
}
if (flp->lnum > bot && !finish && fp != NULL) {
- /* For "marker" and "syntax" methods:
- * - If a change caused a nested fold to be removed, we need to
- * delete it and continue at least until where it ended.
- * - If a change caused a nested fold to be created, or this fold
- * to continue below its original end, need to finish this fold.
- */
+ // For "marker" and "syntax" methods:
+ // - If a change caused a nested fold to be removed, we need to
+ // delete it and continue at least until where it ended.
+ // - If a change caused a nested fold to be created, or this fold
+ // to continue below its original end, need to finish this fold.
if (getlevel != foldlevelMarker
&& getlevel != foldlevelExpr
&& getlevel != foldlevelSyntax) {
@@ -2300,9 +2299,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
i = 0;
fp2 = fp;
if (lvl >= level) {
- /* Compute how deep the folds currently are, if it's deeper
- * than "lvl" then some must be deleted, need to update
- * at least one nested fold. */
+ // Compute how deep the folds currently are, if it's deeper
+ // than "lvl" then some must be deleted, need to update
+ // at least one nested fold.
ll = flp->lnum - fp->fd_top;
while (foldFind(&fp2->fd_nested, ll, &fp2)) {
++i;
@@ -2321,9 +2320,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
}
}
- /* At the start of the first nested fold and at the end of the current
- * fold: check if existing folds at this level, before the current
- * one, need to be deleted or truncated. */
+ // At the start of the first nested fold and at the end of the current
+ // fold: check if existing folds at this level, before the current
+ // one, need to be deleted or truncated.
if (fp == NULL
&& (lvl != level
|| flp->lnum_save >= bot
@@ -2356,10 +2355,10 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
|| (lvl >= level
&& fp->fd_top <= flp->lnum_save))))) {
if (fp->fd_top + fp->fd_len + concat > firstlnum) {
- /* Use existing fold for the new fold. If it starts
- * before where we started looking, extend it. If it
- * starts at another line, update nested folds to keep
- * their position, compensating for the new fd_top. */
+ // Use existing fold for the new fold. If it starts
+ // before where we started looking, extend it. If it
+ // starts at another line, update nested folds to keep
+ // their position, compensating for the new fd_top.
if (fp->fd_top == firstlnum) {
// We have found a fold beginning exactly where we want one.
} else if (fp->fd_top >= startlnum) {
@@ -2503,8 +2502,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
bot = flp->lnum;
}
- /* Line numbers in the nested fold are relative to the start of
- * this fold. */
+ // Line numbers in the nested fold are relative to the start of
+ // this fold.
flp->lnum = flp->lnum_save - fp->fd_top;
flp->off += fp->fd_top;
i = (int)(fp - (fold_T *)gap->ga_data);
@@ -2547,8 +2546,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
break;
}
- /* leave flp->lnum_save to lnum of the line that was used to get
- * the level, flp->lnum to the lnum of the next line. */
+ // leave flp->lnum_save to lnum of the line that was used to get
+ // the level, flp->lnum to the lnum of the next line.
flp->lnum_save = flp->lnum;
flp->lnum = ll;
}
@@ -2633,8 +2632,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level,
deleteFoldEntry(flp->wp, gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
}
- /* Need to redraw the lines we inspected, which might be further down than
- * was asked for. */
+ // Need to redraw the lines we inspected, which might be further down than
+ // was asked for.
if (bot < flp->lnum - 1) {
bot = flp->lnum - 1;
}
@@ -2947,8 +2946,8 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2)
garray_T *gap1 = &fp1->fd_nested;
garray_T *gap2 = &fp2->fd_nested;
- /* If the last nested fold in fp1 touches the first nested fold in fp2,
- * merge them recursively. */
+ // If the last nested fold in fp1 touches the first nested fold in fp2,
+ // merge them recursively.
if (foldFind(gap1, fp1->fd_len - 1L, &fp3) && foldFind(gap2, 0L, &fp4)) {
foldMerge(wp, fp3, gap2, fp4);
}
@@ -2985,8 +2984,8 @@ static void foldlevelIndent(fline_T *flp)
buf = flp->wp->w_buffer;
s = skipwhite(ml_get_buf(buf, lnum, false));
- /* empty line or lines starting with a character in 'foldignore': level
- * depends on surrounding lines */
+ // empty line or lines starting with a character in 'foldignore': level
+ // depends on surrounding lines
if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) {
// first and last line can't be undefined, use level 0
if (lnum == 1 || lnum == buf->b_ml.ml_line_count) {
@@ -3089,8 +3088,8 @@ static void foldlevelExpr(fline_T *flp)
// "-1", "0", "1", ..: set fold level
default:
if (n < 0) {
- /* Use the current level for the next line, so that "a1"
- * will work there. */
+ // Use the current level for the next line, so that "a1"
+ // will work there.
flp->lvl_next = flp->lvl;
} else {
flp->lvl_next = n;
@@ -3099,8 +3098,8 @@ static void foldlevelExpr(fline_T *flp)
break;
}
- /* If the level is unknown for the first or the last line in the file, use
- * level 0. */
+ // If the level is unknown for the first or the last line in the file, use
+ // level 0.
if (flp->lvl < 0) {
if (lnum <= 1) {
flp->lvl = 0;
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
index a5f76e1c6a..f35817c466 100644
--- a/src/nvim/generators/c_grammar.lua
+++ b/src/nvim/generators/c_grammar.lua
@@ -16,6 +16,7 @@ local ws = S(' \t') + nl
local fill = ws ^ 0
local c_comment = P('//') * (not_nl ^ 0)
local c_preproc = P('#') * (not_nl ^ 0)
+local dllexport = P('DLLEXPORT') * (ws ^ 1)
local typed_container =
(P('ArrayOf(') + P('DictionaryOf(') + P('Dict(')) * ((any - P(')')) ^ 1) * P(')')
local c_id = (
@@ -33,6 +34,7 @@ local c_param = Ct(c_param_type * C(c_id))
local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0)
local c_params = Ct(c_void + c_param_list)
local c_proto = Ct(
+ (dllexport ^ -1) *
Cg(c_type, 'return_type') * Cg(c_id, 'name') *
fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
Cg(Cc(false), 'fast') *
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
index e38a0af0ec..21f8c3855e 100644
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -419,7 +419,7 @@ local function process_function(fn)
if not fn.fast then
write_shifted_output(output, string.format([[
- if (!nlua_is_deferred_safe(lstate)) {
+ if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "%s");
}
]], fn.name))
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
index 97491679a4..c7d5a1a191 100755
--- a/src/nvim/generators/gen_declarations.lua
+++ b/src/nvim/generators/gen_declarations.lua
@@ -216,7 +216,16 @@ local footer = [[
#include "nvim/func_attr.h"
]]
-local non_static = header
+local non_static = header .. [[
+#ifndef DLLEXPORT
+# ifdef WIN32
+# define DLLEXPORT __declspec(dllexport)
+# else
+# define DLLEXPORT
+# endif
+#endif
+]]
+
local static = header
local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"'
@@ -269,6 +278,7 @@ while init ~= nil do
declaration = declaration:gsub(' $', '')
declaration = declaration:gsub('^ ', '')
declaration = declaration .. ';'
+
if os.getenv('NVIM_GEN_DECLARATIONS_LINE_NUMBERS') == '1' then
declaration = declaration .. (' // %s/%s:%u'):format(
curdir, curfile, declline)
@@ -277,6 +287,7 @@ while init ~= nil do
if declaration:sub(1, 6) == 'static' then
static = static .. declaration
else
+ declaration = 'DLLEXPORT ' .. declaration
non_static = non_static .. declaration
end
declendpos = e
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 1d120bbe6b..73cfffb0fb 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -335,7 +335,7 @@ EXTERN int garbage_collect_at_exit INIT(= false);
#define SID_WINLAYOUT -7 // changing window size
#define SID_LUA -8 // for Lua scripts/chunks
#define SID_API_CLIENT -9 // for API clients
-#define SID_STR -10 // for sourcing a string
+#define SID_STR -10 // for sourcing a string with no script item
// Script CTX being sourced or was sourced to define the current function.
EXTERN sctx_T current_sctx INIT(= { 0 COMMA 0 COMMA 0 });
@@ -1034,14 +1034,22 @@ typedef enum {
/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead.
typedef enum {
kCdScopeInvalid = -1,
- kCdScopeWindow, ///< Affects one window.
- kCdScopeTab, ///< Affects one tab page.
- kCdScopeGlobal, ///< Affects the entire Nvim instance.
+ kCdScopeWindow, ///< Affects one window.
+ kCdScopeTabpage, ///< Affects one tab page.
+ kCdScopeGlobal, ///< Affects the entire Nvim instance.
} CdScope;
#define MIN_CD_SCOPE kCdScopeWindow
#define MAX_CD_SCOPE kCdScopeGlobal
+/// What caused the current directory to change.
+typedef enum {
+ kCdCauseOther = -1,
+ kCdCauseManual, ///< Using `:cd`, `:tcd`, `:lcd` or `chdir()`.
+ kCdCauseWindow, ///< Switching to another window.
+ kCdCauseAuto, ///< On 'autochdir'.
+} CdCause;
+
// Only filled for Win32.
EXTERN char windowsVersion[20] INIT(= { 0 });
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 3f93bb9a09..59ebafd9c8 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -790,7 +790,7 @@ int nlua_call(lua_State *lstate)
Error err = ERROR_INIT;
size_t name_len;
const char_u *name = (const char_u *)luaL_checklstring(lstate, 1, &name_len);
- if (!nlua_is_deferred_safe(lstate)) {
+ if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "vimL function");
}
@@ -846,7 +846,7 @@ free_vim_args:
static int nlua_rpcrequest(lua_State *lstate)
{
- if (!nlua_is_deferred_safe(lstate)) {
+ if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "rpcrequest");
}
return nlua_rpc(lstate, true);
@@ -1316,7 +1316,7 @@ Object nlua_call_ref(LuaRef ref, const char *name, Array args, bool retval, Erro
/// check if the current execution context is safe for calling deferred API
/// methods. Luv callbacks are unsafe as they are called inside the uv loop.
-bool nlua_is_deferred_safe(lua_State *lstate)
+bool nlua_is_deferred_safe(void)
{
return in_fast_callback == 0;
}
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
index 5ca4cc82a5..51b7430957 100644
--- a/src/nvim/lua/vim.lua
+++ b/src/nvim/lua/vim.lua
@@ -57,28 +57,29 @@ end
function vim._load_package(name)
local basename = name:gsub('%.', '/')
local paths = {"lua/"..basename..".lua", "lua/"..basename.."/init.lua"}
- for _,path in ipairs(paths) do
- local found = vim.api.nvim_get_runtime_file(path, false)
- if #found > 0 then
- local f, err = loadfile(found[1])
- return f or error(err)
- end
+ local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true})
+ if #found > 0 then
+ local f, err = loadfile(found[1])
+ return f or error(err)
end
+ local so_paths = {}
for _,trail in ipairs(vim._so_trails) do
local path = "lua"..trail:gsub('?', basename) -- so_trails contains a leading slash
- local found = vim.api.nvim_get_runtime_file(path, false)
- if #found > 0 then
- -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
- -- a) strip prefix up to and including the first dash, if any
- -- b) replace all dots by underscores
- -- c) prepend "luaopen_"
- -- So "foo-bar.baz" should result in "luaopen_bar_baz"
- local dash = name:find("-", 1, true)
- local modname = dash and name:sub(dash + 1) or name
- local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
- return f or error(err)
- end
+ table.insert(so_paths, path)
+ end
+
+ found = vim.api.nvim__get_runtime(so_paths, false, {is_lua=true})
+ if #found > 0 then
+ -- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
+ -- a) strip prefix up to and including the first dash, if any
+ -- b) replace all dots by underscores
+ -- c) prepend "luaopen_"
+ -- So "foo-bar.baz" should result in "luaopen_bar_baz"
+ local dash = name:find("-", 1, true)
+ local modname = dash and name:sub(dash + 1) or name
+ local f, err = package.loadlib(found[1], "luaopen_"..modname:gsub("%.", "_"))
+ return f or error(err)
end
return nil
end
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 9a82eccc6f..00a43c9c79 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -583,9 +583,9 @@ void getout(int exitval)
{
exiting = true;
- /* When running in Ex mode an error causes us to exit with a non-zero exit
- * code. POSIX requires this, although it's not 100% clear from the
- * standard. */
+ // When running in Ex mode an error causes us to exit with a non-zero exit
+ // code. POSIX requires this, although it's not 100% clear from the
+ // standard.
if (exmode_active) {
exitval += ex_exitval;
}
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 835c2adbe5..ea9acdf31a 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -121,8 +121,8 @@ int setmark_pos(int c, pos_T *pos, int fnum)
return OK;
}
- /* Allow setting '[ and '] for an autocommand that simulates reading a
- * file. */
+ // Allow setting '[ and '] for an autocommand that simulates reading a
+ // file.
if (c == '[') {
buf->b_op_start = *pos;
return OK;
@@ -338,8 +338,8 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
posp = NULL;
- /* Check for special key, can't be a mark name and might cause islower()
- * to crash. */
+ // Check for special key, can't be a mark name and might cause islower()
+ // to crash.
if (c < 0) {
return posp;
}
@@ -434,8 +434,7 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
}
pos_copy.lnum = -1; // can't get file
} else {
- pos_copy.lnum = 0; /* mark exists, but is not valid in
- current buffer */
+ pos_copy.lnum = 0; // mark exists, but is not valid in current buffer
}
}
}
@@ -457,10 +456,10 @@ pos_T *getnextmark(pos_T *startpos, int dir, int begin_line)
pos = *startpos;
- /* When searching backward and leaving the cursor on the first non-blank,
- * position must be in a previous line.
- * When searching forward and leaving the cursor on the first non-blank,
- * position must be in a next line. */
+ // When searching backward and leaving the cursor on the first non-blank,
+ // position must be in a previous line.
+ // When searching forward and leaving the cursor on the first non-blank,
+ // position must be in a next line.
if (dir == BACKWARD && begin_line) {
pos.col = 0;
} else if (dir == FORWARD && begin_line) {
@@ -569,8 +568,8 @@ int check_mark(pos_T *pos)
return FAIL;
}
if (pos->lnum <= 0) {
- /* lnum is negative if mark is in another file can can't get that
- * file, error message already give then. */
+ // lnum is negative if mark is in another file can can't get that
+ // file, error message already give then.
if (pos->lnum == 0) {
EMSG(_(e_marknotset));
}
@@ -1058,9 +1057,9 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo
*/
FOR_ALL_TAB_WINDOWS(tab, win) {
if (!cmdmod.lockmarks) {
- /* Marks in the jumplist. When deleting lines, this may create
- * duplicate marks in the jumplist, they will be removed later. */
- for (i = 0; i < win->w_jumplistlen; ++i) {
+ // Marks in the jumplist. When deleting lines, this may create
+ // duplicate marks in the jumplist, they will be removed later.
+ for (i = 0; i < win->w_jumplistlen; i++) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum));
}
@@ -1083,8 +1082,8 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo
one_adjust_nodel(&(win->w_old_visual_lnum));
}
- /* topline and cursor position for windows with the same buffer
- * other than the current window */
+ // topline and cursor position for windows with the same buffer
+ // other than the current window
if (win != curwin) {
if (win->w_topline >= line1 && win->w_topline <= line2) {
if (amount == MAXLNUM) { // topline is deleted
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index fd7012e895..39c1e36147 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -467,7 +467,7 @@ static mtnode_t *merge_node(MarkTree *b, mtnode_t *p, int i)
unrelative(x->key[x->n].pos, &x->key[x->n+1+k].pos);
}
if (x->level) {
- memmove(&x->ptr[x->n+1], y->ptr, (size_t)(y->n + 1) * sizeof(mtnode_t *));
+ memmove(&x->ptr[x->n+1], y->ptr, ((size_t)y->n + 1) * sizeof(mtnode_t *));
for (int k = 0; k < y->n+1; k++) {
x->ptr[x->n+k+1]->parent = x;
}
@@ -489,7 +489,7 @@ static void pivot_right(MarkTree *b, mtnode_t *p, int i)
mtnode_t *x = p->ptr[i], *y = p->ptr[i+1];
memmove(&y->key[1], y->key, (size_t)y->n * sizeof(mtkey_t));
if (y->level) {
- memmove(&y->ptr[1], y->ptr, (size_t)(y->n + 1) * sizeof(mtnode_t *));
+ memmove(&y->ptr[1], y->ptr, ((size_t)y->n + 1) * sizeof(mtnode_t *));
}
y->key[0] = p->key[i];
refkey(b, y, 0);
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 253ddfc253..62cc3b56ed 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -190,9 +190,9 @@ enc_canon_table[] =
#define IDX_BIG5 29
{ "big5", ENC_DBCS, DBCS_CHT },
- /* MS-DOS and MS-Windows codepages are included here, so that they can be
- * used on Unix too. Most of them are similar to ISO-8859 encodings, but
- * not exactly the same. */
+ // MS-DOS and MS-Windows codepages are included here, so that they can be
+ // used on Unix too. Most of them are similar to ISO-8859 encodings, but
+ // not exactly the same.
#define IDX_CP437 30
{ "cp437", ENC_8BIT, 437 }, // like iso-8859-1
#define IDX_CP737 31
@@ -1066,8 +1066,8 @@ bool utf_printable(int c)
*/
return iswprint(c);
#else
- /* Sorted list of non-overlapping intervals.
- * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */
+ // Sorted list of non-overlapping intervals.
+ // 0xd800-0xdfff is reserved for UTF-16, actually illegal.
static struct interval nonprint[] =
{
{ 0x070f, 0x070f }, { 0x180b, 0x180e }, { 0x200b, 0x200f }, { 0x202a, 0x202e },
@@ -1354,12 +1354,12 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2
return c1 == 0 ? -1 : 1;
}
- /* Continue with bytewise comparison to produce some result that
- * would make comparison operations involving this function transitive.
- *
- * If only one string had an error, comparison should be made with
- * folded version of the other string. In this case it is enough
- * to fold just one character to determine the result of comparison. */
+ // Continue with bytewise comparison to produce some result that
+ // would make comparison operations involving this function transitive.
+ //
+ // If only one string had an error, comparison should be made with
+ // folded version of the other string. In this case it is enough
+ // to fold just one character to determine the result of comparison.
if (c1 != -1 && c2 == -1) {
n1 = utf_char2bytes(utf_fold(c1), buffer);
@@ -1637,8 +1637,8 @@ int utf_head_off(const char_u *base, const char_u *p)
while (q > base && (*q & 0xc0) == 0x80) {
--q;
}
- /* Check for illegal sequence. Do allow an illegal byte after where we
- * started. */
+ // Check for illegal sequence. Do allow an illegal byte after where we
+ // started.
len = utf8len_tab[*q];
if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) {
return 0;
@@ -2335,8 +2335,8 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen
fromlen = slen;
for (;; ) {
if (len == 0 || ICONV_ERRNO == ICONV_E2BIG) {
- /* Allocate enough room for most conversions. When re-allocating
- * increase the buffer size. */
+ // Allocate enough room for most conversions. When re-allocating
+ // increase the buffer size.
len = len + fromlen * 2 + 40;
p = xmalloc(len);
if (done > 0) {
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 20ae5a4042..0874af5ee1 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -200,17 +200,17 @@ struct block0 {
*/
#define b0_flags b0_fname[B0_FNAME_SIZE_ORG - 2]
-/* The lowest two bits contain the fileformat. Zero means it's not set
- * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
- * EOL_MAC + 1. */
+// The lowest two bits contain the fileformat. Zero means it's not set
+// (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
+// EOL_MAC + 1.
#define B0_FF_MASK 3
-/* Swap file is in directory of edited file. Used to find the file from
- * different mount points. */
+// Swap file is in directory of edited file. Used to find the file from
+// different mount points.
#define B0_SAME_DIR 4
-/* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
- * When empty there is only the NUL. */
+// The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
+// When empty there is only the NUL.
#define B0_HAS_FENC 8
#define STACK_INCR 5 // nr of entries added to ml_stack at a time
@@ -524,9 +524,9 @@ void ml_open_file(buf_T *buf)
// Flush block zero, so others can read it
if (mf_sync(mfp, MFS_ZERO) == OK) {
- /* Mark all blocks that should be in the swapfile as dirty.
- * Needed for when the 'swapfile' option was reset, so that
- * the swap file was deleted, and then on again. */
+ // Mark all blocks that should be in the swapfile as dirty.
+ // Needed for when the 'swapfile' option was reset, so that
+ // the swap file was deleted, and then on again.
mf_set_dirty(mfp);
break;
}
@@ -580,8 +580,8 @@ void ml_close(buf_T *buf, int del_file)
XFREE_CLEAR(buf->b_ml.ml_chunksize);
buf->b_ml.ml_mfp = NULL;
- /* Reset the "recovered" flag, give the ATTENTION prompt the next time
- * this buffer is loaded. */
+ // Reset the "recovered" flag, give the ATTENTION prompt the next time
+ // this buffer is loaded.
buf->b_flags &= ~BF_RECOVERED;
}
@@ -860,8 +860,8 @@ void ml_recover(bool checkext)
/*
* open the memfile from the old swap file
*/
- p = vim_strsave(fname_used); /* save "fname_used" for the message:
- mf_open() will consume "fname_used"! */
+ p = vim_strsave(fname_used); // save "fname_used" for the message:
+ // mf_open() will consume "fname_used"!
mfp = mf_open(fname_used, O_RDONLY);
fname_used = p;
if (mfp == NULL || mfp->mf_fd < 0) {
@@ -1199,8 +1199,8 @@ void ml_recover(bool checkext)
* Line ml_line_count + 1 in the dummy empty line.
*/
if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1) {
- /* Recovering an empty file results in two lines and the first line is
- * empty. Don't set the modified flag then. */
+ // Recovering an empty file results in two lines and the first line is
+ // empty. Don't set the modified flag then.
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) {
changed_internal();
buf_inc_changedtick(curbuf);
@@ -1305,8 +1305,8 @@ int recover_names(char_u *fname, int list, int nr, char_u **fname_out)
if (fname != NULL) {
#ifdef HAVE_READLINK
- /* Expand symlink in the file name, because the swap file is created
- * with the actual file instead of with the symlink. */
+ // Expand symlink in the file name, because the swap file is created
+ // with the actual file instead of with the symlink.
if (resolve_symlink(fname, fname_buf) == OK) {
fname_res = fname_buf;
} else
@@ -1761,9 +1761,9 @@ void ml_preserve(buf_T *buf, int message, bool do_fsync)
return;
}
- /* We only want to stop when interrupted here, not when interrupted
- * before. */
- got_int = FALSE;
+ // We only want to stop when interrupted here, not when interrupted
+ // before.
+ got_int = false;
ml_flush_line(buf); // flush buffered line
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block
@@ -3222,9 +3222,9 @@ int resolve_symlink(const char_u *fname, char_u *buf)
ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
if (ret <= 0) {
if (errno == EINVAL || errno == ENOENT) {
- /* Found non-symlink or not existing file, stop here.
- * When at the first level use the unmodified name, skip the
- * call to vim_FullName(). */
+ // Found non-symlink or not existing file, stop here.
+ // When at the first level use the unmodified name, skip the
+ // call to vim_FullName().
if (depth == 1) {
return FAIL;
}
@@ -4200,8 +4200,8 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
size += lnum - 1;
}
- /* Don't count the last line break if 'noeol' and ('bin' or
- * 'nofixeol'). */
+ // Don't count the last line break if 'noeol' and ('bin' or
+ // 'nofixeol').
if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
&& lnum > buf->b_ml.ml_line_count) {
size -= ffdos + 1;
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 85e062009a..d89f58163f 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -343,8 +343,8 @@ static int add_menu_path(const char_u *const menu_path, vimmenu_T *menuarg,
}
menup = &menu->next;
- /* Count menus, to find where this one needs to be inserted.
- * Ignore menus that are not in the menubar (PopUp and Toolbar) */
+ // Count menus, to find where this one needs to be inserted.
+ // Ignore menus that are not in the menubar (PopUp and Toolbar)
if (parent != NULL || menu_is_menubar(menu->name)) {
if (menu->priority <= pri_tab[pri_idx]) {
lower_pri = menup;
@@ -596,8 +596,8 @@ static int remove_menu(vimmenu_T **menup, char_u *name, int modes, bool silent)
break;
}
- /* Remove the menu item for the given mode[s]. If the menu item
- * is no longer valid in ANY mode, delete it */
+ // Remove the menu item for the given mode[s]. If the menu item
+ // is no longer valid in ANY mode, delete it
menu->modes &= ~modes;
if (modes & MENU_TIP_MODE) {
free_menu_string(menu, MENU_INDEX_TIP);
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 493c704f42..732e5ffc1f 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -349,8 +349,8 @@ static const struct nv_cmd {
// Sorted index of commands in nv_cmds[].
static short nv_cmd_idx[NV_CMDS_SIZE];
-/* The highest index for which
- * nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char] */
+// The highest index for which
+// nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]
static int nv_max_linear;
/*
@@ -3623,8 +3623,8 @@ void do_check_scrollbind(bool check)
static colnr_T old_leftcol = 0;
if (check && curwin->w_p_scb) {
- /* If a ":syncbind" command was just used, don't scroll, only reset
- * the values. */
+ // If a ":syncbind" command was just used, don't scroll, only reset
+ // the values.
if (did_syncbind) {
did_syncbind = false;
} else if (curwin == old_curwin) {
@@ -4264,8 +4264,8 @@ void scroll_redraw(int up, long count)
break;
}
}
- /* Mark w_topline as valid, otherwise the screen jumps back at the
- * end of the file. */
+ // Mark w_topline as valid, otherwise the screen jumps back at the
+ // end of the file.
check_cursor_moved(curwin);
curwin->w_valid |= VALID_TOPLINE;
}
@@ -4712,9 +4712,9 @@ dozet:
if (ptr == NULL) {
pos_T pos = curwin->w_cursor;
- /* Find bad word under the cursor. When 'spell' is
- * off this fails and find_ident_under_cursor() is
- * used below. */
+ // Find bad word under the cursor. When 'spell' is
+ // off this fails and find_ident_under_cursor() is
+ // used below.
emsg_off++;
len = spell_move_to(curwin, FORWARD, true, true, NULL);
emsg_off--;
@@ -4833,10 +4833,8 @@ static void nv_colon(cmdarg_T *cap)
&& (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
|| cap->oap->start.col >
(colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
- || did_emsg
- )) {
- /* The start of the operator has become invalid by the Ex command.
- */
+ || did_emsg)) {
+ // The start of the operator has become invalid by the Ex command.
clearopbeep(cap->oap);
}
}
@@ -5667,8 +5665,8 @@ static int normal_search(cmdarg_T *cap, int dir, char_u *pat, int opt, int *wrap
}
}
- /* "/$" will put the cursor after the end of the line, may need to
- * correct that here */
+ // "/$" will put the cursor after the end of the line, may need to
+ // correct that here
check_cursor();
return i;
}
@@ -5848,16 +5846,15 @@ static void nv_brackets(cmdarg_T *cap)
}
c = gchar_cursor();
if (c == '{' || c == '}') {
- /* Must have found end/start of class: use it.
- * Or found the place to be at. */
+ // Must have found end/start of class: use it.
+ // Or found the place to be at.
if ((c == findc && norm) || (n == 1 && !norm)) {
new_pos = curwin->w_cursor;
pos = &new_pos;
n = 0;
- }
- /* if no match found at all, we started outside of the
- * class and we're inside now. Just go on. */
- else if (new_pos.lnum == 0) {
+ } else if (new_pos.lnum == 0) {
+ // if no match found at all, we started outside of the
+ // class and we're inside now. Just go on.
new_pos = curwin->w_cursor;
pos = &new_pos;
}
@@ -6306,8 +6303,8 @@ static void v_swap_corners(int cmdchar)
curwin->w_cursor.lnum = old_cursor.lnum;
curwin->w_curswant = right;
- /* 'selection "exclusive" and cursor at right-bottom corner: move it
- * right one column */
+ // 'selection "exclusive" and cursor at right-bottom corner: move it
+ // right one column
if (old_cursor.lnum >= VIsual.lnum && *p_sel == 'e') {
++curwin->w_curswant;
}
@@ -6479,8 +6476,8 @@ static void v_visop(cmdarg_T *cap)
{
static char_u trans[] = "YyDdCcxdXdAAIIrr";
- /* Uppercase means linewise, except in block mode, then "D" deletes till
- * the end of the line, and "C" replaces till EOL */
+ // Uppercase means linewise, except in block mode, then "D" deletes till
+ // the end of the line, and "C" replaces till EOL
if (isupper(cap->cmdchar)) {
if (VIsual_mode != Ctrl_V) {
VIsual_mode_orig = VIsual_mode;
@@ -6912,8 +6909,8 @@ static void nv_g_cmd(cmdarg_T *cap)
VIsual_active = true;
VIsual_reselect = true;
- /* Set Visual to the start and w_cursor to the end of the Visual
- * area. Make sure they are on an existing character. */
+ // Set Visual to the start and w_cursor to the end of the Visual
+ // area. Make sure they are on an existing character.
check_cursor();
VIsual = curwin->w_cursor;
curwin->w_cursor = tpos;
@@ -6956,10 +6953,9 @@ static void nv_g_cmd(cmdarg_T *cap)
nv_visual(cap);
break;
- /* "gn", "gN" visually select next/previous search match
- * "gn" selects next match
- * "gN" selects previous match
- */
+ // "gn", "gN" visually select next/previous search match
+ // "gn" selects next match
+ // "gN" selects previous match
case 'N':
case 'n':
if (!current_search(cap->count1, cap->nchar == 'n')) {
@@ -7033,9 +7029,9 @@ static void nv_g_cmd(cmdarg_T *cap)
} else {
i = curwin->w_leftcol;
}
- /* Go to the middle of the screen line. When 'number' or
- * 'relativenumber' is on and lines are wrapping the middle can be more
- * to the left. */
+ // Go to the middle of the screen line. When 'number' or
+ // 'relativenumber' is on and lines are wrapping the middle can be more
+ // to the left.
if (cap->nchar == 'm') {
i += (curwin->w_width_inner - curwin_col_off()
+ ((curwin->w_p_wrap && i > 0)
@@ -7683,11 +7679,10 @@ static void nv_wordcmd(cmdarg_T *cap)
*/
static void adjust_cursor(oparg_T *oap)
{
- /* The cursor cannot remain on the NUL when:
- * - the column is > 0
- * - not in Visual mode or 'selection' is "o"
- * - 'virtualedit' is not "all" and not "onemore".
- */
+ // The cursor cannot remain on the NUL when:
+ // - the column is > 0
+ // - not in Visual mode or 'selection' is "o"
+ // - 'virtualedit' is not "all" and not "onemore".
if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL
&& (!VIsual_active || *p_sel == 'o')
&& !virtual_active() &&
@@ -7956,8 +7951,8 @@ static void nv_edit(cmdarg_T *cap)
if (curwin->w_cursor.coladd && cap->cmdchar != 'A') {
int save_State = State;
- /* Pretend Insert mode here to allow the cursor on the
- * character past the end of the line */
+ // Pretend Insert mode here to allow the cursor on the
+ // character past the end of the line
State = INSERT;
coladvance(getviscol());
State = save_State;
@@ -7974,9 +7969,9 @@ static void invoke_edit(cmdarg_T *cap, int repl, int cmd, int startln)
{
int restart_edit_save = 0;
- /* Complicated: When the user types "a<C-O>a" we don't want to do Insert
- * mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow
- * it. */
+ // Complicated: When the user types "a<C-O>a" we don't want to do Insert
+ // mode recursively. But when doing "a<C-O>." or "a<C-O>rx" we do allow
+ // it.
if (repl || !stuff_empty()) {
restart_edit_save = restart_edit;
} else {
@@ -8260,8 +8255,8 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
&& curwin->w_cursor.col < curbuf->b_op_start.col)
|| (VIsual_mode == 'V'
&& curwin->w_cursor.lnum < curbuf->b_op_start.lnum)) {
- /* cursor is at the end of the line or end of file, put
- * forward. */
+ // cursor is at the end of the line or end of file, put
+ // forward.
dir = FORWARD;
}
// May have been reset in do_put().
@@ -8275,8 +8270,8 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
xfree(savereg);
}
- /* What to reselect with "gv"? Selecting the just put text seems to
- * be the most useful, since the original text was removed. */
+ // What to reselect with "gv"? Selecting the just put text seems to
+ // be the most useful, since the original text was removed.
if (was_visual) {
curbuf->b_visual.vi_start = curbuf->b_op_start;
curbuf->b_visual.vi_end = curbuf->b_op_end;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 8bc2b3781a..55c34586cb 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -435,9 +435,9 @@ static void shift_block(oparg_T *oap, int amount)
* non-whitespace character.
*/
- /* If "bd.startspaces" is set, "bd.textstart" points to the character,
- * the part of which is displayed at the block's beginning. Let's start
- * searching from the next character. */
+ // If "bd.startspaces" is set, "bd.textstart" points to the character,
+ // the part of which is displayed at the block's beginning. Let's start
+ // searching from the next character.
if (bd.startspaces) {
MB_PTR_ADV(non_white);
}
@@ -614,8 +614,8 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
skipped, offset-startcol, kExtmarkUndo);
if (lnum == oap->end.lnum) {
- /* Set "']" mark to the end of the block instead of the end of
- * the insert in the first line. */
+ // Set "']" mark to the end of the block instead of the end of
+ // the insert in the first line.
curbuf->b_op_end.lnum = oap->end.lnum;
curbuf->b_op_end.col = offset;
}
@@ -1846,8 +1846,8 @@ int op_replace(oparg_T *oap, int c)
numc -= (oap->end_vcol - bd.end_vcol) + 1;
}
- /* A double-wide character can be replaced only up to half the
- * times. */
+ // A double-wide character can be replaced only up to half the
+ // times.
if ((*mb_char2cells)(c) > 1) {
if ((numc & 1) && !bd.is_short) {
++bd.endspaces;
@@ -1938,8 +1938,8 @@ int op_replace(oparg_T *oap, int c)
n = gchar_cursor();
if (n != NUL) {
if ((*mb_char2len)(c) > 1 || (*mb_char2len)(n) > 1) {
- /* This is slow, but it handles replacing a single-byte
- * with a multi-byte and the other way around. */
+ // This is slow, but it handles replacing a single-byte
+ // with a multi-byte and the other way around.
if (curwin->w_cursor.lnum == oap->end.lnum) {
oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
}
@@ -1949,8 +1949,8 @@ int op_replace(oparg_T *oap, int c)
int end_vcol = 0;
if (curwin->w_cursor.lnum == oap->end.lnum) {
- /* oap->end has to be recalculated when
- * the tab breaks */
+ // oap->end has to be recalculated when
+ // the tab breaks
end_vcol = getviscol2(oap->end.col,
oap->end.coladd);
}
@@ -1969,9 +1969,9 @@ int op_replace(oparg_T *oap, int c)
virtcols -= oap->start.coladd;
}
- /* oap->end has been trimmed so it's effectively inclusive;
- * as a result an extra +1 must be counted so we don't
- * trample the NUL byte. */
+ // oap->end has been trimmed so it's effectively inclusive;
+ // as a result an extra +1 must be counted so we don't
+ // trample the NUL byte.
coladvance_force(getviscol2(oap->end.col, oap->end.coladd) + 1);
curwin->w_cursor.col -= (virtcols + 1);
for (; virtcols >= 0; virtcols--) {
@@ -2228,8 +2228,8 @@ void op_insert(oparg_T *oap, long count1)
++curwin->w_cursor.col;
}
if (bd.is_short && !bd.is_MAX) {
- /* First line was too short, make it longer and adjust the
- * values in "bd". */
+ // First line was too short, make it longer and adjust the
+ // values in "bd".
if (u_save_cursor() == FAIL) {
return;
}
@@ -2386,8 +2386,8 @@ int op_change(oparg_T *oap)
}
}
- /* First delete the text in the region. In an empty buffer only need to
- * save for undo */
+ // First delete the text in the region. In an empty buffer only need to
+ // save for undo
if (curbuf->b_ml.ml_flags & ML_EMPTY) {
if (u_save_cursor() == FAIL) {
return FALSE;
@@ -3872,10 +3872,9 @@ char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_co
++comment_flags;
}
- /* If we found a colon, it means that we are not processing a line
- * starting with a closing part of a three-part comment. That's good,
- * because we don't want to remove those as this would be annoying.
- */
+ // If we found a colon, it means that we are not processing a line
+ // starting with a closing part of a three-part comment. That's good,
+ // because we don't want to remove those as this would be annoying.
if (*comment_flags == ':' || *comment_flags == NUL) {
line += lead_len;
}
@@ -4054,8 +4053,8 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions
curwin->w_buffer->b_op_end.col = sumsize;
}
- /* Only report the change in the first line here, del_lines() will report
- * the deleted line. */
+ // Only report the change in the first line here, del_lines() will report
+ // the deleted line.
changed_lines(curwin->w_cursor.lnum, currsize,
curwin->w_cursor.lnum + 1, 0L, true);
@@ -4172,8 +4171,8 @@ void op_format(oparg_T *oap, int keep_cursor)
{
long old_line_count = curbuf->b_ml.ml_line_count;
- /* Place the cursor where the "gq" or "gw" command was given, so that "u"
- * can put it back there. */
+ // Place the cursor where the "gq" or "gw" command was given, so that "u"
+ // can put it back there.
curwin->w_cursor = oap->cursor_start;
if (u_save((linenr_T)(oap->start.lnum - 1),
@@ -4190,8 +4189,8 @@ void op_format(oparg_T *oap, int keep_cursor)
// Set '[ mark at the start of the formatted area
curbuf->b_op_start = oap->start;
- /* For "gw" remember the cursor position and put it back below (adjusted
- * for joined and split lines). */
+ // For "gw" remember the cursor position and put it back below (adjusted
+ // for joined and split lines).
if (keep_cursor) {
saved_cursor = oap->cursor_start;
}
@@ -4221,8 +4220,8 @@ void op_format(oparg_T *oap, int keep_cursor)
if (oap->is_VIsual) {
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_old_cursor_lnum != 0) {
- /* When lines have been inserted or deleted, adjust the end of
- * the Visual area to be redrawn. */
+ // When lines have been inserted or deleted, adjust the end of
+ // the Visual area to be redrawn.
if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum) {
wp->w_old_cursor_lnum += old_line_count;
} else {
@@ -4244,9 +4243,9 @@ void op_formatexpr(oparg_T *oap)
}
if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0) {
- /* As documented: when 'formatexpr' returns non-zero fall back to
- * internal formatting. */
- op_format(oap, FALSE);
+ // As documented: when 'formatexpr' returns non-zero fall back to
+ // internal formatting.
+ op_format(oap, false);
}
}
@@ -4424,8 +4423,8 @@ void format_lines(linenr_T line_count, int avoid_fex)
*/
if (is_end_par || force_format) {
if (need_set_indent) {
- /* replace indent in first line with minimal number of
- * tabs and spaces, according to current options */
+ // replace indent in first line with minimal number of
+ // tabs and spaces, according to current options
(void)set_indent(get_indent(), SIN_CHANGED);
}
@@ -4451,8 +4450,8 @@ void format_lines(linenr_T line_count, int avoid_fex)
// at end of par.: need to set indent of next par.
need_set_indent = is_end_par;
if (is_end_par) {
- /* When called with a negative line count, break at the
- * end of the paragraph. */
+ // When called with a negative line count, break at the
+ // end of the paragraph.
if (line_count < 0) {
break;
}
@@ -4674,9 +4673,9 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool
} else {
bdp->startspaces = oap->end_vcol - oap->start_vcol + 1;
if (is_del && oap->op_type != OP_LSHIFT) {
- /* just putting the sum of those two into
- * bdp->startspaces doesn't work for Visual replace,
- * so we have to split the tab in two */
+ // just putting the sum of those two into
+ // bdp->startspaces doesn't work for Visual replace,
+ // so we have to split the tab in two
bdp->startspaces = bdp->start_char_vcols
- (bdp->start_vcol - oap->start_vcol);
bdp->endspaces = bdp->end_vcol - oap->end_vcol - 1;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 659e16268b..a8b86ec0a0 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -615,8 +615,8 @@ static void set_option_default(int opt_idx, int opt_flags)
uint32_t flags = options[opt_idx].flags;
if (varp != NULL) { // skip hidden option, nothing to do for it
if (flags & P_STRING) {
- /* Use set_string_option_direct() for local options to handle
- * freeing and allocating the value. */
+ // Use set_string_option_direct() for local options to handle
+ // freeing and allocating the value.
if (options[opt_idx].indir != PV_NONE) {
set_string_option_direct(NULL, opt_idx,
options[opt_idx].def_val, opt_flags, 0);
@@ -1094,8 +1094,8 @@ int do_set(char_u *arg, int opt_flags)
flags = P_STRING;
}
- /* Skip all options that are not window-local (used when showing
- * an already loaded buffer in a window). */
+ // Skip all options that are not window-local (used when showing
+ // an already loaded buffer in a window).
if ((opt_flags & OPT_WINONLY)
&& (opt_idx < 0 || options[opt_idx].var != VAR_WIN)) {
goto skip;
@@ -1514,8 +1514,8 @@ int do_set(char_u *arg, int opt_flags)
}
}
- /* concatenate the two strings; add a ',' if
- * needed */
+ // concatenate the two strings; add a ',' if
+ // needed
if (adding || prepending) {
comma = ((flags & P_COMMA) && *origval != NUL
&& *newval != NUL);
@@ -1540,8 +1540,8 @@ int do_set(char_u *arg, int opt_flags)
}
}
- /* Remove newval[] from origval[]. (Note: "i" has
- * been set above and is used here). */
+ // Remove newval[] from origval[]. (Note: "i" has
+ // been set above and is used here).
if (removing) {
STRCPY(newval, origval);
if (*s) {
@@ -3510,7 +3510,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
xfree(wp->w_p_lcs_chars.multispace);
}
if (multispace_len > 0) {
- wp->w_p_lcs_chars.multispace = xmalloc((size_t)(multispace_len + 1) * sizeof(int));
+ wp->w_p_lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(int));
wp->w_p_lcs_chars.multispace[multispace_len] = NUL;
} else {
wp->w_p_lcs_chars.multispace = NULL;
@@ -4044,8 +4044,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
}
}
- /* Arabic requires a utf-8 encoding, inform the user if its not
- * set. */
+ // Arabic requires a utf-8 encoding, inform the user if its not
+ // set.
if (STRCMP(p_enc, "utf-8") != 0) {
static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
@@ -4070,12 +4070,12 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
changed_window_setting();
}
- /* 'arabicshape' isn't reset, it is a global option and
- * another window may still need it "on". */
+ // 'arabicshape' isn't reset, it is a global option and
+ // another window may still need it "on".
}
- /* 'delcombine' isn't reset, it is a global option and another
- * window may still want it "on". */
+ // 'delcombine' isn't reset, it is a global option and another
+ // window may still want it "on".
// Revert to the default keymap
curbuf->b_p_iminsert = B_IMODE_NONE;
@@ -5218,8 +5218,8 @@ int makeset(FILE *fd, int opt_flags, int local_only)
continue;
}
- /* Do not store options like 'bufhidden' and 'syntax' in a vimrc
- * file, they are always buffer-specific. */
+ // Do not store options like 'bufhidden' and 'syntax' in a vimrc
+ // file, they are always buffer-specific.
if ((opt_flags & OPT_GLOBAL) && (p->flags & P_NOGLOB)) {
continue;
}
@@ -5339,9 +5339,9 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint6
return FAIL;
}
if (*valuep != NULL) {
- /* Output 'pastetoggle' as key names. For other
- * options some characters have to be escaped with
- * CTRL-V or backslash */
+ // Output 'pastetoggle' as key names. For other
+ // options some characters have to be escaped with
+ // CTRL-V or backslash
if (valuep == &p_pt) {
s = *valuep;
while (*s != NUL) {
@@ -6605,8 +6605,8 @@ void ExpandOldSetting(int *num_file, char_u ***file)
char_u *buf = vim_strsave_escaped(var, escape_chars);
#ifdef BACKSLASH_IN_FILENAME
- /* For MS-Windows et al. we don't double backslashes at the start and
- * before a file name character. */
+ // For MS-Windows et al. we don't double backslashes at the start and
+ // before a file name character.
for (var = buf; *var != NUL; MB_PTR_ADV(var)) {
if (var[0] == '\\' && var[1] == '\\'
&& expand_option_idx >= 0
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index ea4f2ecaf1..24dc86e034 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -3005,8 +3005,8 @@ static void ungetchr(void)
at_start = prev_at_start;
prev_at_start = false;
- /* Backup regparse, so that it's at the same position as before the
- * getchr(). */
+ // Backup regparse, so that it's at the same position as before the
+ // getchr().
regparse -= prevchr_len;
}
@@ -6414,8 +6414,8 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
int c1, c2, c11, c12;
int junk;
- /* we have to handle the strcmp ourselves, since it is necessary to
- * deal with the composing characters by ignoring them: */
+ // we have to handle the strcmp ourselves, since it is necessary to
+ // deal with the composing characters by ignoring them:
str1 = s1;
str2 = s2;
c1 = c2 = 0;
@@ -7186,8 +7186,8 @@ static regengine_T nfa_regengine =
(char_u *)""
};
-/* Which regexp engine to use? Needed for vim_regcomp().
- * Must match with 'regexpengine'. */
+// Which regexp engine to use? Needed for vim_regcomp().
+// Must match with 'regexpengine'.
static int regexp_engine = 0;
#ifdef REGEXP_DEBUG
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index ec213d0adf..c8b7190b4a 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -374,8 +374,8 @@ nfa_regcomp_start (
/* A reasonable estimation for maximum size */
nstate_max = (STRLEN(expr) + 1) * 25;
- /* Some items blow up in size, such as [A-z]. Add more space for that.
- * When it is still not enough realloc_post_list() will be used. */
+ // Some items blow up in size, such as [A-z]. Add more space for that.
+ // When it is still not enough realloc_post_list() will be used.
nstate_max += 1000;
/* Size for postfix representation of expr. */
@@ -1426,8 +1426,8 @@ static int nfa_regatom(void)
}
break;
- /* Catch \%^ and \%$ regardless of where they appear in the
- * pattern -- regardless of whether or not it makes sense. */
+ // Catch \%^ and \%$ regardless of where they appear in the
+ // pattern -- regardless of whether or not it makes sense.
case '^':
EMIT(NFA_BOF);
break;
@@ -1468,13 +1468,13 @@ static int nfa_regatom(void)
EMIT(NFA_OPT_CHARS);
EMIT(n);
- /* Emit as "\%(\%[abc]\)" to be able to handle
- * "\%[abc]*" which would cause the empty string to be
- * matched an unlimited number of times. NFA_NOPEN is
- * added only once at a position, while NFA_SPLIT is
- * added multiple times. This is more efficient than
- * not allowing NFA_SPLIT multiple times, it is used
- * a lot. */
+ // Emit as "\%(\%[abc]\)" to be able to handle
+ // "\%[abc]*" which would cause the empty string to be
+ // matched an unlimited number of times. NFA_NOPEN is
+ // added only once at a position, while NFA_SPLIT is
+ // added multiple times. This is more efficient than
+ // not allowing NFA_SPLIT multiple times, it is used
+ // a lot.
EMIT(NFA_NOPEN);
break;
}
@@ -1884,8 +1884,8 @@ static int nfa_regpiece(void)
int my_post_start;
int quest;
- /* Save the current parse state, so that we can use it if <atom>{m,n} is
- * next. */
+ // Save the current parse state, so that we can use it if <atom>{m,n} is
+ // next.
save_parse_state(&old_state);
/* store current pos in the postfix form, for \{m,n} involving 0s */
@@ -1969,12 +1969,11 @@ static int nfa_regpiece(void)
break;
case Magic('{'):
- /* a{2,5} will expand to 'aaa?a?a?'
- * a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy
- * version of '?'
- * \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the
- * parenthesis have the same id
- */
+ // a{2,5} will expand to 'aaa?a?a?'
+ // a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy
+ // version of '?'
+ // \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the
+ // parenthesis have the same id
greedy = true;
c2 = peekchr();
@@ -1985,8 +1984,8 @@ static int nfa_regpiece(void)
if (!read_limits(&minval, &maxval))
EMSG_RET_FAIL(_("E870: (NFA regexp) Error reading repetition limits"));
- /* <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to
- * <atom>* */
+ // <atom>{0,inf}, <atom>{0,} and <atom>{} are equivalent to
+ // <atom>*
if (minval == 0 && maxval == MAX_LIMIT) {
if (greedy)
/* \{}, \{0,} */
@@ -3329,10 +3328,10 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
break;
}
- /* Allow "NFA_MOPEN" as a valid postfix representation for
- * the empty regexp "". In this case, the NFA will be
- * NFA_MOPEN -> NFA_MCLOSE. Note that this also allows
- * empty groups of parenthesis, and empty mbyte chars */
+ // Allow "NFA_MOPEN" as a valid postfix representation for
+ // the empty regexp "". In this case, the NFA will be
+ // NFA_MOPEN -> NFA_MCLOSE. Note that this also allows
+ // empty groups of parenthesis, and empty mbyte chars
if (stackp == stack) {
s = alloc_state(mopen, NULL, NULL);
if (s == NULL)
@@ -3345,8 +3344,8 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
break;
}
- /* At least one node was emitted before NFA_MOPEN, so
- * at least one node will be between NFA_MOPEN and NFA_MCLOSE */
+ // At least one node was emitted before NFA_MOPEN, so
+ // at least one node will be between NFA_MOPEN and NFA_MCLOSE
e = POP();
s = alloc_state(mopen, e.start, NULL); /* `(' */
if (s == NULL)
@@ -3503,14 +3502,14 @@ static void nfa_postprocess(nfa_regprog_T *prog)
int ch_invisible = failure_chance(prog->state[i].out, 0);
int ch_follows = failure_chance(prog->state[i].out1->out, 0);
- /* Postpone when the invisible match is expensive or has a
- * lower chance of failing. */
+ // Postpone when the invisible match is expensive or has a
+ // lower chance of failing.
if (c == NFA_START_INVISIBLE_BEFORE
|| c == NFA_START_INVISIBLE_BEFORE_NEG) {
- /* "before" matches are very expensive when
- * unbounded, always prefer what follows then,
- * unless what follows will always match.
- * Otherwise strongly prefer what follows. */
+ // "before" matches are very expensive when
+ // unbounded, always prefer what follows then,
+ // unless what follows will always match.
+ // Otherwise strongly prefer what follows.
if (prog->state[i].val <= 0 && ch_follows > 0) {
directly = false;
} else {
@@ -3529,9 +3528,9 @@ static void nfa_postprocess(nfa_regprog_T *prog)
}
}
-/****************************************************************
-* NFA execution code.
-****************************************************************/
+/////////////////////////////////////////////////////////////////
+// NFA execution code.
+/////////////////////////////////////////////////////////////////
/* Values for done in nfa_pim_T. */
#define NFA_PIM_UNUSED 0 /* pim not used */
@@ -4197,8 +4196,8 @@ skip_add:
save_ptr = NULL;
memset(&save_multipos, 0, sizeof(save_multipos));
- /* Set the position (with "off" added) in the subexpression. Save
- * and restore it when it was in use. Otherwise fill any gap. */
+ // Set the position (with "off" added) in the subexpression. Save
+ // and restore it when it was in use. Otherwise fill any gap.
if (REG_MULTI) {
if (subidx < sub->in_use) {
save_multipos = sub->list.multi[subidx];
@@ -4297,8 +4296,8 @@ skip_add:
sub = &subs->norm;
}
- /* We don't fill in gaps here, there must have been an MOPEN that
- * has done that. */
+ // We don't fill in gaps here, there must have been an MOPEN that
+ // has done that.
save_in_use = sub->in_use;
if (sub->in_use <= subidx)
sub->in_use = subidx + 1;
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 67df0c9258..5ade6244f9 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -11,6 +11,7 @@
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
+#include "nvim/lua/executor.h"
#include "nvim/misc1.h"
#include "nvim/option.h"
#include "nvim/os/os.h"
@@ -157,6 +158,34 @@ int do_in_path(char_u *path, char *name, int flags, DoInRuntimepathCB callback,
return did_one ? OK : FAIL;
}
+RuntimeSearchPath runtime_search_path_get_cached(int *ref)
+ FUNC_ATTR_NONNULL_ALL
+{
+ runtime_search_path_validate();
+
+ *ref = 0;
+ if (runtime_search_path_ref == NULL) {
+ // cached path was unreferenced. keep a ref to
+ // prevent runtime_search_path() to freeing it too early
+ (*ref)++;
+ runtime_search_path_ref = ref;
+ }
+ return runtime_search_path;
+}
+
+void runtime_search_path_unref(RuntimeSearchPath path, int *ref)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (*ref) {
+ if (runtime_search_path_ref == ref) {
+ runtime_search_path_ref = NULL;
+ } else {
+ runtime_search_path_free(path);
+ }
+ }
+}
+
+
/// Find the file "name" in all directories in "path" and invoke
/// "callback(fname, cookie)".
/// "name" can contain wildcards.
@@ -167,7 +196,6 @@ int do_in_path(char_u *path, char *name, int flags, DoInRuntimepathCB callback,
/// return FAIL when no file could be sourced, OK otherwise.
int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void *cookie)
{
- runtime_search_path_validate();
char_u *tail;
int num_files;
char_u **files;
@@ -182,14 +210,8 @@ int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void
verbose_leave();
}
- RuntimeSearchPath path = runtime_search_path;
- int ref = 0;
- if (runtime_search_path_ref == NULL) {
- // cached path was unreferenced. keep a ref to
- // prevent runtime_search_path() to freeing it too early
- ref++;
- runtime_search_path_ref = &ref;
- }
+ int ref;
+ RuntimeSearchPath path = runtime_search_path_get_cached(&ref);
// Loop over all entries in cached path
for (size_t j = 0; j < kv_size(path); j++) {
@@ -206,7 +228,6 @@ int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void
if (name == NULL) {
(*callback)((char_u *)item.path, cookie);
- did_one = true;
} else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
STRCPY(buf, item.path);
add_pathsep((char *)buf);
@@ -255,17 +276,70 @@ int do_in_cached_path(char_u *name, int flags, DoInRuntimepathCB callback, void
}
}
- if (ref) {
- if (runtime_search_path_ref == &ref) {
- runtime_search_path_ref = NULL;
- } else {
- runtime_search_path_free(path);
+ runtime_search_path_unref(path, &ref);
+
+ return did_one ? OK : FAIL;
+}
+
+Array runtime_inspect(void)
+{
+ RuntimeSearchPath path = runtime_search_path;
+ Array rv = ARRAY_DICT_INIT;
+
+ for (size_t i = 0; i < kv_size(path); i++) {
+ SearchPathItem *item = &kv_A(path, i);
+ Array entry = ARRAY_DICT_INIT;
+ ADD(entry, STRING_OBJ(cstr_to_string(item->path)));
+ ADD(entry, BOOLEAN_OBJ(item->after));
+ if (item->has_lua != kNone) {
+ ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue));
}
+ ADD(rv, ARRAY_OBJ(entry));
}
+ return rv;
+}
+ArrayOf(String) runtime_get_named(bool lua, Array pat, bool all)
+{
+ int ref;
+ RuntimeSearchPath path = runtime_search_path_get_cached(&ref);
+ ArrayOf(String) rv = ARRAY_DICT_INIT;
+ static char buf[MAXPATHL];
- return did_one ? OK : FAIL;
+ for (size_t i = 0; i < kv_size(path); i++) {
+ SearchPathItem *item = &kv_A(path, i);
+ if (lua) {
+ if (item->has_lua == kNone) {
+ size_t size = (size_t)snprintf(buf, sizeof buf, "%s/lua/", item->path);
+ item->has_lua = (size < sizeof buf && os_isdir((char_u *)buf)) ? kTrue : kFalse;
+ }
+ if (item->has_lua == kFalse) {
+ continue;
+ }
+ }
+
+ for (size_t j = 0; j < pat.size; j++) {
+ Object pat_item = pat.items[j];
+ if (pat_item.type == kObjectTypeString) {
+ size_t size = (size_t)snprintf(buf, sizeof buf, "%s/%s",
+ item->path, pat_item.data.string.data);
+ if (size < sizeof buf) {
+ if (os_file_is_readable(buf)) {
+ ADD(rv, STRING_OBJ(cstr_to_string(buf)));
+ if (!all) {
+ goto done;
+ }
+ }
+ }
+ }
+ }
+ }
+
+done:
+ runtime_search_path_unref(path, &ref);
+ return rv;
}
+
/// Find "name" in "path". When found, invoke the callback function for
/// it: callback(fname, "cookie")
/// When "flags" has DIP_ALL repeat for all matches, otherwise only the first
@@ -338,7 +412,7 @@ static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp
if (h == 0) {
char *allocated = xstrdup(entry);
map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1);
- kv_push(*search_path, ((SearchPathItem){ allocated, after }));
+ kv_push(*search_path, ((SearchPathItem){ allocated, after, kNone }));
}
}
@@ -481,6 +555,13 @@ void runtime_search_path_free(RuntimeSearchPath path)
void runtime_search_path_validate(void)
{
+ if (!nlua_is_deferred_safe()) {
+ // Cannot rebuild search path in an async context. As a plugin will invoke
+ // itself asynchronously from sync code in the same plugin, the sought
+ // after lua/autoload module will most likely already be in the cached path.
+ // Thus prefer using the stale cache over erroring out in this situation.
+ return;
+ }
if (!runtime_search_path_valid) {
if (!runtime_search_path_ref) {
runtime_search_path_free(runtime_search_path);
diff --git a/src/nvim/runtime.h b/src/nvim/runtime.h
index db31ae4e1e..4337a0b3cd 100644
--- a/src/nvim/runtime.h
+++ b/src/nvim/runtime.h
@@ -10,6 +10,7 @@ typedef void (*DoInRuntimepathCB)(char_u *, void *);
typedef struct {
char *path;
bool after;
+ TriState has_lua;
} SearchPathItem;
typedef kvec_t(SearchPathItem) RuntimeSearchPath;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 0bd9dbe0d5..63f3267d8a 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -5164,8 +5164,8 @@ void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, in
if (row >= 0) {
if (wild_menu_showing == 0 || wild_menu_showing == WM_LIST) {
if (msg_scrolled > 0) {
- /* Put the wildmenu just above the command line. If there is
- * no room, scroll the screen one line up. */
+ // Put the wildmenu just above the command line. If there is
+ // no room, scroll the screen one line up.
if (cmdline_row == Rows - 1) {
msg_scroll_up(false);
msg_scrolled++;
@@ -7031,8 +7031,8 @@ int showmode(void)
if (VIsual_active) {
char *p;
- /* Don't concatenate separate words to avoid translation
- * problems. */
+ // Don't concatenate separate words to avoid translation
+ // problems.
switch ((VIsual_select ? 4 : 0)
+ (VIsual_mode == Ctrl_V) * 2
+ (VIsual_mode == 'V')) {
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 3d30932d69..1b54d12042 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -839,14 +839,14 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
}
- /* With the SEARCH_END option move to the last character
- * of the match. Don't do it for an empty match, end
- * should be same as start then. */
+ // With the SEARCH_END option move to the last character
+ // of the match. Don't do it for an empty match, end
+ // should be same as start then.
if ((options & SEARCH_END) && !(options & SEARCH_NOOF)
&& !(matchpos.lnum == endpos.lnum
&& matchpos.col == endpos.col)) {
- /* For a match in the first column, set the position
- * on the NUL in the previous line. */
+ // For a match in the first column, set the position
+ // on the NUL in the previous line.
pos->lnum = lnum + endpos.lnum;
pos->col = endpos.col;
if (endpos.col == 0) {
@@ -1498,8 +1498,8 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat)
p = skipwhite(ptr);
pos->col = (colnr_T)(p - ptr);
- /* when adding lines the matching line may be empty but it is not
- * ignored because we are interested in the next line -- Acevedo */
+ // when adding lines the matching line may be empty but it is not
+ // ignored because we are interested in the next line -- Acevedo
if ((compl_cont_status & CONT_ADDING)
&& !(compl_cont_status & CONT_SOL)) {
if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) {
@@ -1566,9 +1566,9 @@ int searchc(cmdarg_T *cap, int t_cmd)
c = *lastc;
// For multi-byte re-use last lastc_bytes[] and lastc_bytelen.
- /* Force a move of at least one char, so ";" and "," will move the
- * cursor, even if the cursor is right in front of char we are looking
- * at. */
+ // Force a move of at least one char, so ";" and "," will move the
+ // cursor, even if the cursor is right in front of char we are looking
+ // at.
if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) {
stop = false;
}
@@ -2084,10 +2084,10 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (linep[pos.col - 1] == 'R'
&& linep[pos.col] == '"'
&& vim_strchr(linep + pos.col + 1, '(') != NULL) {
- /* Possible start of raw string. Now that we have the
- * delimiter we can check if it ends before where we
- * started searching, or before the previously found
- * raw string start. */
+ // Possible start of raw string. Now that we have the
+ // delimiter we can check if it ends before where we
+ // started searching, or before the previously found
+ // raw string start.
if (!find_rawstring_end(linep, &pos,
count > 0 ? &match_pos : &curwin->w_cursor)) {
count++;
@@ -2208,8 +2208,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
case '"':
- /* a quote that is preceded with an odd number of backslashes is
- * ignored */
+ // a quote that is preceded with an odd number of backslashes is
+ // ignored
if (do_quotes) {
int col;
@@ -2282,8 +2282,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
bslcnt++;
}
}
- /* Only accept a match when 'M' is in 'cpo' or when escaping
- * is what we expect. */
+ // Only accept a match when 'M' is in 'cpo' or when escaping
+ // is what we expect.
if (cpo_bsl || (bslcnt & 1) == match_escaped) {
if (c == initc) {
count++;
@@ -3505,8 +3505,8 @@ int current_block(oparg_T *oap, long count, int include, int what, int other)
// Include the character under the cursor.
oap->inclusive = true;
} else {
- /* End is before the start (no text in between <>, [], etc.): don't
- * operate on any text. */
+ // End is before the start (no text in between <>, [], etc.): don't
+ // operate on any text.
curwin->w_cursor = start_pos;
}
}
@@ -4044,8 +4044,8 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
}
if (!vis_empty) {
- /* Check if the existing selection exactly spans the text inside
- * quotes. */
+ // Check if the existing selection exactly spans the text inside
+ // quotes.
if (vis_bef_curs) {
inside_quotes = VIsual.col > 0
&& line[VIsual.col - 1] == quotechar
@@ -4072,11 +4072,11 @@ bool current_quote(oparg_T *oap, long count, bool include, int quotechar)
}
if (!vis_empty && line[col_start] == quotechar) {
- /* Already selecting something and on a quote character. Find the
- * next quoted string. */
+ // Already selecting something and on a quote character. Find the
+ // next quoted string.
if (vis_bef_curs) {
- /* Assume we are on a closing quote: move to after the next
- * opening quote. */
+ // Assume we are on a closing quote: move to after the next
+ // opening quote.
col_start = find_next_quote(line, col_start + 1, quotechar, NULL);
if (col_start < 0) {
goto abort_search;
@@ -4800,8 +4800,8 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
file_line = xmalloc(LSIZE);
if (type != CHECK_PATH && type != FIND_DEFINE
- /* when CONT_SOL is set compare "ptr" with the beginning of the line
- * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */
+ // when CONT_SOL is set compare "ptr" with the beginning of the line
+ // is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo
&& !(compl_cont_status & CONT_SOL)) {
pat = xmalloc(len + 5);
assert(len <= INT_MAX);
@@ -4946,10 +4946,9 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
// Nothing found, use the rest of the line.
p = incl_regmatch.endp[0];
i = (int)STRLEN(p);
- }
- /* Avoid checking before the start of the line, can
- * happen if \zs appears in the regexp. */
- else if (p > line) {
+ } else if (p > line) {
+ // Avoid checking before the start of the line, can
+ // happen if \zs appears in the regexp.
if (p[-1] == '"' || p[-1] == '<') {
--p;
++i;
@@ -5129,9 +5128,9 @@ search_line:
// IOSIZE > compl_length, so the STRNCPY works
STRNCPY(IObuff, aux, i);
- /* Get the next line: when "depth" < 0 from the current
- * buffer, otherwise from the included file. Jump to
- * exit_matched when past the last line. */
+ // Get the next line: when "depth" < 0 from the current
+ // buffer, otherwise from the included file. Jump to
+ // exit_matched when past the last line.
if (depth < 0) {
if (lnum >= end_lnum) {
goto exit_matched;
@@ -5142,9 +5141,9 @@ search_line:
goto exit_matched;
}
- /* we read a line, set "already" to check this "line" later
- * if depth >= 0 we'll increase files[depth].lnum far
- * bellow -- Acevedo */
+ // we read a line, set "already" to check this "line" later
+ // if depth >= 0 we'll increase files[depth].lnum far
+ // bellow -- Acevedo
already = aux = p = skipwhite(line);
p = find_word_start(p);
p = find_word_end(p);
@@ -5195,8 +5194,8 @@ search_line:
if (did_show) {
msg_putchar('\n'); // cursor below last one
}
- if (!got_int) { /* don't display if 'q' typed
- at "--more--" message */
+ if (!got_int) { // don't display if 'q' typed
+ // at "--more--" message
msg_home_replace_hl(curr_fname);
}
prev_fname = curr_fname;
@@ -5209,10 +5208,10 @@ search_line:
match_count++);
}
- /* Set matched flag for this file and all the ones that
- * include it */
- for (i = 0; i <= depth; ++i) {
- files[i].matched = TRUE;
+ // Set matched flag for this file and all the ones that
+ // include it
+ for (i = 0; i <= depth; i++) {
+ files[i].matched = true;
}
} else if (--count <= 0) {
found = true;
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 2a501f4714..e3a6236ae4 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -2602,7 +2602,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
upp = vim_strsave(items[1]);
} else if (is_aff_rule(items, itemcnt, "REP", 2)
|| is_aff_rule(items, itemcnt, "REPSAL", 2)) {
- /* Ignore REP/REPSAL count */;
+ // Ignore REP/REPSAL count
if (!isdigit(*items[1])) {
smsg(_("Expected REP(SAL) count in %s line %d"),
fname, lnum);
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index ac4c81f6b3..3afc2aff52 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -230,11 +230,10 @@ struct name_list {
static char *(spo_name_tab[SPO_COUNT]) =
{ "ms=", "me=", "hs=", "he=", "rs=", "re=", "lc=" };
-/* The sp_off_flags are computed like this:
- * offset from the start of the matched text: (1 << SPO_XX_OFF)
- * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
- * When both are present, only one is used.
- */
+// The sp_off_flags are computed like this:
+// offset from the start of the matched text: (1 << SPO_XX_OFF)
+// offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT))
+// When both are present, only one is used.
#define SPTYPE_MATCH 1 // match keyword with this group ID
#define SPTYPE_START 2 // match a regexp, start of item
@@ -345,7 +344,7 @@ static int next_seqnr = 1; // value to use for si_seqnr
*/
static int next_match_col; // column for start of next match
static lpos_T next_match_m_endpos; // position for end of next match
-static lpos_T next_match_h_startpos; // pos. for highl. start of next match
+static lpos_T next_match_h_startpos; // pos. for highl. start of next match
static lpos_T next_match_h_endpos; // pos. for highl. end of next match
static int next_match_idx; // index of matched item
static long next_match_flags; // flags for next match
@@ -492,8 +491,8 @@ void syntax_start(win_T *wp, linenr_T lnum)
// First line is always valid, no matter "minlines".
first_stored = 1;
} else {
- /* Need to parse "minlines" lines before state can be considered
- * valid to store. */
+ // Need to parse "minlines" lines before state can be considered
+ // valid to store.
first_stored = current_lnum + syn_block->b_syn_sync_minlines;
}
} else {
@@ -514,12 +513,12 @@ void syntax_start(win_T *wp, linenr_T lnum)
(void)syn_finish_line(false);
current_lnum++;
- /* If we parsed at least "minlines" lines or started at a valid
- * state, the current state is considered valid. */
+ // If we parsed at least "minlines" lines or started at a valid
+ // state, the current state is considered valid.
if (current_lnum >= first_stored) {
- /* Check if the saved state entry is for the current line and is
- * equal to the current state. If so, then validate all saved
- * states that depended on a change before the parsed line. */
+ // Check if the saved state entry is for the current line and is
+ // equal to the current state. If so, then validate all saved
+ // states that depended on a change before the parsed line.
if (prev == NULL) {
prev = syn_stack_find_entry(current_lnum - 1);
}
@@ -548,19 +547,18 @@ void syntax_start(win_T *wp, linenr_T lnum)
sp = sp->sst_next;
}
load_current_state(prev);
- }
- /* Store the state at this line when it's the first one, the line
- * where we start parsing, or some distance from the previously
- * saved state. But only when parsed at least 'minlines'. */
- else if (prev == NULL
- || current_lnum == lnum
- || current_lnum >= prev->sst_lnum + dist) {
+ } else if (prev == NULL
+ // Store the state at this line when it's the first one, the line
+ // where we start parsing, or some distance from the previously
+ // saved state. But only when parsed at least 'minlines'.
+ || current_lnum == lnum
+ || current_lnum >= prev->sst_lnum + dist) {
prev = store_current_state();
}
}
- /* This can take a long time: break when CTRL-C pressed. The current
- * state will be wrong then. */
+ // This can take a long time: break when CTRL-C pressed. The current
+ // state will be wrong then.
line_breakcheck();
if (got_int) {
current_lnum = lnum;
@@ -664,8 +662,8 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
* 1. Search backwards for the end of a C-style comment.
*/
if (syn_block->b_syn_sync_flags & SF_CCOMMENT) {
- /* Need to make syn_buf the current buffer for a moment, to be able to
- * use find_start_comment(). */
+ // Need to make syn_buf the current buffer for a moment, to be able to
+ // use find_start_comment().
curwin_save = curwin;
curwin = wp;
curbuf_save = curbuf;
@@ -793,9 +791,9 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
++current_col;
}
- /* syn_current_attr() will have skipped the check for
- * an item that ends here, need to do that now. Be
- * careful not to go past the NUL. */
+ // syn_current_attr() will have skipped the check for
+ // an item that ends here, need to do that now. Be
+ // careful not to go past the NUL.
prev_current_col = current_col;
if (syn_getcurline()[current_col] != NUL) {
++current_col;
@@ -987,9 +985,8 @@ static void syn_update_ends(bool startofline)
check_keepend();
}
-/****************************************
- * Handling of the state stack cache.
- */
+/////////////////////////////////////////
+// Handling of the state stack cache.
/*
* EXPLANATION OF THE SYNTAX STATE STACK CACHE
@@ -1081,8 +1078,8 @@ static void syn_stack_alloc(void)
}
if (syn_block->b_sst_array != NULL) {
- /* When shrinking the array, cleanup the existing stack.
- * Make sure that all valid entries fit in the new array. */
+ // When shrinking the array, cleanup the existing stack.
+ // Make sure that all valid entries fit in the new array.
while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len
&& syn_stack_cleanup()) {
;
@@ -1165,9 +1162,9 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
p = np;
continue;
}
- /* This state is below the changed area. Remember the line
- * that needs to be parsed before this entry can be made valid
- * again. */
+ // This state is below the changed area. Remember the line
+ // that needs to be parsed before this entry can be made valid
+ // again.
if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) {
if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) {
p->sst_change_lnum += buf->b_mod_xlines;
@@ -1638,8 +1635,8 @@ int get_syntax_attr(const colnr_T col, bool *const can_spell, const bool keep_st
int attr = 0;
if (can_spell != NULL) {
- /* Default: Only do spelling when there is no @Spell cluster or when
- * ":syn spell toplevel" was used. */
+ // Default: Only do spelling when there is no @Spell cluster or when
+ // ":syn spell toplevel" was used.
*can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
? (syn_block->b_spell_cluster_id == 0)
: (syn_block->b_syn_spell == SYNSPL_TOP);
@@ -1901,15 +1898,15 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
syn_add_start_off(&pos, &regmatch,
spp, SPO_MS_OFF, -1);
if (pos.lnum > current_lnum) {
- /* must have used end of match in a next line,
- * we can't handle that */
+ // must have used end of match in a next line,
+ // we can't handle that
spp->sp_startcol = MAXCOL;
continue;
}
startcol = pos.col;
- /* remember the next column where this pattern
- * matches in the current line */
+ // remember the next column where this pattern
+ // matches in the current line
spp->sp_startcol = startcol;
/*
@@ -1999,8 +1996,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
/*
* keep the best match so far in next_match_*
*/
- /* Highlighting must start after startpos and end
- * before endpos. */
+ // Highlighting must start after startpos and end
+ // before endpos.
if (hl_startpos.lnum == current_lnum
&& (int)hl_startpos.col < startcol) {
hl_startpos.col = startcol;
@@ -2029,8 +2026,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
if (next_match_idx >= 0 && next_match_col == (int)current_col) {
synpat_T *lspp;
- /* When a zero-width item matched which has a nextgroup,
- * don't push the item but set nextgroup. */
+ // When a zero-width item matched which has a nextgroup,
+ // don't push the item but set nextgroup.
lspp = &(SYN_ITEMS(syn_block)[next_match_idx]);
if (next_match_m_endpos.lnum == current_lnum
&& next_match_m_endpos.col == current_col
@@ -2127,8 +2124,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
* done in the current item.
*/
if (syn_block->b_spell_cluster_id == 0) {
- /* There is no @Spell cluster: Do spelling for items without
- * @NoSpell cluster. */
+ // There is no @Spell cluster: Do spelling for items without
+ // @NoSpell cluster.
if (syn_block->b_nospell_cluster_id == 0
|| current_trans_id == 0) {
*can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP);
@@ -2180,8 +2177,8 @@ static int syn_current_attr(const bool syncing, const bool displaying, bool *con
}
}
} else if (can_spell != NULL) {
- /* Default: Only do spelling when there is no @Spell cluster or when
- * ":syn spell toplevel" was used. */
+ // Default: Only do spelling when there is no @Spell cluster or when
+ // ":syn spell toplevel" was used.
*can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT
? (syn_block->b_spell_cluster_id == 0)
: (syn_block->b_syn_spell == SYNSPL_TOP);
@@ -2365,8 +2362,8 @@ static void check_state_ends(void)
current_next_list = NULL;
}
- /* When the ended item has "extend", another item with
- * "keepend" now needs to check for its end. */
+ // When the ended item has "extend", another item with
+ // "keepend" now needs to check for its end.
had_extend = (cur_si->si_flags & HL_EXTEND);
pop_current_state();
@@ -2541,9 +2538,9 @@ static void update_si_end(stateitem_T *sip, int startcol, bool force)
return;
}
- /* Don't update when it's already done. Can be a match of an end pattern
- * that started in a previous line. Watch out: can also be a "keepend"
- * from a containing item. */
+ // Don't update when it's already done. Can be a match of an end pattern
+ // that started in a previous line. Watch out: can also be a "keepend"
+ // from a containing item.
if (!force && sip->si_m_endpos.lnum >= current_lnum) {
return;
}
@@ -2822,8 +2819,8 @@ static void find_endpos(int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_
}
limit_pos(hl_endpos, m_endpos);
- /* now the match ends where the highlighting ends, it is turned
- * into the matchgroup for the end */
+ // now the match ends where the highlighting ends, it is turned
+ // into the matchgroup for the end
*m_endpos = *hl_endpos;
} else {
*end_idx = 0;
@@ -5570,8 +5567,8 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in
// If ssp has a "containedin" list and "cur_si" is in it, return TRUE.
if (cur_si != NULL && ssp->cont_in_list != NULL
&& !(cur_si->si_flags & HL_MATCH)) {
- /* Ignore transparent items without a contains argument. Double check
- * that we don't go back past the first one. */
+ // Ignore transparent items without a contains argument. Double check
+ // that we don't go back past the first one.
while ((cur_si->si_flags & HL_TRANS_CONT)
&& cur_si > (stateitem_T *)(current_state.ga_data)) {
--cur_si;
@@ -5635,8 +5632,8 @@ static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, in
}
if (item >= SYNID_CLUSTER) {
scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list;
- /* restrict recursiveness to 30 to avoid an endless loop for a
- * cluster that includes itself (indirectly) */
+ // restrict recursiveness to 30 to avoid an endless loop for a
+ // cluster that includes itself (indirectly)
if (scl_list != NULL && depth < 30) {
++depth;
r = in_id_list(NULL, scl_list, ssp, contained);
@@ -5931,8 +5928,8 @@ int syn_get_sub_char(void)
int syn_get_stack_item(int i)
{
if (i >= current_state.ga_len) {
- /* Need to invalidate the state, because we didn't properly finish it
- * for the last character, "keep_state" was TRUE. */
+ // Need to invalidate the state, because we didn't properly finish it
+ // for the last character, "keep_state" was TRUE.
invalidate_current_state();
current_col = MAXCOL;
return -1;
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index ee92a2c642..83b06e2f6d 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -230,8 +230,8 @@ int do_tag(char_u *tag, int type, int count, int forceit, int verbose)
if (g_do_tagpreview != 0) {
if (ptag_entry.tagname != NULL
&& STRCMP(ptag_entry.tagname, tag) == 0) {
- /* Jumping to same tag: keep the current match, so that
- * the CursorHold autocommand example works. */
+ // Jumping to same tag: keep the current match, so that
+ // the CursorHold autocommand example works.
cur_match = ptag_entry.cur_match;
cur_fnum = ptag_entry.cur_fnum;
} else {
@@ -407,9 +407,9 @@ int do_tag(char_u *tag, int type, int count, int forceit, int verbose)
tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
}
- /* Curwin will change in the call to jumpto_tag() if ":stag" was
- * used or an autocommand jumps to another window; store value of
- * tagstackidx now. */
+ // Curwin will change in the call to jumpto_tag() if ":stag" was
+ // used or an autocommand jumps to another window; store value of
+ // tagstackidx now.
curwin->w_tagstackidx = tagstackidx;
if (type != DT_SELECT && type != DT_JUMP) {
curwin->w_tagstack[tagstackidx].cur_match = cur_match;
@@ -418,9 +418,9 @@ int do_tag(char_u *tag, int type, int count, int forceit, int verbose)
}
}
- /* When not using the current buffer get the name of buffer "cur_fnum".
- * Makes sure that the tag order doesn't change when using a remembered
- * position for "cur_match". */
+ // When not using the current buffer get the name of buffer "cur_fnum".
+ // Makes sure that the tag order doesn't change when using a remembered
+ // position for "cur_match".
if (cur_fnum != curbuf->b_fnum) {
buf_T *buf = buflist_findnr(cur_fnum);
@@ -1101,8 +1101,8 @@ static void prepare_pats(pat_T *pats, int has_re)
pats->head = pats->pat;
pats->headlen = pats->len;
if (has_re) {
- /* When the pattern starts with '^' or "\\<", binary searching can be
- * used (much faster). */
+ // When the pattern starts with '^' or "\\<", binary searching can be
+ // used (much faster).
if (pats->pat[0] == '^') {
pats->head = pats->pat + 1;
} else if (pats->pat[0] == '\\' && pats->pat[1] == '<') {
@@ -1500,8 +1500,8 @@ int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int
orgpat.len = (int)STRLEN(pat);
if (curbuf->b_help) {
- /* When "@ab" is specified use only the "ab" language, otherwise
- * search all languages. */
+ // When "@ab" is specified use only the "ab" language, otherwise
+ // search all languages.
if (orgpat.len > 3 && pat[orgpat.len - 3] == '@'
&& ASCII_ISALPHA(pat[orgpat.len - 2])
&& ASCII_ISALPHA(pat[orgpat.len - 1])) {
@@ -1613,9 +1613,9 @@ int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int
}
}
if (s == NULL || *s == NUL) {
- /* Language not in 'helplang': use last, prefer English,
- * unless found already. */
- ++help_pri;
+ // Language not in 'helplang': use last, prefer English,
+ // unless found already.
+ help_pri++;
if (STRICMP(help_lang, "en") != 0) {
++help_pri;
}
@@ -1654,8 +1654,8 @@ int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int
stop_searching = true;
break;
}
- /* When mincount is TAG_MANY, stop when enough matches have been
- * found (for completion). */
+ // When mincount is TAG_MANY, stop when enough matches have been
+ // found (for completion).
if (mincount == TAG_MANY && match_count >= TAG_MANY) {
stop_searching = true;
retval = OK;
@@ -1695,8 +1695,8 @@ int find_tags(char_u *pat, int *num_matches, char_u ***matchesp, int flags, int
vim_fseek(fp, search_info.curr_offset, SEEK_SET);
eof = vim_fgets(lbuf, lbuf_size, fp);
if (!eof && search_info.curr_offset != 0) {
- /* The explicit cast is to work around a bug in gcc 3.4.2
- * (repeated below). */
+ // The explicit cast is to work around a bug in gcc 3.4.2
+ // (repeated below).
search_info.curr_offset = vim_ftell(fp);
if (search_info.curr_offset == search_info.high_offset) {
// oops, gone a bit too far; try from low offset
@@ -1739,9 +1739,9 @@ line_read_in:
char_u *conv_line;
int len;
- /* Convert every line. Converting the pattern from 'enc' to
- * the tags file encoding doesn't work, because characters are
- * not recognized. */
+ // Convert every line. Converting the pattern from 'enc' to
+ // the tags file encoding doesn't work, because characters are
+ // not recognized.
conv_line = string_convert(&vimconv, lbuf, NULL);
if (conv_line != NULL) {
// Copy or swap lbuf and conv_line.
@@ -1764,13 +1764,12 @@ line_read_in:
* format, and for "not sorted" flag.
*/
if (state == TS_START) {
- /* The header ends when the line sorts below "!_TAG_". When
- * case is folded lower case letters sort before "_". */
+ // The header ends when the line sorts below "!_TAG_". When
+ // case is folded lower case letters sort before "_".
if (STRNCMP(lbuf, "!_TAG_", 6) <= 0
|| (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) {
if (STRNCMP(lbuf, "!_TAG_", 6) != 0) {
- /* Non-header item before the header, e.g. "!" itself.
- */
+ // Non-header item before the header, e.g. "!" itself.
goto parse_line;
}
@@ -1781,10 +1780,9 @@ line_read_in:
tag_file_sorted = lbuf[18];
}
if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) {
- /* Prepare to convert every line from the specified
- * encoding to 'encoding'. */
- for (p = lbuf + 20; *p > ' ' && *p < 127; ++p) {
- ;
+ // Prepare to convert every line from the specified
+ // encoding to 'encoding'.
+ for (p = lbuf + 20; *p > ' ' && *p < 127; p++) {
}
*p = NUL;
convert_setup(&vimconv, lbuf + 20, p_enc);
@@ -1820,9 +1818,9 @@ line_read_in:
}
if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) {
- /* Binary search won't work for ignoring case, use linear
- * search. */
- linear = TRUE;
+ // Binary search won't work for ignoring case, use linear
+ // search.
+ linear = true;
state = TS_LINEAR;
}
@@ -1927,9 +1925,8 @@ parse_line:
}
if (tagcmp == 0) {
- /* We've located the tag, now skip back and search
- * forward until the first matching tag is found.
- */
+ // We've located the tag, now skip back and search
+ // forward until the first matching tag is found.
state = TS_SKIP_BACK;
search_info.match_offset = search_info.curr_offset;
continue;
@@ -1966,8 +1963,8 @@ parse_line:
if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) {
state = TS_STEP_FORWARD;
} else {
- /* Have to skip back more. Restore the curr_offset
- * used, otherwise we get stuck at a long line. */
+ // Have to skip back more. Restore the curr_offset
+ // used, otherwise we get stuck at a long line.
search_info.curr_offset = search_info.curr_offset_used;
}
continue;
diff --git a/src/nvim/testdir/test_autochdir.vim b/src/nvim/testdir/test_autochdir.vim
index d071f4b325..0b76828dd7 100644
--- a/src/nvim/testdir/test_autochdir.vim
+++ b/src/nvim/testdir/test_autochdir.vim
@@ -8,13 +8,21 @@ func Test_set_filename()
let cwd = getcwd()
call test_autochdir()
set acd
+
+ let s:li = []
+ autocmd DirChanged auto call add(s:li, "autocd")
+ autocmd DirChanged auto call add(s:li, expand("<afile>"))
+
new
w samples/Xtest
call assert_equal("Xtest", expand('%'))
call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', ''))
+ call assert_equal(["autocd", getcwd()], s:li)
+
bwipe!
+ au! DirChanged
set noacd
- exe 'cd ' . cwd
+ call chdir(cwd)
call delete('samples/Xtest')
endfunc
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index 015979e1be..c350a17236 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -42,9 +42,7 @@ if has('timers')
endfunc
func Test_cursorhold_insert_with_timer_interrupt()
- if !has('job')
- return
- endif
+ CheckFeature job
" Need to move the cursor.
call feedkeys("ggG", "xt")
@@ -551,9 +549,7 @@ endfunc
func Test_OptionSet()
CheckFunction test_override
- if !has("eval") || !exists("+autochdir")
- return
- endif
+ CheckOption autochdir
call test_override('starting', 1)
set nocp
@@ -1328,6 +1324,71 @@ func Test_autocommand_all_events()
call assert_fails('au * x bwipe', 'E1155:')
endfunc
+function s:Before_test_dirchanged()
+ augroup test_dirchanged
+ autocmd!
+ augroup END
+ let s:li = []
+ let s:dir_this = getcwd()
+ let s:dir_foo = s:dir_this . '/Xfoo'
+ call mkdir(s:dir_foo)
+ let s:dir_bar = s:dir_this . '/Xbar'
+ call mkdir(s:dir_bar)
+endfunc
+
+function s:After_test_dirchanged()
+ call chdir(s:dir_this)
+ call delete(s:dir_foo, 'd')
+ call delete(s:dir_bar, 'd')
+ augroup test_dirchanged
+ autocmd!
+ augroup END
+endfunc
+
+function Test_dirchanged_global()
+ call s:Before_test_dirchanged()
+ autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
+ autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
+ call chdir(s:dir_foo)
+ call assert_equal(["cd:", s:dir_foo], s:li)
+ call chdir(s:dir_foo)
+ call assert_equal(["cd:", s:dir_foo], s:li)
+ exe 'lcd ' .. fnameescape(s:dir_bar)
+ call assert_equal(["cd:", s:dir_foo], s:li)
+ call s:After_test_dirchanged()
+endfunc
+
+function Test_dirchanged_local()
+ call s:Before_test_dirchanged()
+ autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
+ autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
+ call chdir(s:dir_foo)
+ call assert_equal([], s:li)
+ exe 'lcd ' .. fnameescape(s:dir_bar)
+ call assert_equal(["lcd:", s:dir_bar], s:li)
+ exe 'lcd ' .. fnameescape(s:dir_bar)
+ call assert_equal(["lcd:", s:dir_bar], s:li)
+ call s:After_test_dirchanged()
+endfunc
+
+function Test_dirchanged_auto()
+ CheckFunction test_autochdir
+ CheckOption autochdir
+ call s:Before_test_dirchanged()
+ call test_autochdir()
+ autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
+ autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
+ set acd
+ cd ..
+ call assert_equal([], s:li)
+ exe 'edit ' . s:dir_foo . '/Xfile'
+ call assert_equal(s:dir_foo, getcwd())
+ call assert_equal(["auto:", s:dir_foo], s:li)
+ set noacd
+ bwipe!
+ call s:After_test_dirchanged()
+endfunc
+
" Test TextChangedI and TextChangedP
" See test/functional/viml/completion_spec.lua'
func Test_ChangedP()
diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim
index 02a23bf82f..0bba321ee2 100644
--- a/src/nvim/testdir/test_cd.vim
+++ b/src/nvim/testdir/test_cd.vim
@@ -12,7 +12,7 @@ func Test_cd_up_and_down()
let path = getcwd()
cd ..
call assert_notequal(path, getcwd())
- exe 'cd ' . path
+ exe 'cd ' .. fnameescape(path)
call assert_equal(path, getcwd())
endfunc
@@ -23,7 +23,7 @@ func Test_cd_no_arg()
cd
call assert_equal($HOME, getcwd())
call assert_notequal(path, getcwd())
- exe 'cd ' . path
+ exe 'cd ' .. fnameescape(path)
call assert_equal(path, getcwd())
else
" Test that cd without argument echoes cwd on non-Unix systems.
@@ -43,6 +43,20 @@ func Test_cd_minus()
call assert_equal(path_dotdot, getcwd())
cd -
call assert_equal(path, getcwd())
+
+ " Test for :cd - without a previous directory
+ let lines =<< trim [SCRIPT]
+ call assert_fails('cd -', 'E186:')
+ call assert_fails('call chdir("-")', 'E186:')
+ call writefile(v:errors, 'Xresult')
+ qall!
+ [SCRIPT]
+ call writefile(lines, 'Xscript')
+ if RunVim([], [], '--clean -S Xscript')
+ call assert_equal([], readfile('Xresult'))
+ endif
+ call delete('Xscript')
+ call delete('Xresult')
endfunc
func Test_cd_with_cpo_chdir()
@@ -61,7 +75,7 @@ func Test_cd_with_cpo_chdir()
" :cd should succeed when buffer has been written.
w!
- exe 'cd ' . path
+ exe 'cd ' .. fnameescape(path)
call assert_equal(path, getcwd())
call delete('Xfoo')
@@ -69,6 +83,124 @@ func Test_cd_with_cpo_chdir()
bw!
endfunc
+" Test for chdir()
+func Test_chdir_func()
+ let topdir = getcwd()
+ call mkdir('Xdir/y/z', 'p')
+
+ " Create a few tabpages and windows with different directories
+ new
+ cd Xdir
+ tabnew
+ tcd y
+ below new
+ below new
+ lcd z
+
+ tabfirst
+ call assert_match('^\[global\] .*/Xdir$', trim(execute('verbose pwd')))
+ call chdir('..')
+ call assert_equal('y', fnamemodify(getcwd(1, 2), ':t'))
+ call assert_equal('z', fnamemodify(getcwd(3, 2), ':t'))
+ tabnext | wincmd t
+ call assert_match('^\[tabpage\] .*/y$', trim(execute('verbose pwd')))
+ call chdir('..')
+ call assert_equal('Xdir', fnamemodify(getcwd(1, 2), ':t'))
+ call assert_equal('Xdir', fnamemodify(getcwd(2, 2), ':t'))
+ call assert_equal('z', fnamemodify(getcwd(3, 2), ':t'))
+ call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t'))
+ 3wincmd w
+ call assert_match('^\[window\] .*/z$', trim(execute('verbose pwd')))
+ call chdir('..')
+ call assert_equal('Xdir', fnamemodify(getcwd(1, 2), ':t'))
+ call assert_equal('Xdir', fnamemodify(getcwd(2, 2), ':t'))
+ call assert_equal('y', fnamemodify(getcwd(3, 2), ':t'))
+ call assert_equal('testdir', fnamemodify(getcwd(1, 1), ':t'))
+
+ " Error case
+ call assert_fails("call chdir('dir-abcd')", 'E472:')
+ silent! let d = chdir("dir_abcd")
+ call assert_equal("", d)
+ " Should not crash
+ call chdir(d)
+
+ only | tabonly
+ call chdir(topdir)
+ call delete('Xdir', 'rf')
+endfunc
+
+" Test for changing to the previous directory '-'
+func Test_prev_dir()
+ let topdir = getcwd()
+ call mkdir('Xdir/a/b/c', 'p')
+
+ " Create a few tabpages and windows with different directories
+ new | only
+ tabnew | new
+ tabnew
+ tabfirst
+ cd Xdir
+ tabnext | wincmd t
+ tcd a
+ wincmd w
+ lcd b
+ tabnext
+ tcd a/b/c
+
+ " Change to the previous directory twice in all the windows.
+ tabfirst
+ cd - | cd -
+ tabnext | wincmd t
+ tcd - | tcd -
+ wincmd w
+ lcd - | lcd -
+ tabnext
+ tcd - | tcd -
+
+ " Check the directory of all the windows
+ tabfirst
+ call assert_equal('Xdir', fnamemodify(getcwd(), ':t'))
+ tabnext | wincmd t
+ call assert_equal('a', fnamemodify(getcwd(), ':t'))
+ wincmd w
+ call assert_equal('b', fnamemodify(getcwd(), ':t'))
+ tabnext
+ call assert_equal('c', fnamemodify(getcwd(), ':t'))
+
+ " Change to the previous directory using chdir()
+ tabfirst
+ call chdir("-") | call chdir("-")
+ tabnext | wincmd t
+ call chdir("-") | call chdir("-")
+ wincmd w
+ call chdir("-") | call chdir("-")
+ tabnext
+ call chdir("-") | call chdir("-")
+
+ " Check the directory of all the windows
+ tabfirst
+ call assert_equal('Xdir', fnamemodify(getcwd(), ':t'))
+ tabnext | wincmd t
+ call assert_equal('a', fnamemodify(getcwd(), ':t'))
+ wincmd w
+ call assert_equal('b', fnamemodify(getcwd(), ':t'))
+ tabnext
+ call assert_equal('c', fnamemodify(getcwd(), ':t'))
+
+ only | tabonly
+ call chdir(topdir)
+ call delete('Xdir', 'rf')
+endfunc
+
+func Test_lcd_split()
+ let curdir = getcwd()
+ lcd ..
+ split
+ lcd -
+ call assert_equal(curdir, getcwd())
+ quit!
+endfunc
+
func Test_cd_from_non_existing_dir()
CheckNotMSWindows
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 52e6ba64cc..18e59bb6b7 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -112,7 +112,7 @@ let s:filename_checks = {
\ 'coco': ['file.atg'],
\ 'conaryrecipe': ['file.recipe'],
\ 'conf': ['auto.master'],
- \ 'config': ['configure.in', 'configure.ac', 'Pipfile', '/etc/hostname.file'],
+ \ 'config': ['configure.in', 'configure.ac', '/etc/hostname.file'],
\ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'],
\ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'],
\ 'crm': ['file.crm'],
@@ -503,8 +503,8 @@ let s:filename_checks = {
\ 'tidy': ['.tidyrc', 'tidyrc', 'tidy.conf'],
\ 'tilde': ['file.t.html'],
\ 'tli': ['file.tli'],
- \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf'],
- \ 'toml': ['file.toml'],
+ \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf', '.tmux-file.conf', '.tmux.conf', 'tmux-file.conf', 'tmux.conf', 'tmux.conf.local'],
+ \ 'toml': ['file.toml', 'Gopkg.lock', 'Pipfile', '/home/user/.cargo/config'],
\ 'tpp': ['file.tpp'],
\ 'treetop': ['file.treetop'],
\ 'trustees': ['trustees.conf'],
diff --git a/src/nvim/testdir/test_find_complete.vim b/src/nvim/testdir/test_find_complete.vim
index 0a00d9432f..32ca9672ef 100644
--- a/src/nvim/testdir/test_find_complete.vim
+++ b/src/nvim/testdir/test_find_complete.vim
@@ -36,7 +36,7 @@ func Test_find_complete()
" We shouldn't find any file till this point
call mkdir('in/path', 'p')
- exe 'cd ' . cwd
+ call chdir(cwd)
call writefile(['Holy Grail'], 'Xfind/file.txt')
call writefile(['Jimmy Hoffa'], 'Xfind/in/file.txt')
call writefile(['Another Holy Grail'], 'Xfind/in/stuff.txt')
@@ -133,12 +133,12 @@ func Test_find_complete()
call assert_equal('Voyager 2', getline(1))
" Check for correct handling of shorten_fname()'s behavior on windows
- exec "cd " . cwd . "/Xfind/in"
+ call chdir(cwd .. "/Xfind/in")
call feedkeys(":find file\t\n", "xt")
call assert_equal('Jimmy Hoffa', getline(1))
" Test for relative to current buffer 'path' item
- exec "cd " . cwd . "/Xfind/"
+ call chdir(cwd . "/Xfind/")
set path=./path
" Open the file where Jimmy Hoffa is found
e in/file.txt
@@ -157,7 +157,7 @@ func Test_find_complete()
call assert_equal('Another Holy Grail', getline(1))
enew | only
- exe 'cd ' . cwd
+ call chdir(cwd)
call delete('Xfind', 'rf')
set path&
endfunc
diff --git a/src/nvim/testdir/test_findfile.vim b/src/nvim/testdir/test_findfile.vim
index d92706dbe5..5a20475d3d 100644
--- a/src/nvim/testdir/test_findfile.vim
+++ b/src/nvim/testdir/test_findfile.vim
@@ -113,7 +113,7 @@ func Test_findfile()
call assert_match('.*/Xdir1/bar', findfile('bar', '**;', 2))
bwipe!
- exe 'cd ' . save_dir
+ call chdir(save_dir)
call CleanFiles()
let &path = save_path
let &shellslash = save_shellslash
@@ -171,7 +171,7 @@ func Test_finddir()
call assert_match('.*/Xdir1/Xdir2', finddir('Xdir2', '**;', 2))
call assert_equal('Xdir3', finddir('Xdir3', '**;', 1))
- exe 'cd ' . save_dir
+ call chdir(save_dir)
call CleanFiles()
let &path = save_path
let &shellslash = save_shellslash
diff --git a/src/nvim/testdir/test_getcwd.vim b/src/nvim/testdir/test_getcwd.vim
index 2ff396b641..a75583cd2c 100644
--- a/src/nvim/testdir/test_getcwd.vim
+++ b/src/nvim/testdir/test_getcwd.vim
@@ -46,7 +46,7 @@ endfunction
let g:cwd=getcwd()
function TearDown()
q
- exec "cd " . g:cwd
+ call chdir(g:cwd)
call delete("Xtopdir", "rf")
endfunction
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 64d618c38f..43e6325aa5 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -69,8 +69,8 @@
* All data is allocated and will all be freed when the buffer is unloaded.
*/
-/* Uncomment the next line for including the u_check() function. This warns
- * for errors in the debug information. */
+// Uncomment the next line for including the u_check() function. This warns
+// for errors in the debug information.
// #define U_DEBUG 1
#define UH_MAGIC 0x18dade // value for uh_magic when in use
#define UE_MAGIC 0xabc123 // value for ue_magic when in use
@@ -291,8 +291,8 @@ bool undo_allowed(buf_T *buf)
return false;
}
- /* Don't allow changes in the buffer while editing the cmdline. The
- * caller of getcmdline() may get confused. */
+ // Don't allow changes in the buffer while editing the cmdline. The
+ // caller of getcmdline() may get confused.
if (textlock != 0) {
EMSG(_(e_secure));
return false;
@@ -1921,8 +1921,8 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event)
u_undoredo(false, do_buf_event);
- /* Advance for next redo. Set "newhead" when at the end of the
- * redoable changes. */
+ // Advance for next redo. Set "newhead" when at the end of the
+ // redoable changes.
if (curbuf->b_u_curhead->uh_prev.ptr == NULL) {
curbuf->b_u_newhead = curbuf->b_u_curhead;
}
@@ -1967,8 +1967,8 @@ void undo_time(long step, bool sec, bool file, bool absolute)
u_oldcount = -1;
}
- /* "target" is the node below which we want to be.
- * Init "closest" to a value we can't reach. */
+ // "target" is the node below which we want to be.
+ // Init "closest" to a value we can't reach.
if (absolute) {
target = step;
closest = -1;
@@ -1977,9 +1977,9 @@ void undo_time(long step, bool sec, bool file, bool absolute)
target = (long)(curbuf->b_u_time_cur) + step;
} else if (dofile) {
if (step < 0) {
- /* Going back to a previous write. If there were changes after
- * the last write, count that as moving one file-write, so
- * that ":earlier 1f" undoes all changes since the last save. */
+ // Going back to a previous write. If there were changes after
+ // the last write, count that as moving one file-write, so
+ // that ":earlier 1f" undoes all changes since the last save.
uhp = curbuf->b_u_curhead;
if (uhp != NULL) {
uhp = uhp->uh_next.ptr;
@@ -2003,8 +2003,8 @@ void undo_time(long step, bool sec, bool file, bool absolute)
// Moving forward to a newer write.
target = curbuf->b_u_save_nr_cur + step;
if (target > curbuf->b_u_save_nr_last) {
- /* Go to after last write: after the latest change. Use
- * the sequence number for that. */
+ // Go to after last write: after the latest change. Use
+ // the sequence number for that.
target = curbuf->b_u_seq_last + 1;
dofile = false;
}
@@ -2072,10 +2072,10 @@ void undo_time(long step, bool sec, bool file, bool absolute)
}
if (round == 1 && !(dofile && val == 0)) {
- /* Remember the header that is closest to the target.
- * It must be at least in the right direction (checked with
- * "b_u_seq_cur"). When the timestamp is equal find the
- * highest/lowest sequence number. */
+ // Remember the header that is closest to the target.
+ // It must be at least in the right direction (checked with
+ // "b_u_seq_cur"). When the timestamp is equal find the
+ // highest/lowest sequence number.
if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur
: uhp->uh_seq > curbuf->b_u_seq_cur)
&& ((dosec && val == closest)
@@ -2095,8 +2095,8 @@ void undo_time(long step, bool sec, bool file, bool absolute)
}
}
- /* Quit searching when we found a match. But when searching for a
- * time we need to continue looking for the best uh_seq. */
+ // Quit searching when we found a match. But when searching for a
+ // time we need to continue looking for the best uh_seq.
if (target == val && !dosec) {
target = uhp->uh_seq;
break;
@@ -2112,12 +2112,11 @@ void undo_time(long step, bool sec, bool file, bool absolute)
&& uhp->uh_alt_next.ptr->uh_walk != nomark
&& uhp->uh_alt_next.ptr->uh_walk != mark) {
uhp = uhp->uh_alt_next.ptr;
- }
- /* go up in the tree if we haven't been there and we are at the
- * start of alternate branches */
- else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
- && uhp->uh_next.ptr->uh_walk != nomark
- && uhp->uh_next.ptr->uh_walk != mark) {
+ } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ // go up in the tree if we haven't been there and we are at the
+ // start of alternate branches
+ && uhp->uh_next.ptr->uh_walk != nomark
+ && uhp->uh_next.ptr->uh_walk != mark) {
// If still at the start we don't go through this change.
if (uhp == curbuf->b_u_curhead) {
uhp->uh_walk = nomark;
@@ -2297,8 +2296,8 @@ static void u_undoredo(int undo, bool do_buf_event)
bool empty_buffer; // buffer became empty
u_header_T *curhead = curbuf->b_u_curhead;
- /* Don't want autocommands using the undo structures here, they are
- * invalid till the end. */
+ // Don't want autocommands using the undo structures here, they are
+ // invalid till the end.
block_autocmds();
#ifdef U_DEBUG
@@ -2549,8 +2548,8 @@ static void u_undoredo(int undo, bool do_buf_event)
}
}
- /* The timestamp can be the same for multiple changes, just use the one of
- * the undone/redone change. */
+ // The timestamp can be the same for multiple changes, just use the one of
+ // the undone/redone change.
curbuf->b_u_time_cur = curhead->uh_time;
unblock_autocmds();
@@ -2709,12 +2708,11 @@ void ex_undolist(exarg_T *eap)
&& uhp->uh_alt_next.ptr->uh_walk != nomark
&& uhp->uh_alt_next.ptr->uh_walk != mark) {
uhp = uhp->uh_alt_next.ptr;
- }
- /* go up in the tree if we haven't been there and we are at the
- * start of alternate branches */
- else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
- && uhp->uh_next.ptr->uh_walk != nomark
- && uhp->uh_next.ptr->uh_walk != mark) {
+ } else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL
+ // go up in the tree if we haven't been there and we are at the
+ // start of alternate branches
+ && uhp->uh_next.ptr->uh_walk != nomark
+ && uhp->uh_next.ptr->uh_walk != mark) {
uhp = uhp->uh_next.ptr;
--changes;
} else {
@@ -2906,8 +2904,8 @@ static void u_freeheader(buf_T *buf, u_header_T *uhp, u_header_T **uhpp)
{
u_header_T *uhap;
- /* When there is an alternate redo list free that branch completely,
- * because we can never go there. */
+ // When there is an alternate redo list free that branch completely,
+ // because we can never go there.
if (uhp->uh_alt_next.ptr != NULL) {
u_freebranch(buf, uhp->uh_alt_next.ptr, uhpp);
}
@@ -2942,8 +2940,8 @@ static void u_freebranch(buf_T *buf, u_header_T *uhp, u_header_T **uhpp)
{
u_header_T *tofree, *next;
- /* If this is the top branch we may need to use u_freeheader() to update
- * all the pointers. */
+ // If this is the top branch we may need to use u_freeheader() to update
+ // all the pointers.
if (uhp == buf->b_u_oldhead) {
while (buf->b_u_oldhead != NULL) {
u_freeheader(buf, buf->b_u_oldhead, uhpp);
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 1fe4aa1add..dfe1ffdbd4 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -23,6 +23,7 @@
#include "nvim/fold.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
+#include "nvim/globals.h"
#include "nvim/hashtab.h"
#include "nvim/main.h"
#include "nvim/mark.h"
@@ -298,8 +299,8 @@ newwindow:
tabpage_T *oldtab = curtab;
tabpage_T *newtab;
- /* First create a new tab with the window, then go back to
- * the old tab and close the window there. */
+ // First create a new tab with the window, then go back to
+ // the old tab and close the window there.
wp = curwin;
if (win_new_tabpage((int)Prenum, NULL) == OK
&& valid_tabpage(oldtab)) {
@@ -519,8 +520,8 @@ wingotofile:
postponed_split = -1;
}
- /* Execute the command right here, required when
- * "wincmd g}" was used in a function. */
+ // Execute the command right here, required when
+ // "wincmd g}" was used in a function.
do_nv_ident('g', xchar);
break;
@@ -922,8 +923,8 @@ int win_split(int size, int flags)
return FAIL;
}
- /* When creating the help window make a snapshot of the window layout.
- * Otherwise clear the snapshot, it's now invalid. */
+ // When creating the help window make a snapshot of the window layout.
+ // Otherwise clear the snapshot, it's now invalid.
if (flags & WSP_HELP) {
make_snapshot(SNAP_HELP_IDX);
} else {
@@ -1260,8 +1261,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
frame_append(curfrp, frp);
}
- /* Set w_fraction now so that the cursor keeps the same relative
- * vertical position. */
+ // Set w_fraction now so that the cursor keeps the same relative
+ // vertical position.
if (!did_set_fraction) {
set_fraction(oldwin);
}
@@ -1287,8 +1288,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
frp->fr_height = curfrp->fr_height;
- /* "new_size" of the current window goes to the new window, use
- * one column for the vertical separator */
+ // "new_size" of the current window goes to the new window, use
+ // one column for the vertical separator
win_new_width(wp, new_size);
if (before) {
wp->w_vsep_width = 1;
@@ -1328,8 +1329,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
}
frp->fr_width = curfrp->fr_width;
- /* "new_size" of the current window goes to the new window, use
- * one row for the status line */
+ // "new_size" of the current window goes to the new window, use
+ // one row for the status line
win_new_height(wp, new_size);
if (flags & (WSP_TOP | WSP_BOT)) {
int new_fr_height = curfrp->fr_height - new_size;
@@ -1388,8 +1389,8 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
'v');
}
- /* Don't change the window height/width to 'winheight' / 'winwidth' if a
- * size was given. */
+ // Don't change the window height/width to 'winheight' / 'winwidth' if a
+ // size was given.
if (flags & WSP_VERT) {
i = p_wiw;
if (size != 0) {
@@ -1462,6 +1463,8 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
}
newp->w_localdir = (oldp->w_localdir == NULL)
? NULL : vim_strsave(oldp->w_localdir);
+ newp->w_prevdir = (oldp->w_prevdir == NULL)
+ ? NULL : vim_strsave(oldp->w_prevdir);
// copy tagstack and folds
for (i = 0; i < oldp->w_tagstacklen; i++) {
@@ -1589,8 +1592,8 @@ int make_windows(int count, bool vertical)
int todo;
if (vertical) {
- /* Each windows needs at least 'winminwidth' lines and a separator
- * column. */
+ // Each windows needs at least 'winminwidth' lines and a separator
+ // column.
maxcount = (curwin->w_width + curwin->w_vsep_width
- (p_wiw - p_wmw)) / (p_wmw + 1);
} else {
@@ -1679,8 +1682,8 @@ static void win_exchange(long Prenum)
frp = curwin->w_frame->fr_prev;
}
- /* We can only exchange a window with another window, not with a frame
- * containing windows. */
+ // We can only exchange a window with another window, not with a frame
+ // containing windows.
if (frp == NULL || frp->fr_win == NULL || frp->fr_win == curwin) {
return;
}
@@ -1890,8 +1893,8 @@ void win_move_after(win_T *win1, win_T *win2)
win1->w_status_height = win2->w_status_height;
win2->w_status_height = height;
if (win1->w_vsep_width == 1) {
- /* Remove the vertical separator from win1, add it to the last
- * window, win2. Adjust the frame widths. */
+ // Remove the vertical separator from win1, add it to the last
+ // window, win2. Adjust the frame widths.
win2->w_vsep_width = 1;
win2->w_frame->fr_width += 1;
win1->w_vsep_width = 0;
@@ -1955,8 +1958,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
bool hnc;
if (topfr->fr_layout == FR_LEAF) {
- /* Set the width/height of this frame.
- * Redraw when size or position changes */
+ // Set the width/height of this frame.
+ // Redraw when size or position changes
if (topfr->fr_height != height || topfr->fr_win->w_winrow != row
|| topfr->fr_width != width ||
topfr->fr_win->w_wincol != col) {
@@ -2028,8 +2031,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
} else if (totwincount > 1
&& (room + (totwincount - 2))
/ (totwincount - 1) > p_wiw) {
- /* Can make all windows wider than 'winwidth', spread
- * the room equally. */
+ // Can make all windows wider than 'winwidth', spread
+ // the room equally.
next_curwin_size = (room + p_wiw
+ (totwincount - 1) * p_wmw
+ (totwincount - 1)) / totwincount;
@@ -2084,8 +2087,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
new_size += n;
}
- /* Skip frame that is full width when splitting or closing a
- * window, unless equalizing all frames. */
+ // Skip frame that is full width when splitting or closing a
+ // window, unless equalizing all frames.
if (!current || dir != 'v' || topfr->fr_parent != NULL
|| (new_size != fr->fr_width)
|| frame_has_win(fr, next_curwin)) {
@@ -2120,8 +2123,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
m = frame_minheight(topfr, next_curwin);
room = height - m;
if (room < 0) {
- /* The room is less then 'winheight', use all space for the
- * current window. */
+ // The room is less then 'winheight', use all space for the
+ // current window.
next_curwin_size = p_wh + room;
room = 0;
} else {
@@ -2159,8 +2162,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
} else if (totwincount > 1
&& (room + (totwincount - 2))
/ (totwincount - 1) > p_wh) {
- /* can make all windows higher than 'winheight',
- * spread the room equally. */
+ // can make all windows higher than 'winheight',
+ // spread the room equally.
next_curwin_size = (room + p_wh
+ (totwincount - 1) * p_wmh
+ (totwincount - 1)) / totwincount;
@@ -2214,8 +2217,8 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
}
new_size += n;
}
- /* Skip frame that is full width when splitting or closing a
- * window, unless equalizing all frames. */
+ // Skip frame that is full width when splitting or closing a
+ // window, unless equalizing all frames.
if (!current || dir != 'h' || topfr->fr_parent != NULL
|| (new_size != fr->fr_height)
|| frame_has_win(fr, next_curwin)) {
@@ -2263,8 +2266,8 @@ void close_windows(buf_T *buf, int keep_curwin)
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
win_close_othertab(wp, false, tp);
- /* Start all over, the tab page may be closed and
- * autocommands may change the window layout. */
+ // Start all over, the tab page may be closed and
+ // autocommands may change the window layout.
nexttp = first_tabpage;
break;
}
@@ -2630,8 +2633,8 @@ int win_close(win_T *win, bool free_buf)
*/
last_status(false);
- /* After closing the help window, try restoring the window layout from
- * before it was opened. */
+ // After closing the help window, try restoring the window layout from
+ // before it was opened.
if (help_window) {
restore_snapshot(SNAP_HELP_IDX, close_curwin);
}
@@ -2703,8 +2706,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false);
}
- /* Careful: Autocommands may have closed the tab page or made it the
- * current tab page. */
+ // Careful: Autocommands may have closed the tab page or made it the
+ // current tab page.
for (ptp = first_tabpage; ptp != NULL && ptp != tp; ptp = ptp->tp_next) {
;
}
@@ -2863,9 +2866,9 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
frame_remove(frp_close);
if (frp_close->fr_parent->fr_layout == FR_COL) {
- /* When 'winfixheight' is set, try to find another frame in the column
- * (as close to the closed frame as possible) to distribute the height
- * to. */
+ // When 'winfixheight' is set, try to find another frame in the column
+ // (as close to the closed frame as possible) to distribute the height
+ // to.
if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh) {
frp = frp_close->fr_prev;
frp3 = frp_close->fr_next;
@@ -2922,8 +2925,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
*dirp = 'h';
}
- /* If rows/columns go to a window below/right its positions need to be
- * updated. Can only be done after the sizes have been updated. */
+ // If rows/columns go to a window below/right its positions need to be
+ // updated. Can only be done after the sizes have been updated.
if (frp2 == frp_close->fr_next) {
int row = win->w_winrow;
int col = win->w_wincol;
@@ -2932,8 +2935,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
}
if (frp2->fr_next == NULL && frp2->fr_prev == NULL) {
- /* There is no other frame in this list, move its info to the parent
- * and remove it. */
+ // There is no other frame in this list, move its info to the parent
+ // and remove it.
frp2->fr_parent->fr_layout = frp2->fr_layout;
frp2->fr_parent->fr_child = frp2->fr_child;
FOR_ALL_FRAMES(frp, frp2->fr_child) {
@@ -2951,8 +2954,8 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp)
frp2 = frp->fr_parent;
if (frp2 != NULL && frp2->fr_layout == frp->fr_layout) {
- /* The frame above the parent has the same layout, have to merge
- * the frames into this list. */
+ // The frame above the parent has the same layout, have to merge
+ // the frames into this list.
if (frp2->fr_child == frp) {
frp2->fr_child = frp->fr_child;
}
@@ -3641,8 +3644,8 @@ static int win_alloc_firstwin(win_T *oldwin)
{
curwin = win_alloc(NULL, false);
if (oldwin == NULL) {
- /* Very first window, need to create an empty buffer for it and
- * initialize from scratch. */
+ // Very first window, need to create an empty buffer for it and
+ // initialize from scratch.
curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
if (curbuf == NULL) {
return FAIL;
@@ -3732,6 +3735,7 @@ void free_tabpage(tabpage_T *tp)
}
xfree(tp->tp_localdir);
+ xfree(tp->tp_prevdir);
xfree(tp);
}
@@ -4014,10 +4018,10 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a
const int row = win_comp_pos(); // recompute w_winrow for all windows
diff_need_scrollbind = true;
- /* The tabpage line may have appeared or disappeared, may need to resize
- * the frames for that. When the Vim window was resized need to update
- * frame sizes too. Use the stored value of p_ch, so that it can be
- * different for each tab page. */
+ // The tabpage line may have appeared or disappeared, may need to resize
+ // the frames for that. When the Vim window was resized need to update
+ // frame sizes too. Use the stored value of p_ch, so that it can be
+ // different for each tab page.
if (p_ch != curtab->tp_ch_used) {
clear_cmdline = true;
}
@@ -4112,8 +4116,8 @@ void goto_tabpage(int n)
tp = curtab->tp_next;
}
} else if (n < 0) {
- /* "gT": go to previous tab page, wrap around end. "N gT" repeats
- * this N times. */
+ // "gT": go to previous tab page, wrap around end. "N gT" repeats
+ // this N times.
ttp = curtab;
for (i = n; i < 0; ++i) {
for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL;
@@ -4540,9 +4544,9 @@ static void win_enter_ext(win_T *const wp, const int flags)
}
}
if (os_chdir(new_dir) == 0) {
- if (!p_acd && !strequal(new_dir, cwd)) {
+ if (!p_acd && pathcmp(new_dir, cwd, -1) != 0) {
do_autocmd_dirchanged(new_dir, curwin->w_localdir
- ? kCdScopeWindow : kCdScopeTab, true);
+ ? kCdScopeWindow : kCdScopeTabpage, kCdCauseWindow);
}
shorten_fnames(true);
}
@@ -4550,8 +4554,8 @@ static void win_enter_ext(win_T *const wp, const int flags)
// Window doesn't have a local directory and we are not in the global
// directory: Change to the global directory.
if (os_chdir((char *)globaldir) == 0) {
- if (!p_acd && !strequal((char *)globaldir, cwd)) {
- do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, true);
+ if (!p_acd && pathcmp((char *)globaldir, cwd, -1) != 0) {
+ do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, kCdCauseWindow);
}
}
XFREE_CLEAR(globaldir);
@@ -4677,9 +4681,9 @@ static win_T *win_alloc(win_T *after, bool hidden)
new_wp->w_vars = tv_dict_alloc();
init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
- /* Don't execute autocommands while the window is not properly
- * initialized yet. gui_create_scrollbar() may trigger a FocusGained
- * event. */
+ // Don't execute autocommands while the window is not properly
+ // initialized yet. gui_create_scrollbar() may trigger a FocusGained
+ // event.
block_autocmds();
/*
* link the window in the window list
@@ -4742,8 +4746,8 @@ static void win_free(win_T *wp, tabpage_T *tp)
// reduce the reference count to the argument list.
alist_unlink(wp->w_alist);
- /* Don't execute autocommands while the window is halfway being deleted.
- * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
+ // Don't execute autocommands while the window is halfway being deleted.
+ // gui_mch_destroy_scrollbar() may trigger a FocusGained event.
block_autocmds();
clear_winopt(&wp->w_onebuf_opt);
@@ -4770,6 +4774,7 @@ static void win_free(win_T *wp, tabpage_T *tp)
}
xfree(wp->w_localdir);
+ xfree(wp->w_prevdir);
/* Remove the window from the b_wininfo lists, it may happen that the
* freed memory is re-used for another window. */
@@ -5200,8 +5205,8 @@ static void frame_setheight(frame_T *curfrp, int height)
frame_new_height(curfrp, height, false, false);
}
} else if (curfrp->fr_parent->fr_layout == FR_ROW) {
- /* Row of frames: Also need to resize frames left and right of this
- * one. First check for the minimal height of these. */
+ // Row of frames: Also need to resize frames left and right of this
+ // one. First check for the minimal height of these.
h = frame_minheight(curfrp->fr_parent, NULL);
if (height < h) {
height = h;
@@ -5261,13 +5266,13 @@ static void frame_setheight(frame_T *curfrp, int height)
*/
take = height - curfrp->fr_height;
- /* If there is not enough room, also reduce the height of a window
- * with 'winfixheight' set. */
+ // If there is not enough room, also reduce the height of a window
+ // with 'winfixheight' set.
if (height > room + room_cmdline - room_reserved) {
room_reserved = room + room_cmdline - height;
}
- /* If there is only a 'winfixheight' window and making the
- * window smaller, need to make the other window taller. */
+ // If there is only a 'winfixheight' window and making the
+ // window smaller, need to make the other window taller.
if (take < 0 && room - curfrp->fr_height < room_reserved) {
room_reserved = 0;
}
@@ -5342,8 +5347,8 @@ void win_setwidth(int width)
void win_setwidth_win(int width, win_T *wp)
{
- /* Always keep current window at least one column wide, even when
- * 'winminwidth' is zero. */
+ // Always keep current window at least one column wide, even when
+ // 'winminwidth' is zero.
if (wp == curwin) {
if (width < p_wmw) {
width = p_wmw;
@@ -5394,8 +5399,8 @@ static void frame_setwidth(frame_T *curfrp, int width)
}
if (curfrp->fr_parent->fr_layout == FR_COL) {
- /* Column of frames: Also need to resize frames above and below of
- * this one. First check for the minimal width of these. */
+ // Column of frames: Also need to resize frames above and below of
+ // this one. First check for the minimal width of these.
w = frame_minwidth(curfrp->fr_parent, NULL);
if (width < w) {
width = w;
@@ -5442,13 +5447,13 @@ static void frame_setwidth(frame_T *curfrp, int width)
*/
take = width - curfrp->fr_width;
- /* If there is not enough room, also reduce the width of a window
- * with 'winfixwidth' set. */
+ // If there is not enough room, also reduce the width of a window
+ // with 'winfixwidth' set.
if (width > room - room_reserved) {
room_reserved = room - width;
}
- /* If there is only a 'winfixwidth' window and making the
- * window smaller, need to make the other window narrower. */
+ // If there is only a 'winfixwidth' window and making the
+ // window smaller, need to make the other window narrower.
if (take < 0 && room - curfrp->fr_width < room_reserved) {
room_reserved = 0;
}
@@ -5557,8 +5562,8 @@ void win_drag_status_line(win_T *dragwin, int offset)
curfr = fr;
if (fr != topframe) { // more than one window
fr = fr->fr_parent;
- /* When the parent frame is not a column of frames, its parent should
- * be. */
+ // When the parent frame is not a column of frames, its parent should
+ // be.
if (fr->fr_layout != FR_COL) {
curfr = fr;
if (fr != topframe) { // only a row of windows, may drag statusline
@@ -6009,9 +6014,9 @@ void command_height(void)
frame_T *frp;
int old_p_ch = curtab->tp_ch_used;
- /* Use the value of p_ch that we remembered. This is needed for when the
- * GUI starts up, we can't be sure in what order things happen. And when
- * p_ch was changed in another tab page. */
+ // Use the value of p_ch that we remembered. This is needed for when the
+ // GUI starts up, we can't be sure in what order things happen. And when
+ // p_ch was changed in another tab page.
curtab->tp_ch_used = p_ch;
// Find bottom frame with width of screen.
@@ -6270,8 +6275,8 @@ static void last_status_rec(frame_T *fr, bool statusline)
EMSG(_(e_noroom));
return;
}
- /* In a column of frames: go to frame above. If already at
- * the top or in a row of frames: go to parent. */
+ // In a column of frames: go to frame above. If already at
+ // the top or in a row of frames: go to parent.
if (fp->fr_parent->fr_layout == FR_COL && fp->fr_prev != NULL) {
fp = fp->fr_prev;
} else {
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 6b644ed519..d8914a3ab7 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -91,6 +91,14 @@ describe('API', function()
nvim('exec', 'set nowrap', false)
eq('nowrap\n\tLast set from anonymous :source',
nvim('exec', 'verbose set wrap?', true))
+
+ -- Using script var to force creation of a script item
+ nvim('exec', [[
+ let s:a = 1
+ set nowrap
+ ]], false)
+ eq('nowrap\n\tLast set from anonymous :source (script id 1)',
+ nvim('exec', 'verbose set wrap?', true))
end)
it('multiline input', function()
@@ -132,6 +140,43 @@ describe('API', function()
-- try no spaces before continuations to catch off-by-one error
nvim('exec', 'let ab = #{\n\\a: 98,\n"\\ b: 2\n\\}', false)
eq({a = 98}, request('nvim_eval', 'g:ab'))
+
+ -- Script scope (s:)
+ eq('ahoy! script-scoped varrrrr', nvim('exec', [[
+ let s:pirate = 'script-scoped varrrrr'
+ function! s:avast_ye_hades(s) abort
+ return a:s .. ' ' .. s:pirate
+ endfunction
+ echo <sid>avast_ye_hades('ahoy!')
+ ]], true))
+
+ eq('ahoy! script-scoped varrrrr', nvim('exec', [[
+ let s:pirate = 'script-scoped varrrrr'
+ function! Avast_ye_hades(s) abort
+ return a:s .. ' ' .. s:pirate
+ endfunction
+ echo nvim_exec('echo Avast_ye_hades(''ahoy!'')', 1)
+ ]], true))
+
+ eq('Vim(call):E5555: API call: Vim(echo):E121: Undefined variable: s:pirate',
+ pcall_err(request, 'nvim_exec', [[
+ let s:pirate = 'script-scoped varrrrr'
+ call nvim_exec('echo s:pirate', 1)
+ ]], false))
+
+ -- Script items are created only on script var access
+ eq('1\n0', nvim('exec', [[
+ echo expand("<SID>")->empty()
+ let s:a = 123
+ echo expand("<SID>")->empty()
+ ]], true))
+
+ eq('1\n0', nvim('exec', [[
+ echo expand("<SID>")->empty()
+ function s:a() abort
+ endfunction
+ echo expand("<SID>")->empty()
+ ]], true))
end)
it('non-ASCII input', function()
diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua
index 6f2da24cf2..f4a1642ebf 100644
--- a/test/functional/autocmd/dirchanged_spec.lua
+++ b/test/functional/autocmd/dirchanged_spec.lua
@@ -6,6 +6,7 @@ local command = h.command
local eq = h.eq
local eval = h.eval
local request = h.request
+local iswin = h.iswin
describe('autocmd DirChanged', function()
local curdir = string.gsub(lfs.currentdir(), '\\', '/')
@@ -14,6 +15,11 @@ describe('autocmd DirChanged', function()
curdir .. '/Xtest-functional-autocmd-dirchanged.dir2',
curdir .. '/Xtest-functional-autocmd-dirchanged.dir3',
}
+ local win_dirs = {
+ curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR1',
+ curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR2',
+ curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR3',
+ }
setup(function() for _, dir in pairs(dirs) do h.mkdir(dir) end end)
teardown(function() for _, dir in pairs(dirs) do h.rmdir(dir) end end)
@@ -27,17 +33,20 @@ describe('autocmd DirChanged', function()
command([[autocmd DirChanged * let g:getcwd = substitute(g:getcwd, '\\', '/', 'g')]])
end)
- it('sets v:event', function()
+ it('sets v:event and <amatch>', function()
command('lcd '..dirs[1])
eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
eq(1, eval('g:cdcount'))
command('tcd '..dirs[2])
- eq({cwd=dirs[2], scope='tab', changed_window=false}, eval('g:ev'))
+ eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev'))
+ eq('tabpage', eval('g:amatch'))
eq(2, eval('g:cdcount'))
command('cd '..dirs[3])
eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev'))
+ eq('global', eval('g:amatch'))
eq(3, eval('g:cdcount'))
end)
@@ -63,17 +72,6 @@ describe('autocmd DirChanged', function()
eq(dirs[3], eval('getcwd()'))
end)
- it('sets <amatch> to CWD "scope"', function()
- command('lcd '..dirs[1])
- eq('window', eval('g:amatch'))
-
- command('tcd '..dirs[2])
- eq('tab', eval('g:amatch'))
-
- command('cd '..dirs[3])
- eq('global', eval('g:amatch'))
- end)
-
it('does not trigger if :cd fails', function()
command('let g:ev = {}')
@@ -106,13 +104,79 @@ describe('autocmd DirChanged', function()
command('split '..dirs[1]..'/foo')
eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('auto', eval('g:amatch'))
command('split '..dirs[2]..'/bar')
eq({cwd=dirs[2], scope='window', changed_window=false}, eval('g:ev'))
+ eq('auto', eval('g:amatch'))
eq(2, eval('g:cdcount'))
end)
+ it('does not trigger if directory has not changed', function()
+ command('lcd '..dirs[1])
+ eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
+ eq(1, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('lcd '..dirs[1])
+ eq({}, eval('g:ev'))
+ eq(1, eval('g:cdcount'))
+
+ if iswin() then
+ command('lcd '..win_dirs[1])
+ eq({}, eval('g:ev'))
+ eq(1, eval('g:cdcount'))
+ end
+
+ command('tcd '..dirs[2])
+ eq({cwd=dirs[2], scope='tabpage', changed_window=false}, eval('g:ev'))
+ eq('tabpage', eval('g:amatch'))
+ eq(2, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('tcd '..dirs[2])
+ eq({}, eval('g:ev'))
+ eq(2, eval('g:cdcount'))
+
+ if iswin() then
+ command('tcd '..win_dirs[2])
+ eq({}, eval('g:ev'))
+ eq(2, eval('g:cdcount'))
+ end
+
+ command('cd '..dirs[3])
+ eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev'))
+ eq('global', eval('g:amatch'))
+ eq(3, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('cd '..dirs[3])
+ eq({}, eval('g:ev'))
+ eq(3, eval('g:cdcount'))
+
+ if iswin() then
+ command('cd '..win_dirs[3])
+ eq({}, eval('g:ev'))
+ eq(3, eval('g:cdcount'))
+ end
+
+ command('set autochdir')
+
+ command('split '..dirs[1]..'/foo')
+ eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev'))
+ eq('auto', eval('g:amatch'))
+ eq(4, eval('g:cdcount'))
+ command('let g:ev = {}')
+ command('split '..dirs[1]..'/bar')
+ eq({}, eval('g:ev'))
+ eq(4, eval('g:cdcount'))
+
+ if iswin() then
+ command('split '..win_dirs[1]..'/baz')
+ eq({}, eval('g:ev'))
+ eq(4, eval('g:cdcount'))
+ end
+ end)
+
it("is triggered by switching to win/tab with different CWD #6054", function()
command('lcd '..dirs[3]) -- window 3
command('split '..dirs[2]..'/foo') -- window 2
@@ -122,6 +186,7 @@ describe('autocmd DirChanged', function()
command('2wincmd w') -- window 2
eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
eq(4, eval('g:cdcount'))
command('tabnew') -- tab 2 (tab-local CWD)
@@ -129,8 +194,10 @@ describe('autocmd DirChanged', function()
command('tcd '..dirs[3])
command('tabnext') -- tab 1 (no tab-local CWD)
eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev'))
+ eq('window', eval('g:amatch'))
command('tabnext') -- tab 2
- eq({cwd=dirs[3], scope='tab', changed_window=true}, eval('g:ev'))
+ eq({cwd=dirs[3], scope='tabpage', changed_window=true}, eval('g:ev'))
+ eq('tabpage', eval('g:amatch'))
eq(7, eval('g:cdcount'))
command('tabnext') -- tab 1
@@ -138,6 +205,31 @@ describe('autocmd DirChanged', function()
eq(9, eval('g:cdcount'))
command('tabnext') -- tab 2 (has the *same* CWD)
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+
+ if iswin() then
+ command('tabnew') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tcd '..win_dirs[3])
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 1
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 2
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 1
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('lcd '..win_dirs[3]) -- window 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 2
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabnext') -- tab 1
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ command('tabprevious') -- tab 3
+ eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
+ end
end)
it('is triggered by nvim_set_current_dir()', function()
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index bf2559f8d7..cc6e2c8067 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -328,6 +328,15 @@ describe('startup', function()
eq({9003, '\thowdy'}, exec_lua [[ return { _G.y, _G.z } ]])
end)
+ it("handles require from &packpath in an async handler", function()
+ -- NO! you cannot just speed things up by calling async functions during startup!
+ -- It doesn't make anything actually faster! NOOOO!
+ pack_clear [[ lua require'async_leftpad'('brrrr', 'async_res') ]]
+
+ -- haha, async leftpad go brrrrr
+ eq('\tbrrrr', exec_lua [[ return _G.async_res ]])
+ end)
+
it("handles :packadd during startup", function()
-- control group: opt/bonus is not availabe by default
pack_clear [[
diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua
index bdf6ae76d1..fa650d611b 100644
--- a/test/functional/ex_cmds/source_spec.lua
+++ b/test/functional/ex_cmds/source_spec.lua
@@ -25,12 +25,19 @@ describe(':source', function()
let b = #{
\ k: "v"
"\ (o_o)
- \ }]])
+ \ }
+ let c = expand("<SID>")->empty()
+ let s:s = 0zbeef.cafe
+ let d = s:s]])
command('source')
eq('2', meths.exec('echo a', true))
eq("{'k': 'v'}", meths.exec('echo b', true))
+ -- Script items are created only on script var access
+ eq("1", meths.exec('echo c', true))
+ eq("0zBEEFCAFE", meths.exec('echo d', true))
+
exec('set cpoptions+=C')
eq('Vim(let):E15: Invalid expression: #{', exc_exec('source'))
end)
@@ -43,7 +50,11 @@ describe(':source', function()
let b = #{
"\ (>_<)
\ K: "V"
- \ }]])
+ \ }
+ function! s:C() abort
+ return expand("<SID>") .. "C()"
+ endfunction
+ let D = {-> s:C()}]])
-- Source the 2nd line only
feed('ggjV')
@@ -55,6 +66,11 @@ describe(':source', function()
feed_command(':source')
eq('4', meths.exec('echo a', true))
eq("{'K': 'V'}", meths.exec('echo b', true))
+ eq("<SNR>1_C()", meths.exec('echo D()', true))
+
+ -- Source last line only
+ feed_command(':$source')
+ eq('Vim(echo):E117: Unknown function: s:C', exc_exec('echo D()'))
exec('set cpoptions+=C')
eq('Vim(let):E15: Invalid expression: #{', exc_exec("'<,'>source"))
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua
new file mode 100644
index 0000000000..7daa7733a0
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_y.lua
@@ -0,0 +1 @@
+return "I am fancy_y.lua"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua
new file mode 100644
index 0000000000..6e81afdd70
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/after/lua/fancy_z.lua
@@ -0,0 +1 @@
+return "I am fancy_z.lua"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua
new file mode 100644
index 0000000000..1b897a96cc
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x.lua
@@ -0,0 +1 @@
+return "I am fancy_x.lua"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua
new file mode 100644
index 0000000000..8c27a43cab
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_x/init.lua
@@ -0,0 +1 @@
+return "I am init.lua of fancy_x!"
diff --git a/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua
new file mode 100644
index 0000000000..b66cbee4f6
--- /dev/null
+++ b/test/functional/fixtures/pack/foo/start/fancyplugin/lua/fancy_y/init.lua
@@ -0,0 +1,2 @@
+
+return "I am init.lua of fancy_y!"
diff --git a/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua b/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua
new file mode 100644
index 0000000000..a312572c5b
--- /dev/null
+++ b/test/functional/fixtures/start/nvim-leftpad/lua/async_leftpad.lua
@@ -0,0 +1,3 @@
+return function (val, res)
+ vim.loop.new_async(function() _G[res] = require'leftpad'(val) end):send()
+end
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index a08c8d8681..33469597a1 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -473,6 +473,78 @@ describe('vim.diagnostic', function()
end)
describe('config()', function()
+ it('works with global, namespace, and ephemeral options', function()
+ eq(1, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = true,
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_error('Some Error', 4, 4, 4, 4),
+ })
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+
+ eq(1, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = false,
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_error('Some Error', 4, 4, 4, 4),
+ }, {virtual_text = true})
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+
+ eq(0, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = {severity=vim.diagnostic.severity.ERROR},
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_warning('Some Warning', 4, 4, 4, 4),
+ }, {virtual_text = true})
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+
+ eq(1, exec_lua [[
+ vim.diagnostic.config({
+ virtual_text = false,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = {severity=vim.diagnostic.severity.ERROR},
+ underline = false,
+ }, diagnostic_ns)
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, {
+ make_warning('Some Warning', 4, 4, 4, 4),
+ }, {
+ virtual_text = {} -- An empty table uses default values
+ })
+
+ return count_extmarks(diagnostic_bufnr, diagnostic_ns)
+ ]])
+ end)
+
it('can use functions for config values', function()
exec_lua [[
vim.diagnostic.config({
diff --git a/test/functional/lua/ffi_spec.lua b/test/functional/lua/ffi_spec.lua
new file mode 100644
index 0000000000..80c01a2b8c
--- /dev/null
+++ b/test/functional/lua/ffi_spec.lua
@@ -0,0 +1,62 @@
+local helpers = require('test.functional.helpers')(after_each)
+local eq = helpers.eq
+local exec_lua = helpers.exec_lua
+local clear = helpers.clear
+
+before_each(clear)
+
+describe('ffi.cdef', function()
+ it('can use Neovim core functions', function()
+ if not exec_lua("return pcall(require, 'ffi')") then
+ pending('missing LuaJIT FFI')
+ end
+
+ eq(12, exec_lua[[
+ local ffi = require('ffi')
+
+ ffi.cdef('int curwin_col_off(void);')
+
+ vim.cmd('set number numberwidth=4 signcolumn=yes:4')
+
+ return ffi.C.curwin_col_off()
+ ]])
+
+ eq(20, exec_lua[=[
+ local ffi = require('ffi')
+
+ ffi.cdef[[
+ typedef unsigned char char_u;
+ typedef struct window_S win_T;
+ typedef struct {} stl_hlrec_t;
+ typedef struct {} StlClickRecord;
+ typedef struct {} Error;
+
+ win_T *find_window_by_handle(int Window, Error *err);
+
+ int build_stl_str_hl(
+ win_T *wp,
+ char_u *out,
+ size_t outlen,
+ char_u *fmt,
+ int use_sandbox,
+ char_u fillchar,
+ int maxwidth,
+ stl_hlrec_t **hltab,
+ StlClickRecord **tabtab
+ );
+ ]]
+
+ return ffi.C.build_stl_str_hl(
+ ffi.C.find_window_by_handle(0, ffi.new('Error')),
+ ffi.new('char_u[1024]'),
+ 1024,
+ ffi.cast('char_u*', 'StatusLineOfLength20'),
+ 0,
+ 0,
+ 0,
+ nil,
+ nil
+ )
+ ]=])
+ end)
+end)
diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua
index 052a8a1ecd..81f1820986 100644
--- a/test/functional/lua/uri_spec.lua
+++ b/test/functional/lua/uri_spec.lua
@@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local exec_lua = helpers.exec_lua
local eq = helpers.eq
+local write_file = require('test.helpers').write_file
describe('URI methods', function()
before_each(function()
@@ -158,6 +159,22 @@ describe('URI methods', function()
end)
+ describe('uri from bufnr', function()
+ it('Windows paths should not be treated as uris', function()
+ if not helpers.iswin() then return end
+
+ local file = helpers.tmpname()
+ write_file(file, 'Test content')
+ local test_case = string.format([[
+ local file = '%s'
+ return vim.uri_from_bufnr(vim.fn.bufadd(file))
+ ]], file)
+ local expected_uri = 'file:///' .. file:gsub("\\", "/")
+ eq(expected_uri, exec_lua(test_case))
+ os.remove(file)
+ end)
+ end)
+
describe('uri to bufnr', function()
it('uri_to_bufnr & uri_from_bufnr returns original uri for non-file uris', function()
local uri = 'jdt://contents/java.base/java.util/List.class?=sql/%5C/home%5C/user%5C/.jabba%5C/jdk%5C/openjdk%5C@1.14.0%5C/lib%5C/jrt-fs.jar%60java.base=/javadoc_location=/https:%5C/%5C/docs.oracle.com%5C/en%5C/java%5C/javase%5C/14%5C/docs%5C/api%5C/=/%3Cjava.util(List.class'
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 8651a38025..a739992611 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -2255,7 +2255,7 @@ end)
describe('lua: require("mod") from packages', function()
before_each(function()
- command('set rtp+=test/functional/fixtures')
+ command('set rtp+=test/functional/fixtures pp+=test/functional/fixtures')
end)
it('propagates syntax error', function()
@@ -2266,4 +2266,13 @@ describe('lua: require("mod") from packages', function()
matches("unexpected symbol", syntax_error_msg)
end)
+
+ it('uses the right order of mod.lua vs mod/init.lua', function()
+ -- lua/fancy_x.lua takes precedence over lua/fancy_x/init.lua
+ eq('I am fancy_x.lua', exec_lua [[ return require'fancy_x' ]])
+ -- but lua/fancy_y/init.lua takes precedence over after/lua/fancy_y.lua
+ eq('I am init.lua of fancy_y!', exec_lua [[ return require'fancy_y' ]])
+ -- safety check: after/lua/fancy_z.lua is still loaded
+ eq('I am fancy_z.lua', exec_lua [[ return require'fancy_z' ]])
+ end)
end)
diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua
index 45fcf945f4..b84e9d1533 100644
--- a/test/functional/plugin/health_spec.lua
+++ b/test/functional/plugin/health_spec.lua
@@ -208,12 +208,12 @@ describe('health.vim', function()
^ |
{Heading:foo: } |
{Bar:========================================================================}|
- {Bullet: -} {Error:ERROR:} No healthcheck found for "foo" plugin. |
+ {Bullet: -} {Error:ERROR}: No healthcheck found for "foo" plugin. |
|
{Heading:success1: health#success1#check} |
{Bar:========================================================================}|
{Heading2:##}{Heading: report 1} |
- {Bullet: -} {Ok:OK:} everything is fine |
+ {Bullet: -} {Ok:OK}: everything is fine |
|
]]}
end)