diff options
49 files changed, 1402 insertions, 984 deletions
@@ -189,8 +189,16 @@ contributed under the Vim license and (2) externally maintained libraries. The externally maintained libraries used by Neovim are: - Klib: a Generic Library in C. MIT/X11 license. - - libuv. Copyright Joyent, Inc. and other Node contributors. Node.js license. + - Lua: MIT license - LuaJIT: a Just-In-Time Compiler for Lua. Copyright Mike Pall. MIT license. + - Luv: Apache 2.0 license + - libmpack: MIT license + - libtermkey: MIT license + - libuv. Copyright Joyent, Inc. and other Node contributors. Node.js license. + - libvterm: MIT license + - lua-compat: MIT license + - tree-sitter: MIT license + - xdiff: LGPL license ==== diff --git a/MAINTAIN.md b/MAINTAIN.md index 58d977f247..73578a8c5d 100644 --- a/MAINTAIN.md +++ b/MAINTAIN.md @@ -10,14 +10,13 @@ General guidelines * Write down what was decided * Constraints are good * Use automation to solve problems -* Never break the API +* Never break the API... but sometimes break the UI Ticket triage ------------- -In practice we haven't found a meaningful way to forecast more precisely than -"next" and "after next". That means there are usually one or two (at most) -planned milestones: +In practice we haven't found a way to forecast more precisely than "next" and +"after next". So there are usually one or two (at most) planned milestones: - Next bugfix-release (1.0.x) - Next feature-release (1.x.0) @@ -25,16 +24,16 @@ planned milestones: The forecasting problem might be solved with an explicit priority system (like Bram's todo.txt). Meanwhile the Neovim priority system is defined by: -- PRs nearing completion (RDY). +- PRs nearing completion. - Issue labels. E.g. the `+plan` label increases the ticket's priority merely for having a plan written down: it is _closer to completion_ than tickets without a plan. - Comment activity or new information. -Anything that isn't in the next milestone, and doesn't have a RDY PR ... is +Anything that isn't in the next milestone, and doesn't have a finished PR—is just not something you care very much about, by construction. Post-release you can review open issues, but chances are your next milestone is already getting -full :) +full... :) Release policy -------------- diff --git a/contrib/uncrustify.cfg b/contrib/uncrustify.cfg index 567354600c..6fcde7ad82 100644 --- a/contrib/uncrustify.cfg +++ b/contrib/uncrustify.cfg @@ -1,4 +1,4 @@ -# Uncrustify-0.73.0-159-81b1bc77 +# Uncrustify-0.73.0-164-c9a58467 # # General options diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index f27d1e01a0..9d15bd52a5 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -9139,11 +9139,23 @@ synstack({lnum}, {col}) *synstack()* valid positions. system({cmd} [, {input}]) *system()* *E677* - Get the output of {cmd} as a |string| (use |systemlist()| to - get a |List|). {cmd} is treated exactly as in |jobstart()|. - Not to be used for interactive commands. + Gets the output of {cmd} as a |string| (|systemlist()| returns + a |List|) and sets |v:shell_error| to the error code. + {cmd} is treated as in |jobstart()|: + If {cmd} is a List it runs directly (no 'shell'). + If {cmd} is a String it runs in the 'shell', like this: > + :call jobstart(split(&shell) + split(&shellcmdflag) + ['{cmd}']) - If {input} is a string it is written to a pipe and passed as +< Not to be used for interactive commands. + + Result is a String, filtered to avoid platform-specific quirks: + - <CR><NL> is replaced with <NL> + - NUL characters are replaced with SOH (0x01) + + Example: > + :echo system(['ls', expand('%:h')]) + +< If {input} is a string it is written to a pipe and passed as stdin to the command. The string is written as-is, line separators are not changed. If {input} is a |List| it is written to the pipe as @@ -9165,29 +9177,12 @@ system({cmd} [, {input}]) *system()* *E677* Note: Use |shellescape()| or |::S| with |expand()| or |fnamemodify()| to escape special characters in a command - argument. Newlines in {cmd} may cause the command to fail. - The characters in 'shellquote' and 'shellxquote' may also - cause trouble. - - Result is a String. Example: > - :let files = system("ls " . shellescape(expand('%:h'))) - :let files = system('ls ' . expand('%:h:S')) - -< To make the result more system-independent, the shell output - is filtered to replace <CR> with <NL> for Macintosh, and - <CR><NL> with <NL> for DOS-like systems. - To avoid the string being truncated at a NUL, all NUL - characters are replaced with SOH (0x01). - - The command executed is constructed using several options when - {cmd} is a string: 'shell' 'shellcmdflag' {cmd} - - The resulting error code can be found in |v:shell_error|. + argument. 'shellquote' and 'shellxquote' must be properly + configured. Example: > + :echo system('ls '..shellescape(expand('%:h'))) + :echo system('ls '..expand('%:h:S')) - Note that any wrong value in the options mentioned above may - make the function fail. It has also been reported to fail - when using a security agent application. - Unlike ":!cmd" there is no automatic check for changed files. +< Unlike ":!cmd" there is no automatic check for changed files. Use |:checktime| to force a check. Can also be used as a |method|: > diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 5731569947..032c28c659 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1,15 +1,15 @@ *lua.txt* Nvim - NVIM REFERENCE MANUAL + NVIM REFERENCE MANUAL -Lua engine *lua* *Lua* +Lua engine *lua* *Lua* Type |gO| to see the table of contents. ============================================================================== -INTRODUCTION *lua-intro* +INTRODUCTION *lua-intro* The Lua 5.1 language is builtin and always available. Try this command to get an idea of what lurks beneath: > @@ -27,11 +27,12 @@ are on 'runtimepath': ~/.config/nvim/lua/foo.lua then `require('foo')` loads "~/.config/nvim/lua/foo.lua", and "runtime/lua/foo.lua" is not used. See |lua-require| to understand how Nvim -finds and loads Lua modules. The conventions are similar to VimL plugins, -with some extra features. See |lua-require-example| for a walkthrough. +finds and loads Lua modules. The conventions are similar to those of +Vimscript |plugin|s, with some extra features. See |lua-require-example| for +a walkthrough. ============================================================================== -IMPORTING LUA MODULES *lua-require* +IMPORTING LUA MODULES *lua-require* *lua-package-path* Nvim automatically adjusts `package.path` and `package.cpath` according to @@ -157,7 +158,7 @@ function without any parentheses. This is most often used to approximate ------------------------------------------------------------------------------ -LUA PLUGIN EXAMPLE *lua-require-example* +LUA PLUGIN EXAMPLE *lua-require-example* The following example plugin adds a command `:MakeCharBlob` which transforms current buffer into a long `unsigned char` array. Lua contains transformation @@ -234,7 +235,7 @@ lua/charblob.lua: > } ============================================================================== -COMMANDS *lua-commands* +COMMANDS *lua-commands* These commands execute a Lua chunk from either the command line (:lua, :luado) or a file (:luafile) on the given line [range]. As always in Lua, each chunk @@ -298,19 +299,20 @@ arguments separated by " " (space) instead of "\t" (tab). :luado if bp:match(line) then return "-->\t" .. line end < - *:luafile* + *:luafile* :[range]luafile {file} - Execute Lua script in {file}. - The whole argument is used as a single file name. + Execute Lua script in {file}. + The whole argument is used as the filename (like + |:edit|), spaces do not need to be escaped. + Alternatively you can |:source| Lua files. - Examples: - > + Examples: > :luafile script.lua :luafile % < ============================================================================== -luaeval() *lua-eval* *luaeval()* +luaeval() *lua-eval* *luaeval()* The (dual) equivalent of "vim.eval" for passing Lua values to Nvim is "luaeval". "luaeval" takes an expression string and an optional argument used @@ -324,8 +326,7 @@ semantically equivalent in Lua to: end Lua nils, numbers, strings, tables and booleans are converted to their -respective VimL types. An error is thrown if conversion of any other Lua types -is attempted. +respective Vimscript types. Conversion of other Lua types is an error. The magic global "_A" contains the second argument to luaeval(). @@ -348,21 +349,21 @@ cases there is the following agreement: 3. Table with string keys, at least one of which contains NUL byte, is also considered to be a dictionary, but this time it is converted to a |msgpack-special-map|. - *lua-special-tbl* + *lua-special-tbl* 4. Table with `vim.type_idx` key may be a dictionary, a list or floating-point value: - - `{[vim.type_idx]=vim.types.float, [vim.val_idx]=1}` is converted to - a floating-point 1.0. Note that by default integral Lua numbers are - converted to |Number|s, non-integral are converted to |Float|s. This + - `{[vim.type_idx]=vim.types.float, [vim.val_idx]=1}` is converted to + a floating-point 1.0. Note that by default integral Lua numbers are + converted to |Number|s, non-integral are converted to |Float|s. This variant allows integral |Float|s. - - `{[vim.type_idx]=vim.types.dictionary}` is converted to an empty - dictionary, `{[vim.type_idx]=vim.types.dictionary, [42]=1, a=2}` is - converted to a dictionary `{'a': 42}`: non-string keys are ignored. - Without `vim.type_idx` key tables with keys not fitting in 1., 2. or 3. + - `{[vim.type_idx]=vim.types.dictionary}` is converted to an empty + dictionary, `{[vim.type_idx]=vim.types.dictionary, [42]=1, a=2}` is + converted to a dictionary `{'a': 42}`: non-string keys are ignored. + Without `vim.type_idx` key tables with keys not fitting in 1., 2. or 3. are errors. - - `{[vim.type_idx]=vim.types.list}` is converted to an empty list. As well - as `{[vim.type_idx]=vim.types.list, [42]=1}`: integral keys that do not - form a 1-step sequence from 1 to N are ignored, as well as all + - `{[vim.type_idx]=vim.types.list}` is converted to an empty list. As well + as `{[vim.type_idx]=vim.types.list, [42]=1}`: integral keys that do not + form a 1-step sequence from 1 to N are ignored, as well as all non-integral keys. Examples: > @@ -373,13 +374,13 @@ Examples: > : endfunction :echo Rand(1,10) -Note: second argument to `luaeval` undergoes VimL to Lua conversion -("marshalled"), so changes to Lua containers do not affect values in VimL. -Return value is also always converted. When converting, -|msgpack-special-dict|s are treated specially. +Note: second argument to `luaeval` is converted ("marshalled") from Vimscript +to Lua, so changes to Lua containers do not affect values in Vimscript. Return +value is also always converted. When converting, |msgpack-special-dict|s are +treated specially. ============================================================================== -Vimscript v:lua interface *v:lua-call* +Vimscript v:lua interface *v:lua-call* From Vimscript the special `v:lua` prefix can be used to call Lua functions which are global or accessible from global tables. The expression > @@ -419,7 +420,7 @@ Note: `v:lua` without a call is not allowed in a Vimscript expression: ============================================================================== -Lua standard modules *lua-stdlib* +Lua standard modules *lua-stdlib* The Nvim Lua "standard library" (stdlib) is the `vim` module, which exposes various functions and sub-modules. It is always loaded, thus require("vim") @@ -453,7 +454,7 @@ Note that underscore-prefixed functions (e.g. "_os_proc_children") are internal/private and must not be used by plugins. ------------------------------------------------------------------------------ -VIM.LOOP *lua-loop* *vim.loop* +VIM.LOOP *lua-loop* *vim.loop* `vim.loop` exposes all features of the Nvim event-loop. This is a low-level API that provides functionality for networking, filesystem, and process @@ -464,7 +465,7 @@ management. Try this command to see available functions: > Reference: https://github.com/luvit/luv/blob/master/docs.md Examples: https://github.com/luvit/luv/tree/master/examples - *E5560* *lua-loop-callbacks* + *E5560* *lua-loop-callbacks* It is an error to directly invoke `vim.api` functions (except |api-fast|) in `vim.loop` callbacks. For example, this is an error: > @@ -500,7 +501,7 @@ Example: repeating timer print('sleeping'); -Example: File-change detection *watch-file* +Example: File-change detection *watch-file* 1. Save this code to a file. 2. Execute it with ":luafile %". 3. Use ":Watch %" to watch any file. @@ -526,7 +527,7 @@ Example: File-change detection *watch-file* "command! -nargs=1 Watch call luaeval('watch_file(_A)', expand('<args>'))") -Example: TCP echo-server *tcp-server* +Example: TCP echo-server *tcp-server* 1. Save this code to a file. 2. Execute it with ":luafile %". 3. Note the port number. @@ -556,7 +557,7 @@ Example: TCP echo-server *tcp-server* print('TCP echo-server listening on port: '..server:getsockname().port) ------------------------------------------------------------------------------ -VIM.HIGHLIGHT *lua-highlight* +VIM.HIGHLIGHT *lua-highlight* Nvim includes a function for highlighting a selection on yank (see for example https://github.com/machakann/vim-highlightedyank). To enable it, add @@ -591,21 +592,19 @@ vim.highlight.range({bufnr}, {ns}, {higroup}, {start}, {finish}, {rtype}, {inclu range is inclusive (default false). ------------------------------------------------------------------------------ -VIM.REGEX *lua-regex* +VIM.REGEX *lua-regex* Vim regexes can be used directly from lua. Currently they only allow matching within a single line. -vim.regex({re}) *vim.regex()* +vim.regex({re}) *vim.regex()* + Parse the Vim regex {re} and return a regex object. Regexes are + "magic" and case-insensitive by default, regardless of 'magic' and + 'ignorecase'. The can be controlled with flags, see |/magic|. - Parse the regex {re} and return a regex object. 'magic' and - 'ignorecase' options are ignored, lua regexes always defaults to magic - and ignoring case. The behavior can be changed with flags in - the beginning of the string |/magic|. +Methods on the regex object: -Regex objects support the following methods: - -regex:match_str({str}) *regex:match_str()* +regex:match_str({str}) *regex:match_str()* Match the string against the regex. If the string should match the regex precisely, surround the regex with `^` and `$`. If the was a match, the byte indices for the beginning and end of @@ -613,7 +612,7 @@ regex:match_str({str}) *regex:match_str()* As any integer is truth-y, `regex:match()` can be directly used as a condition in an if-statement. -regex:match_line({bufnr}, {line_idx}[, {start}, {end}]) *regex:match_line()* +regex:match_line({bufnr}, {line_idx}[, {start}, {end}]) *regex:match_line()* Match line {line_idx} (zero-based) in buffer {bufnr}. If {start} and {end} are supplied, match only this byte index range. Otherwise see |regex:match_str()|. If {start} is used, then the returned byte @@ -692,67 +691,65 @@ VIM.MPACK *lua-mpack* The *vim.mpack* module provides packing and unpacking of lua objects to msgpack encoded strings. |vim.NIL| and |vim.empty_dict()| are supported. -vim.mpack.pack({obj}) *vim.mpack.pack* +vim.mpack.pack({obj}) *vim.mpack.pack* Packs a lua object {obj} and returns the msgpack representation as a string -vim.mpack.unpack({str}) *vim.mpack.unpack* +vim.mpack.unpack({str}) *vim.mpack.unpack* Unpacks the msgpack encoded {str} and returns a lua object ------------------------------------------------------------------------------ -VIM *lua-builtin* +VIM *lua-builtin* -vim.api.{func}({...}) *vim.api* +vim.api.{func}({...}) *vim.api* Invokes Nvim |API| function {func} with arguments {...}. Example: call the "nvim_get_current_line()" API function: > print(tostring(vim.api.nvim_get_current_line())) -vim.version() *vim.version* - Returns the version of the current neovim build. +vim.version() *vim.version* + Gets the version of the current Nvim build. -vim.in_fast_event() *vim.in_fast_event()* +vim.in_fast_event() *vim.in_fast_event()* Returns true if the code is executing as part of a "fast" event handler, where most of the API is disabled. These are low-level events (e.g. |lua-loop-callbacks|) which can be invoked whenever Nvim polls for input. When this is `false` most API functions are callable (but may be subject to other restrictions such as |textlock|). -vim.NIL *vim.NIL* - Special value used to represent NIL in msgpack-rpc and |v:null| in - vimL interaction, and similar cases. Lua `nil` cannot be used as - part of a lua table representing a Dictionary or Array, as it - is equivalent to a missing value: `{"foo", nil}` is the same as - `{"foo"}` +vim.NIL *vim.NIL* + Special value representing NIL in |RPC| and |v:null| in Vimscript + conversion, and similar cases. Lua `nil` cannot be used as part of + a Lua table representing a Dictionary or Array, because it is + treated as missing: `{"foo", nil}` is the same as `{"foo"}`. -vim.empty_dict() *vim.empty_dict()* - Creates a special table which will be converted to an empty - dictionary when converting lua values to vimL or API types. The - table is empty, and this property is marked using a metatable. An - empty table `{}` without this metatable will default to convert to - an array/list. +vim.empty_dict() *vim.empty_dict()* + Creates a special empty table (marked with a metatable), which Nvim + converts to an empty dictionary when translating Lua values to + Vimscript or API types. Nvim by default converts an empty table `{}` + without this metatable to an list/array. - Note: if numeric keys are added to the table, the metatable will be - ignored and the dict converted to a list/array anyway. + Note: if numeric keys are present in the table, Nvim ignores the + metatable marker and converts the dict to a list/array anyway. -vim.rpcnotify({channel}, {method}[, {args}...]) *vim.rpcnotify()* - Sends {event} to {channel} via |RPC| and returns immediately. - If {channel} is 0, the event is broadcast to all channels. +vim.rpcnotify({channel}, {method}[, {args}...]) *vim.rpcnotify()* + Sends {event} to {channel} via |RPC| and returns immediately. If + {channel} is 0, the event is broadcast to all channels. - This function also works in a fast callback |lua-loop-callbacks|. + This function also works in a fast callback |lua-loop-callbacks|. -vim.rpcrequest({channel}, {method}[, {args}...]) *vim.rpcrequest()* - Sends a request to {channel} to invoke {method} via - |RPC| and blocks until a response is received. +vim.rpcrequest({channel}, {method}[, {args}...]) *vim.rpcrequest()* + Sends a request to {channel} to invoke {method} via |RPC| and blocks + until a response is received. - Note: NIL values as part of the return value is represented as - |vim.NIL| special value + Note: NIL values as part of the return value is represented as + |vim.NIL| special value -vim.stricmp({a}, {b}) *vim.stricmp()* +vim.stricmp({a}, {b}) *vim.stricmp()* Compares strings case-insensitively. Returns 0, 1 or -1 if strings are equal, {a} is greater than {b} or {a} is lesser than {b}, respectively. -vim.str_utfindex({str}[, {index}]) *vim.str_utfindex()* +vim.str_utfindex({str}[, {index}]) *vim.str_utfindex()* Convert byte index to UTF-32 and UTF-16 indicies. If {index} is not supplied, the length of the string is used. All indicies are zero-based. Returns two values: the UTF-32 and UTF-16 indicies respectively. @@ -840,40 +837,40 @@ vim.wait({time} [, {callback}, {interval}, {fast_only}]) *vim.wait()* end < -vim.type_idx *vim.type_idx* - Type index for use in |lua-special-tbl|. Specifying one of the - values from |vim.types| allows typing the empty table (it is - unclear whether empty Lua table represents empty list or empty array) - and forcing integral numbers to be |Float|. See |lua-special-tbl| for - more details. +vim.type_idx *vim.type_idx* + Type index for use in |lua-special-tbl|. Specifying one of the values + from |vim.types| allows typing the empty table (it is unclear whether + empty Lua table represents empty list or empty array) and forcing + integral numbers to be |Float|. See |lua-special-tbl| for more + details. -vim.val_idx *vim.val_idx* - Value index for tables representing |Float|s. A table representing - floating-point value 1.0 looks like this: > +vim.val_idx *vim.val_idx* + Value index for tables representing |Float|s. A table representing + floating-point value 1.0 looks like this: > { [vim.type_idx] = vim.types.float, [vim.val_idx] = 1.0, } -< See also |vim.type_idx| and |lua-special-tbl|. - -vim.types *vim.types* - Table with possible values for |vim.type_idx|. Contains two sets - of key-value pairs: first maps possible values for |vim.type_idx| - to human-readable strings, second maps human-readable type names to - values for |vim.type_idx|. Currently contains pairs for `float`, - `array` and `dictionary` types. - - Note: one must expect that values corresponding to `vim.types.float`, - `vim.types.array` and `vim.types.dictionary` fall under only two - following assumptions: - 1. Value may serve both as a key and as a value in a table. Given the - properties of Lua tables this basically means “value is not `nil`”. - 2. For each value in `vim.types` table `vim.types[vim.types[value]]` - is the same as `value`. - No other restrictions are put on types, and it is not guaranteed that - values corresponding to `vim.types.float`, `vim.types.array` and - `vim.types.dictionary` will not change or that `vim.types` table will - only contain values for these three types. +< See also |vim.type_idx| and |lua-special-tbl|. + +vim.types *vim.types* + Table with possible values for |vim.type_idx|. Contains two sets of + key-value pairs: first maps possible values for |vim.type_idx| to + human-readable strings, second maps human-readable type names to + values for |vim.type_idx|. Currently contains pairs for `float`, + `array` and `dictionary` types. + + Note: one must expect that values corresponding to `vim.types.float`, + `vim.types.array` and `vim.types.dictionary` fall under only two + following assumptions: + 1. Value may serve both as a key and as a value in a table. Given the + properties of Lua tables this basically means “value is not `nil`”. + 2. For each value in `vim.types` table `vim.types[vim.types[value]]` + is the same as `value`. + No other restrictions are put on types, and it is not guaranteed that + values corresponding to `vim.types.float`, `vim.types.array` and + `vim.types.dictionary` will not change or that `vim.types` table will + only contain values for these three types. ------------------------------------------------------------------------------ LUA-VIMSCRIPT BRIDGE *lua-vimscript* @@ -966,8 +963,8 @@ vim.env *vim.env* *lua-vim-optlocal* *lua-vim-setlocal* -In vimL, there is a succint and simple way to set options. For more -information, see |set-option|. In Lua, the corresponding method is `vim.opt`. +In Vimscript, there is an way to set options |set-option|. In Lua, the +corresponding method is `vim.opt`. `vim.opt` provides several conveniences for setting and controlling options from within Lua. @@ -975,18 +972,18 @@ from within Lua. Examples: ~ To set a boolean toggle: - In vimL: + In Vimscript: `set number` In Lua: `vim.opt.number = true` To set an array of values: - In vimL: + In Vimscript: `set wildignore=*.o,*.a,__pycache__` In Lua, there are two ways you can do this now. One is very similar to - the vimL way: + the Vimscript form: `vim.opt.wildignore = '*.o,*.a,__pycache__'` However, vim.opt also supports a more elegent way of setting @@ -1019,7 +1016,7 @@ from within Lua. vim.opt.wildignore:remove { "node_modules" } < To set a map of values: - In vimL: + In Vimscript: `set listchars=space:_,tab:>~` In Lua: diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 6851cd1511..5fdd5fc3c0 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -172,15 +172,16 @@ Using Vim scripts *using-scripts* For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. *:so* *:source* *load-vim-script* -:so[urce] {file} Runs |Ex| commands or Lua code (".lua" files) read - from {file}. +:[range]so[urce] [file] Runs |Ex| commands or Lua code (".lua" files) from + [file], or from the current buffer if no [file] is + given. Triggers the |SourcePre| autocommand. *:source!* -:so[urce]! {file} Runs |Normal-mode| commands read from {file}. When - used after |:global|, |:argdo|, |:windo|, |:bufdo|, in +:[range]so[urce]! {file} + Runs |Normal-mode| commands from {file}. When used + after |:global|, |:argdo|, |:windo|, |:bufdo|, in a loop or when another command follows the display won't be updated while executing the commands. - Cannot be used in the |sandbox|. *:ru* *:runtime* :ru[ntime][!] [where] {file} .. diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 4dea053bc7..64824b2e3f 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -472,6 +472,7 @@ Compile-time features: X11 integration (see |x11-selection|) Eval: + Vim9script *js_encode()* *js_decode()* *v:none* (used by Vim to represent JavaScript "undefined"); use |v:null| instead. diff --git a/runtime/lua/vim/lsp/_snippet.lua b/runtime/lua/vim/lsp/_snippet.lua new file mode 100644 index 0000000000..0140b0aee3 --- /dev/null +++ b/runtime/lua/vim/lsp/_snippet.lua @@ -0,0 +1,399 @@ +local P = {} + +---Take characters until the target characters (The escape sequence is '\' + char) +---@param targets string[] The character list for stop consuming text. +---@param specials string[] If the character isn't contained in targets/specials, '\' will be left. +P.take_until = function(targets, specials) + targets = targets or {} + specials = specials or {} + + return function(input, pos) + local new_pos = pos + local raw = {} + local esc = {} + while new_pos <= #input do + local c = string.sub(input, new_pos, new_pos) + if c == '\\' then + table.insert(raw, '\\') + new_pos = new_pos + 1 + c = string.sub(input, new_pos, new_pos) + if not vim.tbl_contains(targets, c) and not vim.tbl_contains(specials, c) then + table.insert(esc, '\\') + end + table.insert(raw, c) + table.insert(esc, c) + new_pos = new_pos + 1 + else + if vim.tbl_contains(targets, c) then + break + end + table.insert(raw, c) + table.insert(esc, c) + new_pos = new_pos + 1 + end + end + + if new_pos == pos then + return P.unmatch(pos) + end + + return { + parsed = true, + value = { + raw = table.concat(raw, ''), + esc = table.concat(esc, '') + }, + pos = new_pos, + } + end +end + +P.unmatch = function(pos) + return { + parsed = false, + value = nil, + pos = pos, + } +end + +P.map = function(parser, map) + return function(input, pos) + local result = parser(input, pos) + if result.parsed then + return { + parsed = true, + value = map(result.value), + pos = result.pos, + } + end + return P.unmatch(pos) + end +end + +P.lazy = function(factory) + return function(input, pos) + return factory()(input, pos) + end +end + +P.token = function(token) + return function(input, pos) + local maybe_token = string.sub(input, pos, pos + #token - 1) + if token == maybe_token then + return { + parsed = true, + value = maybe_token, + pos = pos + #token, + } + end + return P.unmatch(pos) + end +end + +P.pattern = function(p) + return function(input, pos) + local maybe_match = string.match(string.sub(input, pos), '^' .. p) + if maybe_match then + return { + parsed = true, + value = maybe_match, + pos = pos + #maybe_match, + } + end + return P.unmatch(pos) + end +end + +P.many = function(parser) + return function(input, pos) + local values = {} + local new_pos = pos + while new_pos <= #input do + local result = parser(input, new_pos) + if not result.parsed then + break + end + table.insert(values, result.value) + new_pos = result.pos + end + if #values > 0 then + return { + parsed = true, + value = values, + pos = new_pos, + } + end + return P.unmatch(pos) + end +end + +P.any = function(...) + local parsers = { ... } + return function(input, pos) + for _, parser in ipairs(parsers) do + local result = parser(input, pos) + if result.parsed then + return result + end + end + return P.unmatch(pos) + end +end + +P.opt = function(parser) + return function(input, pos) + local result = parser(input, pos) + return { + parsed = true, + value = result.value, + pos = result.pos, + } + end +end + +P.seq = function(...) + local parsers = { ... } + return function(input, pos) + local values = {} + local new_pos = pos + for _, parser in ipairs(parsers) do + local result = parser(input, new_pos) + if result.parsed then + table.insert(values, result.value) + new_pos = result.pos + else + return P.unmatch(pos) + end + end + return { + parsed = true, + value = values, + pos = new_pos, + } + end +end + +local Node = {} + +Node.Type = { + SNIPPET = 0, + TABSTOP = 1, + PLACEHOLDER = 2, + VARIABLE = 3, + CHOICE = 4, + TRANSFORM = 5, + FORMAT = 6, + TEXT = 7, +} + +function Node:__tostring() + local insert_text = {} + if self.type == Node.Type.SNIPPET then + for _, c in ipairs(self.children) do + table.insert(insert_text, tostring(c)) + end + elseif self.type == Node.Type.CHOICE then + table.insert(insert_text, self.items[1]) + elseif self.type == Node.Type.PLACEHOLDER then + for _, c in ipairs(self.children or {}) do + table.insert(insert_text, tostring(c)) + end + elseif self.type == Node.Type.TEXT then + table.insert(insert_text, self.esc) + end + return table.concat(insert_text, '') +end + +--@see https://code.visualstudio.com/docs/editor/userdefinedsnippets#_grammar + +local S = {} +S.dollar = P.token('$') +S.open = P.token('{') +S.close = P.token('}') +S.colon = P.token(':') +S.slash = P.token('/') +S.comma = P.token(',') +S.pipe = P.token('|') +S.plus = P.token('+') +S.minus = P.token('-') +S.question = P.token('?') +S.int = P.map(P.pattern('[0-9]+'), function(value) + return tonumber(value, 10) +end) +S.var = P.pattern('[%a_][%w_]+') +S.text = function(targets, specials) + return P.map(P.take_until(targets, specials), function(value) + return setmetatable({ + type = Node.Type.TEXT, + raw = value.raw, + esc = value.esc, + }, Node) + end) +end + +S.toplevel = P.lazy(function() + return P.any(S.placeholder, S.tabstop, S.variable, S.choice) +end) + +S.format = P.any( + P.map(P.seq(S.dollar, S.int), function(values) + return setmetatable({ + type = Node.Type.FORMAT, + capture_index = values[2], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.int, S.close), function(values) + return setmetatable({ + type = Node.Type.FORMAT, + capture_index = values[3], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.int, S.colon, S.slash, P.any( + P.token('upcase'), + P.token('downcase'), + P.token('capitalize'), + P.token('camelcase'), + P.token('pascalcase') + ), S.close), function(values) + return setmetatable({ + type = Node.Type.FORMAT, + capture_index = values[3], + modifier = values[6], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.int, S.colon, P.any( + P.seq(S.question, P.take_until({ ':' }, { '\\' }), S.colon, P.take_until({ '}' }, { '\\' })), + P.seq(S.plus, P.take_until({ '}' }, { '\\' })), + P.seq(S.minus, P.take_until({ '}' }, { '\\' })) + ), S.close), function(values) + return setmetatable({ + type = Node.Type.FORMAT, + capture_index = values[3], + if_text = values[5][2].esc, + else_text = (values[5][4] or {}).esc, + }, Node) + end) +) + +S.transform = P.map(P.seq( + S.slash, + P.take_until({ '/' }, { '\\' }), + S.slash, + P.many(P.any(S.format, S.text({ '$', '/' }, { '\\' }))), + S.slash, + P.opt(P.pattern('[ig]+')) +), function(values) + return setmetatable({ + type = Node.Type.TRANSFORM, + pattern = values[2].raw, + format = values[4], + option = values[6], + }, Node) +end) + +S.tabstop = P.any( + P.map(P.seq(S.dollar, S.int), function(values) + return setmetatable({ + type = Node.Type.TABSTOP, + tabstop = values[2], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.int, S.close), function(values) + return setmetatable({ + type = Node.Type.TABSTOP, + tabstop = values[3], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.int, S.transform, S.close), function(values) + return setmetatable({ + type = Node.Type.TABSTOP, + tabstop = values[3], + transform = values[4], + }, Node) + end) +) + +S.placeholder = P.any( + P.map(P.seq(S.dollar, S.open, S.int, S.colon, P.many(P.any(S.toplevel, S.text({ '$', '}' }, { '\\' }))), S.close), function(values) + return setmetatable({ + type = Node.Type.PLACEHOLDER, + tabstop = values[3], + children = values[5], + }, Node) + end) +) + +S.choice = P.map(P.seq( + S.dollar, + S.open, + S.int, + S.pipe, + P.many( + P.map(P.seq(S.text({ ',', '|' }), P.opt(S.comma)), function(values) + return values[1].esc + end) + ), + S.pipe, + S.close +), function(values) + return setmetatable({ + type = Node.Type.CHOICE, + tabstop = values[3], + items = values[5], + }, Node) +end) + +S.variable = P.any( + P.map(P.seq(S.dollar, S.var), function(values) + return setmetatable({ + type = Node.Type.VARIABLE, + name = values[2], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.var, S.close), function(values) + return setmetatable({ + type = Node.Type.VARIABLE, + name = values[3], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.var, S.transform, S.close), function(values) + return setmetatable({ + type = Node.Type.VARIABLE, + name = values[3], + transform = values[4], + }, Node) + end), + P.map(P.seq(S.dollar, S.open, S.var, S.colon, P.many(P.any(S.toplevel, S.text({ '$', '}' }, { '\\' }))), S.close), function(values) + return setmetatable({ + type = Node.Type.VARIABLE, + name = values[3], + children = values[5], + }, Node) + end) +) + +S.snippet = P.map(P.many(P.any(S.toplevel, S.text({ '$' }, { '}', '\\' }))), function(values) + return setmetatable({ + type = Node.Type.SNIPPET, + children = values, + }, Node) +end) + +local M = {} + +---The snippet node type enum +---@types table<string, number> +M.NodeType = Node.Type + +---Parse snippet string and returns the AST +---@param input string +---@return table +function M.parse(input) + local result = S.snippet(input, 1) + if not result.parsed then + error('snippet parsing failed.') + end + return result.value +end + +return M diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index a4c8b69f6c..5a22a311e0 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1,4 +1,5 @@ local protocol = require 'vim.lsp.protocol' +local snippet = require 'vim.lsp._snippet' local vim = vim local validate = vim.validate local api = vim.api @@ -523,74 +524,18 @@ function M.apply_text_document_edit(text_document_edit, index) M.apply_text_edits(text_document_edit.edits, bufnr) end ----@private ---- Recursively parses snippets in a completion entry. ---- ----@param input (string) Snippet text to parse for snippets ----@param inner (bool) Whether this function is being called recursively ----@returns 2-tuple of strings: The first is the parsed result, the second is the ----unparsed rest of the input -local function parse_snippet_rec(input, inner) - local res = "" - - local close, closeend = nil, nil - if inner then - close, closeend = input:find("}", 1, true) - while close ~= nil and input:sub(close-1,close-1) == "\\" do - close, closeend = input:find("}", closeend+1, true) - end - end - - local didx = input:find('$', 1, true) - if didx == nil and close == nil then - return input, "" - elseif close ~=nil and (didx == nil or close < didx) then - -- No inner placeholders - return input:sub(0, close-1), input:sub(closeend+1) - end - - res = res .. input:sub(0, didx-1) - input = input:sub(didx+1) - - local tabstop, tabstopend = input:find('^%d+') - local placeholder, placeholderend = input:find('^{%d+:') - local choice, choiceend = input:find('^{%d+|') - - if tabstop then - input = input:sub(tabstopend+1) - elseif choice then - input = input:sub(choiceend+1) - close, closeend = input:find("|}", 1, true) - - res = res .. input:sub(0, close-1) - input = input:sub(closeend+1) - elseif placeholder then - -- TODO: add support for variables - input = input:sub(placeholderend+1) - - -- placeholders and variables are recursive - while input ~= "" do - local r, tail = parse_snippet_rec(input, true) - r = r:gsub("\\}", "}") - - res = res .. r - input = tail - end - else - res = res .. "$" - end - - return res, input -end - --- Parses snippets in a completion entry. --- ----@param input (string) unparsed snippet ----@returns (string) parsed snippet +---@param input string unparsed snippet +---@returns string parsed snippet function M.parse_snippet(input) - local res, _ = parse_snippet_rec(input, false) - - return res + local ok, parsed = pcall(function() + return tostring(snippet.parse(input)) + end) + if not ok then + return input + end + return parsed end ---@private diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 5410343365..a19adca942 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -4084,7 +4084,7 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir, bool fast) flags |= CP_EQUAL; } } else { - word = (const char *)tv_get_string_chk(tv); + word = tv_get_string_chk(tv); memset(cptext, 0, sizeof(cptext)); } if (word == NULL || (!empty && *word == NUL)) { @@ -8345,7 +8345,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); inc_cursor(); if (p_sta && in_indent) { - ts = (int)get_sw_value(curbuf); + ts = get_sw_value(curbuf); want_vcol = (want_vcol / ts) * ts; } else { want_vcol = tabstop_start(want_vcol, @@ -8538,7 +8538,7 @@ static void ins_mousescroll(int dir) if (dir == MSCR_DOWN || dir == MSCR_UP) { if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { scroll_redraw(dir, - (long)(curwin->w_botline - curwin->w_topline)); + (curwin->w_botline - curwin->w_topline)); } else { scroll_redraw(dir, 3L); } @@ -8852,7 +8852,7 @@ static bool ins_tab(void) AppendToRedobuff("\t"); if (p_sta && ind) { // insert tab in indent, use 'shiftwidth' - temp = (int)get_sw_value(curbuf); + temp = get_sw_value(curbuf); temp -= get_nolist_virtcol() % temp; } else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts != 0) { diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index c02f730431..0251ea9957 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -2,14 +2,13 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> - #include <uv.h> +#include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" +#include "nvim/event/process.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/event/process.h" -#include "nvim/event/libuv_process.h" #include "nvim/log.h" #include "nvim/macros.h" #include "nvim/os/os.h" @@ -68,7 +67,7 @@ int libuv_process_spawn(LibuvProcess *uvproc) #ifdef WIN32 // pipe must be readable for IOCP to work on Windows. uvproc->uvstdio[1].flags |= proc->overlapped ? - (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0; + (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0; #endif uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t, &proc->out.uv.pipe); diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index e341513ae1..892c46dd04 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -3,7 +3,6 @@ #include <stdarg.h> #include <stdint.h> - #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index f534fc483f..a90cbc4e80 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -49,8 +49,6 @@ #include <stdarg.h> #include <stdbool.h> #include <stdint.h> - - #include <uv.h> #include "nvim/event/multiqueue.h" @@ -89,7 +87,7 @@ typedef struct { # include "event/multiqueue.c.generated.h" #endif -static Event NILEVENT = { .handler = NULL, .argv = {NULL} }; +static Event NILEVENT = { .handler = NULL, .argv = { NULL } }; MultiQueue *multiqueue_new_parent(PutCallback put_cb, void *data) { @@ -104,8 +102,7 @@ MultiQueue *multiqueue_new_child(MultiQueue *parent) return multiqueue_new(parent, NULL, NULL); } -static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb, - void *data) +static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb, void *data) { MultiQueue *rv = xmalloc(sizeof(MultiQueue)); QUEUE_INIT(&rv->headtail); diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 8b366d0f3c..dae4dad16d 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -3,20 +3,19 @@ #include <assert.h> #include <stdlib.h> - #include <uv.h> -#include "nvim/os/shell.h" +#include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" +#include "nvim/event/process.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/event/process.h" -#include "nvim/event/libuv_process.h" -#include "nvim/os/process.h" -#include "nvim/os/pty_process.h" #include "nvim/globals.h" -#include "nvim/macros.h" #include "nvim/log.h" +#include "nvim/macros.h" +#include "nvim/os/process.h" +#include "nvim/os/pty_process.h" +#include "nvim/os/shell.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/process.c.generated.h" @@ -62,14 +61,14 @@ int process_spawn(Process *proc, bool in, bool out, bool err) int status; switch (proc->type) { - case kProcessTypeUv: - status = libuv_process_spawn((LibuvProcess *)proc); - break; - case kProcessTypePty: - status = pty_process_spawn((PtyProcess *)proc); - break; - default: - abort(); + case kProcessTypeUv: + status = libuv_process_spawn((LibuvProcess *)proc); + break; + case kProcessTypePty: + status = pty_process_spawn((PtyProcess *)proc); + break; + default: + abort(); } if (status) { @@ -139,9 +138,8 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL } // Wait until all children exit and all close events are processed. - LOOP_PROCESS_EVENTS_UNTIL( - loop, loop->events, -1, - kl_empty(loop->children) && multiqueue_empty(loop->events)); + LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, + kl_empty(loop->children) && multiqueue_empty(loop->events)); pty_process_teardown(loop); } @@ -189,7 +187,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events) // We can only return if all streams/handles are closed and the job // exited. LOOP_PROCESS_EVENTS_UNTIL(proc->loop, events, -1, - proc->refcount == 1); + proc->refcount == 1); } else { LOOP_PROCESS_EVENTS(proc->loop, events, 0); } @@ -222,16 +220,16 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL proc->exit_signal = SIGTERM; switch (proc->type) { - case kProcessTypeUv: - os_proc_tree_kill(proc->pid, SIGTERM); - break; - case kProcessTypePty: - // close all streams for pty processes to send SIGHUP to the process - process_close_streams(proc); - pty_process_close_master((PtyProcess *)proc); - break; - default: - abort(); + case kProcessTypeUv: + os_proc_tree_kill(proc->pid, SIGTERM); + break; + case kProcessTypePty: + // close all streams for pty processes to send SIGHUP to the process + process_close_streams(proc); + pty_process_close_master((PtyProcess *)proc); + break; + default: + abort(); } // (Re)start timer to verify that stopped process(es) died. @@ -325,14 +323,14 @@ static void process_close(Process *proc) } switch (proc->type) { - case kProcessTypeUv: - libuv_process_close((LibuvProcess *)proc); - break; - case kProcessTypePty: - pty_process_close((PtyProcess *)proc); - break; - default: - abort(); + case kProcessTypeUv: + libuv_process_close((LibuvProcess *)proc); + break; + case kProcessTypePty: + pty_process_close((PtyProcess *)proc); + break; + default: + abort(); } } @@ -369,7 +367,7 @@ static void flush_stream(Process *proc, Stream *stream) // Poll for data and process the generated events. loop_poll_events(proc->loop, 0); if (stream->events) { - multiqueue_process_events(stream->events); + multiqueue_process_events(stream->events); } // Stream can be closed if it is empty. diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index efa56932d2..f070c8179f 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -2,19 +2,18 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> - #include <uv.h> -#include "nvim/event/rstream.h" #include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/memory.h" +#include "nvim/event/loop.h" +#include "nvim/event/rstream.h" #include "nvim/log.h" +#include "nvim/memory.h" #include "nvim/misc1.h" -#include "nvim/event/loop.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/rstream.c.generated.h" @@ -160,14 +159,13 @@ static void fread_idle_cb(uv_idle_t *handle) } // Synchronous read - uv_fs_read( - handle->loop, - &req, - stream->fd, - &stream->uvbuf, - 1, - (int64_t) stream->fpos, - NULL); + uv_fs_read(handle->loop, + &req, + stream->fd, + &stream->uvbuf, + 1, + (int64_t)stream->fpos, + NULL); uv_fs_req_cleanup(&req); @@ -178,7 +176,7 @@ static void fread_idle_cb(uv_idle_t *handle) } // no errors (req.result (ssize_t) is positive), it's safe to cast. - size_t nread = (size_t) req.result; + size_t nread = (size_t)req.result; rbuffer_produced(stream->buffer, nread); stream->fpos += nread; invoke_read_cb(stream, nread, false); diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 23228aa63a..7948a7be83 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -3,30 +3,28 @@ #include <assert.h> #include <stdint.h> - #include <uv.h> +#include "nvim/ascii.h" +#include "nvim/charset.h" #include "nvim/event/loop.h" -#include "nvim/event/socket.h" #include "nvim/event/rstream.h" +#include "nvim/event/socket.h" #include "nvim/event/wstream.h" -#include "nvim/os/os.h" -#include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/strings.h" -#include "nvim/path.h" +#include "nvim/log.h" +#include "nvim/macros.h" #include "nvim/main.h" #include "nvim/memory.h" -#include "nvim/macros.h" -#include "nvim/charset.h" -#include "nvim/log.h" +#include "nvim/os/os.h" +#include "nvim/path.h" +#include "nvim/strings.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/socket.c.generated.h" #endif -int socket_watcher_init(Loop *loop, SocketWatcher *watcher, - const char *endpoint) +int socket_watcher_init(Loop *loop, SocketWatcher *watcher, const char *endpoint) FUNC_ATTR_NONNULL_ALL { xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr)); @@ -56,9 +54,9 @@ int socket_watcher_init(Loop *loop, SocketWatcher *watcher, int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, port, &(struct addrinfo){ - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - }); + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + }); if (retval != 0) { ELOG("Host lookup failed: %s", endpoint); return retval; @@ -106,7 +104,7 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb) uv_tcp_getsockname(&watcher->uv.tcp.handle, (struct sockaddr *)&sas, &(int){ sizeof(sas) }); uint16_t port = (uint16_t)( - (sas.ss_family == AF_INET) + (sas.ss_family == AF_INET) ? (STRUCT_CAST(struct sockaddr_in, &sas))->sin_port : (STRUCT_CAST(struct sockaddr_in6, &sas))->sin6_port); // v:servername uses the string from watcher->addr @@ -183,7 +181,7 @@ static void connection_cb(uv_stream_t *handle, int status) { SocketWatcher *watcher = handle->data; CREATE_EVENT(watcher->events, connection_event, 2, watcher, - (void *)(uintptr_t)status); + (void *)(uintptr_t)status); } static void close_cb(uv_handle_t *handle) @@ -203,9 +201,8 @@ static void connect_cb(uv_connect_t *req, int status) } } -bool socket_connect(Loop *loop, Stream *stream, - bool is_tcp, const char *address, - int timeout, const char **error) +bool socket_connect(Loop *loop, Stream *stream, bool is_tcp, const char *address, int timeout, + const char **error) { bool success = false; int status; @@ -243,7 +240,6 @@ tcp_retry: uv_tcp_nodelay(tcp, true); uv_tcp_connect(&req, tcp, addrinfo->ai_addr, connect_cb); uv_stream = (uv_stream_t *)tcp; - } else { uv_pipe_t *pipe = &stream->uv.pipe; uv_pipe_init(&loop->uv, pipe, 0); diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index a8ded66ea5..8569b92d56 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -2,15 +2,14 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdio.h> #include <stdbool.h> - +#include <stdio.h> #include <uv.h> +#include "nvim/event/stream.h" #include "nvim/log.h" -#include "nvim/rbuffer.h" #include "nvim/macros.h" -#include "nvim/event/stream.h" +#include "nvim/rbuffer.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif @@ -77,7 +76,7 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream) uv_pipe_open(&stream->uv.pipe, fd); stream->uvstream = STRUCT_CAST(uv_stream_t, &stream->uv.pipe); #ifdef WIN32 - } + } #endif } } diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index b7e30e392b..aa7b9cf2a1 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -2,7 +2,6 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <stdint.h> - #include <uv.h> #include "nvim/event/loop.h" @@ -23,8 +22,7 @@ void time_watcher_init(Loop *loop, TimeWatcher *watcher, void *data) watcher->blockable = false; } -void time_watcher_start(TimeWatcher *watcher, time_cb cb, uint64_t timeout, - uint64_t repeat) +void time_watcher_start(TimeWatcher *watcher, time_cb cb, uint64_t timeout, uint64_t repeat) FUNC_ATTR_NONNULL_ALL { watcher->cb = cb; diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index 2baa667e7d..d81ffa5c15 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -2,17 +2,16 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> - #include <uv.h> -#include "nvim/log.h" #include "nvim/event/loop.h" #include "nvim/event/wstream.h" -#include "nvim/vim.h" +#include "nvim/log.h" #include "nvim/memory.h" +#include "nvim/vim.h" #define DEFAULT_MAXMEM 1024 * 1024 * 2000 @@ -117,10 +116,7 @@ err: /// @param cb Pointer to function that will be responsible for freeing /// the buffer data(passing 'free' will work as expected). /// @return The allocated WBuffer instance -WBuffer *wstream_new_buffer(char *data, - size_t size, - size_t refcount, - wbuffer_data_finalizer cb) +WBuffer *wstream_new_buffer(char *data, size_t size, size_t refcount, wbuffer_data_finalizer cb) FUNC_ATTR_NONNULL_ARG(1) { WBuffer *rv = xmalloc(sizeof(WBuffer)); diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 8096b1bc0c..5485355885 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1353,7 +1353,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, ui_cursor_goto(Rows - 1, 0); if (do_out) { - if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL) { + if (u_save((line2), (linenr_T)(line2 + 1)) == FAIL) { xfree(cmd_buf); goto error; } @@ -3068,7 +3068,7 @@ void ex_change(exarg_T *eap) // make sure the cursor is not beyond the end of the file now check_cursor_lnum(); - deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum)); + deleted_lines_mark(eap->line1, (eap->line2 - lnum)); // ":append" on the line above the deleted lines. eap->line2 = eap->line1; @@ -4085,7 +4085,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle + copy_len + sublen + 1); // copy the text up to the part that matched - memmove(new_end, sub_firstline + copycol, (size_t)copy_len); + memmove(new_end, sub_firstline + copycol, copy_len); new_end += copy_len; // Finally, at this point we can know where the match actually will diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 08081f443c..2a0d365548 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2645,7 +2645,7 @@ static char_u *find_command(exarg_T *eap, int *full) const int c1 = eap->cmd[0]; const int c2 = len == 1 ? NUL : eap->cmd[1]; - if (command_count != (int)CMD_SIZE) { + if (command_count != CMD_SIZE) { iemsg((char *)_("E943: Command table needs to be updated, run 'make'")); getout(1); } @@ -2660,7 +2660,7 @@ static char_u *find_command(exarg_T *eap, int *full) eap->cmdidx = CMD_bang; } - for (; (int)eap->cmdidx < (int)CMD_SIZE; + for (; (int)eap->cmdidx < CMD_SIZE; eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1)) { if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, (char *)eap->cmd, (size_t)len) == 0) { @@ -2870,7 +2870,7 @@ int cmd_exists(const char *const name) for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) { int j; for (j = 0; name[j] != NUL; j++) { - if (name[j] != (char)cmdmods[i].name[j]) { + if (name[j] != cmdmods[i].name[j]) { break; } } @@ -2990,7 +2990,7 @@ const char * set_one_cmd_context(expand_T *xp, const char *buff) xp->xp_context = EXPAND_UNSUCCESSFUL; return NULL; } - for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < (int)CMD_SIZE; + for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < CMD_SIZE; ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1)) { if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd, len) == 0) { break; @@ -5144,7 +5144,7 @@ static int check_more(int message, bool forceit) */ char_u *get_command_name(expand_T *xp, int idx) { - if (idx >= (int)CMD_SIZE) { + if (idx >= CMD_SIZE) { return get_user_command_name(idx); } return cmdnames[idx].cmd_name; @@ -6240,7 +6240,7 @@ static void do_ucmd(exarg_T *eap) static char_u *get_user_command_name(int idx) { - return get_user_commands(NULL, idx - (int)CMD_SIZE); + return get_user_commands(NULL, idx - CMD_SIZE); } /* * Function given to ExpandGeneric() to obtain the list of user address type names. diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index a23ade4ec9..870c6ca2b1 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1221,7 +1221,7 @@ retry: // move the linerest to before the converted characters line_start = ptr - linerest; memmove(line_start, buffer, (size_t)linerest); - size = (long)((char_u *)top - ptr); + size = ((char_u *)top - ptr); } # endif @@ -1397,7 +1397,7 @@ retry: // move the linerest to before the converted characters line_start = dest - linerest; memmove(line_start, buffer, (size_t)linerest); - size = (long)((ptr + real_size) - dest); + size = ((ptr + real_size) - dest); ptr = dest; } else if (!curbuf->b_p_bin) { bool incomplete_tail = false; @@ -1652,7 +1652,7 @@ rewind_retry: } } } - linerest = (long)(ptr - line_start); + linerest = (ptr - line_start); os_breakcheck(); } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 567cf9c8c3..bfc72e6af8 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -309,7 +309,7 @@ foldinfo_T fold_info(win_T *win, linenr_T lnum) linenr_T last; if (hasFoldingWin(win, lnum, NULL, &last, false, &info)) { - info.fi_lines = (long)(last - lnum + 1); + info.fi_lines = (last - lnum + 1); } else { info.fi_lines = 0; } @@ -2374,14 +2374,14 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, // nested folds (with relative line numbers) down. foldMarkAdjustRecurse(flp->wp, &fp->fd_nested, (linenr_T)0, (linenr_T)MAXLNUM, - (long)(fp->fd_top - firstlnum), 0L); + (fp->fd_top - firstlnum), 0L); } else { // Will move fold down, move nested folds relatively up. foldMarkAdjustRecurse(flp->wp, &fp->fd_nested, (linenr_T)0, - (long)(firstlnum - fp->fd_top - 1), + (firstlnum - fp->fd_top - 1), (linenr_T)MAXLNUM, - (long)(fp->fd_top - firstlnum)); + (fp->fd_top - firstlnum)); } fp->fd_len += fp->fd_top - firstlnum; fp->fd_top = firstlnum; @@ -2444,7 +2444,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, * to stop just above startlnum. */ fp->fd_len = startlnum - fp->fd_top; foldMarkAdjustRecurse(flp->wp, &fp->fd_nested, - (linenr_T)fp->fd_len, (linenr_T)MAXLNUM, + fp->fd_len, (linenr_T)MAXLNUM, (linenr_T)MAXLNUM, 0L); fold_changed = true; } @@ -2622,8 +2622,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *const gap, const int level, if (fp2->fd_top < flp->lnum) { // Make fold that includes lnum start at lnum. foldMarkAdjustRecurse(flp->wp, &fp2->fd_nested, - (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1), - (linenr_T)MAXLNUM, (long)(fp2->fd_top-flp->lnum)); + (linenr_T)0, (flp->lnum - fp2->fd_top - 1), + (linenr_T)MAXLNUM, (fp2->fd_top-flp->lnum)); fp2->fd_len -= flp->lnum - fp2->fd_top; fp2->fd_top = flp->lnum; fold_changed = true; @@ -2767,8 +2767,8 @@ static void foldRemove(win_T *const wp, garray_T *gap, linenr_T top, linenr_T bo if (fp->fd_top + fp->fd_len - 1 > bot) { // 5: Make fold that includes bot start below bot. foldMarkAdjustRecurse(wp, &fp->fd_nested, - (linenr_T)0, (long)(bot - fp->fd_top), - (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1)); + (linenr_T)0, (bot - fp->fd_top), + (linenr_T)MAXLNUM, (fp->fd_top - bot - 1)); fp->fd_len -= bot - fp->fd_top + 1; fp->fd_top = bot + 1; break; diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index d071203db1..ce5bfabd9f 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -90,7 +90,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg) lua_pop(lstate, 1); } -/// Return version of current neovim build +/// Gets the version of the current Nvim build. /// /// @param lstate Lua interpreter state. static int nlua_nvim_version(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 56a03620e3..a0dee7ace8 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -387,7 +387,7 @@ static void shift_block(oparg_T *oap, int amount) } for (; ascii_iswhite(*bd.textstart); ) { // TODO: is passing bd.textstart for start of the line OK? - incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (colnr_T)(bd.start_vcol)); + incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (bd.start_vcol)); total += incr; bd.start_vcol += incr; } @@ -506,7 +506,7 @@ static void shift_block(oparg_T *oap, int amount) } // replace the line ml_replace(curwin->w_cursor.lnum, newp, false); - changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol); + changed_bytes(curwin->w_cursor.lnum, bd.textcol); extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum-1, startcol, oldlen, newlen, kExtmarkUndo); @@ -1253,7 +1253,7 @@ static void stuffescaped(const char *arg, int literally) arg++; } if (arg > start) { - stuffReadbuffLen(start, (long)(arg - start)); + stuffReadbuffLen(start, (arg - start)); } // stuff a single special character @@ -3227,7 +3227,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) oldlen = STRLEN(oldp); for (ptr = oldp; vcol < col && *ptr; ) { // Count a tab for what it's worth (if list mode not on) - incr = lbr_chartabsize_adv(oldp, &ptr, (colnr_T)vcol); + incr = lbr_chartabsize_adv(oldp, &ptr, vcol); vcol += incr; } bd.textcol = (colnr_T)(ptr - oldp); @@ -4026,8 +4026,8 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions const int spaces_removed = (int)((curr - curr_start) - spaces[t]); linenr_T lnum = curwin->w_cursor.lnum + t; colnr_T mincol = (colnr_T)0; - long lnum_amount = (linenr_T)-t; - long col_amount = (long)(cend - newp - spaces_removed); + long lnum_amount = -t; + long col_amount = (cend - newp - spaces_removed); mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed); @@ -4635,7 +4635,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool prev_pstart = line; while (bdp->start_vcol < oap->start_vcol && *pstart) { // Count a tab for what it's worth (if list mode not on) - incr = lbr_chartabsize(line, pstart, (colnr_T)bdp->start_vcol); + incr = lbr_chartabsize(line, pstart, bdp->start_vcol); bdp->start_vcol += incr; if (ascii_iswhite(*pstart)) { bdp->pre_whitesp += incr; @@ -4686,7 +4686,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) { // Count a tab for what it's worth (if list mode not on) prev_pend = pend; - incr = lbr_chartabsize_adv(line, &pend, (colnr_T)bdp->end_vcol); + incr = lbr_chartabsize_adv(line, &pend, bdp->end_vcol); bdp->end_vcol += incr; } if (bdp->end_vcol <= oap->end_vcol @@ -5908,18 +5908,18 @@ void cursor_pos_info(dict_T *dict) if (dict != NULL) { // Don't shorten this message, the user asked for it. - tv_dict_add_nr(dict, S_LEN("words"), (varnumber_T)word_count); - tv_dict_add_nr(dict, S_LEN("chars"), (varnumber_T)char_count); + tv_dict_add_nr(dict, S_LEN("words"), word_count); + tv_dict_add_nr(dict, S_LEN("chars"), char_count); tv_dict_add_nr(dict, S_LEN("bytes"), (varnumber_T)(byte_count + bom_count)); STATIC_ASSERT(sizeof("visual") == sizeof("cursor"), "key_len argument in tv_dict_add_nr is wrong"); tv_dict_add_nr(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes", - sizeof("visual_bytes") - 1, (varnumber_T)byte_count_cursor); + sizeof("visual_bytes") - 1, byte_count_cursor); tv_dict_add_nr(dict, l_VIsual_active ? "visual_chars" : "cursor_chars", - sizeof("visual_chars") - 1, (varnumber_T)char_count_cursor); + sizeof("visual_chars") - 1, char_count_cursor); tv_dict_add_nr(dict, l_VIsual_active ? "visual_words" : "cursor_words", - sizeof("visual_words") - 1, (varnumber_T)word_count_cursor); + sizeof("visual_words") - 1, word_count_cursor); } } diff --git a/src/nvim/os/dl.c b/src/nvim/os/dl.c index 8483d316f3..b2e3994d10 100644 --- a/src/nvim/os/dl.c +++ b/src/nvim/os/dl.c @@ -7,10 +7,10 @@ #include <stdint.h> #include <uv.h> -#include "nvim/os/dl.h" -#include "nvim/os/os.h" #include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/dl.h" +#include "nvim/os/os.h" /// possible function prototypes that can be called by os_libcall() /// int -> int @@ -38,12 +38,8 @@ typedef int (*int_int_fn)(int i); /// not NULL. NULL when using `int_out`. /// @param[out] int_out the output integer param /// @return true on success, false on failure -bool os_libcall(const char *libname, - const char *funcname, - const char *argv, - int argi, - char **str_out, - int *int_out) +bool os_libcall(const char *libname, const char *funcname, const char *argv, int argi, + char **str_out, int *int_out) { if (!libname || !funcname) { return false; @@ -53,17 +49,17 @@ bool os_libcall(const char *libname, // open the dynamic loadable library if (uv_dlopen(libname, &lib)) { - EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); - uv_dlclose(&lib); - return false; + EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); + uv_dlclose(&lib); + return false; } // find and load the requested function in the library gen_fn fn; - if (uv_dlsym(&lib, funcname, (void **) &fn)) { - EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); - uv_dlclose(&lib); - return false; + if (uv_dlsym(&lib, funcname, (void **)&fn)) { + EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); + uv_dlclose(&lib); + return false; } // call the library and save the result @@ -71,17 +67,17 @@ bool os_libcall(const char *libname, // exceptions. jmp's on Unix seem to interact trickily with signals as // well. So for now we only support those libraries that are well-behaved. if (str_out) { - str_str_fn sfn = (str_str_fn) fn; - int_str_fn ifn = (int_str_fn) fn; + str_str_fn sfn = (str_str_fn)fn; + int_str_fn ifn = (int_str_fn)fn; const char *res = argv ? sfn(argv) : ifn(argi); // assume that ptr values of NULL, 1 or -1 are illegal - *str_out = (res && (intptr_t) res != 1 && (intptr_t) res != -1) + *str_out = (res && (intptr_t)res != 1 && (intptr_t)res != -1) ? xstrdup(res) : NULL; } else { - str_int_fn sfn = (str_int_fn) fn; - int_int_fn ifn = (int_int_fn) fn; + str_int_fn sfn = (str_int_fn)fn; + int_int_fn ifn = (int_int_fn)fn; *int_out = argv ? sfn(argv) : ifn(argi); } diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 92b5e14824..0fc3f35ffc 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -6,20 +6,20 @@ #include <assert.h> #include <uv.h> -#include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/charset.h" +#include "nvim/eval.h" +#include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/os/os.h" +#include "nvim/macros.h" +#include "nvim/map.h" #include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/os.h" #include "nvim/path.h" -#include "nvim/macros.h" #include "nvim/strings.h" -#include "nvim/eval.h" -#include "nvim/ex_getln.h" #include "nvim/version.h" -#include "nvim/map.h" +#include "nvim/vim.h" #ifdef WIN32 #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 @@ -206,7 +206,7 @@ size_t os_get_fullenv_size(void) # if defined(HAVE__NSGETENVIRON) char **environ = *_NSGetEnviron(); # else - extern char **environ; + extern char **environ; # endif while (environ[len] != NULL) { @@ -219,7 +219,9 @@ size_t os_get_fullenv_size(void) void os_free_fullenv(char **env) { - if (!env) { return; } + if (!env) { + return; + } for (char **it = env; *it; it++) { XFREE_CLEAR(*it); } @@ -262,7 +264,7 @@ void os_copy_fullenv(char **env, size_t env_size) # if defined(HAVE__NSGETENVIRON) char **environ = *_NSGetEnviron(); # else - extern char **environ; + extern char **environ; # endif for (size_t i = 0; i < env_size && environ[i] != NULL; i++) { @@ -322,7 +324,7 @@ char *os_getenvname_at_index(size_t index) # if defined(HAVE__NSGETENVIRON) char **environ = *_NSGetEnviron(); # else - extern char **environ; + extern char **environ; # endif // check if index is inside the environ array @@ -566,16 +568,12 @@ void expand_env(char_u *src, char_u *dst, int dstlen) /// @param esc Escape spaces in expanded variables /// @param one `srcp` is a single filename /// @param prefix Start again after this (can be NULL) -void expand_env_esc(char_u *restrict srcp, - char_u *restrict dst, - int dstlen, - bool esc, - bool one, +void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, bool esc, bool one, char_u *prefix) FUNC_ATTR_NONNULL_ARG(1, 2) { - char_u *tail; - char_u *var; + char_u *tail; + char_u *var; bool copy_char; bool mustfree; // var was allocated, need to free it later bool at_start = true; // at start of a name @@ -621,7 +619,7 @@ void expand_env_esc(char_u *restrict srcp, while (c-- > 0 && *tail != NUL && *tail != '}') { *var++ = *tail++; } - } else // NOLINT + } else // NOLINT #endif { while (c-- > 0 && *tail != NUL && vim_isIDc(*tail)) { @@ -642,7 +640,7 @@ void expand_env_esc(char_u *restrict srcp, var = (char_u *)vim_getenv((char *)dst); mustfree = true; #if defined(UNIX) - } + } #endif } else if (src[1] == NUL // home directory || vim_ispathsep(src[1]) @@ -673,7 +671,7 @@ void expand_env_esc(char_u *restrict srcp, ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; var = ExpandOne(&xpc, dst, NULL, - WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE); + WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE); mustfree = true; } #else @@ -687,7 +685,7 @@ void expand_env_esc(char_u *restrict srcp, // If 'shellslash' is set change backslashes to forward slashes. // Can't use slash_adjust(), p_ssl may be set temporarily. if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL) { - char_u *p = vim_strsave(var); + char_u *p = vim_strsave(var); if (mustfree) { xfree(var); @@ -701,7 +699,7 @@ void expand_env_esc(char_u *restrict srcp, // If "var" contains white space, escape it with a backslash. // Required for ":e ~/tt" when $HOME includes a space. if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL) { - char_u *p = vim_strsave_escaped(var, (char_u *)" \t"); + char_u *p = vim_strsave_escaped(var, (char_u *)" \t"); if (mustfree) { xfree(var); @@ -721,8 +719,9 @@ void expand_env_esc(char_u *restrict srcp, #if defined(BACKSLASH_IN_FILENAME) && dst[-1] != ':' #endif - && vim_ispathsep(*tail)) + && vim_ispathsep(*tail)) { ++tail; + } dst += c; src = tail; copy_char = false; @@ -826,14 +825,11 @@ static char *remove_tail(char *path, char *pend, char *dirname) /// @param[out] len Location where current directory length should be saved. /// /// @return Next iter argument value or NULL when iteration should stop. -const void *vim_env_iter(const char delim, - const char *const val, - const void *const iter, - const char **const dir, - size_t *const len) +const void *vim_env_iter(const char delim, const char *const val, const void *const iter, + const char **const dir, size_t *const len) FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { - const char *varval = (const char *) iter; + const char *varval = (const char *)iter; if (varval == NULL) { varval = val; } @@ -843,7 +839,7 @@ const void *vim_env_iter(const char delim, *len = strlen(varval); return NULL; } else { - *len = (size_t) (dirend - varval); + *len = (size_t)(dirend - varval); return dirend + 1; } } @@ -861,14 +857,11 @@ const void *vim_env_iter(const char delim, /// @param[out] len Location where current directory length should be saved. /// /// @return Next iter argument value or NULL when iteration should stop. -const void *vim_env_iter_rev(const char delim, - const char *const val, - const void *const iter, - const char **const dir, - size_t *const len) +const void *vim_env_iter_rev(const char delim, const char *const val, const void *const iter, + const char **const dir, size_t *const len) FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { - const char *varend = (const char *) iter; + const char *varend = (const char *)iter; if (varend == NULL) { varend = val + strlen(val) - 1; } @@ -880,7 +873,7 @@ const void *vim_env_iter_rev(const char delim, return NULL; } else { *dir = colon + 1; - *len = (size_t) (varend - colon); + *len = (size_t)(varend - colon); return colon - 1; } } @@ -955,10 +948,9 @@ char *vim_getenv(const char *name) // Find runtime path relative to the nvim binary: ../share/nvim/runtime if (vim_path == NULL) { vim_get_prefix_from_exepath(exe_name); - if (append_path( - exe_name, - "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR, - MAXPATHL) == OK) { + if (append_path(exe_name, + "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR, + MAXPATHL) == OK) { vim_path = exe_name; // -V507 } } @@ -1043,8 +1035,8 @@ char *vim_getenv(const char *name) /// a list of them. /// /// @return length of the string put into dst, does not include NUL byte. -size_t home_replace(const buf_T *const buf, const char_u *src, - char_u *const dst, size_t dstlen, const bool one) +size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst, size_t dstlen, + const bool one) FUNC_ATTR_NONNULL_ARG(3) { size_t dirlen = 0; diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index fa359fa32e..1ae6ca4244 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -8,9 +8,9 @@ /// replacement. #include <assert.h> -#include <stddef.h> -#include <stdbool.h> #include <fcntl.h> +#include <stdbool.h> +#include <stddef.h> #include "auto/config.h" @@ -20,13 +20,13 @@ #include <uv.h> -#include "nvim/os/fileio.h" -#include "nvim/memory.h" -#include "nvim/os/os.h" #include "nvim/globals.h" -#include "nvim/rbuffer.h" #include "nvim/macros.h" +#include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/fileio.h" +#include "nvim/os/os.h" +#include "nvim/rbuffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/fileio.c.generated.h" @@ -44,8 +44,8 @@ /// does not have kFileCreate\*). /// /// @return Error code, or 0 on success. @see os_strerror() -int file_open(FileDescriptor *const ret_fp, const char *const fname, - const int flags, const int mode) +int file_open(FileDescriptor *const ret_fp, const char *const fname, const int flags, + const int mode) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { int os_open_flags = 0; @@ -99,8 +99,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname, /// FILE_WRITE_ONLY or FILE_READ_ONLY is required. /// /// @return Error code (@see os_strerror()) or 0. Currently always returns 0. -int file_open_fd(FileDescriptor *const ret_fp, const int fd, - const int flags) +int file_open_fd(FileDescriptor *const ret_fp, const int fd, const int flags) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { ret_fp->wr = !!(flags & (kFileCreate @@ -131,8 +130,8 @@ int file_open_fd(FileDescriptor *const ret_fp, const int fd, /// does not have kFileCreate\*). /// /// @return [allocated] Opened file or NULL in case of error. -FileDescriptor *file_open_new(int *const error, const char *const fname, - const int flags, const int mode) +FileDescriptor *file_open_new(int *const error, const char *const fname, const int flags, + const int mode) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { FileDescriptor *const fp = xmalloc(sizeof(*fp)); @@ -152,8 +151,7 @@ FileDescriptor *file_open_new(int *const error, const char *const fname, /// does not have FILE_CREATE\*). /// /// @return [allocated] Opened file or NULL in case of error. -FileDescriptor *file_open_fd_new(int *const error, const int fd, - const int flags) +FileDescriptor *file_open_fd_new(int *const error, const int fd, const int flags) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { FileDescriptor *const fp = xmalloc(sizeof(*fp)); @@ -277,8 +275,7 @@ static void file_rb_write_full_cb(RBuffer *const rv, FileDescriptor *const fp) /// bytes. /// /// @return error_code (< 0) or number of bytes read. -ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, - const size_t size) +ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, const size_t size) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { assert(!fp->wr); @@ -362,8 +359,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, /// @param[in] size Amount of bytes to write. /// /// @return Number of bytes written or libuv error code (< 0). -ptrdiff_t file_write(FileDescriptor *const fp, const char *const buf, - const size_t size) +ptrdiff_t file_write(FileDescriptor *const fp, const char *const buf, const size_t size) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { assert(fp->wr); @@ -392,8 +388,8 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size) assert(!fp->wr); size_t read_bytes = 0; do { - const ptrdiff_t new_read_bytes = file_read( - fp, skipbuf, MIN(size - read_bytes, sizeof(skipbuf))); + const ptrdiff_t new_read_bytes = + file_read(fp, skipbuf, MIN(size - read_bytes, sizeof(skipbuf))); if (new_read_bytes < 0) { return new_read_bytes; } else if (new_read_bytes == 0) { diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index b8ba2487f3..d50d68c99e 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -2,12 +2,12 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com // fs.c -- filesystem access -#include <stdbool.h> -#include <stddef.h> #include <assert.h> -#include <limits.h> -#include <fcntl.h> #include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdbool.h> +#include <stddef.h> #include "auto/config.h" @@ -17,14 +17,14 @@ #include <uv.h> -#include "nvim/os/os.h" -#include "nvim/os/os_defs.h" #include "nvim/ascii.h" +#include "nvim/assert.h" #include "nvim/memory.h" #include "nvim/message.h" -#include "nvim/assert.h" #include "nvim/misc1.h" #include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/strings.h" @@ -37,18 +37,18 @@ #endif #define RUN_UV_FS_FUNC(ret, func, ...) \ - do { \ - bool did_try_to_free = false; \ + do { \ + bool did_try_to_free = false; \ uv_call_start: {} \ - uv_fs_t req; \ - ret = func(&fs_loop, &req, __VA_ARGS__); \ - uv_fs_req_cleanup(&req); \ - if (ret == UV_ENOMEM && !did_try_to_free) { \ - try_to_free_memory(); \ - did_try_to_free = true; \ - goto uv_call_start; \ - } \ - } while (0) + uv_fs_t req; \ + ret = func(&fs_loop, &req, __VA_ARGS__); \ + uv_fs_req_cleanup(&req); \ + if (ret == UV_ENOMEM && !did_try_to_free) { \ + try_to_free_memory(); \ + did_try_to_free = true; \ + goto uv_call_start; \ + } \ + } while (0) // Many fs functions from libuv return that value on success. static const int kLibuvSuccess = 0; @@ -199,16 +199,16 @@ int os_nodetype(const char *name) } switch (guess) { - case UV_TTY: // FILE_TYPE_CHAR - return NODE_WRITABLE; - case UV_FILE: // FILE_TYPE_DISK - return NODE_NORMAL; - case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c - case UV_UDP: // unix only - case UV_TCP: // unix only - case UV_UNKNOWN_HANDLE: - default: - return NODE_OTHER; // Vim os_win32.c default + case UV_TTY: // FILE_TYPE_CHAR + return NODE_WRITABLE; + case UV_FILE: // FILE_TYPE_DISK + return NODE_NORMAL; + case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c + case UV_UDP: // unix only + case UV_TCP: // unix only + case UV_UNKNOWN_HANDLE: + default: + return NODE_OTHER; // Vim os_win32.c default } #endif } @@ -326,7 +326,7 @@ static bool is_executable_ext(const char *name, char **abspath) sizeof(os_buf) - (size_t)(buf_end - os_buf), ENV_SEPSTR); if (ext_len != 0) { bool in_pathext = nameext_len == ext_len - && 0 == mb_strnicmp((char_u *)nameext, (char_u *)ext, ext_len); + && 0 == mb_strnicmp((char_u *)nameext, (char_u *)ext, ext_len); if (((in_pathext || is_unix_shell) && is_executable(name, abspath)) || is_executable(os_buf, abspath)) { @@ -436,17 +436,17 @@ FILE *os_fopen(const char *path, const char *flags) // Per table in fopen(3) manpage. if (flags[1] == '\0' || flags[1] == 'b') { switch (flags[0]) { - case 'r': - iflags = O_RDONLY; - break; - case 'w': - iflags = O_WRONLY | O_CREAT | O_TRUNC; - break; - case 'a': - iflags = O_WRONLY | O_CREAT | O_APPEND; - break; - default: - abort(); + case 'r': + iflags = O_RDONLY; + break; + case 'w': + iflags = O_WRONLY | O_CREAT | O_TRUNC; + break; + case 'a': + iflags = O_WRONLY | O_CREAT | O_APPEND; + break; + default: + abort(); } #ifdef WIN32 if (flags[1] == 'b') { @@ -458,17 +458,17 @@ FILE *os_fopen(const char *path, const char *flags) // char 1 is always '+' ('b' is handled above). assert(flags[1] == '+'); switch (flags[0]) { - case 'r': - iflags = O_RDWR; - break; - case 'w': - iflags = O_RDWR | O_CREAT | O_TRUNC; - break; - case 'a': - iflags = O_RDWR | O_CREAT | O_APPEND; - break; - default: - abort(); + case 'r': + iflags = O_RDWR; + break; + case 'w': + iflags = O_RDWR | O_CREAT | O_TRUNC; + break; + case 'a': + iflags = O_RDWR | O_CREAT | O_APPEND; + break; + default: + abort(); } } // Per fopen(3) manpage: default to 0666, it will be umask-adjusted. @@ -553,8 +553,8 @@ os_dup_dup: /// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes read or libuv error code (< 0). -ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, - const size_t size, const bool non_blocking) +ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, const size_t size, + const bool non_blocking) FUNC_ATTR_WARN_UNUSED_RESULT { *ret_eof = false; @@ -609,8 +609,8 @@ ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, /// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes read or libuv error code (< 0). -ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, - size_t iov_size, const bool non_blocking) +ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, size_t iov_size, + const bool non_blocking) FUNC_ATTR_NONNULL_ALL { *ret_eof = false; @@ -668,8 +668,7 @@ ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, /// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes written or libuv error code (< 0). -ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, - const bool non_blocking) +ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, const bool non_blocking) FUNC_ATTR_WARN_UNUSED_RESULT { if (buf == NULL) { @@ -884,8 +883,7 @@ int os_mkdir(const char *path, int32_t mode) /// of the higher level directories. /// /// @return `0` for success, libuv error code for failure. -int os_mkdir_recurse(const char *const dir, int32_t mode, - char **const failed_dir) +int os_mkdir_recurse(const char *const dir, int32_t mode, char **const failed_dir) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { // Get end of directory name in "dir". @@ -1058,8 +1056,7 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info) /// Compare the inodes of two FileInfos /// /// @return `true` if the two FileInfos represent the same file. -bool os_fileinfo_id_equal(const FileInfo *file_info_1, - const FileInfo *file_info_2) +bool os_fileinfo_id_equal(const FileInfo *file_info_1, const FileInfo *file_info_2) FUNC_ATTR_NONNULL_ALL { return file_info_1->stat.st_ino == file_info_2->stat.st_ino @@ -1149,8 +1146,7 @@ bool os_fileid_equal(const FileID *file_id_1, const FileID *file_id_2) /// @param file_id Pointer to a `FileID` /// @param file_info Pointer to a `FileInfo` /// @return `true` if the `FileID` and the `FileInfo` represent te same file. -bool os_fileid_equal_fileinfo(const FileID *file_id, - const FileInfo *file_info) +bool os_fileid_equal_fileinfo(const FileID *file_id, const FileInfo *file_info) FUNC_ATTR_NONNULL_ALL { return file_id->inode == file_info->stat.st_ino @@ -1219,8 +1215,7 @@ char *os_resolve_shortcut(const char *fname) EMSG2("utf8_to_utf16 failed: %d", r); } else if (p != NULL) { // Get a pointer to the IPersistFile interface. - hr = pslw->lpVtbl->QueryInterface( - pslw, &IID_IPersistFile, (void **)&ppf); + hr = pslw->lpVtbl->QueryInterface(pslw, &IID_IPersistFile, (void **)&ppf); if (hr != S_OK) { goto shortcut_errorw; } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index eca245650a..4c6e9ee4d3 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -2,28 +2,27 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <string.h> #include <stdbool.h> - +#include <string.h> #include <uv.h> #include "nvim/api/private/defs.h" -#include "nvim/os/input.h" +#include "nvim/ascii.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" -#include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/ui.h" -#include "nvim/memory.h" -#include "nvim/keymap.h" -#include "nvim/mbyte.h" -#include "nvim/fileio.h" #include "nvim/ex_cmds2.h" +#include "nvim/fileio.h" #include "nvim/getchar.h" +#include "nvim/keymap.h" #include "nvim/main.h" +#include "nvim/mbyte.h" +#include "nvim/memory.h" #include "nvim/misc1.h" -#include "nvim/state.h" #include "nvim/msgpack_rpc/channel.h" +#include "nvim/os/input.h" +#include "nvim/state.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #define READ_BUFFER_SIZE 0xfff #define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4) @@ -102,8 +101,7 @@ static void create_cursorhold_event(bool events_enabled) /// /// wait until either the input buffer is non-empty or , if `events` is not NULL /// until `events` is non-empty. -int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, - MultiQueue *events) +int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, MultiQueue *events) { if (maxlen && rbuffer_size(input_buffer)) { return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); @@ -192,7 +190,7 @@ void os_breakcheck(void) /// @return `true` if file descriptor refers to a terminal. bool os_isatty(int fd) { - return uv_guess_handle(fd) == UV_TTY; + return uv_guess_handle(fd) == UV_TTY; } size_t input_enqueue(String keys) @@ -208,8 +206,8 @@ size_t input_enqueue(String keys) // K_SPECIAL(0x80) or CSI(0x9B). uint8_t buf[19] = { 0 }; unsigned int new_size - = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true, - false); + = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true, + false); if (new_size) { new_size = handle_mouse_event(&ptr, buf, new_size); @@ -234,13 +232,13 @@ size_t input_enqueue(String keys) // copy the character, escaping CSI and K_SPECIAL if ((uint8_t)*ptr == CSI) { - rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ K_SPECIAL }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KS_EXTRA }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KE_CSI }, 1); } else if ((uint8_t)*ptr == K_SPECIAL) { - rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ K_SPECIAL }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KS_SPECIAL }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KE_FILLER }, 1); } else { rbuffer_write(input_buffer, ptr, 1); } @@ -301,8 +299,7 @@ static uint8_t check_multiclick(int code, int grid, int row, int col) // Mouse event handling code(Extract row/col if available and detect multiple // clicks) -static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, - unsigned int bufsize) +static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, unsigned int bufsize) { int mouse_code = 0; int type = 0; @@ -318,7 +315,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, if (type != KS_EXTRA || !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE) - || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { + || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { return bufsize; } @@ -364,8 +361,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, return bufsize; } -size_t input_enqueue_mouse(int code, uint8_t modifier, - int grid, int row, int col) +size_t input_enqueue_mouse(int code, uint8_t modifier, int grid, int row, int col) { modifier |= check_multiclick(code, grid, row, col); uint8_t buf[7], *p = buf; @@ -437,8 +433,7 @@ bool input_available(void) return rbuffer_size(input_buffer) != 0; } -static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data, - bool at_eof) +static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data, bool at_eof) { if (at_eof) { input_done(); diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 18dcfeafa0..2c9cb699fc 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -1,9 +1,9 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include "nvim/vim.h" #include "nvim/os/input.h" #include "nvim/os/os_win_console.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/os_win_console.c.generated.h" diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c index c7b473a012..e70bc71961 100644 --- a/src/nvim/os/process.c +++ b/src/nvim/os/process.c @@ -23,16 +23,16 @@ #endif #if defined(__APPLE__) || defined(BSD) -# include <sys/sysctl.h> # include <pwd.h> +# include <sys/sysctl.h> #endif +#include "nvim/api/private/helpers.h" #include "nvim/globals.h" #include "nvim/log.h" -#include "nvim/os/process.h" #include "nvim/os/os.h" #include "nvim/os/os_defs.h" -#include "nvim/api/private/helpers.h" +#include "nvim/os/process.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/process.c.generated.h" diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c index 775e303f84..0625d6994e 100644 --- a/src/nvim/os/pty_conpty_win.c +++ b/src/nvim/os/pty_conpty_win.c @@ -3,9 +3,9 @@ #include <uv.h> -#include "nvim/vim.h" #include "nvim/os/os.h" #include "nvim/os/pty_conpty_win.h" +#include "nvim/vim.h" #ifndef EXTENDED_STARTUPINFO_PRESENT # define EXTENDED_STARTUPINFO_PRESENT 0x00080000 @@ -54,8 +54,7 @@ TriState os_dyn_conpty_init(void) return kTrue; } -conpty_t *os_conpty_init(char **in_name, char **out_name, - uint16_t width, uint16_t height) +conpty_t *os_conpty_init(char **in_name, char **out_name, uint16_t width, uint16_t height) { static int count = 0; conpty_t *conpty_object = xcalloc(1, sizeof(*conpty_object)); @@ -65,36 +64,34 @@ conpty_t *os_conpty_init(char **in_name, char **out_name, char buf[MAXPATHL]; SECURITY_ATTRIBUTES sa = { 0 }; const DWORD mode = PIPE_ACCESS_INBOUND - | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; + | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; sa.nLength = sizeof(sa); snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-in-%d-%d", os_get_pid(), count); *in_name = xstrdup(buf); - if ((in_read = CreateNamedPipeA( - *in_name, - mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 1, - 0, - 0, - 30000, - &sa)) == INVALID_HANDLE_VALUE) { + if ((in_read = CreateNamedPipeA(*in_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { emsg = "create input pipe failed"; goto failed; } snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-out-%d-%d", os_get_pid(), count); *out_name = xstrdup(buf); - if ((out_write = CreateNamedPipeA( - *out_name, - mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 1, - 0, - 0, - 30000, - &sa)) == INVALID_HANDLE_VALUE) { + if ((out_write = CreateNamedPipeA(*out_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { emsg = "create output pipe failed"; goto failed; } @@ -113,22 +110,20 @@ conpty_t *os_conpty_init(char **in_name, char **out_name, InitializeProcThreadAttributeList(NULL, 1, 0, & bytes_required); conpty_object->si_ex.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)xmalloc(bytes_required); - if (!InitializeProcThreadAttributeList( - conpty_object->si_ex.lpAttributeList, - 1, - 0, - &bytes_required)) { + if (!InitializeProcThreadAttributeList(conpty_object->si_ex.lpAttributeList, + 1, + 0, + &bytes_required)) { emsg = "InitializeProcThreadAttributeList failed"; goto failed; } - if (!UpdateProcThreadAttribute( - conpty_object->si_ex.lpAttributeList, - 0, - PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, - conpty_object->pty, - sizeof(conpty_object->pty), - NULL, - NULL)) { + if (!UpdateProcThreadAttribute(conpty_object->si_ex.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + conpty_object->pty, + sizeof(conpty_object->pty), + NULL, + NULL)) { emsg = "UpdateProcThreadAttribute failed"; goto failed; } @@ -150,38 +145,35 @@ finished: return conpty_object; } -bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, - wchar_t *name, wchar_t *cmd_line, wchar_t *cwd, - wchar_t *env) +bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *name, + wchar_t *cmd_line, wchar_t *cwd, wchar_t *env) { PROCESS_INFORMATION pi = { 0 }; - if (!CreateProcessW( - name, - cmd_line, - NULL, - NULL, - false, - EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, - env, - cwd, - &conpty_object->si_ex.StartupInfo, - &pi)) { + if (!CreateProcessW(name, + cmd_line, + NULL, + NULL, + false, + EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, + env, + cwd, + &conpty_object->si_ex.StartupInfo, + &pi)) { return false; } *process_handle = pi.hProcess; return true; } -void os_conpty_set_size(conpty_t *conpty_object, - uint16_t width, uint16_t height) +void os_conpty_set_size(conpty_t *conpty_object, uint16_t width, uint16_t height) { - assert(width <= SHRT_MAX); - assert(height <= SHRT_MAX); - COORD size = { (int16_t)width, (int16_t)height }; - if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { - ELOG("ResizePseudoConsoel failed: error code: %d", - os_translate_sys_error((int)GetLastError())); - } + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { + ELOG("ResizePseudoConsoel failed: error code: %d", + os_translate_sys_error((int)GetLastError())); + } } void os_conpty_free(conpty_t *conpty_object) diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 36d6dbe2db..d94de2e397 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -5,11 +5,10 @@ #include <stdbool.h> #include <stdlib.h> #include <string.h> - -#include <termios.h> +#include <sys/ioctl.h> #include <sys/types.h> #include <sys/wait.h> -#include <sys/ioctl.h> +#include <termios.h> // forkpty is not in POSIX, so headers are platform-specific #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -26,15 +25,14 @@ #include <uv.h> -#include "nvim/lib/klist.h" - #include "nvim/event/loop.h" +#include "nvim/event/process.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/event/process.h" -#include "nvim/os/pty_process_unix.h" +#include "nvim/lib/klist.h" #include "nvim/log.h" #include "nvim/os/os.h" +#include "nvim/os/pty_process_unix.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_unix.c.generated.h" diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 2bf73d08e6..f78f3e66f5 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,15 +4,14 @@ #include <assert.h> #include <stdbool.h> #include <stdlib.h> - #include <winpty_constants.h> -#include "nvim/os/os.h" #include "nvim/ascii.h" -#include "nvim/memory.h" #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 -#include "nvim/os/pty_process_win.h" +#include "nvim/memory.h" +#include "nvim/os/os.h" #include "nvim/os/pty_conpty_win.h" +#include "nvim/os/pty_process_win.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_win.c.generated.h" @@ -59,8 +58,8 @@ int pty_process_spawn(PtyProcess *ptyproc) if (os_has_conpty_working()) { if ((conpty_object = - os_conpty_init(&in_name, &out_name, - ptyproc->width, ptyproc->height)) != NULL) { + os_conpty_init(&in_name, &out_name, + ptyproc->width, ptyproc->height)) != NULL) { ptyproc->type = kConpty; } } @@ -94,20 +93,18 @@ int pty_process_spawn(PtyProcess *ptyproc) if (!proc->in.closed) { in_req = xmalloc(sizeof(uv_connect_t)); - uv_pipe_connect( - in_req, - &proc->in.uv.pipe, - in_name, - pty_process_connect_cb); + uv_pipe_connect(in_req, + &proc->in.uv.pipe, + in_name, + pty_process_connect_cb); } if (!proc->out.closed) { out_req = xmalloc(sizeof(uv_connect_t)); - uv_pipe_connect( - out_req, - &proc->out.uv.pipe, - out_name, - pty_process_connect_cb); + uv_pipe_connect(out_req, + &proc->out.uv.pipe, + out_name, + pty_process_connect_cb); } if (proc->cwd != NULL) { @@ -146,13 +143,12 @@ int pty_process_spawn(PtyProcess *ptyproc) goto cleanup; } } else { - spawncfg = winpty_spawn_config_new( - WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, - NULL, // Optional application name - cmd_line, - cwd, - env, - &err); + spawncfg = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, + NULL, // Optional application name + cmd_line, + cwd, + env, + &err); if (spawncfg == NULL) { emsg = "winpty_spawn_config_new failed"; goto cleanup; @@ -176,13 +172,12 @@ int pty_process_spawn(PtyProcess *ptyproc) } proc->pid = (int)GetProcessId(process_handle); - if (!RegisterWaitForSingleObject( - &ptyproc->finish_wait, - process_handle, - pty_process_finish1, - ptyproc, - INFINITE, - WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) { + if (!RegisterWaitForSingleObject(&ptyproc->finish_wait, + process_handle, + pty_process_finish1, + ptyproc, + INFINITE, + WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) { abort(); } @@ -193,8 +188,8 @@ int pty_process_spawn(PtyProcess *ptyproc) } (ptyproc->type == kConpty) ? - (void *)(ptyproc->object.conpty = conpty_object) : - (void *)(ptyproc->object.winpty = winpty_object); + (void *)(ptyproc->object.conpty = conpty_object) : + (void *)(ptyproc->object.winpty = winpty_object); ptyproc->process_handle = process_handle; winpty_object = NULL; conpty_object = NULL; @@ -235,8 +230,7 @@ const char *pty_process_tty_name(PtyProcess *ptyproc) return "?"; } -void pty_process_resize(PtyProcess *ptyproc, uint16_t width, - uint16_t height) +void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) FUNC_ATTR_NONNULL_ALL { if (ptyproc->type == kConpty @@ -454,15 +448,24 @@ int translate_winpty_error(int winpty_errno) } switch (winpty_errno) { - case WINPTY_ERROR_OUT_OF_MEMORY: return UV_ENOMEM; - case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: return UV_EAI_FAIL; - case WINPTY_ERROR_LOST_CONNECTION: return UV_ENOTCONN; - case WINPTY_ERROR_AGENT_EXE_MISSING: return UV_ENOENT; - case WINPTY_ERROR_UNSPECIFIED: return UV_UNKNOWN; - case WINPTY_ERROR_AGENT_DIED: return UV_ESRCH; - case WINPTY_ERROR_AGENT_TIMEOUT: return UV_ETIMEDOUT; - case WINPTY_ERROR_AGENT_CREATION_FAILED: return UV_EAI_FAIL; - default: return UV_UNKNOWN; + case WINPTY_ERROR_OUT_OF_MEMORY: + return UV_ENOMEM; + case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: + return UV_EAI_FAIL; + case WINPTY_ERROR_LOST_CONNECTION: + return UV_ENOTCONN; + case WINPTY_ERROR_AGENT_EXE_MISSING: + return UV_ENOENT; + case WINPTY_ERROR_UNSPECIFIED: + return UV_UNKNOWN; + case WINPTY_ERROR_AGENT_DIED: + return UV_ESRCH; + case WINPTY_ERROR_AGENT_TIMEOUT: + return UV_ETIMEDOUT; + case WINPTY_ERROR_AGENT_CREATION_FAILED: + return UV_EAI_FAIL; + default: + return UV_UNKNOWN; } } diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 2974245857..f0d446b4c5 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -1,36 +1,35 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include <string.h> #include <assert.h> #include <stdbool.h> #include <stdlib.h> - +#include <string.h> #include <uv.h> #include "nvim/ascii.h" -#include "nvim/fileio.h" -#include "nvim/lib/kvec.h" -#include "nvim/log.h" -#include "nvim/event/loop.h" +#include "nvim/charset.h" #include "nvim/event/libuv_process.h" +#include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/ex_cmds.h" +#include "nvim/fileio.h" +#include "nvim/lib/kvec.h" +#include "nvim/log.h" +#include "nvim/main.h" +#include "nvim/memline.h" +#include "nvim/memory.h" +#include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/option_defs.h" #include "nvim/os/shell.h" #include "nvim/os/signal.h" #include "nvim/path.h" -#include "nvim/types.h" -#include "nvim/main.h" -#include "nvim/vim.h" -#include "nvim/message.h" -#include "nvim/memory.h" -#include "nvim/ui.h" #include "nvim/screen.h" -#include "nvim/memline.h" -#include "nvim/option_defs.h" -#include "nvim/charset.h" #include "nvim/strings.h" +#include "nvim/types.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #define DYNAMIC_BUFFER_INIT { NULL, 0, 0 } #define NS_1_SECOND 1000000000U // 1 second, in nanoseconds @@ -47,8 +46,7 @@ typedef struct { # include "os/shell.c.generated.h" #endif -static void save_patterns(int num_pat, char_u **pat, int *num_file, - char_u ***file) +static void save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***file) { *file = xmalloc((size_t)num_pat * sizeof(char_u *)); for (int i = 0; i < num_pat; i++) { @@ -99,22 +97,21 @@ static bool have_dollars(int num, char_u **file) /// copied into *file. /// /// @returns OK for success or FAIL for error. -int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, - char_u ***file, int flags) +int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags) FUNC_ATTR_NONNULL_ARG(3) FUNC_ATTR_NONNULL_ARG(4) { int i; size_t len; - char_u *p; + char_u *p; bool dir; char_u *extra_shell_arg = NULL; ShellOpts shellopts = kShellOptExpand | kShellOptSilent; int j; - char_u *tempname; - char_u *command; - FILE *fd; - char_u *buffer; + char_u *tempname; + char_u *command; + FILE *fd; + char_u *buffer; #define STYLE_ECHO 0 // use "echo", the default #define STYLE_GLOB 1 // use "glob", for csh #define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh @@ -215,7 +212,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, } if (is_fish_shell) { - len += sizeof("egin;"" end") - 1; + len += sizeof("egin;" " end") - 1; } command = xmalloc(len); @@ -319,9 +316,9 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, if (shell_style == STYLE_PRINT) { extra_shell_arg = (char_u *)"-G"; // Use zsh NULL_GLOB option - // If we use -f then shell variables set in .cshrc won't get expanded. - // vi can do it, so we will too, but it is only necessary if there is a "$" - // in one of the patterns, otherwise we can still use the fast option. + // If we use -f then shell variables set in .cshrc won't get expanded. + // vi can do it, so we will too, but it is only necessary if there is a "$" + // in one of the patterns, otherwise we can still use the fast option. } else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat)) { extra_shell_arg = (char_u *)"-f"; // Use csh fast option } @@ -409,7 +406,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, } p = skipwhite(p); // skip to next entry } - // file names are separated with NL + // file names are separated with NL } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) { buffer[len] = NUL; // make sure the buffer ends in NUL p = buffer; @@ -422,7 +419,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, } p = skipwhite(p); // skip leading white space } - // file names are separated with NUL + // file names are separated with NUL } else { // Some versions of zsh use spaces instead of NULs to separate // results. Only do this when there is no NUL before the end of the @@ -705,22 +702,14 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args) /// returned buffer is not NULL) /// @return the return code of the process, -1 if the process couldn't be /// started properly -int os_system(char **argv, - const char *input, - size_t len, - char **output, +int os_system(char **argv, const char *input, size_t len, char **output, size_t *nread) FUNC_ATTR_NONNULL_ARG(1) { return do_os_system(argv, input, len, output, nread, true, false); } -static int do_os_system(char **argv, - const char *input, - size_t len, - char **output, - size_t *nread, - bool silent, - bool forward_output) +static int do_os_system(char **argv, const char *input, size_t len, char **output, size_t *nread, + bool silent, bool forward_output) { out_data_decide_throttle(0); // Initialize throttle decider. out_data_ring(NULL, 0); // Initialize output ring-buffer. @@ -851,8 +840,7 @@ static void dynamic_buffer_ensure(DynamicBuffer *buf, size_t desired) buf->data = xrealloc(buf->data, buf->cap); } -static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, - void *data, bool eof) +static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof) { DynamicBuffer *dbuf = data; @@ -1015,8 +1003,7 @@ end: ui_flush(); } -static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, - bool eof) +static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof) { size_t cnt; char *ptr = rbuffer_read_ptr(buf, &cnt); @@ -1049,10 +1036,10 @@ static size_t tokenize(const char_u *const str, char **const argv) FUNC_ATTR_NONNULL_ARG(1) { size_t argc = 0; - const char *p = (const char *) str; + const char *p = (const char *)str; while (*p != NUL) { - const size_t len = word_length((const char_u *) p); + const size_t len = word_length((const char_u *)p); if (argv != NULL) { // Fill the slot @@ -1060,7 +1047,7 @@ static size_t tokenize(const char_u *const str, char **const argv) } argc++; - p = (const char *) skipwhite((char_u *) (p + len)); + p = (const char *)skipwhite((char_u *)(p + len)); } return argc; @@ -1115,7 +1102,7 @@ static void read_input(DynamicBuffer *buf) dynamic_buffer_ensure(buf, buf->len + len); buf->data[buf->len++] = NUL; } else { - char_u *s = vim_strchr(lp + written, NL); + char_u *s = vim_strchr(lp + written, NL); len = s == NULL ? l : (size_t)(s - (lp + written)); dynamic_buffer_ensure(buf, buf->len + len); memcpy(buf->data + buf->len, lp + written, len); diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index bc774b8ebc..65b1845d01 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -3,25 +3,24 @@ #include <assert.h> #include <stdbool.h> - #include <uv.h> #ifndef WIN32 # include <signal.h> // for sigset_t #endif #include "nvim/ascii.h" -#include "nvim/log.h" -#include "nvim/vim.h" -#include "nvim/globals.h" -#include "nvim/memline.h" #include "nvim/eval.h" +#include "nvim/event/loop.h" +#include "nvim/event/signal.h" #include "nvim/fileio.h" +#include "nvim/globals.h" +#include "nvim/log.h" #include "nvim/main.h" +#include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/misc1.h" -#include "nvim/event/signal.h" #include "nvim/os/signal.h" -#include "nvim/event/loop.h" +#include "nvim/vim.h" static SignalWatcher spipe, shup, squit, sterm, susr1; #ifdef SIGPWR @@ -124,27 +123,27 @@ static char * signal_name(int signum) { switch (signum) { #ifdef SIGPWR - case SIGPWR: - return "SIGPWR"; + case SIGPWR: + return "SIGPWR"; #endif #ifdef SIGPIPE - case SIGPIPE: - return "SIGPIPE"; + case SIGPIPE: + return "SIGPIPE"; #endif - case SIGTERM: - return "SIGTERM"; + case SIGTERM: + return "SIGTERM"; #ifdef SIGQUIT - case SIGQUIT: - return "SIGQUIT"; + case SIGQUIT: + return "SIGQUIT"; #endif - case SIGHUP: - return "SIGHUP"; + case SIGHUP: + return "SIGHUP"; #ifdef SIGUSR1 - case SIGUSR1: - return "SIGUSR1"; + case SIGUSR1: + return "SIGUSR1"; #endif - default: - return "Unknown"; + default: + return "Unknown"; } } @@ -173,34 +172,34 @@ static void on_signal(SignalWatcher *handle, int signum, void *data) assert(signum >= 0); switch (signum) { #ifdef SIGPWR - case SIGPWR: - // Signal of a power failure(eg batteries low), flush the swap files to - // be safe - ml_sync_all(false, false, true); - break; + case SIGPWR: + // Signal of a power failure(eg batteries low), flush the swap files to + // be safe + ml_sync_all(false, false, true); + break; #endif #ifdef SIGPIPE - case SIGPIPE: - // Ignore - break; + case SIGPIPE: + // Ignore + break; #endif - case SIGTERM: + case SIGTERM: #ifdef SIGQUIT - case SIGQUIT: + case SIGQUIT: #endif - case SIGHUP: - if (!rejecting_deadly) { - deadly_signal(signum); - } - break; + case SIGHUP: + if (!rejecting_deadly) { + deadly_signal(signum); + } + break; #ifdef SIGUSR1 - case SIGUSR1: - apply_autocmds(EVENT_SIGNAL, (char_u *)"SIGUSR1", curbuf->b_fname, true, - curbuf); - break; -#endif - default: - ELOG("invalid signal: %d", signum); - break; + case SIGUSR1: + apply_autocmds(EVENT_SIGNAL, (char_u *)"SIGUSR1", curbuf->b_fname, true, + curbuf); + break; +#endif + default: + ELOG("invalid signal: %d", signum); + break; } } diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 93b8d5ca12..10b0d391bf 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -3,11 +3,11 @@ #include <stdbool.h> -#include "nvim/os/stdpaths_defs.h" +#include "nvim/ascii.h" +#include "nvim/memory.h" #include "nvim/os/os.h" +#include "nvim/os/stdpaths_defs.h" #include "nvim/path.h" -#include "nvim/memory.h" -#include "nvim/ascii.h" /// Names of the environment variables, mapped to XDGVarType values static const char *xdg_env_vars[] = { @@ -137,8 +137,7 @@ char *stdpaths_user_conf_subpath(const char *fname) /// @param[in] escape_commas If true, all commas will be escaped. /// /// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`. -char *stdpaths_user_data_subpath(const char *fname, - const size_t trailing_pathseps, +char *stdpaths_user_data_subpath(const char *fname, const size_t trailing_pathseps, const bool escape_commas) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 9ea74716aa..d9f4fe9e37 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -3,15 +3,14 @@ #include <assert.h> #include <limits.h> - #include <uv.h> #include "nvim/assert.h" -#include "nvim/os/time.h" -#include "nvim/os/input.h" #include "nvim/event/loop.h" -#include "nvim/os/os.h" #include "nvim/main.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" static uv_mutex_t delay_mutex; static uv_cond_t delay_cond; @@ -169,8 +168,7 @@ struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL /// @param result[out] Pointer to a 'char' where the result should be placed /// @param result_len length of result buffer /// @return human-readable string of current local time -char *os_ctime_r(const time_t *restrict clock, char *restrict result, - size_t result_len) +char *os_ctime_r(const time_t *restrict clock, char *restrict result, size_t result_len) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { struct tm clock_local; @@ -219,5 +217,5 @@ char *os_strptime(const char *str, const char *format, struct tm *tm) Timestamp os_time(void) FUNC_ATTR_WARN_UNUSED_RESULT { - return (Timestamp) time(NULL); + return (Timestamp)time(NULL); } diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index 16e17a9c60..2687c66f24 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -6,11 +6,10 @@ #include <uv.h> #include "auto/config.h" - #include "nvim/ascii.h" -#include "nvim/os/os.h" #include "nvim/garray.h" #include "nvim/memory.h" +#include "nvim/os/os.h" #include "nvim/strings.h" #ifdef HAVE_PWD_H # include <pwd.h> diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 7ec0a9585b..3257eac9a9 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -385,7 +385,7 @@ int update_screen(int type) // non-displayed part of msg_grid is considered invalid. for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) { grid_clear_line(&msg_grid, msg_grid.line_offset[i], - (int)msg_grid.Columns, false); + msg_grid.Columns, false); } } if (msg_use_msgsep()) { @@ -2627,7 +2627,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc shl->endcol = MAXCOL; shl->attr_cur = 0; shl->is_addpos = false; - v = (long)(ptr - line); + v = (ptr - line); if (cur != NULL) { cur->pos.cur = 0; } @@ -3061,7 +3061,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc * Do this for 'search_hl' and the match list (ordered by * priority). */ - v = (long)(ptr - line); + v = (ptr - line); cur = wp->w_match_head; shl_flag = false; while (cur != NULL || !shl_flag) { @@ -3405,7 +3405,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc /* Get syntax attribute, unless still at the start of the line * (double-wide char that doesn't fit). */ - v = (long)(ptr - line); + v = (ptr - line); if (has_syntax && v > 0) { /* Get the syntax attribute for the character. If there * is an error, disable syntax highlighting. */ @@ -3453,7 +3453,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc * Only do this when there is no syntax highlighting, the * @Spell cluster is not used or the current syntax item * contains the @Spell cluster. */ - v = (long)(ptr - line); + v = (ptr - line); if (has_spell && v >= word_end && v > cur_checked_col) { spell_attr = 0; if (!attr_pri) { @@ -3944,7 +3944,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // At end of the text line or just after the last character. if (c == NUL && eol_hl_off == 0) { - long prevcol = (long)(ptr - line) - 1; + long prevcol = (ptr - line) - 1; // we're not really at that column when skipping some text if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol) { @@ -6597,7 +6597,7 @@ void screenclear(void) // blank out the default grid for (i = 0; i < default_grid.Rows; i++) { grid_clear_line(&default_grid, default_grid.line_offset[i], - (int)default_grid.Columns, true); + default_grid.Columns, true); default_grid.line_wraps[i] = false; } @@ -6770,7 +6770,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } grid->line_offset[j + line_count] = temp; grid->line_wraps[j + line_count] = false; - grid_clear_line(grid, temp, (int)grid->Columns, false); + grid_clear_line(grid, temp, grid->Columns, false); } } @@ -6822,7 +6822,7 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } grid->line_offset[j - line_count] = temp; grid->line_wraps[j - line_count] = false; - grid_clear_line(grid, temp, (int)grid->Columns, false); + grid_clear_line(grid, temp, grid->Columns, false); } } @@ -6919,7 +6919,7 @@ int showmode(void) } if (edit_submode_extra != NULL) { MSG_PUTS_ATTR(" ", attr); // Add a space in between. - if ((int)edit_submode_highl < (int)HLF_COUNT) { + if ((int)edit_submode_highl < HLF_COUNT) { sub_attr = win_hl_attr(curwin, edit_submode_highl); } else { sub_attr = attr; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 49e451062c..64206b4269 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -7007,7 +7007,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } if (ascii_isdigit(*arg)) { - color = atoi((char *)arg); + color = atoi(arg); } else if (STRICMP(arg, "fg") == 0) { if (cterm_normal_fg_color) { color = cterm_normal_fg_color - 1; @@ -7867,20 +7867,20 @@ void highlight_changed(void) need_highlight_changed = false; /// Translate builtin highlight groups into attributes for quick lookup. - for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { + for (int hlf = 0; hlf < HLF_COUNT; hlf++) { id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf])); if (id == 0) { abort(); } int final_id = syn_get_final_id(id); - if (hlf == (int)HLF_SNC) { + if (hlf == HLF_SNC) { id_SNC = final_id; - } else if (hlf == (int)HLF_S) { + } else if (hlf == HLF_S) { id_S = final_id; } highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id, - hlf == (int)HLF_INACTIVE); + hlf == HLF_INACTIVE); if (highlight_attr[hlf] != highlight_attr_last[hlf]) { if (hlf == HLF_MSG) { diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 6705ab98c2..ec277f7a4e 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -2,19 +2,19 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include "nvim/tui/input.h" -#include "nvim/vim.h" -#include "nvim/api/vim.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/vim.h" #include "nvim/ascii.h" -#include "nvim/charset.h" -#include "nvim/main.h" -#include "nvim/macros.h" #include "nvim/aucmd.h" +#include "nvim/charset.h" #include "nvim/ex_docmd.h" +#include "nvim/macros.h" +#include "nvim/main.h" #include "nvim/option.h" -#include "nvim/os/os.h" #include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/tui/input.h" +#include "nvim/vim.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif @@ -53,7 +53,7 @@ void tinput_init(TermInput *input, Loop *loop) // ls *.md | xargs nvim #ifdef WIN32 if (!os_isatty(input->in_fd)) { - input->in_fd = os_get_conin_fd(); + input->in_fd = os_get_conin_fd(); } #else if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) { @@ -279,25 +279,25 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key) } switch (ev) { - case TERMKEY_MOUSE_PRESS: - if (button == 4) { - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp"); - } else if (button == 5) { - len += (size_t)snprintf(buf + len, sizeof(buf) - len, - "ScrollWheelDown"); - } else { - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse"); - last_pressed_button = button; - } - break; - case TERMKEY_MOUSE_DRAG: - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag"); - break; - case TERMKEY_MOUSE_RELEASE: - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release"); - break; - case TERMKEY_MOUSE_UNKNOWN: - abort(); + case TERMKEY_MOUSE_PRESS: + if (button == 4) { + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp"); + } else if (button == 5) { + len += (size_t)snprintf(buf + len, sizeof(buf) - len, + "ScrollWheelDown"); + } else { + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse"); + last_pressed_button = button; + } + break; + case TERMKEY_MOUSE_DRAG: + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag"); + break; + case TERMKEY_MOUSE_RELEASE: + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release"); + break; + case TERMKEY_MOUSE_UNKNOWN: + abort(); } len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row); @@ -428,7 +428,7 @@ static bool handle_forced_escape(TermInput *input) // skip the ESC and NUL and push one <esc> to the input buffer size_t rcnt; termkey_push_bytes(input->tk, rbuffer_read_ptr(input->read_stream.buffer, - &rcnt), 1); + &rcnt), 1); rbuffer_consumed(input->read_stream.buffer, 2); tk_getkeys(input, true); return true; @@ -618,8 +618,7 @@ static void handle_raw_buffer(TermInput *input, bool force) } while (rbuffer_size(input->read_stream.buffer)); } -static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, - void *data, bool eof) +static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof) { TermInput *input = data; @@ -637,7 +636,7 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, // If 'ttimeout' is not set, start the timer with a timeout of 0 to process // the next input. long ms = input->ttimeout ? - (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0; + (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0; // Stop the current timer if already running time_watcher_stop(&input->timer_handle); time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0); diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index ff2a357752..ce48059b94 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -5,11 +5,10 @@ #include <stdbool.h> #include <string.h> - #include <unibilium.h> -#include "nvim/log.h" #include "nvim/globals.h" +#include "nvim/log.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" @@ -29,12 +28,12 @@ bool terminfo_is_term_family(const char *term, const char *family) size_t tlen = strlen(term); size_t flen = strlen(family); return tlen >= flen - && 0 == memcmp(term, family, flen) - // Per commentary in terminfo, minus is the only valid suffix separator. - // The screen terminfo may have a terminal name like screen.xterm. By making - // the dot(.) a valid separator, such terminal names will also be the - // terminal family of the screen. - && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]); + && 0 == memcmp(term, family, flen) + // Per commentary in terminfo, minus is the only valid suffix separator. + // The screen terminfo may have a terminal name like screen.xterm. By making + // the dot(.) a valid separator, such terminal names will also be the + // terminal family of the screen. + && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]); } bool terminfo_is_bsd_console(const char *term) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index dcc086a0cf..fb5e12c20e 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -4,47 +4,45 @@ // Terminal UI functions. Invoked (by ui_bridge.c) on the TUI thread. #include <assert.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> -#include <limits.h> - -#include <uv.h> #include <unibilium.h> +#include <uv.h> #if defined(HAVE_TERMIOS_H) # include <termios.h> #endif -#include "nvim/lib/kvec.h" - +#include "nvim/api/private/helpers.h" +#include "nvim/api/vim.h" #include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/log.h" -#include "nvim/ui.h" +#include "nvim/event/loop.h" +#include "nvim/event/signal.h" #include "nvim/highlight.h" -#include "nvim/map.h" +#include "nvim/lib/kvec.h" +#include "nvim/log.h" #include "nvim/main.h" +#include "nvim/map.h" #include "nvim/memory.h" #include "nvim/option.h" -#include "nvim/api/vim.h" -#include "nvim/api/private/helpers.h" -#include "nvim/event/loop.h" -#include "nvim/event/signal.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/signal.h" #include "nvim/os/tty.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif +#include "nvim/cursor_shape.h" +#include "nvim/macros.h" #include "nvim/strings.h" #include "nvim/syntax.h" -#include "nvim/ui_bridge.h" -#include "nvim/ugrid.h" #include "nvim/tui/input.h" -#include "nvim/tui/tui.h" #include "nvim/tui/terminfo.h" -#include "nvim/cursor_shape.h" -#include "nvim/macros.h" +#include "nvim/tui/tui.h" +#include "nvim/ugrid.h" +#include "nvim/ui_bridge.h" // Space reserved in two output buffers to make the cursor normal or invisible // when flushing. No existing terminal will require 32 bytes to do that. @@ -53,17 +51,17 @@ #define TOO_MANY_EVENTS 1000000 #define STARTS_WITH(str, prefix) \ - (strlen(str) >= (sizeof(prefix) - 1) \ - && 0 == memcmp((str), (prefix), sizeof(prefix) - 1)) + (strlen(str) >= (sizeof(prefix) - 1) \ + && 0 == memcmp((str), (prefix), sizeof(prefix) - 1)) #define TMUX_WRAP(is_tmux, seq) \ - ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq) + ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq) #define LINUXSET0C "\x1b[?0c" #define LINUXSET1C "\x1b[?1c" #ifdef NVIM_UNIBI_HAS_VAR_FROM #define UNIBI_SET_NUM_VAR(var, num) \ do { \ - (var) = unibi_var_from_num((num)); \ + (var) = unibi_var_from_num((num)); \ } while (0) #else #define UNIBI_SET_NUM_VAR(var, num) (var).i = (num); @@ -180,8 +178,7 @@ UI *tui_start(void) return ui_bridge_attach(ui, tui_main, tui_scheduler); } -static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, - char * buf, size_t len) +static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char * buf, size_t len) { const char *str = unibi_get_str(data->ut, unibi_index); if (!str) { @@ -263,10 +260,10 @@ static void terminfo_start(UI *ui) long vtev = vte_version_env ? strtol(vte_version_env, NULL, 10) : 0; bool iterm_env = termprg && strstr(termprg, "iTerm.app"); bool nsterm = (termprg && strstr(termprg, "Apple_Terminal")) - || terminfo_is_term_family(term, "nsterm"); + || terminfo_is_term_family(term, "nsterm"); bool konsole = terminfo_is_term_family(term, "konsole") - || os_getenv("KONSOLE_PROFILE_NAME") - || os_getenv("KONSOLE_DBUS_SESSION"); + || os_getenv("KONSOLE_PROFILE_NAME") + || os_getenv("KONSOLE_DBUS_SESSION"); const char *konsolev_env = os_getenv("KONSOLE_VERSION"); long konsolev = konsolev_env ? strtol(konsolev_env, NULL, 10) : (konsole ? 1 : 0); @@ -508,15 +505,15 @@ static bool attrs_differ(UI *ui, int id1, int id2, bool rgb) if (rgb) { return a1.rgb_fg_color != a2.rgb_fg_color - || a1.rgb_bg_color != a2.rgb_bg_color - || a1.rgb_ae_attr != a2.rgb_ae_attr - || a1.rgb_sp_color != a2.rgb_sp_color; + || a1.rgb_bg_color != a2.rgb_bg_color + || a1.rgb_ae_attr != a2.rgb_ae_attr + || a1.rgb_sp_color != a2.rgb_sp_color; } else { return a1.cterm_fg_color != a2.cterm_fg_color - || a1.cterm_bg_color != a2.cterm_bg_color - || a1.cterm_ae_attr != a2.cterm_ae_attr - || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL) - && a1.rgb_sp_color != a2.rgb_sp_color); + || a1.cterm_bg_color != a2.cterm_bg_color + || a1.cterm_ae_attr != a2.cterm_ae_attr + || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL) + && a1.rgb_sp_color != a2.rgb_sp_color); } } @@ -593,10 +590,10 @@ static void update_attrs(UI *ui, int attr_id) if ((undercurl || underline) && data->unibi_ext.set_underline_color != -1) { int color = attrs.rgb_sp_color; if (color != -1) { - UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red - UNIBI_SET_NUM_VAR(data->params[1], (color >> 8) & 0xff); // green - UNIBI_SET_NUM_VAR(data->params[2], color & 0xff); // blue - unibi_out_ext(ui, data->unibi_ext.set_underline_color); + UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red + UNIBI_SET_NUM_VAR(data->params[1], (color >> 8) & 0xff); // green + UNIBI_SET_NUM_VAR(data->params[2], color & 0xff); // blue + unibi_out_ext(ui, data->unibi_ext.set_underline_color); } } @@ -639,14 +636,14 @@ static void update_attrs(UI *ui, int attr_id) data->default_attr = fg == -1 && bg == -1 - && !bold && !italic && !underline && !undercurl && !reverse && !standout - && !strikethrough; + && !bold && !italic && !underline && !undercurl && !reverse && !standout + && !strikethrough; // Non-BCE terminals can't clear with non-default background color. Some BCE // terminals don't support attributes either, so don't rely on it. But assume // italic and bold has no effect if there is no text. data->can_clear_attr = !reverse && !standout && !underline && !undercurl - && !strikethrough && (data->bce || bg == -1); + && !strikethrough && (data->bce || bg == -1); } static void final_column_wrap(UI *ui) @@ -802,8 +799,7 @@ safe_move: ugrid_goto(grid, row, col); } -static void clear_region(UI *ui, int top, int bot, int left, int right, - int attr_id) +static void clear_region(UI *ui, int top, int bot, int left, int right, int attr_id) { TUIData *data = ui->data; UGrid *grid = &data->grid; @@ -1006,7 +1002,7 @@ static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args) static void tui_update_menu(UI *ui) { - // Do nothing; menus are for GUI only + // Do nothing; menus are for GUI only } static void tui_busy_start(UI *ui) @@ -1096,10 +1092,14 @@ static void tui_set_mode(UI *ui, ModeShape mode) int shape; switch (c.shape) { - default: abort(); break; - case SHAPE_BLOCK: shape = 1; break; - case SHAPE_HOR: shape = 3; break; - case SHAPE_VER: shape = 5; break; + default: + abort(); break; + case SHAPE_BLOCK: + shape = 1; break; + case SHAPE_HOR: + shape = 3; break; + case SHAPE_VER: + shape = 5; break; } UNIBI_SET_NUM_VAR(data->params[0], shape + (int)(c.blinkon == 0)); unibi_out_ext(ui, data->unibi_ext.set_cursor_style); @@ -1124,8 +1124,8 @@ static void tui_mode_change(UI *ui, String mode, Integer mode_idx) } static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 - Integer endrow, Integer startcol, Integer endcol, - Integer rows, Integer cols FUNC_ATTR_UNUSED) + Integer endrow, Integer startcol, Integer endcol, Integer rows, + Integer cols FUNC_ATTR_UNUSED) { TUIData *data = ui->data; UGrid *grid = &data->grid; @@ -1134,16 +1134,16 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 bool fullwidth = left == 0 && right == ui->width-1; data->scroll_region_is_full_screen = fullwidth - && top == 0 && bot == ui->height-1; + && top == 0 && bot == ui->height-1; ugrid_scroll(grid, top, bot, left, right, (int)rows); bool can_scroll = data->can_scroll - && (data->scroll_region_is_full_screen - || (data->can_change_scroll_region - && ((left == 0 && right == ui->width - 1) - || data->can_set_lr_margin - || data->can_set_left_right_margin))); + && (data->scroll_region_is_full_screen + || (data->can_change_scroll_region + && ((left == 0 && right == ui->width - 1) + || data->can_set_lr_margin + || data->can_set_left_right_margin))); if (can_scroll) { // Change terminal scroll region and move cursor to the top @@ -1184,8 +1184,7 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 } } -static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, - HlAttrs cterm_attrs, Array info) +static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, HlAttrs cterm_attrs, Array info) { TUIData *data = ui->data; kv_a(data->attrs, (size_t)id) = attrs; @@ -1201,8 +1200,7 @@ static void tui_visual_bell(UI *ui) unibi_out(ui, unibi_flash_screen); } -static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, - Integer rgb_sp, +static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp, Integer cterm_fg, Integer cterm_bg) { TUIData *data = ui->data; @@ -1379,9 +1377,8 @@ static void tui_option_set(UI *ui, String name, Object value) } } -static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, - Integer endcol, Integer clearcol, Integer clearattr, - LineFlags flags, const schar_T *chunk, +static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, Integer endcol, + Integer clearcol, Integer clearattr, LineFlags flags, const schar_T *chunk, const sattr_T *attrs) { TUIData *data = ui->data; @@ -1461,8 +1458,8 @@ static void tui_guess_size(UI *ui) did_user_set_dimensions = true; assert(Columns >= INT_MIN && Columns <= INT_MAX); assert(Rows >= INT_MIN && Rows <= INT_MAX); - width = (int)Columns; - height = (int)Rows; + width = Columns; + height = Rows; goto end; } @@ -1561,8 +1558,7 @@ static void out(void *ctx, const char *str, size_t len) data->bufpos += len; } -static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str, - const char *val) +static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str, const char *val) { if (!unibi_get_str(ut, str)) { unibi_set_str(ut, str, val); @@ -1596,9 +1592,8 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name) /// Patches the terminfo records after loading from system or built-in db. /// Several entries in terminfo are known to be deficient or outright wrong; /// and several terminal emulators falsely announce incorrect terminal types. -static void patch_terminfo_bugs(TUIData *data, const char *term, - const char *colorterm, long vte_version, - long konsolev, bool iterm_env, bool nsterm) +static void patch_terminfo_bugs(TUIData *data, const char *term, const char *colorterm, + long vte_version, long konsolev, bool iterm_env, bool nsterm) { unibi_term *ut = data->ut; const char *xterm_version = os_getenv("XTERM_VERSION"); @@ -1606,8 +1601,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool roxterm = !!os_getenv("ROXTERM_ID"); #endif bool xterm = terminfo_is_term_family(term, "xterm") - // Treat Terminal.app as generic xterm-like, for now. - || nsterm; + // Treat Terminal.app as generic xterm-like, for now. + || nsterm; bool kitty = terminfo_is_term_family(term, "xterm-kitty"); bool linuxvt = terminfo_is_term_family(term, "linux"); bool bsdvt = terminfo_is_bsd_console(term); @@ -1618,18 +1613,18 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); bool st = terminfo_is_term_family(term, "st"); bool gnome = terminfo_is_term_family(term, "gnome") - || terminfo_is_term_family(term, "vte"); + || terminfo_is_term_family(term, "vte"); bool iterm = terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iterm2") - || terminfo_is_term_family(term, "iTerm.app") - || terminfo_is_term_family(term, "iTerm2.app"); + || terminfo_is_term_family(term, "iterm2") + || terminfo_is_term_family(term, "iTerm.app") + || terminfo_is_term_family(term, "iTerm2.app"); bool alacritty = terminfo_is_term_family(term, "alacritty"); // None of the following work over SSH; see :help TERM . bool iterm_pretending_xterm = xterm && iterm_env; bool gnome_pretending_xterm = xterm && colorterm - && strstr(colorterm, "gnome-terminal"); + && strstr(colorterm, "gnome-terminal"); bool mate_pretending_xterm = xterm && colorterm - && strstr(colorterm, "mate-terminal"); + && strstr(colorterm, "mate-terminal"); bool true_xterm = xterm && !!xterm_version && !bsdvt; bool cygwin = terminfo_is_term_family(term, "cygwin"); @@ -1839,8 +1834,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q"); if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b[ q"); @@ -1849,25 +1844,25 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // does not support DECSCUSR. // See http://linuxgazette.net/137/anonymous.html for more info data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", - "\x1b[?" - "%?" - // The parameter passed to Ss is the DECSCUSR parameter, so the - // terminal capability has to translate into the Linux idiosyncratic - // parameter. - // - // linuxvt only supports block and underline. It is also only - // possible to have a steady block (no steady underline) - "%p1%{2}%<" "%t%{8}" // blink block - "%e%p1%{2}%=" "%t%{112}" // steady block - "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block) - "%e%p1%{4}%=" "%t%{4}" // steady underline - "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline) - "%e%p1%{6}%=" "%t%{2}" // steady bar - "%e%{0}" // anything else - "%;" "%dc"); + "\x1b[?" + "%?" + // The parameter passed to Ss is the DECSCUSR parameter, so the + // terminal capability has to translate into the Linux idiosyncratic + // parameter. + // + // linuxvt only supports block and underline. It is also only + // possible to have a steady block (no steady underline) + "%p1%{2}%<" "%t%{8}" // blink block + "%e%p1%{2}%=" "%t%{112}" // steady block + "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block) + "%e%p1%{4}%=" "%t%{4}" // steady underline + "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline) + "%e%p1%{6}%=" "%t%{2}" // steady bar + "%e%{0}" // anything else + "%;" "%dc"); if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b[?c"); @@ -1875,34 +1870,34 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // Konsole before version 18.07.70: set up a nonce profile. This has // side-effects on temporary font resizing. #6798 data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", - TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?" - "%p1%{3}%<" "%t%{0}" // block - "%e%p1%{5}%<" "%t%{2}" // underline - "%e%{1}" // everything else is bar - "%;%d;BlinkingCursorEnabled=%?" - "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special, - "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag. - "%;%d\x07")); + TMUX_WRAP(tmux, + "\x1b]50;CursorShape=%?" + "%p1%{3}%<" "%t%{0}" // block + "%e%p1%{5}%<" "%t%{2}" // underline + "%e%{1}" // everything else is bar + "%;%d;BlinkingCursorEnabled=%?" + "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special, + "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag. + "%;%d\x07")); if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, - "\x1b]50;\x07"); + "\x1b]50;\x07"); } } } /// This adds stuff that is not in standard terminfo as extended unibilium /// capabilities. -static void augment_terminfo(TUIData *data, const char *term, - long vte_version, - long konsolev, bool iterm_env, bool nsterm) +static void augment_terminfo(TUIData *data, const char *term, long vte_version, long konsolev, + bool iterm_env, bool nsterm) { unibi_term *ut = data->ut; bool xterm = terminfo_is_term_family(term, "xterm") - // Treat Terminal.app as generic xterm-like, for now. - || nsterm; + // Treat Terminal.app as generic xterm-like, for now. + || nsterm; bool bsdvt = terminfo_is_bsd_console(term); bool dtterm = terminfo_is_term_family(term, "dtterm"); bool rxvt = terminfo_is_term_family(term, "rxvt"); @@ -1911,9 +1906,9 @@ static void augment_terminfo(TUIData *data, const char *term, bool screen = terminfo_is_term_family(term, "screen"); bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); bool iterm = terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iterm2") - || terminfo_is_term_family(term, "iTerm.app") - || terminfo_is_term_family(term, "iTerm2.app"); + || terminfo_is_term_family(term, "iterm2") + || terminfo_is_term_family(term, "iTerm.app") + || terminfo_is_term_family(term, "iTerm2.app"); bool alacritty = terminfo_is_term_family(term, "alacritty"); // None of the following work over SSH; see :help TERM . bool iterm_pretending_xterm = xterm && iterm_env; @@ -1928,19 +1923,18 @@ static void augment_terminfo(TUIData *data, const char *term, || teraterm // per TeraTerm "Supported Control Functions" doco || rxvt) { // per command.C data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut, - "ext.resize_screen", - "\x1b[8;%p1%d;%p2%dt"); + "ext.resize_screen", + "\x1b[8;%p1%d;%p2%dt"); } if (putty || xterm || rxvt) { data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut, - "ext.reset_scroll_region", - "\x1b[r"); + "ext.reset_scroll_region", + "\x1b[r"); } // terminfo describes strikethrough modes as rmxx/smxx with respect // to the ECMA-48 strikeout/crossed-out attributes. - data->unibi_ext.enter_strikethrough_mode = (int)unibi_find_ext_str( - ut, "smxx"); + data->unibi_ext.enter_strikethrough_mode = unibi_find_ext_str(ut, "smxx"); // Dickey ncurses terminfo does not include the setrgbf and setrgbb // capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. Adding @@ -1955,29 +1949,29 @@ static void augment_terminfo(TUIData *data, const char *term, // can use colons like ISO 8613-6:1994/ITU T.416:1993 says. bool has_colon_rgb = !tmux && !screen - && !vte_version // VTE colon-support has a big memory leak. #7573 - && (iterm || iterm_pretending_xterm // per VT100Terminal.m - // per http://invisible-island.net/xterm/xterm.log.html#xterm_282 - || true_xterm); + && !vte_version // VTE colon-support has a big memory leak. #7573 + && (iterm || iterm_pretending_xterm // per VT100Terminal.m + // per http://invisible-island.net/xterm/xterm.log.html#xterm_282 + || true_xterm); data->unibi_ext.set_rgb_foreground = unibi_find_ext_str(ut, "setrgbf"); if (-1 == data->unibi_ext.set_rgb_foreground) { if (has_colon_rgb) { data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf", - "\x1b[38:2:%p1%d:%p2%d:%p3%dm"); + "\x1b[38:2:%p1%d:%p2%d:%p3%dm"); } else { data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf", - "\x1b[38;2;%p1%d;%p2%d;%p3%dm"); + "\x1b[38;2;%p1%d;%p2%d;%p3%dm"); } } data->unibi_ext.set_rgb_background = unibi_find_ext_str(ut, "setrgbb"); if (-1 == data->unibi_ext.set_rgb_background) { if (has_colon_rgb) { data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb", - "\x1b[48:2:%p1%d:%p2%d:%p3%dm"); + "\x1b[48:2:%p1%d:%p2%d:%p3%dm"); } else { data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb", - "\x1b[48;2;%p1%d;%p2%d;%p3%dm"); + "\x1b[48;2;%p1%d;%p2%d;%p3%dm"); } } @@ -1985,63 +1979,59 @@ static void augment_terminfo(TUIData *data, const char *term, // FIXME: Bypassing tmux like this affects the cursor colour globally, in // all panes, which is not particularly desirable. A better approach // would use a tmux control sequence and an extra if(screen) test. - data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( - ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\")); + data->unibi_ext.set_cursor_color = + (int)unibi_add_ext_str(ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\")); } else if ((xterm || rxvt || tmux || alacritty) && (vte_version == 0 || vte_version >= 3900)) { // Supported in urxvt, newer VTE. - data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( - ut, "ext.set_cursor_color", "\033]12;#%p1%06x\007"); + data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(ut, "ext.set_cursor_color", + "\033]12;#%p1%06x\007"); } if (-1 != data->unibi_ext.set_cursor_color) { - data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str( - ut, "ext.reset_cursor_color", "\x1b]112\x07"); + data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str(ut, "ext.reset_cursor_color", + "\x1b]112\x07"); } - data->unibi_ext.save_title = (int)unibi_add_ext_str( - ut, "ext.save_title", "\x1b[22;0t"); - data->unibi_ext.restore_title = (int)unibi_add_ext_str( - ut, "ext.restore_title", "\x1b[23;0t"); + data->unibi_ext.save_title = (int)unibi_add_ext_str(ut, "ext.save_title", "\x1b[22;0t"); + data->unibi_ext.restore_title = (int)unibi_add_ext_str(ut, "ext.restore_title", "\x1b[23;0t"); /// Terminals usually ignore unrecognized private modes, and there is no /// known ambiguity with these. So we just set them unconditionally. - data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str( - ut, "ext.enable_lr_margin", "\x1b[?69h"); - data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str( - ut, "ext.disable_lr_margin", "\x1b[?69l"); - data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str( - ut, "ext.enable_bpaste", "\x1b[?2004h"); - data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str( - ut, "ext.disable_bpaste", "\x1b[?2004l"); + data->unibi_ext.enable_lr_margin = + (int)unibi_add_ext_str(ut, "ext.enable_lr_margin", "\x1b[?69h"); + data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, "ext.disable_lr_margin", + "\x1b[?69l"); + data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, "ext.enable_bpaste", + "\x1b[?2004h"); + data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, "ext.disable_bpaste", + "\x1b[?2004l"); // For urxvt send BOTH xterm and old urxvt sequences. #8695 - data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str( - ut, "ext.enable_focus", - rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h"); - data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str( - ut, "ext.disable_focus", - rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l"); - data->unibi_ext.enable_mouse = (int)unibi_add_ext_str( - ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h"); - data->unibi_ext.disable_mouse = (int)unibi_add_ext_str( - ut, "ext.disable_mouse", "\x1b[?1002l\x1b[?1006l"); + data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, "ext.enable_focus", + rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h"); + data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, "ext.disable_focus", + rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l"); + data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, "ext.enable_mouse", + "\x1b[?1002h\x1b[?1006h"); + data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, "ext.disable_mouse", + "\x1b[?1002l\x1b[?1006l"); // Extended underline. // terminfo will have Smulx for this (but no support for colors yet). data->unibi_ext.set_underline_style = unibi_find_ext_str(ut, "Smulx"); if (data->unibi_ext.set_underline_style == -1) { - int ext_bool_Su = unibi_find_ext_bool(ut, "Su"); // used by kitty - if (vte_version >= 5102 - || (ext_bool_Su != -1 - && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))) { - data->unibi_ext.set_underline_style = (int)unibi_add_ext_str( - ut, "ext.set_underline_style", "\x1b[4:%p1%dm"); - } + int ext_bool_Su = unibi_find_ext_bool(ut, "Su"); // used by kitty + if (vte_version >= 5102 + || (ext_bool_Su != -1 + && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))) { + data->unibi_ext.set_underline_style = (int)unibi_add_ext_str(ut, "ext.set_underline_style", + "\x1b[4:%p1%dm"); + } } if (data->unibi_ext.set_underline_style != -1) { - // Only support colon syntax. #9270 - data->unibi_ext.set_underline_color = (int)unibi_add_ext_str( - ut, "ext.set_underline_color", "\x1b[58:2::%p1%d:%p2%d:%p3%dm"); + // Only support colon syntax. #9270 + data->unibi_ext.set_underline_color = (int)unibi_add_ext_str(ut, "ext.set_underline_color", + "\x1b[58:2::%p1%d:%p2%d:%p3%dm"); } } @@ -2134,8 +2124,7 @@ static const char *tui_get_stty_erase(void) /// libtermkey hook to override terminfo entries. /// @see TermInput.tk_ti_hook_fn -static const char *tui_tk_ti_getstr(const char *name, const char *value, - void *data) +static const char *tui_tk_ti_getstr(const char *name, const char *value, void *data) { static const char *stty_erase = NULL; if (stty_erase == NULL) { diff --git a/test/README.md b/test/README.md index 8669ab6f3e..7a93c45f1c 100644 --- a/test/README.md +++ b/test/README.md @@ -256,6 +256,8 @@ Number; !must be defined to function properly): - `VALGRIND_LOG` (F) (S): overrides valgrind log file name used for `VALGRIND`. +- `TEST_COLORS` (F) (U) (D): enable pretty colors in test runner. + - `TEST_SKIP_FRAGILE` (F) (D): makes test suite skip some fragile tests. - `TEST_TIMEOUT` (FU) (I): specifies maximum time, in seconds, before the test diff --git a/test/busted/outputHandlers/nvim.lua b/test/busted/outputHandlers/nvim.lua index 191387e1b9..31d3415e35 100644 --- a/test/busted/outputHandlers/nvim.lua +++ b/test/busted/outputHandlers/nvim.lua @@ -3,7 +3,7 @@ local global_helpers = require('test.helpers') -- Colors are disabled by default. #15610 local colors = setmetatable({}, {__index = function() return function(s) return s end end}) -if os.getenv "NVIM_COLORS" then +if os.getenv "TEST_COLORS" then colors = require 'term.colors' end diff --git a/test/functional/plugin/lsp/snippet_spec.lua b/test/functional/plugin/lsp/snippet_spec.lua new file mode 100644 index 0000000000..4e127743eb --- /dev/null +++ b/test/functional/plugin/lsp/snippet_spec.lua @@ -0,0 +1,152 @@ +local helpers = require('test.functional.helpers')(after_each) +local snippet = require('vim.lsp._snippet') + +local eq = helpers.eq +local exec_lua = helpers.exec_lua + +describe('vim.lsp._snippet', function() + before_each(helpers.clear) + after_each(helpers.clear) + + local parse = function(...) + return exec_lua('return require("vim.lsp._snippet").parse(...)', ...) + end + + it('should parse only text', function() + eq({ + type = snippet.NodeType.SNIPPET, + children = { + { + type = snippet.NodeType.TEXT, + raw = 'TE\\$\\}XT', + esc = 'TE$}XT' + } + } + }, parse('TE\\$\\}XT')) + end) + + it('should parse tabstop', function() + eq({ + type = snippet.NodeType.SNIPPET, + children = { + { + type = snippet.NodeType.TABSTOP, + tabstop = 1, + }, + { + type = snippet.NodeType.TABSTOP, + tabstop = 2, + } + } + }, parse('$1${2}')) + end) + + it('should parse placeholders', function() + eq({ + type = snippet.NodeType.SNIPPET, + children = { + { + type = snippet.NodeType.PLACEHOLDER, + tabstop = 1, + children = { + { + type = snippet.NodeType.PLACEHOLDER, + tabstop = 2, + children = { + { + type = snippet.NodeType.TEXT, + raw = 'TE\\$\\}XT', + esc = 'TE$}XT' + }, + { + type = snippet.NodeType.TABSTOP, + tabstop = 3, + }, + { + type = snippet.NodeType.TABSTOP, + tabstop = 1, + transform = { + type = snippet.NodeType.TRANSFORM, + pattern = 'regex', + option = 'i', + format = { + { + type = snippet.NodeType.FORMAT, + capture_index = 1, + modifier = 'upcase' + } + } + }, + }, + { + type = snippet.NodeType.TEXT, + raw = 'TE\\$\\}XT', + esc = 'TE$}XT' + }, + } + } + } + }, + } + }, parse('${1:${2:TE\\$\\}XT$3${1/regex/${1:/upcase}/i}TE\\$\\}XT}}')) + end) + + it('should parse variables', function() + eq({ + type = snippet.NodeType.SNIPPET, + children = { + { + type = snippet.NodeType.VARIABLE, + name = 'VAR', + }, + { + type = snippet.NodeType.VARIABLE, + name = 'VAR', + }, + { + type = snippet.NodeType.VARIABLE, + name = 'VAR', + children = { + { + type = snippet.NodeType.TABSTOP, + tabstop = 1, + } + } + }, + { + type = snippet.NodeType.VARIABLE, + name = 'VAR', + transform = { + type = snippet.NodeType.TRANSFORM, + pattern = 'regex', + format = { + { + type = snippet.NodeType.FORMAT, + capture_index = 1, + modifier = 'upcase', + } + } + } + }, + } + }, parse('$VAR${VAR}${VAR:$1}${VAR/regex/${1:/upcase}/}')) + end) + + it('should parse choice', function() + eq({ + type = snippet.NodeType.SNIPPET, + children = { + { + type = snippet.NodeType.CHOICE, + tabstop = 1, + items = { + ',', + '|' + } + } + } + }, parse('${1|\\,,\\||}')) + end) + +end) + diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index a9ea26343d..7df5eb049c 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -1444,8 +1444,10 @@ describe('LSP', function() { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', insertTextFormat=2, textEdit={} }, -- nested snippet tokens { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} }, + -- braced tabstop + { label='foocar', sortText="j", insertText='foodar()${0}', insertTextFormat=2, textEdit={} }, -- plain text - { label='foocar', sortText="j", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} }, + { label='foocar', sortText="k", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} }, } local completion_list_items = {items=completion_list} local expected = { @@ -1457,8 +1459,9 @@ describe('LSP', function() { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="f", textEdit={newText='foobar'} } } } } }, { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foobar(place holder, more ...holder{})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="g", insertText='foodar', insertTextFormat=2, textEdit={newText='foobar(${1:place holder}, ${2:more ...holder{\\}})'} } } } } }, { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ1, var2 *typ2) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="h", insertText='foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', insertTextFormat=2, textEdit={} } } } } }, - { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ2,typ3 tail) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} } } } } }, - { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(${1:var1})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="j", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} } } } } }, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(var1 typ2 tail) {}', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="i", insertText='foodar(${1:var1 ${2|typ2,typ3|} ${3:tail}}) {$0\\}', insertTextFormat=2, textEdit={} } } } } }, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar()', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="j", insertText='foodar()${0}', insertTextFormat=2, textEdit={} } } } } }, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = 'Unknown', menu = '', word = 'foodar(${1:var1})', user_data = { nvim = { lsp = { completion_item = { label='foocar', sortText="k", insertText='foodar(${1:var1})', insertTextFormat=1, textEdit={} } } } } }, } eq(expected, exec_lua([[return vim.lsp.util.text_document_completion_list_to_complete_items(...)]], completion_list, prefix)) |