diff options
186 files changed, 6291 insertions, 2497 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fa8d05f6b5..11f27dde21 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -36,7 +36,7 @@ body: - type: input attributes: label: "$TERM environment variable" - placeholder: "echo $TERM" + placeholder: "xterm-256color" validations: required: true @@ -52,11 +52,11 @@ body: attributes: label: "How to reproduce the issue" description: | - - Steps to reproduce using `nvim -u NORC` or `nvim -u NONE` (try both). + - Steps to reproduce using `nvim --clean` ("factory defaults"). - For build failures: list the exact steps including CMake flags (if any). - For shell-related problems: try `env -i TERM=ansi-256color "$(which nvim)"`. placeholder: | - nvim -u NONE + nvim --clean :edit foo yiwp validations: diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 4c9c526946..09df580b45 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -1,8 +1,11 @@ name: "Commit Linter" -on: pull_request +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] jobs: lint-commits: runs-on: ubuntu-latest + if: github.event.pull_request.draft == false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe3540f1f6..e9c1173007 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,6 +19,7 @@ Reporting problems - [Check the FAQ][wiki-faq]. - [Search existing issues][github-issues] (including closed!) - Update Neovim to the latest version to see if your problem persists. +- Try to reproduce with `nvim --clean` ("factory defaults"). - [Bisect](https://neovim.io/doc/user/starting.html#bisect) your config: disable plugins incrementally, to narrow down the cause of the issue. - [Bisect][git-bisect] Neovim's source code to find the cause of a regression, if you can. This is _extremely_ helpful. - When reporting a crash, [include a stacktrace](https://github.com/neovim/neovim/wiki/FAQ#backtrace-linux). diff --git a/ci/build.ps1 b/ci/build.ps1 index 53e4328e02..8876ac31ef 100644 --- a/ci/build.ps1 +++ b/ci/build.ps1 @@ -72,7 +72,7 @@ if ($compiler -eq 'MINGW') { & C:\msys64\usr\bin\mkdir -p /var/cache/pacman/pkg # Build third-party dependencies - C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Su" ; exitIfFailed + C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm -Syu" ; exitIfFailed C:\msys64\usr\bin\bash -lc "pacman --verbose --noconfirm --needed -S $mingwPackages" ; exitIfFailed } elseif ($compiler -eq 'MSVC') { diff --git a/runtime/autoload/health.vim b/runtime/autoload/health.vim index 0f7983f175..73c1459f86 100644 --- a/runtime/autoload/health.vim +++ b/runtime/autoload/health.vim @@ -26,8 +26,8 @@ endfunction " Runs all discovered healthchecks if a:plugin_names is empty. function! health#check(plugin_names) abort let healthchecks = empty(a:plugin_names) - \ ? s:discover_health_checks() - \ : s:to_fn_names(a:plugin_names) + \ ? s:discover_healthchecks() + \ : s:get_healthcheck(a:plugin_names) tabnew setlocal wrap breakindent linebreak @@ -41,25 +41,29 @@ function! health#check(plugin_names) abort call setline(1, 'ERROR: No healthchecks found.') else redraw|echo 'Running healthchecks...' - for c in healthchecks - let output = '' - call append('$', split(printf("\n%s\n%s", c, repeat('=',72)), "\n")) + for name in sort(keys(healthchecks)) + let [func, type] = healthchecks[name] + let s:output = [] try - let output = "\n\n".execute('call '.c.'()') + if func == '' + throw 'healthcheck_not_found' + endif + eval type == 'v' ? call(func, []) : luaeval(func) catch - if v:exception =~# '^Vim\%((\a\+)\)\=:E117.*\V'.c - let output = execute( - \ 'call health#report_error(''No healthcheck found for "' - \ .s:to_plugin_name(c) - \ .'" plugin.'')') + let s:output = [] " Clear the output + if v:exception =~# 'healthcheck_not_found' + call health#report_error('No healthcheck found for "'.name.'" plugin.') else - let output = execute( - \ 'call health#report_error(''Failed to run healthcheck for "' - \ .s:to_plugin_name(c) - \ .'" plugin. Exception:''."\n".v:throwpoint."\n".v:exception)') + call health#report_error(printf( + \ "Failed to run healthcheck for \"%s\" plugin. Exception:\n%s\n%s", + \ name, v:throwpoint, v:exception)) endif endtry - call append('$', split(output, "\n") + ['']) + let header = [name. ': ' . func, repeat('=', 72)] + " remove empty line after header from report_start + let s:output = s:output[0] == '' ? s:output[1:] : s:output + let s:output = header + s:output + [''] + call append('$', s:output) redraw endfor endif @@ -71,9 +75,13 @@ function! health#check(plugin_names) abort redraw|echo '' endfunction +function! s:collect_output(output) + let s:output += split(a:output, "\n", 1) +endfunction + " Starts a new report. function! health#report_start(name) abort - echo "\n## " . a:name + call s:collect_output("\n## " . a:name) endfunction " Indents lines *except* line 1 of a string if it contains newlines. @@ -119,21 +127,21 @@ endfunction " }}} " Use {msg} to report information in the current section function! health#report_info(msg) abort " {{{ - echo s:format_report_message('INFO', a:msg) + call s:collect_output(s:format_report_message('INFO', a:msg)) endfunction " }}} " Reports a successful healthcheck. function! health#report_ok(msg) abort " {{{ - echo s:format_report_message('OK', a:msg) + call s:collect_output(s:format_report_message('OK', a:msg)) endfunction " }}} " Reports a health warning. " a:1: Optional advice (string or list) function! health#report_warn(msg, ...) abort " {{{ if a:0 > 0 - echo s:format_report_message('WARNING', a:msg, a:1) + call s:collect_output(s:format_report_message('WARNING', a:msg, a:1)) else - echo s:format_report_message('WARNING', a:msg) + call s:collect_output(s:format_report_message('WARNING', a:msg)) endif endfunction " }}} @@ -141,37 +149,73 @@ endfunction " }}} " a:1: Optional advice (string or list) function! health#report_error(msg, ...) abort " {{{ if a:0 > 0 - echo s:format_report_message('ERROR', a:msg, a:1) + call s:collect_output(s:format_report_message('ERROR', a:msg, a:1)) else - echo s:format_report_message('ERROR', a:msg) + call s:collect_output(s:format_report_message('ERROR', a:msg)) endif endfunction " }}} -function! s:filepath_to_function(name) abort - return substitute(substitute(substitute(a:name, '.*autoload[\/]', '', ''), - \ '\.vim', '#check', ''), '[\/]', '#', 'g') +" From a path return a list [{name}, {func}, {type}] representing a healthcheck +function! s:filepath_to_healthcheck(path) abort + if a:path =~# 'vim$' + let name = matchstr(a:path, '\zs[^\/]*\ze\.vim$') + let func = 'health#'.name.'#check' + let type = 'v' + else + let base_path = substitute(a:path, + \ '.*lua[\/]\(.\{-}\)[\/]health\([\/]init\)\?\.lua$', + \ '\1', '') + let name = substitute(base_path, '[\/]', '.', 'g') + let func = 'require("'.name.'.health").check()' + let type = 'l' + endif + return [name, func, type] endfunction -function! s:discover_health_checks() abort - let healthchecks = globpath(&runtimepath, 'autoload/health/*.vim', 1, 1) - let healthchecks = map(healthchecks, '<SID>filepath_to_function(v:val)') - return healthchecks +function! s:discover_healthchecks() abort + return s:get_healthcheck('*') +endfunction + +" Returns Dictionary {name: [func, type], ..} representing healthchecks +function! s:get_healthcheck(plugin_names) abort + let health_list = s:get_healthcheck_list(a:plugin_names) + let healthchecks = {} + for c in health_list + let normalized_name = substitute(c[0], '-', '_', 'g') + let existent = get(healthchecks, normalized_name, []) + " Prefer Lua over vim entries + if existent != [] && existent[2] == 'l' + continue + else + let healthchecks[normalized_name] = c + endif + endfor + let output = {} + for v in values(healthchecks) + let output[v[0]] = v[1:] + endfor + return output endfunction -" Translates a list of plugin names to healthcheck function names. -function! s:to_fn_names(plugin_names) abort +" Returns list of lists [ [{name}, {func}, {type}] ] representing healthchecks +function! s:get_healthcheck_list(plugin_names) abort let healthchecks = [] - let plugin_names = type('') ==# type(a:plugin_names) - \ ? split(a:plugin_names, '', v:false) + let plugin_names = type('') == type(a:plugin_names) + \ ? split(a:plugin_names, ' ', v:false) \ : a:plugin_names for p in plugin_names - call add(healthchecks, 'health#'.p.'#check') + " support vim/lsp/health{/init/}.lua as :checkhealth vim.lsp + let p = substitute(p, '\.', '/', 'g') + let p = substitute(p, '*$', '**', 'g') " find all submodule e.g vim* + let paths = nvim_get_runtime_file('autoload/health/'.p.'.vim', v:true) + \ + nvim_get_runtime_file('lua/**/'.p.'/health/init.lua', v:true) + \ + nvim_get_runtime_file('lua/**/'.p.'/health.lua', v:true) + if len(paths) == 0 + let healthchecks += [[p, '', '']] " healthchek not found + else + let healthchecks += map(uniq(sort(paths)), + \'<SID>filepath_to_healthcheck(v:val)') + end endfor return healthchecks endfunction - -" Extracts 'foo' from 'health#foo#check'. -function! s:to_plugin_name(fn_name) abort - return substitute(a:fn_name, - \ '\v.*health\#(.+)\#check.*', '\1', '') -endfunction diff --git a/runtime/autoload/health/lsp.vim b/runtime/autoload/health/lsp.vim deleted file mode 100644 index 2d2ba91cdf..0000000000 --- a/runtime/autoload/health/lsp.vim +++ /dev/null @@ -1,5 +0,0 @@ -function! health#lsp#check() abort - call health#report_start('Checking language server client configuration') - lua require 'vim.lsp.health'.check_health() -endfunction - diff --git a/runtime/autoload/health/treesitter.vim b/runtime/autoload/health/treesitter.vim deleted file mode 100644 index 5f167310ce..0000000000 --- a/runtime/autoload/health/treesitter.vim +++ /dev/null @@ -1,5 +0,0 @@ -function! health#treesitter#check() abort - call health#report_start('Checking treesitter configuration') - lua require 'vim.treesitter.health'.check_health() -endfunction - diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index b6edc4c4d8..ef0282848f 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -1711,7 +1711,8 @@ fun! s:NetrwOptionsSafe(islocal) if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif setl fo=nroql2 - call s:NetrwSetSafeSetting("&go","begmr") + " call s:NetrwSetSafeSetting("&go","begmr") + if &go =~ '\ca' | call s:NetrwSetSafeSetting("&go",substitute(&go,'\ca','','g')) | endif call s:NetrwSetSafeSetting("&l:hid",0) call s:NetrwSetSafeSetting("&l:im",0) setl isk+=@ isk+=* isk+=/ diff --git a/runtime/autoload/provider/pythonx.vim b/runtime/autoload/provider/pythonx.vim index c292b374b6..0eeb35cba8 100644 --- a/runtime/autoload/provider/pythonx.vim +++ b/runtime/autoload/provider/pythonx.vim @@ -96,7 +96,7 @@ function! provider#pythonx#CheckForModule(prog, module, major_version) abort if prog_version !~ '^' . a:major_version return [0, prog_path . ' is Python ' . prog_version . ' and cannot provide Python ' \ . a:major_version . '.'] - elseif prog_version =~ '^' . a:major_version && prog_version < min_version + elseif prog_version =~ '^' . a:major_version && str2nr(prog_version[2:]) < str2nr(min_version[2:]) return [0, prog_path . ' is Python ' . prog_version . ' and cannot provide Python >= ' \ . min_version . '.'] endif diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index df345e4981..1ad0a6883e 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -130,7 +130,9 @@ end of a range, -1 denotes the last line/column. Exception: the following API functions use "mark-like" indexing (1-based lines, 0-based columns): + |nvim_get_mark()| |nvim_buf_get_mark()| + |nvim_buf_set_mark()| |nvim_win_get_cursor()| |nvim_win_set_cursor()| @@ -706,7 +708,7 @@ nvim_create_buf({listed}, {scratch}) *nvim_create_buf()* buf_open_scratch nvim_create_namespace({name}) *nvim_create_namespace()* - Creates a new namespace, or gets an existing one. + Creates a new *namespace* or gets an existing one. Namespaces are used for buffer highlights and virtual text, see |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. @@ -735,6 +737,23 @@ nvim_del_keymap({mode}, {lhs}) *nvim_del_keymap()* See also: ~ |nvim_set_keymap()| +nvim_del_mark({name}) *nvim_del_mark()* + Deletes a uppercase/file named mark. See |mark-motions|. + + Note: + fails with error if a lowercase or buffer local named mark + is used. + + Parameters: ~ + {name} Mark name + + Return: ~ + true if the mark was deleted, else false. + + See also: ~ + |nvim_buf_del_mark()| + |nvim_get_mark()| + nvim_del_var({name}) *nvim_del_var()* Removes a global (g:) variable. @@ -828,7 +847,7 @@ nvim_feedkeys({keys}, {mode}, {escape_csi}) *nvim_feedkeys()* On execution error: does not fail, but updates v:errmsg. To input sequences like <C-o> use |nvim_replace_termcodes()| - (typically with escape_csi=true) to replace the keycodes. Then + (typically with escape_csi=true) to replace |keycodes|, then pass the result to nvim_feedkeys(). Example: > @@ -866,32 +885,33 @@ nvim_get_api_info() *nvim_get_api_info()* {fast} nvim_get_chan_info({chan}) *nvim_get_chan_info()* - Get information about a channel. + Gets information about a channel. Return: ~ Dictionary describing a channel, with these keys: - • "stream" the stream underlying the channel + • "id" Channel id. + • "argv" (optional) Job arguments list. + • "stream" Stream underlying the channel. • "stdio" stdin and stdout of this Nvim instance • "stderr" stderr of this Nvim instance • "socket" TCP/IP socket or named pipe - • "job" job with communication over its stdio - - • "mode" how data received on the channel is interpreted - • "bytes" send and receive raw bytes - • "terminal" a |terminal| instance interprets ASCII - sequences - • "rpc" |RPC| communication on the channel is active - - • "pty" Name of pseudoterminal, if one is used (optional). - On a POSIX system, this will be a device path like - /dev/pts/1. Even if the name is unknown, the key will - still be present to indicate a pty is used. This is - currently the case when using winpty on windows. - • "buffer" buffer with connected |terminal| instance - (optional) - • "client" information about the client on the other end - of the RPC channel, if it has added it using - |nvim_set_client_info()|. (optional) + • "job" Job with communication over its stdio. + + • "mode" How data received on the channel is interpreted. + • "bytes" Send and receive raw bytes. + • "terminal" |terminal| instance interprets ASCII + sequences. + • "rpc" |RPC| communication on the channel is active. + + • "pty" (optional) Name of pseudoterminal. On a POSIX + system this is a device path like "/dev/pts/1". If the + name is unknown, the key will still be present if a pty + is used (e.g. for winpty on Windows). + • "buffer" (optional) Buffer with connected |terminal| + instance. + • "client" (optional) Info about the peer (client on the + other end of the RPC channel), if provided by it via + |nvim_set_client_info()|. nvim_get_color_by_name({name}) *nvim_get_color_by_name()* Returns the 24-bit RGB value of a |nvim_get_color_map()| color @@ -917,7 +937,7 @@ nvim_get_color_map() *nvim_get_color_map()* Return: ~ Map of color names and RGB values. -nvim_get_commands({opts}) *nvim_get_commands()* +nvim_get_commands({*opts}) *nvim_get_commands()* Gets a map of global (non-buffer-local) Ex commands. Currently only |user-commands| are supported, not builtin Ex @@ -930,7 +950,7 @@ nvim_get_commands({opts}) *nvim_get_commands()* Return: ~ Map of maps describing commands. -nvim_get_context({opts}) *nvim_get_context()* +nvim_get_context({*opts}) *nvim_get_context()* Gets a map of the current editor state. Parameters: ~ @@ -1008,6 +1028,27 @@ nvim_get_keymap({mode}) *nvim_get_keymap()* Array of maparg()-like dictionaries describing mappings. The "buffer" key is always zero. +nvim_get_mark({name}) *nvim_get_mark()* + Return a tuple (row, col, buffer, buffername) representing the + position of the uppercase/file named mark. See |mark-motions|. + + Marks are (1,0)-indexed. |api-indexing| + + Note: + fails with error if a lowercase or buffer local named mark + is used. + + Parameters: ~ + {name} Mark name + + Return: ~ + 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if + the mark is not set. + + See also: ~ + |nvim_buf_set_mark()| + |nvim_del_mark()| + nvim_get_mode() *nvim_get_mode()* Gets the current mode. |mode()| "blocking" is true if Nvim is waiting for input. @@ -1079,10 +1120,6 @@ nvim_get_runtime_file({name}, {all}) *nvim_get_runtime_file()* It is not an error to not find any files. An empty array is returned then. - To find a directory, `name` must end with a forward slash, - like "rplugin/python/". Without the slash it would instead - look for an ordinary file called "rplugin/python". - Attributes: ~ {fast} @@ -1251,7 +1288,7 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()* For instance, for a floating display, first create an empty buffer using |nvim_create_buf()|, then display it using |nvim_open_win()|, and then call this function. Then - |nvim_chan_send()| cal be called immediately to process + |nvim_chan_send()| can be called immediately to process sequences in a virtual terminal having the intended size. Parameters: ~ @@ -1261,156 +1298,6 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()* Return: ~ Channel id, or 0 on error -nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()* - Open a new window. - - Currently this is used to open floating and external windows. - Floats are windows that are drawn above the split layout, at - some anchor position in some other window. Floats can be drawn - internally or by external GUI with the |ui-multigrid| - extension. External windows are only supported with multigrid - GUIs, and are displayed as separate top-level windows. - - For a general overview of floats, see |api-floatwin|. - - Exactly one of `external` and `relative` must be specified. - The `width` and `height` of the new window must be specified. - - With relative=editor (row=0,col=0) refers to the top-left - corner of the screen-grid and (row=Lines-1,col=Columns-1) - refers to the bottom-right corner. Fractional values are - allowed, but the builtin implementation (used by non-multigrid - UIs) will always round down to nearest integer. - - Out-of-bounds values, and configurations that make the float - not fit inside the main editor, are allowed. The builtin - implementation truncates values so floats are fully within the - main screen grid. External GUIs could let floats hover outside - of the main window like a tooltip, but this should not be used - to specify arbitrary WM screen positions. - - Example (Lua): window-relative float > - vim.api.nvim_open_win(0, false, - {relative='win', row=3, col=3, width=12, height=3}) -< - - Example (Lua): buffer-relative float (travels as buffer is - scrolled) > - vim.api.nvim_open_win(0, false, - {relative='win', width=12, height=3, bufpos={100,10}}) -< - - Attributes: ~ - not allowed when |textlock| is active - - Parameters: ~ - {buffer} Buffer to display, or 0 for current buffer - {enter} Enter the window (make it the current window) - {config} Map defining the window configuration. Keys: - • `relative`: Sets the window layout to "floating", placed - at (row,col) coordinates relative to: - • "editor" The global editor grid - • "win" Window given by the `win` field, or - current window. - • "cursor" Cursor position in current window. - - • `win` : |window-ID| for relative="win". - • `anchor`: Decides which corner of the float to place - at (row,col): - • "NW" northwest (default) - • "NE" northeast - • "SW" southwest - • "SE" southeast - - • `width` : Window width (in character cells). - Minimum of 1. - • `height` : Window height (in character cells). - Minimum of 1. - • `bufpos` : Places float relative to buffer - text (only when relative="win"). Takes a tuple - of zero-indexed [line, column]. `row` and - `col` if given are applied relative to this - position, else they default to `row=1` and - `col=0` (thus like a tooltip near the buffer - text). - • `row` : Row position in units of "screen cell - height", may be fractional. - • `col` : Column position in units of "screen - cell width", may be fractional. - • `focusable` : Enable focus by user actions - (wincmds, mouse events). Defaults to true. - Non-focusable windows can be entered by - |nvim_set_current_win()|. - • `external` : GUI should display the window as - an external top-level window. Currently - accepts no other positioning configuration - together with this. - • `zindex`: Stacking order. floats with higher`zindex`go on top on floats with lower indices. Must - be larger than zero. The following screen - elements have hard-coded z-indices: - • 100: insert completion popupmenu - • 200: message scrollback - • 250: cmdline completion popupmenu (when - wildoptions+=pum) The default value for - floats are 50. In general, values below 100 - are recommended, unless there is a good - reason to overshadow builtin elements. - - • `style`: Configure the appearance of the window. - Currently only takes one non-empty value: - • "minimal" Nvim will display the window with - many UI options disabled. This is useful - when displaying a temporary float where the - text should not be edited. Disables - 'number', 'relativenumber', 'cursorline', - 'cursorcolumn', 'foldcolumn', 'spell' and - 'list' options. 'signcolumn' is changed to - `auto` and 'colorcolumn' is cleared. The - end-of-buffer region is hidden by setting - `eob` flag of 'fillchars' to a space char, - and clearing the |EndOfBuffer| region in - 'winhighlight'. - - • `border`: Style of (optional) window border. This can - either be a string or an array. The string - values are - • "none": No border (default). - • "single": A single line box. - • "double": A double line box. - • "rounded": Like "single", but with rounded - corners ("╭" etc.). - • "solid": Adds padding by a single whitespace - cell. - • "shadow": A drop shadow effect by blending - with the background. - • If it is an array, it should have a length - of eight or any divisor of eight. The array - will specifify the eight chars building up - the border in a clockwise fashion starting - with the top-left corner. As an example, the - double box style could be specified as [ - "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. If - the number of chars are less than eight, - they will be repeated. Thus an ASCII border - could be specified as [ "/", "-", "\\", "|" - ], or all chars the same as [ "x" ]. An - empty string can be used to turn off a - specific border, for instance, [ "", "", "", - ">", "", "", "", "<" ] will only make - vertical borders but not horizontal ones. By - default, `FloatBorder` highlight is used, - which links to `VertSplit` when not defined. - It could also be specified by character: [ - {"+", "MyCorner"}, {"x", "MyBorder"} ]. - - • `noautocmd` : If true then no buffer-related - autocommand events such as |BufEnter|, - |BufLeave| or |BufWinEnter| may fire from - calling this function. - - Return: ~ - Window handle, or 0 on error - nvim_out_write({str}) *nvim_out_write()* Writes a message to the Vim output buffer. Does not append "\n", the message is buffered (won't display) until a linefeed @@ -1779,7 +1666,7 @@ nvim_set_hl({ns_id}, {name}, {val}) *nvim_set_hl()* default cterm attributes are same as attributes of gui color -nvim_set_keymap({mode}, {lhs}, {rhs}, {opts}) *nvim_set_keymap()* +nvim_set_keymap({mode}, {lhs}, {rhs}, {*opts}) *nvim_set_keymap()* Sets a global |mapping| for the given mode. To set a buffer-local mapping, use |nvim_buf_set_keymap()|. @@ -2063,6 +1950,24 @@ nvim_buf_del_keymap({buffer}, {mode}, {lhs}) *nvim_buf_del_keymap()* See also: ~ |nvim_del_keymap()| +nvim_buf_del_mark({buffer}, {name}) *nvim_buf_del_mark()* + Deletes a named mark in the buffer. See |mark-motions|. + + Note: + only deletes marks set in the buffer, if the mark is not + set in the buffer it will return false. + + Parameters: ~ + {buffer} Buffer to set the mark on + {name} Mark name + + Return: ~ + true if the mark was deleted, else false. + + See also: ~ + |nvim_buf_set_mark()| + |nvim_del_mark()| + nvim_buf_del_var({buffer}, {name}) *nvim_buf_del_var()* Removes a buffer-scoped (b:) variable @@ -2107,7 +2012,7 @@ nvim_buf_get_changedtick({buffer}) *nvim_buf_get_changedtick()* Return: ~ `b:changedtick` value. -nvim_buf_get_commands({buffer}, {opts}) *nvim_buf_get_commands()* +nvim_buf_get_commands({buffer}, {*opts}) *nvim_buf_get_commands()* Gets a map of buffer-local |user-commands|. Parameters: ~ @@ -2119,7 +2024,7 @@ nvim_buf_get_commands({buffer}, {opts}) *nvim_buf_get_commands()* *nvim_buf_get_extmark_by_id()* nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}, {opts}) - Gets the position (0-indexed) of an extmark {id}. + Gets the position (0-indexed) of an extmark. Parameters: ~ {buffer} Buffer handle, or 0 for current buffer @@ -2170,12 +2075,12 @@ nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts}) Parameters: ~ {buffer} Buffer handle, or 0 for current buffer {ns_id} Namespace id from |nvim_create_namespace()| - {start} Start of range, given as 0-indexed (row, col) or - valid extmark id (whose position defines the - bound) - {end} End of range (inclusive), given as 0-indexed - (row, col) or valid extmark id (whose position - defines the bound) + {start} Start of range: a 0-indexed (row, col) or valid + extmark id (whose position defines the bound). + |api-indexing| + {end} End of range (inclusive): a 0-indexed (row, col) + or valid extmark id (whose position defines the + bound). |api-indexing| {opts} Optional parameters. Keys: • limit: Maximum number of marks to return • details Whether to include the details dict @@ -2217,8 +2122,8 @@ nvim_buf_get_lines({buffer}, {start}, {end}, {strict_indexing}) Array of lines, or empty array for unloaded buffer. nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()* - Return a tuple (row,col) representing the position of the - named mark. + Returns a tuple (row,col) representing the position of the + named mark. See |mark-motions|. Marks are (1,0)-indexed. |api-indexing| @@ -2227,7 +2132,12 @@ nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()* {name} Mark name Return: ~ - (row, col) tuple + (row, col) tuple, (0, 0) if the mark is not set, or is an + uppercase/file mark set in another buffer. + + See also: ~ + |nvim_buf_set_mark()| + |nvim_buf_del_mark()| nvim_buf_get_name({buffer}) *nvim_buf_get_name()* Gets the full file name for the buffer @@ -2310,7 +2220,7 @@ nvim_buf_line_count({buffer}) *nvim_buf_line_count()* Line count, or 0 for unloaded buffer. |api-buffer| *nvim_buf_set_extmark()* -nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) +nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts}) Creates or updates an extmark. To create a new extmark, pass id=0. The extmark id will be @@ -2328,8 +2238,10 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) Parameters: ~ {buffer} Buffer handle, or 0 for current buffer {ns_id} Namespace id from |nvim_create_namespace()| - {line} Line where to place the mark, 0-based - {col} Column where to place the mark, 0-based + {line} Line where to place the mark, 0-based. + |api-indexing| + {col} Column where to place the mark, 0-based. + |api-indexing| {opts} Optional parameters. • id : id of the extmark to edit. • end_line : ending line of the mark, 0-based @@ -2338,6 +2250,10 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) exclusive. • hl_group : name of the highlight group used to highlight this mark. + • hl_eol : when true, for a multiline highlight + covering the EOL of a line, continue the + highlight for the rest of the screen line + (just like for diff and cursorline highlight). • virt_text : virtual text to link to this mark. A list of [text, highlight] tuples, each representing a text chunk with specified @@ -2373,10 +2289,28 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) color • "blend": blend with background text color. - • hl_eol : when true, for a multiline highlight - covering the EOL of a line, continue the - highlight for the rest of the screen line - (just like for diff and cursorline highlight). + • virt_lines : virtual lines to add next to this + mark This should be an array over lines, where + each line in turn is an array over [text, + highlight] tuples. In general, buffer and + window options do not affect the display of + the text. In particular 'wrap' and 'linebreak' + options do not take effect, so the number of + extra screen lines will always match the size + of the array. However the 'tabstop' buffer + option is still used for hard tabs. By default + lines are placed below the buffer line + containing the mark. • Note: currently virtual lines are limited to + one block per buffer. Thus setting a new mark + disables any previous `virt_lines` decoration. + However plugins should not rely on this + behaviour, as this limitation is planned to be + removed. + • virt_lines_above: place virtual lines above + instead. + • virt_lines_leftcol: Place extmarks in the + leftmost column of the window, bypassing sign + and number columns. • ephemeral : for use with |nvim_set_decoration_provider| callbacks. The mark will only be used for the current redraw @@ -2399,7 +2333,7 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {opts}) Id of the created/updated extmark *nvim_buf_set_keymap()* -nvim_buf_set_keymap({buffer}, {mode}, {lhs}, {rhs}, {opts}) +nvim_buf_set_keymap({buffer}, {mode}, {lhs}, {rhs}, {*opts}) Sets a buffer-local |mapping| for the given mode. Parameters: ~ @@ -2435,6 +2369,29 @@ nvim_buf_set_lines({buffer}, {start}, {end}, {strict_indexing}, {replacement}) error. {replacement} Array of lines to use as replacement + *nvim_buf_set_mark()* +nvim_buf_set_mark({buffer}, {name}, {line}, {col}) + Sets a named mark in the given buffer, all marks are allowed + file/uppercase, visual, last change, etc. See |mark-motions|. + + Marks are (1,0)-indexed. |api-indexing| + + Note: + Passing 0 as line deletes the mark + + Parameters: ~ + {buffer} Buffer to set the mark on + {name} Mark name + {line} Line number + {col} Column/row number + + Return: ~ + true if the mark was set, else false. + + See also: ~ + |nvim_buf_del_mark()| + |nvim_buf_get_mark()| + nvim_buf_set_name({buffer}, {name}) *nvim_buf_set_name()* Sets the full file name for a buffer @@ -2534,20 +2491,6 @@ nvim_win_get_buf({window}) *nvim_win_get_buf()* Return: ~ Buffer handle -nvim_win_get_config({window}) *nvim_win_get_config()* - Gets window configuration. - - The returned value may be given to |nvim_open_win()|. - - `relative` is empty for normal windows. - - Parameters: ~ - {window} Window handle, or 0 for current window - - Return: ~ - Map defining the window configuration, see - |nvim_open_win()| - nvim_win_get_cursor({window}) *nvim_win_get_cursor()* Gets the (1,0)-indexed cursor position in the window. |api-indexing| @@ -2658,23 +2601,6 @@ nvim_win_set_buf({window}, {buffer}) *nvim_win_set_buf()* {window} Window handle, or 0 for current window {buffer} Buffer handle -nvim_win_set_config({window}, {config}) *nvim_win_set_config()* - Configures window layout. Currently only for floating and - external windows (including changing a split window to those - layouts). - - When reconfiguring a floating window, absent option keys will - not be changed. `row` / `col` and `relative` must be - reconfigured together. - - Parameters: ~ - {window} Window handle, or 0 for current window - {config} Map defining the window configuration, see - |nvim_open_win()| - - See also: ~ - |nvim_open_win()| - nvim_win_set_cursor({window}, {pos}) *nvim_win_set_cursor()* Sets the (1,0)-indexed cursor position in the window. |api-indexing| @@ -2718,6 +2644,194 @@ nvim_win_set_width({window}, {width}) *nvim_win_set_width()* ============================================================================== +Win_Config Functions *api-win_config* + +nvim_open_win({buffer}, {enter}, {*config}) *nvim_open_win()* + Open a new window. + + Currently this is used to open floating and external windows. + Floats are windows that are drawn above the split layout, at + some anchor position in some other window. Floats can be drawn + internally or by external GUI with the |ui-multigrid| + extension. External windows are only supported with multigrid + GUIs, and are displayed as separate top-level windows. + + For a general overview of floats, see |api-floatwin|. + + Exactly one of `external` and `relative` must be specified. + The `width` and `height` of the new window must be specified. + + With relative=editor (row=0,col=0) refers to the top-left + corner of the screen-grid and (row=Lines-1,col=Columns-1) + refers to the bottom-right corner. Fractional values are + allowed, but the builtin implementation (used by non-multigrid + UIs) will always round down to nearest integer. + + Out-of-bounds values, and configurations that make the float + not fit inside the main editor, are allowed. The builtin + implementation truncates values so floats are fully within the + main screen grid. External GUIs could let floats hover outside + of the main window like a tooltip, but this should not be used + to specify arbitrary WM screen positions. + + Example (Lua): window-relative float > + vim.api.nvim_open_win(0, false, + {relative='win', row=3, col=3, width=12, height=3}) +< + + Example (Lua): buffer-relative float (travels as buffer is + scrolled) > + vim.api.nvim_open_win(0, false, + {relative='win', width=12, height=3, bufpos={100,10}}) +< + + Attributes: ~ + not allowed when |textlock| is active + + Parameters: ~ + {buffer} Buffer to display, or 0 for current buffer + {enter} Enter the window (make it the current window) + {config} Map defining the window configuration. Keys: + • `relative`: Sets the window layout to "floating", placed + at (row,col) coordinates relative to: + • "editor" The global editor grid + • "win" Window given by the `win` field, or + current window. + • "cursor" Cursor position in current window. + + • `win` : |window-ID| for relative="win". + • `anchor`: Decides which corner of the float to place + at (row,col): + • "NW" northwest (default) + • "NE" northeast + • "SW" southwest + • "SE" southeast + + • `width` : Window width (in character cells). + Minimum of 1. + • `height` : Window height (in character cells). + Minimum of 1. + • `bufpos`: Places float relative to buffer text (only + when relative="win"). Takes a tuple of + zero-indexed [line, column].`row`and`col`if given are applied relative to this + position, else they default to: + • `row=1` and `col=0` if `anchor` is "NW" or + "NE" + • `row=0` and `col=0` if `anchor` is "SW" or + "SE" (thus like a tooltip near the buffer + text). + + • `row` : Row position in units of "screen cell + height", may be fractional. + • `col` : Column position in units of "screen + cell width", may be fractional. + • `focusable` : Enable focus by user actions + (wincmds, mouse events). Defaults to true. + Non-focusable windows can be entered by + |nvim_set_current_win()|. + • `external` : GUI should display the window as + an external top-level window. Currently + accepts no other positioning configuration + together with this. + • `zindex`: Stacking order. floats with higher`zindex`go on top on floats with lower indices. Must + be larger than zero. The following screen + elements have hard-coded z-indices: + • 100: insert completion popupmenu + • 200: message scrollback + • 250: cmdline completion popupmenu (when + wildoptions+=pum) The default value for + floats are 50. In general, values below 100 + are recommended, unless there is a good + reason to overshadow builtin elements. + + • `style`: Configure the appearance of the window. + Currently only takes one non-empty value: + • "minimal" Nvim will display the window with + many UI options disabled. This is useful + when displaying a temporary float where the + text should not be edited. Disables + 'number', 'relativenumber', 'cursorline', + 'cursorcolumn', 'foldcolumn', 'spell' and + 'list' options. 'signcolumn' is changed to + `auto` and 'colorcolumn' is cleared. The + end-of-buffer region is hidden by setting + `eob` flag of 'fillchars' to a space char, + and clearing the |EndOfBuffer| region in + 'winhighlight'. + + • `border`: Style of (optional) window border. This can + either be a string or an array. The string + values are + • "none": No border (default). + • "single": A single line box. + • "double": A double line box. + • "rounded": Like "single", but with rounded + corners ("╭" etc.). + • "solid": Adds padding by a single whitespace + cell. + • "shadow": A drop shadow effect by blending + with the background. + • If it is an array, it should have a length + of eight or any divisor of eight. The array + will specifify the eight chars building up + the border in a clockwise fashion starting + with the top-left corner. As an example, the + double box style could be specified as [ + "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. If + the number of chars are less than eight, + they will be repeated. Thus an ASCII border + could be specified as [ "/", "-", "\\", "|" + ], or all chars the same as [ "x" ]. An + empty string can be used to turn off a + specific border, for instance, [ "", "", "", + ">", "", "", "", "<" ] will only make + vertical borders but not horizontal ones. By + default, `FloatBorder` highlight is used, + which links to `VertSplit` when not defined. + It could also be specified by character: [ + {"+", "MyCorner"}, {"x", "MyBorder"} ]. + + • `noautocmd` : If true then no buffer-related + autocommand events such as |BufEnter|, + |BufLeave| or |BufWinEnter| may fire from + calling this function. + + Return: ~ + Window handle, or 0 on error + +nvim_win_get_config({window}) *nvim_win_get_config()* + Gets window configuration. + + The returned value may be given to |nvim_open_win()|. + + `relative` is empty for normal windows. + + Parameters: ~ + {window} Window handle, or 0 for current window + + Return: ~ + Map defining the window configuration, see + |nvim_open_win()| + +nvim_win_set_config({window}, {*config}) *nvim_win_set_config()* + Configures window layout. Currently only for floating and + external windows (including changing a split window to those + layouts). + + When reconfiguring a floating window, absent option keys will + not be changed. `row` / `col` and `relative` must be + reconfigured together. + + Parameters: ~ + {window} Window handle, or 0 for current window + {config} Map defining the window configuration, see + |nvim_open_win()| + + See also: ~ + |nvim_open_win()| + + +============================================================================== Tabpage Functions *api-tabpage* nvim_tabpage_del_var({tabpage}, {name}) *nvim_tabpage_del_var()* diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 7a53f17a78..de74ee891e 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1232,6 +1232,13 @@ Example: > This prevents having the autocommands defined twice (e.g., after sourcing the vimrc file again). + *FileExplorer* +There is one group that is recognized by Vim: FileExplorer. If this group +exists Vim assumes that editing a directory is possible and will trigger a +plugin that lists the files in that directory. This is used by the |netrw| +plugin. This allows you to do: > + browse edit + ============================================================================== 9. Executing autocommands *autocmd-execute* diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt index 14f35acce3..7127c74134 100644 --- a/runtime/doc/develop.txt +++ b/runtime/doc/develop.txt @@ -166,7 +166,7 @@ Docstring format: - Use `<pre>` for code samples. Example: the help for |nvim_open_win()| is generated from a docstring defined -in src/nvim/api/vim.c like this: > +in src/nvim/api/win_config.c like this: > /// Opens a new window. /// ... diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt index 276571d042..75c8a2ad6f 100644 --- a/runtime/doc/diagnostic.txt +++ b/runtime/doc/diagnostic.txt @@ -363,6 +363,13 @@ get({bufnr}, {opts}) *vim.diagnostic.get()* Return: ~ table A list of diagnostic items |diagnostic-structure|. +get_namespaces() *vim.diagnostic.get_namespaces()* + Get current diagnostic namespaces. + + Return: ~ + table A list of active diagnostic namespaces + |vim.diagnostic|. + get_next({opts}) *vim.diagnostic.get_next()* Get the next diagnostic closest to the cursor position. diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt index 4700af41b7..0e7e461a61 100644 --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1183,7 +1183,8 @@ If you want to always use ":confirm", set the 'confirm' option. |:diffsplit|, |:diffpatch|, |:pedit|, |:redir|, |:source|, |:update|, |:visual|, |:vsplit|, and |:qall| if 'confirm' is set. - {only in Win32 GUI} + {only in Win32 GUI, in console `browse edit` works + if the FileExplorer autocommand group exists} When ":browse" is not possible you get an error message. If {command} doesn't support browsing, the {command} is executed without a dialog. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 8305cbf0d5..e956ccaa77 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1307,7 +1307,7 @@ A string constant accepts these special characters: \U.... same as \u but allows up to 8 hex numbers. \b backspace <BS> \e escape <Esc> -\f formfeed <FF> +\f formfeed 0x0C \n newline <NL> \r return <CR> \t tab <Tab> @@ -1316,7 +1316,7 @@ A string constant accepts these special characters: \<xxx> Special key named "xxx". e.g. "\<C-W>" for CTRL-W. This is for use in mappings, the 0x80 byte is escaped. To use the double quote character it must be escaped: "<M-\">". - Don't use <Char-xxxx> to get a utf-8 character, use \uxxxx as + Don't use <Char-xxxx> to get a UTF-8 character, use \uxxxx as mentioned above. Note that "\xff" is stored as the byte 255, which may be invalid in some @@ -2313,7 +2313,7 @@ ceil({expr}) Float round {expr} up changenr() Number current change number chanclose({id}[, {stream}]) Number Closes a channel or one of its streams chansend({id}, {data}) Number Writes {data} to channel -char2nr({expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr} +char2nr({expr}[, {utf8}]) Number ASCII/UTF-8 value of first char in {expr} charidx({string}, {idx} [, {countcc}]) Number char index of byte {idx} in {string} cindent({lnum}) Number C indent for line {lnum} @@ -2544,7 +2544,7 @@ mode([expr]) String current editing mode msgpackdump({list} [, {type}]) List/Blob dump objects to msgpack msgpackparse({data}) List parse msgpack to a list of objects nextnonblank({lnum}) Number line nr of non-blank line >= {lnum} -nr2char({expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr} +nr2char({expr}[, {utf8}]) String single char with ASCII/UTF-8 value {expr} nvim_...({args}...) any call nvim |api| functions or({expr}, {expr}) Number bitwise OR pathshorten({expr}) String shorten directory names in a path @@ -2680,7 +2680,7 @@ stdioopen({dict}) Number open stdio in a headless instance. stdpath({what}) String/List returns the standard path(s) for {what} str2float({expr} [, {quoted}]) Float convert String to Float str2list({expr} [, {utf8}]) List convert each character of {expr} to - ASCII/UTF8 value + ASCII/UTF-8 value str2nr({expr} [, {base} [, {quoted}]]) Number convert String to Number strchars({expr} [, {skipcc}]) Number character length of the String {expr} @@ -6551,9 +6551,9 @@ list2str({list} [, {utf8}]) *list2str()* join(map(list, {nr, val -> nr2char(val)}), '') < |str2list()| does the opposite. - When {utf8} is omitted or zero, the current 'encoding' is used. - With {utf8} is 1, always return utf-8 characters. - With utf-8 composing characters work as expected: > + UTF-8 encoding is always used, {utf8} option has no effect, + and exists only for backwards-compatibility. + With UTF-8 composing characters work as expected: > list2str([97, 769]) returns "á" < Can also be used as a |method|: > @@ -7112,6 +7112,8 @@ mode([expr]) Return a string that indicates the current mode. niI Normal using |i_CTRL-O| in |Insert-mode| niR Normal using |i_CTRL-O| in |Replace-mode| niV Normal using |i_CTRL-O| in |Virtual-Replace-mode| + nt Normal in |terminal-emulator| (insert goes to + Terminal mode) v Visual by character vs Visual by character using |v_CTRL-O| in Select mode V Visual by line @@ -9285,10 +9287,9 @@ str2list({string} [, {utf8}]) *str2list()* str2list("ABC") returns [65, 66, 67] < |list2str()| does the opposite. - When {utf8} is omitted or zero, the current 'encoding' is used. - With {utf8} set to TRUE, always treat the String as utf-8 - characters. With utf-8 composing characters are handled - properly: > + UTF-8 encoding is always used, {utf8} option has no effect, + and exists only for backwards-compatibility. + With UTF-8 composing characters are handled properly: > str2list("á") returns [97, 769] < Can also be used as a |method|: > @@ -11300,7 +11301,7 @@ text... literal then the items also cannot be changed: > const ll = [1, 2, 3] let ll[1] = 5 " Error! -< Nested references are not locked: > +< Nested references are not locked: > let lvar = ['a'] const lconst = [0, lvar] let lconst[0] = 2 " Error! diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index a23ae3fb76..42a9993c8c 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -501,7 +501,7 @@ One command, :DiffGitCached, is provided to show a diff of the current commit in the preview window. It is equivalent to calling "git diff --cached" plus any arguments given to the command. -GPROF +GPROF *ft-gprof-plugin* The gprof filetype plugin defines a mapping <C-]> to jump from a function entry in the gprof flat profile or from a function entry in the call graph diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt index 2baf3a247f..a89263861b 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -55,7 +55,7 @@ Nvim on the interwebs *internet* Nvim home page: https://neovim.io/ Nvim FAQ: https://github.com/neovim/neovim/wiki/FAQ Downloads: https://github.com/neovim/neovim/releases - Vim FAQ: https://vimhelp.appspot.com/vim_faq.txt.html + Vim FAQ: https://vimhelp.org/vim_faq.txt.html *bugs* *bug-report* @@ -312,7 +312,6 @@ notation meaning equivalent decimal value(s) ~ <Tab> tab CTRL-I 9 *tab* *Tab* *linefeed* <NL> linefeed CTRL-J 10 (used for <Nul>) -<FF> formfeed CTRL-L 12 *formfeed* <CR> carriage return CTRL-M 13 *carriage-return* <Return> same as <CR> *<Return>* <Enter> same as <CR> *<Enter>* diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 5b2a8d68b4..ac797de92d 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -1015,6 +1015,9 @@ outgoing_calls() *vim.lsp.buf.outgoing_calls()* cursor in the |quickfix| window. If the symbol can resolve to multiple items, the user can pick one in the |inputlist|. +prepare_rename({err}, {result}) *vim.lsp.buf.prepare_rename()* + TODO: Documentation + *vim.lsp.buf.range_code_action()* range_code_action({context}, {start_pos}, {end_pos}) Performs |vim.lsp.buf.code_action()| for a given range. @@ -1251,8 +1254,8 @@ apply_text_edits({text_edits}, {bufnr}) Applies a list of text edits to a buffer. Parameters: ~ - {text_edits} (table) list of `TextEdit` objects - {buf_nr} (number) Buffer id + {text_edits} table list of `TextEdit` objects + {bufnr} number Buffer id See also: ~ https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit @@ -1472,6 +1475,13 @@ make_floating_popup_options({width}, {height}, {opts}) {width} (number) window width (in character cells) {height} (number) window height (in character cells) {opts} (table, optional) + • offset_x (number) offset to add to `col` + • offset_y (number) offset to add to `row` + • border (string or table) override `border` + • focusable (string or table) override + `focusable` + • zindex (string or table) override `zindex` , + defaults to 50 Return: ~ (table) Options @@ -1562,10 +1572,6 @@ open_floating_preview({contents}, {syntax}, {opts}) height when wrap is enabled • max_width maximal width of floating window • max_height maximal height of floating window - • pad_left number of columns to pad contents - at left - • pad_right number of columns to pad contents - at right • pad_top number of lines to pad contents at top • pad_bottom number of lines to pad contents @@ -1585,10 +1591,10 @@ parse_snippet({input}) *vim.lsp.util.parse_snippet()* Parses snippets in a completion entry. Parameters: ~ - {input} (string) unparsed snippet + {input} string unparsed snippet Return: ~ - (string) parsed snippet + string parsed snippet preview_location({location}, {opts}) *vim.lsp.util.preview_location()* Previews a location in a floating window @@ -1649,10 +1655,6 @@ stylize_markdown({bufnr}, {contents}, {opts}) height • max_width maximal width of floating window • max_height maximal height of floating window - • pad_left number of columns to pad contents - at left - • pad_right number of columns to pad contents - at right • pad_top number of lines to pad contents at top • pad_bottom number of lines to pad contents @@ -1719,6 +1721,16 @@ get_filename() *vim.lsp.log.get_filename()* Return: ~ (string) log filename +get_level() *vim.lsp.log.get_level()* + TODO: Documentation + +set_format_func({handle}) *vim.lsp.log.set_format_func()* + Sets formatting function used to format logs + + Parameters: ~ + {handle} function function to apply to logging arguments, + pass vim.inspect for multi-line formatting + set_level({level}) *vim.lsp.log.set_level()* Sets the current log level. diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 22e323baa7..a6ccf9f35c 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -1206,6 +1206,36 @@ notify({msg}, {log_level}, {_opts}) *vim.notify()* See also: ~ :help nvim_notify +on_key({fn}, {ns_id}) *vim.on_key()* + Adds Lua function {fn} with namespace id {ns_id} as a listener + to every, yes every, input key. + + The Nvim command-line option |-w| is related but does not + support callbacks and cannot be toggled dynamically. + + Note: + {fn} will not be cleared by |nvim_buf_clear_namespace()| + + Note: + {fn} will receive the keys after mappings have been + evaluated + + Parameters: ~ + {fn} function: Callback function. It should take one + string argument. On each key press, Nvim passes + the key char to fn(). |i_CTRL-V| If {fn} is nil, + it removes the callback for the associated + {ns_id} + {ns_id} number? Namespace ID. If nil or 0, generates and + returns a new |nvim_create_namesapce()| id. + + Return: ~ + number Namespace id associated with {fn}. Or count of all + callbacks if on_key() is called without arguments. + + Note: + {fn} will be removed if an error occurs while calling. + paste({lines}, {phase}) *vim.paste()* Paste handler, invoked by |nvim_paste()| when a conforming UI (such as the |TUI|) pastes text into the editor. @@ -1268,8 +1298,7 @@ schedule_wrap({cb}) *vim.schedule_wrap()* deep_equal({a}, {b}) *vim.deep_equal()* Deep compare values for equality - Tables are compared recursively unless they both provide the `eq` methamethod. - All other types are compared using the equality `==` operator. + Tables are compared recursively unless they both provide the `eq` methamethod. All other types are compared using the equality `==` operator. Parameters: ~ {a} first value @@ -1373,20 +1402,25 @@ pesc({s}) *vim.pesc()* See also: ~ https://github.com/rxi/lume -split({s}, {sep}, {plain}) *vim.split()* +split({s}, {sep}, {kwargs}) *vim.split()* Splits a string at each instance of a separator. Examples: > - split(":aa::b:", ":") --> {'','aa','','b',''} - split("axaby", "ab?") --> {'','x','y'} - split(x*yz*o, "*", true) --> {'x','yz','o'} + + split(":aa::b:", ":") --> {'','aa','','b',''} + split("axaby", "ab?") --> {'','x','y'} + split("x*yz*o", "*", {plain=true}) --> {'x','yz','o'} + split("|x|y|z|", "|", {trimempty=true}) --> {'x', 'y', 'z'} < Parameters: ~ - {s} String to split - {sep} Separator string or pattern - {plain} If `true` use `sep` literally (passed to - String.find) + {s} String to split + {sep} Separator string or pattern + {kwargs} Keyword arguments: + • plain: (boolean) If `true` use `sep` literally + (passed to string.find) + • trimempty: (boolean) If `true` remove empty + items from the front and back of the list Return: ~ List-like table of the split components. @@ -1571,12 +1605,14 @@ validate({opt}) *vim.validate()* vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}} => NOP (success) - - vim.validate{arg1={1, 'table'}} - => error('arg1: expected table, got number') - - vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} - => error('arg1: expected even number, got 3') +< +> + vim.validate{arg1={1, 'table'}} + => error('arg1: expected table, got number') +< +> + vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}} + => error('arg1: expected even number, got 3') < Parameters: ~ diff --git a/runtime/doc/mbyte.txt b/runtime/doc/mbyte.txt index a6c797a860..3bbf36c642 100644 --- a/runtime/doc/mbyte.txt +++ b/runtime/doc/mbyte.txt @@ -663,7 +663,7 @@ This file explains what characters are available in UTF-8 and CP1255 encodings, and what the keymaps are to get those characters: glyph encoding keymap ~ -Char utf-8 cp1255 hebrew hebrewp name ~ +Char UTF-8 cp1255 hebrew hebrewp name ~ א 0x5d0 0xe0 t a 'alef ב 0x5d1 0xe1 c b bet ג 0x5d2 0xe2 d g gimel @@ -716,11 +716,11 @@ Vowel marks and special punctuation: ױ 0x5f1 0xd5 VY VY vav-yod ײ 0x5f2 0xd6 YY YY yod-yod -The following are only available in utf-8 +The following are only available in UTF-8 Cantillation marks: glyph -Char utf-8 hebrew name +Char UTF-8 hebrew name ב֑ 0x591 C: etnahta ב֒ 0x592 Cs segol ב֓ 0x593 CS shalshelet @@ -803,7 +803,7 @@ ASCII. On MS-Windows UTF-16 is also used (previously UCS-2), which uses internally. Vim has comprehensive UTF-8 support. It works well in: -- xterm with utf-8 support enabled +- xterm with UTF-8 support enabled - MS-Windows GUI - several other platforms @@ -814,14 +814,14 @@ a space to fill the gap. *bom-bytes* When reading a file a BOM (Byte Order Mark) can be used to recognize the Unicode encoding: - EF BB BF utf-8 - FE FF utf-16 big endian - FF FE utf-16 little endian - 00 00 FE FF utf-32 big endian - FF FE 00 00 utf-32 little endian - -Utf-8 is the recommended encoding. Note that it's difficult to tell utf-16 -and utf-32 apart. Utf-16 is often used on MS-Windows, utf-32 is not + EF BB BF UTF-8 + FE FF UTF-16 big endian + FF FE UTF-16 little endian + 00 00 FE FF UTF-32 big endian + FF FE 00 00 UTF-32 little endian + +UTF-8 is the recommended encoding. Note that it's difficult to tell UTF-16 +and UTF-32 apart. UTF-16 is often used on MS-Windows, UTF-32 is not widespread as file format. @@ -888,10 +888,10 @@ Motif. Use the ":hi Menu font={fontname}" command for this. |:highlight| TYPING UTF-8 *utf-8-typing* If you are using X-Windows, you should find an input method that supports -utf-8. +UTF-8. -If your system does not provide support for typing utf-8, you can use the -'keymap' feature. This allows writing a keymap file, which defines a utf-8 +If your system does not provide support for typing UTF-8, you can use the +'keymap' feature. This allows writing a keymap file, which defines a UTF-8 character as a sequence of ASCII characters. See |mbyte-keymap|. If everything else fails, you can type any character as four hex bytes: > diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt index 5ad69d1122..e83b17f9a0 100644 --- a/runtime/doc/nvim_terminal_emulator.txt +++ b/runtime/doc/nvim_terminal_emulator.txt @@ -53,7 +53,7 @@ next key is sent unless it is <C-N>. Use <C-\><C-N> to return to normal-mode. Terminal-mode forces these local options: - 'nocursorline' + 'cursorlineopt' = number 'nocursorcolumn' 'scrolloff' = 0 'sidescrolloff' = 0 @@ -171,7 +171,7 @@ program window A terminal window for the executed program. When "run" is The current window is used to show the source code. When gdb pauses the source file location will be displayed, if possible. A sign is used to -highlight the current position, using highlight group debugPC. +highlight the current position, using highlight group debugPC. If the buffer in the current window is modified, another window will be opened to display the current gdb position. @@ -222,7 +222,7 @@ Put focus on the gdb window and type: > run Vim will start running in the program window. Put focus there and type: > :help gui -Gdb will run into the ex_help breakpoint. The source window now shows the +Gdb will run into the ex_help breakpoint. The source window now shows the ex_cmds.c file. A red "1 " marker will appear in the signcolumn where the breakpoint was set. The line where the debugger stopped is highlighted. You can now step through the program. You will see the highlighting move as the diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 85be6eddaa..981bdd09fc 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1409,9 +1409,9 @@ A jump table for the options with a short description can be found at |Q_op|. When this option is set it overrules 'shellslash' for completion: - When this option is set to "slash", a forward slash is used for path completion in insert mode. This is useful when editing HTML tag, or - Makefile with 'noshellslash' on Windows. + Makefile with 'noshellslash' on MS-Windows. - When this option is set to "backslash", backslash is used. This is - useful when editing a batch file with 'shellslash' set on Windows. + useful when editing a batch file with 'shellslash' set on MS-Windows. - When this option is empty, same character is used as for 'shellslash'. For Insert mode completion the buffer-local value is used. For diff --git a/runtime/doc/pi_health.txt b/runtime/doc/pi_health.txt index bb688770fc..179c1066cd 100644 --- a/runtime/doc/pi_health.txt +++ b/runtime/doc/pi_health.txt @@ -5,7 +5,7 @@ Author: TJ DeVries <devries.timothyj@gmail.com> Type |gO| to see the table of contents. ============================================================================== -Introduction *health* +Introduction *health* health.vim is a minimal framework to help with troubleshooting user configuration. Nvim ships with healthchecks for configuration, performance, @@ -18,65 +18,136 @@ To run the healthchecks, use this command: > Plugin authors are encouraged to write new healthchecks. |health-dev| ============================================================================== -Commands *health-commands* +Commands *health-commands* - *:checkhealth* *:CheckHealth* + *:checkhealth* *:CheckHealth* :checkhealth Run all healthchecks. - *E5009* - Nvim depends on |$VIMRUNTIME| and 'runtimepath' to find - the standard "runtime files" for syntax highlighting, - filetype-specific behavior, and standard plugins - (including :checkhealth). If the runtime files cannot - be found then those features will not work. + *E5009* + Nvim depends on |$VIMRUNTIME|, 'runtimepath' and 'packpath' to + find the standard "runtime files" for syntax highlighting, + filetype-specific behavior, and standard plugins (including + :checkhealth). If the runtime files cannot be found then + those features will not work. :checkhealth {plugins} - Run healthcheck(s) for one or more plugins. E.g. to run - only the standard Nvim healthcheck: > + Run healthcheck(s) for one or more plugins. E.g. to run only + the standard Nvim healthcheck: > :checkhealth nvim -< To run the healthchecks for the "foo" and "bar" plugins - (assuming these plugins are on your 'runtimepath' and - they have implemented health#foo#check() and - health#bar#check(), respectively): > +< + To run the healthchecks for the "foo" and "bar" plugins + (assuming these plugins are on 'runtimepath' or 'packpath' and + they have implemented the Lua or Vimscript interface + require("foo.health").check() and health#bar#check(), + respectively): > :checkhealth foo bar < + To run healthchecks for lua submodules, use dot notation or + "*" to refer to all submodules. For example nvim provides + `vim.lsp` and `vim.treesitter` > + :checkhealth vim.lsp vim.treesitter + :checkhealth vim* +< ============================================================================== -Functions *health-functions* +Lua Functions *health-functions-lua* *health-lua* + +The Lua "health" module can be used to create new healthchecks (see also +|health-functions-vim|). To get started, simply use: > + local health = require('health') +< +health.report_start({name}) *health.report_start()* + Starts a new report. Most plugins should call this only once, but if + you want different sections to appear in your report, call this once + per section. + +health.report_info({msg}) *health.report_info()* + Reports an informational message. + +health.report_ok({msg}) *health.report_ok()* + Reports a "success" message. + +health.report_warn({msg} [, {advice}]) *health.report_warn()* + Reports a warning. {advice} is an optional List of suggestions. + +health.report_error({msg} [, {advice}]) *health.report_error()* + Reports an error. {advice} is an optional List of suggestions. + +============================================================================== +Create a Lua healthcheck *health-dev-lua* + +Healthchecks are functions that check the user environment, configuration, +etc. Nvim has built-in healthchecks in $VIMRUNTIME/autoload/health/. -health.vim functions are for creating new healthchecks. They mostly just do -some layout and formatting, to give users a consistent presentation. +To add a new healthcheck for your own plugin, simply define a Lua module in +your plugin that returns a table with a "check()" function. |:checkhealth| +will automatically find and invoke this function. -health#report_start({name}) *health#report_start* - Starts a new report. Most plugins should call this only once, but if +If your plugin is named "foo", then its healthcheck module should be a file in +one of these locations on 'runtimepath' or 'packpath': + - lua/foo/health/init.lua + - lua/foo/health.lua + +If your plugin provides a submodule named "bar" for which you want a separate +healthcheck, define the healthcheck at one of these locations on 'runtimepath' +or 'packpath': + - lua/foo/bar/health/init.lua + - lua/foo/bar/health.lua + +All submodules should return a Lua table containing the method `check()`. + +Copy this sample code into `lua/foo/health/init.lua` or `lua/foo/health.lua`, +replacing "foo" in the path with your plugin name: > + + local M = {} + local health = require("health") + + M.check = function() + health.report_start("my_plugin report") + -- make sure setup function parameters are ok + if check_setup() then + health.report_ok("Setup function is correct") + else + health.report_error("Setup function is incorrect") + end + -- do some more checking + -- ... + end + + return M + +============================================================================== +Vimscript Functions *health-functions-vimscript* *health-vimscript* + +health.vim functions are for creating new healthchecks. (See also +|health-functions-lua|) + +health#report_start({name}) *health#report_start* + Starts a new report. Most plugins should call this only once, but if you want different sections to appear in your report, call this once per section. -health#report_info({msg}) *health#report_info* - Reports an informational message. +health#report_info({msg}) *health#report_info* + Reports an informational message. -health#report_ok({msg}) *health#report_ok* - Reports a "success" message. +health#report_ok({msg}) *health#report_ok* + Reports a "success" message. -health#report_warn({msg}, [{advice}]) *health#report_warn* +health#report_warn({msg} [, {advice}]) *health#report_warn* Reports a warning. {advice} is an optional List of suggestions. -health#report_error({msg}, [{advice}]) *health#report_error* +health#report_error({msg} [, {advice}]) *health#report_error* Reports an error. {advice} is an optional List of suggestions. -health#{plugin}#check() *health.user_checker* +health#{plugin}#check() *health.user_checker* Healthcheck function for {plugin}. Called by |:checkhealth| automatically. Example: > - function! health#my_plug#check() abort - silent call s:check_environment_vars() - silent call s:check_python_configuration() - endfunction + function! health#my_plug#check() abort + silent call s:check_environment_vars() + silent call s:check_python_configuration() + endfunction < - All output will be captured from the healthcheck. Use the - health#report_* functions so that your healthcheck has a format - consistent with the standard healthchecks. - ============================================================================== -Create a healthcheck *health-dev* +Create a healthcheck *health-dev-vim* Healthchecks are functions that check the user environment, configuration, etc. Nvim has built-in healthchecks in $VIMRUNTIME/autoload/health/. @@ -88,8 +159,8 @@ health#{plugin}#check() function in autoload/health/{plugin}.vim. If your plugin is named "foo", then its healthcheck function must be > health#foo#check() -defined in this file on 'runtimepath': > - autoload/health/foo.vim +defined in this file on 'runtimepath' or 'packpath': + - autoload/health/foo.vim Copy this sample code into autoload/health/foo.vim and replace "foo" with your plugin name: > @@ -97,7 +168,7 @@ plugin name: > call health#report_start('sanity checks') " perform arbitrary checks " ... - + if looks_good call health#report_ok('found required dependencies') else @@ -106,6 +177,4 @@ plugin name: > endif endfunction -============================================================================== - -vim:tw=78:ts=8:ft=help:fdm=marker +vim:et:tw=78:ts=8:ft=help:fdm=marker diff --git a/runtime/doc/print.txt b/runtime/doc/print.txt index d9320ad315..f54d0429a6 100644 --- a/runtime/doc/print.txt +++ b/runtime/doc/print.txt @@ -690,7 +690,7 @@ There are a couple of points to bear in mind: ============================================================================== 8. Formfeed Characters *printing-formfeed* -By default Vim does not do any special processing of |formfeed| control +By default Vim does not do any special processing of formfeed control characters. Setting the 'printoptions' formfeed item will make Vim recognize formfeed characters and continue printing the current line at the beginning of the first line on a new page. The use of formfeed characters provides diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index 87a48e6d2a..bb775ec884 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -90,10 +90,11 @@ argument. See |info-message| about capturing the text. *--clean* ---clean Equivalent to "-u NONE -i NONE": +--clean Mimics a fresh install of Nvim: - Skips initializations from files and environment variables. - No 'shada' file is read or written. - Excludes user directories from 'runtimepath' + - Loads builtin plugins, unlike "-u NONE -i NONE". *--noplugin* --noplugin Skip loading plugins. Resets the 'loadplugins' option. diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index ac10aeec88..441ae13df4 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -531,9 +531,11 @@ Query:iter_matches({self}, {node}, {source}, {start}, {stop}) for id, node in pairs(match) do local name = query.captures[id] -- `node` was captured by the `name` capture in the match - - local node_data = metadata[id] -- Node level metadata - +< +> + local node_data = metadata[id] -- Node level metadata +< +> ... use the info here ... end end diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 5d70834ddc..c575dd9fd8 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -1804,7 +1804,7 @@ First of all you must choose a name for your plugin. The features provided by the plugin should be clear from its name. And it should be unlikely that someone else writes a plugin with the same name but which does something different. And please limit the name to 8 characters, to avoid problems on -old Windows systems. +old MS-Windows systems. A script that corrects typing mistakes could be called "typecorr.vim". We will use it here as an example. diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 5e0c6fb32e..c86ca9646b 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types " " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2021 Sep 21 +" Last Change: 2021 Oct 03 " Listen very carefully, I will say this only once if exists("did_load_filetypes") @@ -872,6 +872,9 @@ au BufNewFile,BufRead *.json-patch setf json " Jupyter Notebook is also json au BufNewFile,BufRead *.ipynb setf json +" Other files that look like json +au BufNewFile,BufRead .babelrc,.eslintrc,.prettierrc,.firebaserc setf json + " JSONC au BufNewFile,BufRead *.jsonc setf jsonc @@ -1106,6 +1109,9 @@ au BufNewFile,BufRead *.mysql setf mysql " Mutt setup files (must be before catch *.rc) au BufNewFile,BufRead */etc/Muttrc.d/* call s:StarSetf('muttrc') +" Tcl Shell RC file +au BufNewFile,BufRead tclsh.rc setf tcl + " M$ Resource files au BufNewFile,BufRead *.rc,*.rch setf rc @@ -1801,7 +1807,7 @@ au BufRead,BufNewFile {pending,completed,undo}.data setf taskdata au BufRead,BufNewFile *.task setf taskedit " Tcl (JACL too) -au BufNewFile,BufRead *.tcl,*.tk,*.itcl,*.itk,*.jacl setf tcl +au BufNewFile,BufRead *.tcl,*.tm,*.tk,*.itcl,*.itk,*.jacl,.tclshrc,.wishrc setf tcl " TealInfo au BufNewFile,BufRead *.tli setf tli @@ -1998,14 +2004,15 @@ au BufNewFile,BufRead *.ws[fc] setf wsh " XHTML au BufNewFile,BufRead *.xhtml,*.xht setf xhtml -" X Pixmap (dynamically sets colors, use BufEnter to make it work better) -au BufEnter *.xpm +" X Pixmap (dynamically sets colors, this used to trigger on BufEnter to make +" it work better, but that breaks setting 'filetype' manually) +au BufNewFile,BufRead *.xpm \ if getline(1) =~ "XPM2" | \ setf xpm2 | \ else | \ setf xpm | \ endif -au BufEnter *.xpm2 setf xpm2 +au BufNewFile,BufRead *.xpm2 setf xpm2 " XFree86 config au BufNewFile,BufRead XF86Config diff --git a/runtime/ftplugin/nginx.vim b/runtime/ftplugin/nginx.vim new file mode 100644 index 0000000000..e808db1277 --- /dev/null +++ b/runtime/ftplugin/nginx.vim @@ -0,0 +1,6 @@ +" Vim filetype plugin +" Language: nginx.conf +" Maintainer: Chris Aumann <me@chr4.org> +" Last Change: Apr 15, 2017 + +setlocal commentstring=#\ %s diff --git a/runtime/ftplugin/spec.vim b/runtime/ftplugin/spec.vim index ce00021a69..75eebec56a 100644 --- a/runtime/ftplugin/spec.vim +++ b/runtime/ftplugin/spec.vim @@ -18,8 +18,8 @@ if !exists("no_plugin_maps") && !exists("no_spec_maps") endif endif -if !hasmapto("call <SID>SpecChangelog(\"\")<CR>") - noremap <buffer> <unique> <script> <Plug>SpecChangelog :call <SID>SpecChangelog("")<CR> +if !hasmapto("call SpecChangelog(\"\")<CR>") + noremap <buffer> <unique> <script> <Plug>SpecChangelog :call SpecChangelog("")<CR> endif if !exists("*s:GetRelVer") diff --git a/runtime/indent/cdl.vim b/runtime/indent/cdl.vim index fb4fe27310..0e3c6152b0 100644 --- a/runtime/indent/cdl.vim +++ b/runtime/indent/cdl.vim @@ -1,5 +1,6 @@ " Description: Comshare Dimension Definition Language (CDL) -" Author: Raul Segura Acevedo <raulseguraaceved@netscape.net> +" Maintainer: Raul Segura Acevedo <raulseguraaceved@netscape.net> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> " Last Change: Fri Nov 30 13:35:48 2001 CST if exists("b:did_indent") diff --git a/runtime/indent/cobol.vim b/runtime/indent/cobol.vim index 590a729df4..01f7212602 100644 --- a/runtime/indent/cobol.vim +++ b/runtime/indent/cobol.vim @@ -7,6 +7,7 @@ " Ankit Jain 22.03.2019 Changes & fixes: " Allow chars in 1st 6 columns " #C22032019 +" Ankit Jain 24.09.2021 add b:undo_indent (request by tpope) if exists("b:did_indent") finish @@ -18,6 +19,8 @@ setlocal indentexpr=GetCobolIndent(v:lnum) setlocal indentkeys& setlocal indentkeys+=0<*>,0/,0$,0=01,=~division,=~section,0=~end,0=~then,0=~else,0=~when,*<Return>,. +let b:undo_indent = "setlocal expandtab< indentexpr< indentkeys<" + " Only define the function once. if exists("*GetCobolIndent") finish diff --git a/runtime/indent/config.vim b/runtime/indent/config.vim index c987a78d64..b840b1e391 100644 --- a/runtime/indent/config.vim +++ b/runtime/indent/config.vim @@ -1,9 +1,10 @@ " Vim indent file -" Language: Autoconf configure.{ac,in} file -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2006-12-20 -" TODO: how about nested [()]'s in one line -" what's wrong with '\\\@!'? +" Language: Autoconf configure.{ac,in} file +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 + +" TODO: how about nested [()]'s in one line what's wrong with '\\\@!'? " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -16,6 +17,8 @@ setlocal indentexpr=GetConfigIndent() setlocal indentkeys=!^F,o,O,=then,=do,=else,=elif,=esac,=fi,=fin,=fil,=done setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + " Only define the function once. if exists("*GetConfigIndent") finish diff --git a/runtime/indent/css.vim b/runtime/indent/css.vim index 4d15b8d2dc..793f05820f 100644 --- a/runtime/indent/css.vim +++ b/runtime/indent/css.vim @@ -1,8 +1,10 @@ " Vim indent file -" Language: CSS -" Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2012-05-30 -" Use of shiftwidth() added by Oleg Zubchenko. +" Language: CSS +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 + +" Use of shiftwidth() added by Oleg Zubchenko. if exists("b:did_indent") finish @@ -13,7 +15,7 @@ setlocal indentexpr=GetCSSIndent() setlocal indentkeys=0{,0},!^F,o,O setlocal nosmartindent -let b:undo_indent = "setl smartindent< indentkeys< indentexpr<" +let b:undo_indent = "setl inde< indk< si<" if exists("*GetCSSIndent") finish diff --git a/runtime/indent/d.vim b/runtime/indent/d.vim index b5dd5e8fa7..57f9125890 100644 --- a/runtime/indent/d.vim +++ b/runtime/indent/d.vim @@ -1,7 +1,7 @@ " Vim indent file for the D programming language (version 0.137). -" " Language: D -" Maintainer: Jason Mills<jmills@cs.mun.ca> +" Maintainer: Jason Mills <jmills@cs.mun.ca> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> " Last Change: 2005 Nov 22 " Version: 0.1 " diff --git a/runtime/indent/dtd.vim b/runtime/indent/dtd.vim index 30c06aa8b2..c2b3c0c58e 100644 --- a/runtime/indent/dtd.vim +++ b/runtime/indent/dtd.vim @@ -1,12 +1,15 @@ " Vim indent file -" Language: DTD (Document Type Definition for XML) -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2011-07-08 +" Language: DTD (Document Type Definition for XML) +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 setlocal indentexpr=GetDTDIndent() setlocal indentkeys=!^F,o,O,> setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + if exists("*GetDTDIndent") finish endif diff --git a/runtime/indent/dylan.vim b/runtime/indent/dylan.vim index 6811ec4af5..55255ddfa9 100644 --- a/runtime/indent/dylan.vim +++ b/runtime/indent/dylan.vim @@ -1,8 +1,9 @@ " Vim indent file " Language: Dylan +" Maintainer: Brent A. Fulgham <bfulgham@debian.org> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> " Version: 0.01 " Last Change: 2017 Jun 13 -" Maintainer: Brent A. Fulgham <bfulgham@debian.org> " Only load this indent file when no other was loaded. if exists("b:did_indent") diff --git a/runtime/indent/elm.vim b/runtime/indent/elm.vim index 232c347c66..7b08de7126 100644 --- a/runtime/indent/elm.vim +++ b/runtime/indent/elm.vim @@ -4,7 +4,7 @@ " Original Author: Joseph Hager <ajhager@gmail.com> " Copyright: Joseph Hager <ajhager@gmail.com> " License: BSD3 -" Latest Revision: 2020-05-29 +" Latest Revision: 2021-09-29 " Only load this indent file when no other was loaded. if exists('b:did_indent') @@ -19,6 +19,8 @@ setlocal indentkeys+=0=else,0=if,0=of,0=import,0=then,0=type,0\|,0},0\],0),=-},0 setlocal nolisp setlocal nosmartindent +let b:undo_indent = "setl et< inde< indk< lisp< si<" + " Only define the function once. if exists('*GetElmIndent') finish diff --git a/runtime/indent/eterm.vim b/runtime/indent/eterm.vim index 8ee342fcfa..3accf9bff1 100644 --- a/runtime/indent/eterm.vim +++ b/runtime/indent/eterm.vim @@ -1,7 +1,8 @@ " Vim indent file -" Language: Eterm configuration file -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2006-12-20 +" Language: Eterm configuration file +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 if exists("b:did_indent") finish @@ -12,6 +13,8 @@ setlocal indentexpr=GetEtermIndent() setlocal indentkeys=!^F,o,O,=end setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + if exists("*GetEtermIndent") finish endif diff --git a/runtime/indent/framescript.vim b/runtime/indent/framescript.vim index f9a274eab6..4611d34e85 100644 --- a/runtime/indent/framescript.vim +++ b/runtime/indent/framescript.vim @@ -1,7 +1,8 @@ " Vim indent file -" Language: FrameScript -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2008-07-19 +" Language: FrameScript +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 if exists("b:did_indent") finish @@ -12,6 +13,8 @@ setlocal indentexpr=GetFrameScriptIndent() setlocal indentkeys=!^F,o,O,0=~Else,0=~EndIf,0=~EndLoop,0=~EndSub setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + if exists("*GetFrameScriptIndent") finish endif diff --git a/runtime/indent/idlang.vim b/runtime/indent/idlang.vim index 7402e8688e..e6a1d73775 100644 --- a/runtime/indent/idlang.vim +++ b/runtime/indent/idlang.vim @@ -1,7 +1,8 @@ " IDL (Interactive Data Language) indent file. -" Language: IDL (ft=idlang) +" Language: IDL (ft=idlang) +" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> " Last change: 2017 Jun 13 -" Maintainer: Aleksandar Jelenak <ajelenak AT yahoo.com> " Only load this indent file when no other was loaded. if exists("b:did_indent") diff --git a/runtime/indent/ld.vim b/runtime/indent/ld.vim index a72a3a9548..ddf003e2de 100644 --- a/runtime/indent/ld.vim +++ b/runtime/indent/ld.vim @@ -1,7 +1,8 @@ " Vim indent file -" Language: ld(1) script -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2006-12-20 +" Language: ld(1) script +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 if exists("b:did_indent") finish @@ -12,6 +13,8 @@ setlocal indentexpr=GetLDIndent() setlocal indentkeys=0{,0},!^F,o,O setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + if exists("*GetLDIndent") finish endif diff --git a/runtime/indent/mail.vim b/runtime/indent/mail.vim index 6246b407e9..22bb0f7e12 100644 --- a/runtime/indent/mail.vim +++ b/runtime/indent/mail.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Mail " Maintainer: Bram Moolenaar -" Last Change: 2009 Jun 03 +" Last Change: 2021 Sep 26 if exists("b:did_indent") finish @@ -11,3 +11,5 @@ let b:did_indent = 1 " What works best is auto-indenting, disable other indenting. " For formatting see the ftplugin. setlocal autoindent nosmartindent nocindent indentexpr= + +let b:undo_indent = "setl ai< cin< inde< si<" diff --git a/runtime/indent/make.vim b/runtime/indent/make.vim index 4483efdbd8..76c8f83399 100644 --- a/runtime/indent/make.vim +++ b/runtime/indent/make.vim @@ -1,7 +1,8 @@ " Vim indent file -" Language: Makefile -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2007-05-07 +" Language: Makefile +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 if exists("b:did_indent") finish @@ -12,6 +13,8 @@ setlocal indentexpr=GetMakeIndent() setlocal indentkeys=!^F,o,O,<:>,=else,=endif setlocal nosmartindent +let b:undo_indent = "setl ai< inde< indk<" + if exists("*GetMakeIndent") finish endif diff --git a/runtime/indent/matlab.vim b/runtime/indent/matlab.vim index 6390445c60..10d84602af 100644 --- a/runtime/indent/matlab.vim +++ b/runtime/indent/matlab.vim @@ -2,6 +2,7 @@ " Language: MATLAB " Maintainer: Axel Forsman <axelsfor@gmail.com> " Previous maintainer: Christophe Poucet <christophe.poucet@pandora.be> +" Last Update: 2021-10-01 " Only load if no other indent file is loaded if exists('b:did_indent') | finish | endif @@ -9,6 +10,7 @@ let b:did_indent = 1 setlocal indentexpr=GetMatlabIndent() setlocal indentkeys=!,o,O,e,0=end,0=elseif,0=case,0=otherwise,0=catch,0=function,0=elsei +let b:undo_indent = "setlocal indentexpr< indentkeys<" " The value of the Function indenting format in " MATLAB Editor/Debugger Language Preferences. diff --git a/runtime/indent/mma.vim b/runtime/indent/mma.vim index a76fa8ede0..ebf98b9a38 100644 --- a/runtime/indent/mma.vim +++ b/runtime/indent/mma.vim @@ -1,9 +1,10 @@ " Vim indent file -" Language: Mathematica -" Author: steve layland <layland@wolfram.com> -" Last Change: Sat May 10 18:56:22 CDT 2005 -" Source: http://vim.sourceforge.net/scripts/script.php?script_id=1274 -" http://members.wolfram.com/layland/vim/indent/mma.vim +" Language: Mathematica +" Maintainer: Steve Layland <layland@wolfram.com> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> +" Last Change: Sat May 10 18:56:22 CDT 2005 +" Source: http://vim.sourceforge.net/scripts/script.php?script_id=1274 +" http://members.wolfram.com/layland/vim/indent/mma.vim " " NOTE: " Empty .m files will automatically be presumed to be Matlab files diff --git a/runtime/indent/nginx.vim b/runtime/indent/nginx.vim new file mode 100644 index 0000000000..d4afec1c11 --- /dev/null +++ b/runtime/indent/nginx.vim @@ -0,0 +1,17 @@ +" Vim indent file +" Language: nginx.conf +" Maintainer: Chris Aumann <me@chr4.org> +" Last Change: Apr 15, 2017 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal indentexpr= + +" cindent actually works for nginx' simple file structure +setlocal cindent + +" Just make sure that the comments are not reset as defs would be. +setlocal cinkeys-=0# diff --git a/runtime/indent/occam.vim b/runtime/indent/occam.vim index 4acd42e3c8..2979ac16ac 100644 --- a/runtime/indent/occam.vim +++ b/runtime/indent/occam.vim @@ -1,6 +1,7 @@ " Vim indent file " Language: occam -" Maintainer: Mario Schweigler <ms44@kent.ac.uk> +" Maintainer: Mario Schweigler <ms44@kent.ac.uk> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> " Last Change: 23 April 2003 " Only load this indent file when no other was loaded. diff --git a/runtime/indent/pascal.vim b/runtime/indent/pascal.vim index 1f39fd1cad..b21b7256b2 100644 --- a/runtime/indent/pascal.vim +++ b/runtime/indent/pascal.vim @@ -2,11 +2,9 @@ " Language: Pascal " Maintainer: Neil Carter <n.carter@swansea.ac.uk> " Created: 2004 Jul 13 -" Last Change: 2021 Jul 01 +" Last Change: 2021 Sep 22 " -" This is version 2.0, a complete rewrite. -" -" For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/ +" For further documentation, see https://psy.swansea.ac.uk/staff/carter/vim/ if exists("b:did_indent") @@ -20,13 +18,14 @@ setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for setlocal indentkeys+==program,==function,==procedure,==object,==private setlocal indentkeys+==record,==if,==else,==case -let b:undo_indent = "setl indentkeys< indentexpr<" +let b:undo_indent = 'setlocal indentexpr< indentkeys<' if exists("*GetPascalIndent") finish endif +" ________________________________________________________________ function! s:GetPrevNonCommentLineNum( line_num ) " Skip lines starting with a comment @@ -44,6 +43,7 @@ function! s:GetPrevNonCommentLineNum( line_num ) endfunction +" ________________________________________________________________ function! s:PurifyCode( line_num ) " Strip any trailing comments and whitespace let pureline = 'TODO' @@ -51,6 +51,7 @@ function! s:PurifyCode( line_num ) endfunction +" ________________________________________________________________ function! GetPascalIndent( line_num ) " Line 0 always goes at column 0 @@ -184,7 +185,7 @@ function! GetPascalIndent( line_num ) endif -" ____________________________________________________________________ +" ________________________________________________________________ " Object/Borland Pascal/Delphi Extensions " " Note that extended-pascal is handled here, unless it is simpler to @@ -222,8 +223,6 @@ function! GetPascalIndent( line_num ) endif -" ____________________________________________________________________ - " If nothing changed, return same indent. return indnt endfunction diff --git a/runtime/indent/postscr.vim b/runtime/indent/postscr.vim index 2592bcf62f..0691cd237c 100644 --- a/runtime/indent/postscr.vim +++ b/runtime/indent/postscr.vim @@ -1,7 +1,8 @@ " PostScript indent file -" Language: PostScript -" Maintainer: Mike Williams <mrw@netcomuk.co.uk> -" Last Change: 2nd July 2001 +" Language: PostScript +" Maintainer: Mike Williams <mrw@netcomuk.co.uk> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> +" Last Change: 2nd July 2001 " " Only load this indent file when no other was loaded. diff --git a/runtime/indent/prolog.vim b/runtime/indent/prolog.vim index ecd0894166..ac03c28064 100644 --- a/runtime/indent/prolog.vim +++ b/runtime/indent/prolog.vim @@ -1,7 +1,8 @@ " vim: set sw=4 sts=4: -" Maintainer : Gergely Kontra <kgergely@mcl.hu> -" Revised on : 2002.02.18. 23:34:05 -" Language : Prolog +" Language: Prolog +" Maintainer: Gergely Kontra <kgergely@mcl.hu> (Invalid email address) +" Doug Kearns <dougkearns@gmail.com> +" Revised on: 2002.02.18. 23:34:05 " Last change by: Takuya Fujiwara, 2018 Sep 23 " TODO: diff --git a/runtime/indent/python.vim b/runtime/indent/python.vim index 307b7f656b..668122993e 100644 --- a/runtime/indent/python.vim +++ b/runtime/indent/python.vim @@ -2,7 +2,7 @@ " Language: Python " Maintainer: Bram Moolenaar <Bram@vim.org> " Original Author: David Bustos <bustos@caltech.edu> -" Last Change: 2021 May 26 +" Last Change: 2021 Sep 26 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -17,6 +17,8 @@ setlocal autoindent " indentexpr isn't much help otherwise setlocal indentexpr=GetPythonIndent(v:lnum) setlocal indentkeys+=<:>,=elif,=except +let b:undo_indent = "setl ai< inde< indk< lisp<" + " Only define the function once. if exists("*GetPythonIndent") finish diff --git a/runtime/indent/readline.vim b/runtime/indent/readline.vim index e202ddfd89..0ab0f822c3 100644 --- a/runtime/indent/readline.vim +++ b/runtime/indent/readline.vim @@ -1,7 +1,8 @@ " Vim indent file -" Language: readline configuration file -" Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2006-12-20 +" Language: readline configuration file +" Maintainer: Doug Kearns <dougkearns@gmail.com> +" Previous Maintainer: Nikolai Weibull <now@bitwi.se> +" Last Change: 24 Sep 2021 if exists("b:did_indent") finish @@ -12,6 +13,8 @@ setlocal indentexpr=GetReadlineIndent() setlocal indentkeys=!^F,o,O,=$else,=$endif setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + if exists("*GetReadlineIndent") finish endif diff --git a/runtime/indent/sdl.vim b/runtime/indent/sdl.vim index 6ce30b6797..40fe63fa7c 100644 --- a/runtime/indent/sdl.vim +++ b/runtime/indent/sdl.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: SDL " Maintainer: Michael Piefel <entwurf@piefel.de> -" Last Change: 10 December 2011 +" Last Change: 2021 Oct 03 " Shamelessly stolen from the Vim-Script indent file @@ -14,6 +14,8 @@ let b:did_indent = 1 setlocal indentexpr=GetSDLIndent() setlocal indentkeys+==~end,=~state,*<Return> +let b:undo_indent = "setl inde< indk<" + " Only define the function once. if exists("*GetSDLIndent") " finish diff --git a/runtime/indent/tcl.vim b/runtime/indent/tcl.vim index eafb8dd568..c35150d0e0 100644 --- a/runtime/indent/tcl.vim +++ b/runtime/indent/tcl.vim @@ -1,8 +1,8 @@ " Vim indent file -" Language: Tcl -" Latest Update: Chris Heithoff <chrisheithoff@gmail.com> +" Language: Tcl +" Maintainer: Chris Heithoff <chrisheithoff@gmail.com> " Previous Maintainer: Nikolai Weibull <now@bitwi.se> -" Latest Revision: 2018-12-05 +" Last Change: 24 Sep 2021 if exists("b:did_indent") finish @@ -13,6 +13,8 @@ setlocal indentexpr=GetTclIndent() setlocal indentkeys=0{,0},!^F,o,O,0] setlocal nosmartindent +let b:undo_indent = "setl inde< indk< si<" + if exists("*GetTclIndent") finish endif diff --git a/runtime/indent/tcsh.vim b/runtime/indent/tcsh.vim index ed08e6c6e2..025d9c805d 100644 --- a/runtime/indent/tcsh.vim +++ b/runtime/indent/tcsh.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: C-shell (tcsh) -" Maintainer: GI <a@b.c>, where a='gi1242+vim', b='gmail', c='com' -" Last Modified: Sat 10 Dec 2011 09:23:00 AM EST +" Maintainer: Doug Kearns <a@b.com> where a=dougkearns, b=gmail +" Last Modified: Sun 26 Sep 2021 12:38:38 PM EDT " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -12,6 +12,7 @@ let b:did_indent = 1 setlocal indentexpr=TcshGetIndent() setlocal indentkeys+=e,0=end,0=endsw indentkeys-=0{,0},0),:,0# +let b:undo_indent = "setl inde< indk<" " Only define the function once. if exists("*TcshGetIndent") diff --git a/runtime/indent/zimbu.vim b/runtime/indent/zimbu.vim index 5451877ea7..0e6e2ab1d1 100644 --- a/runtime/indent/zimbu.vim +++ b/runtime/indent/zimbu.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Zimbu " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2016 Jan 25 +" Last Change: 2021 Sep 26 " Only load this indent file when no other was loaded. if exists("b:did_indent") @@ -16,7 +16,7 @@ setlocal indentkeys=0{,0},!^F,o,O,0=ELSE,0=ELSEIF,0=CASE,0=DEFAULT,0=FINALLY " We impose recommended defaults: no Tabs, 'shiftwidth' = 2 setlocal sw=2 et -let b:undo_indent = "setl et< sw< ai< indentkeys< indentexpr=" +let b:undo_indent = "setl ai< cin< et< indentkeys< indentexpr< lisp< sw<" " Only define the function once. if exists("*GetZimbuIndent") diff --git a/runtime/lua/health.lua b/runtime/lua/health.lua new file mode 100644 index 0000000000..142a353bf2 --- /dev/null +++ b/runtime/lua/health.lua @@ -0,0 +1,23 @@ +local M = {} + +function M.report_start(msg) + vim.fn['health#report_start'](msg) +end + +function M.report_info(msg) + vim.fn['health#report_info'](msg) +end + +function M.report_ok(msg) + vim.fn['health#report_ok'](msg) +end + +function M.report_warn(msg, ...) + vim.fn['health#report_warn'](msg, ...) +end + +function M.report_error(msg, ...) + vim.fn['health#report_error'](msg, ...) +end + +return M diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index c7c8c1878e..e8aba6b7a3 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -27,7 +27,10 @@ local global_diagnostic_options = { ---@private local function to_severity(severity) - return type(severity) == 'string' and M.severity[string.upper(severity)] or severity + if type(severity) == 'string' then + return assert(M.severity[string.upper(severity)], string.format("Invalid severity: %s", severity)) + end + return severity end ---@private @@ -125,9 +128,7 @@ local function get_namespace(ns) end end - if not name then - return vim.notify("namespace does not exist or is anonymous", vim.log.levels.ERROR) - end + assert(name, "namespace does not exist or is anonymous") all_namespaces[ns] = { name = name, @@ -398,6 +399,17 @@ local function show_diagnostics(opts, diagnostics) diagnostics = prefix_source(opts.source, diagnostics) end + -- Use global setting for severity_sort since 'show_diagnostics' is namespace + -- independent + local severity_sort = global_diagnostic_options.severity_sort + if severity_sort then + if type(severity_sort) == "table" and severity_sort.reverse then + table.sort(diagnostics, function(a, b) return a.severity > b.severity end) + else + table.sort(diagnostics, function(a, b) return a.severity < b.severity end) + end + end + for i, diagnostic in ipairs(diagnostics) do local prefix = string.format("%d. ", i) local hiname = floating_highlight_map[diagnostic.severity] @@ -510,6 +522,9 @@ local function diagnostic_move_pos(opts, pos) return end + -- Save position in the window's jumplist + vim.api.nvim_win_call(win_id, function() vim.cmd("normal! m'") end) + vim.api.nvim_win_set_cursor(win_id, {pos[1] + 1, pos[2]}) if enable_popup then @@ -1140,7 +1155,6 @@ function M.show_position_diagnostics(opts, bufnr, position) local diagnostics = M.get(bufnr, opts) clamp_line_numbers(bufnr, diagnostics) local position_diagnostics = vim.tbl_filter(match_position_predicate, diagnostics) - table.sort(position_diagnostics, function(a, b) return a.severity < b.severity end) return show_diagnostics(opts, position_diagnostics) end diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index c7a88a0993..a9e27cf6ac 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -41,6 +41,7 @@ lsp._request_name_to_capability = { ['textDocument/documentSymbol'] = 'document_symbol'; ['textDocument/prepareCallHierarchy'] = 'call_hierarchy'; ['textDocument/rename'] = 'rename'; + ['textDocument/prepareRename'] = 'rename'; ['textDocument/codeAction'] = 'code_action'; ['textDocument/codeLens'] = 'code_lens'; ['codeLens/resolve'] = 'code_lens_resolve'; @@ -1383,6 +1384,29 @@ function lsp.buf_notify(bufnr, method, params) return resp end + +---@private +local function adjust_start_col(lnum, line, items, encoding) + local min_start_char = nil + for _, item in pairs(items) do + if item.textEdit and item.textEdit.range.start.line == lnum - 1 then + if min_start_char and min_start_char ~= item.textEdit.range.start.character then + return nil + end + min_start_char = item.textEdit.range.start.character + end + end + if min_start_char then + if encoding == 'utf-8' then + return min_start_char + else + return vim.str_byteindex(line, min_start_char, encoding == 'utf-16') + end + else + return nil + end +end + --- Implements 'omnifunc' compatible LSP completion. --- ---@see |complete-functions| @@ -1418,17 +1442,37 @@ function lsp.omnifunc(findstart, base) -- Get the start position of the current keyword local textMatch = vim.fn.match(line_to_cursor, '\\k*$') - local prefix = line_to_cursor:sub(textMatch+1) local params = util.make_position_params() local items = {} - lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, result) + lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, result, ctx) if err or not result or vim.fn.mode() ~= "i" then return end + + -- Completion response items may be relative to a position different than `textMatch`. + -- Concrete example, with sumneko/lua-language-server: + -- + -- require('plenary.asy| + -- ▲ ▲ ▲ + -- │ │ └── cursor_pos: 20 + -- │ └────── textMatch: 17 + -- └────────────── textEdit.range.start.character: 9 + -- .newText = 'plenary.async' + -- ^^^ + -- prefix (We'd remove everything not starting with `asy`, + -- so we'd eliminate the `plenary.async` result + -- + -- `adjust_start_col` is used to prefer the language server boundary. + -- + local client = lsp.get_client_by_id(ctx.client_id) + local encoding = client and client.offset_encoding or 'utf-16' + local candidates = util.extract_completion_items(result) + local startbyte = adjust_start_col(pos[1], line, candidates, encoding) or textMatch + local prefix = line:sub(startbyte + 1, pos[2]) local matches = util.text_document_completion_list_to_complete_items(result, prefix) -- TODO(ashkan): is this the best way to do this? vim.list_extend(items, matches) - vim.fn.complete(textMatch+1, items) + vim.fn.complete(startbyte + 1, items) end) -- Return -2 to signal that we should continue completion so that we can diff --git a/runtime/lua/vim/lsp/health.lua b/runtime/lua/vim/lsp/health.lua index 855679a2df..ed3eea59df 100644 --- a/runtime/lua/vim/lsp/health.lua +++ b/runtime/lua/vim/lsp/health.lua @@ -1,7 +1,7 @@ local M = {} --- Performs a healthcheck for LSP -function M.check_health() +function M.check() local report_info = vim.fn['health#report_info'] local report_warn = vim.fn['health#report_warn'] diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 255eb65dfe..d9a684a738 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -13,36 +13,6 @@ local function is_dir(filename) return stat and stat.type == 'directory' or false end -local NIL = vim.NIL - ----@private -local recursive_convert_NIL -recursive_convert_NIL = function(v, tbl_processed) - if v == NIL then - return nil - elseif not tbl_processed[v] and type(v) == 'table' then - tbl_processed[v] = true - local inside_list = vim.tbl_islist(v) - return vim.tbl_map(function(x) - if not inside_list or (inside_list and type(x) == "table") then - return recursive_convert_NIL(x, tbl_processed) - else - return x - end - end, v) - end - - return v -end - ----@private ---- Returns its argument, but converts `vim.NIL` to Lua `nil`. ----@param v (any) Argument ----@returns (any) -local function convert_NIL(v) - return recursive_convert_NIL(v, {}) -end - ---@private --- Merges current process env with the given env and returns the result as --- a list of "k=v" strings. @@ -457,7 +427,7 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) ---@private local function handle_body(body) - local ok, decoded = pcall(vim.json.decode, body) + local ok, decoded = pcall(vim.json.decode, body, { luanil = { object = true } }) if not ok then on_error(client_errors.INVALID_SERVER_JSON, decoded) return @@ -466,8 +436,6 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) if type(decoded.method) == 'string' and decoded.id then local err - -- Server Request - decoded.params = convert_NIL(decoded.params) -- Schedule here so that the users functions don't trigger an error and -- we can still use the result. schedule(function() @@ -494,22 +462,16 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) end) -- This works because we are expecting vim.NIL here elseif decoded.id and (decoded.result ~= vim.NIL or decoded.error ~= vim.NIL) then - -- Server Result - decoded.error = convert_NIL(decoded.error) - decoded.result = convert_NIL(decoded.result) -- We sent a number, so we expect a number. local result_id = tonumber(decoded.id) - -- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal. + -- Do not surface RequestCancelled to users, it is RPC-internal. if decoded.error then local mute_error = false if decoded.error.code == protocol.ErrorCodes.RequestCancelled then local _ = log.debug() and log.debug("Received cancellation ack", decoded) mute_error = true - elseif decoded.error.code == protocol.ErrorCodes.ContentModified then - local _ = log.debug() and log.debug("Received content modified ack", decoded) - mute_error = true end if mute_error then @@ -544,7 +506,6 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) end elseif type(decoded.method) == 'string' then -- Notification - decoded.params = convert_NIL(decoded.params) try_call(client_errors.NOTIFICATION_HANDLER_ERROR, dispatchers.notification, decoded.method, decoded.params) else diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index fca956fb57..3751f94caf 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -193,6 +193,7 @@ function M.get_progress_messages() title = ctx.title or "empty title", message = ctx.message, percentage = ctx.percentage, + done = ctx.done, progress = true, } table.insert(new_messages, new_report) diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 18c1e21049..b57b7ad4ad 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -98,17 +98,53 @@ end --- <pre> --- split(":aa::b:", ":") --> {'','aa','','b',''} --- split("axaby", "ab?") --> {'','x','y'} ---- split(x*yz*o, "*", true) --> {'x','yz','o'} +--- split("x*yz*o", "*", {plain=true}) --> {'x','yz','o'} +--- split("|x|y|z|", "|", {trimempty=true}) --> {'x', 'y', 'z'} --- </pre> --- +--- ---@see |vim.gsplit()| --- ---@param s String to split ---@param sep Separator string or pattern ----@param plain If `true` use `sep` literally (passed to String.find) +---@param kwargs Keyword arguments: +--- - plain: (boolean) If `true` use `sep` literally (passed to string.find) +--- - trimempty: (boolean) If `true` remove empty items from the front +--- and back of the list ---@returns List-like table of the split components. -function vim.split(s,sep,plain) - local t={} for c in vim.gsplit(s, sep, plain) do table.insert(t,c) end +function vim.split(s, sep, kwargs) + local plain + local trimempty = false + if type(kwargs) == 'boolean' then + -- Support old signature for backward compatibility + plain = kwargs + else + vim.validate { kwargs = {kwargs, 't', true} } + kwargs = kwargs or {} + plain = kwargs.plain + trimempty = kwargs.trimempty + end + + local t = {} + local skip = trimempty + for c in vim.gsplit(s, sep, plain) do + if c ~= "" then + skip = false + end + + if not skip then + table.insert(t, c) + end + end + + if trimempty then + for i = #t, 1, -1 do + if t[i] ~= "" then + break + end + table.remove(t, i) + end + end + return t end diff --git a/runtime/lua/vim/treesitter/health.lua b/runtime/lua/vim/treesitter/health.lua index e031ba1bd6..53ccc6e88d 100644 --- a/runtime/lua/vim/treesitter/health.lua +++ b/runtime/lua/vim/treesitter/health.lua @@ -9,7 +9,7 @@ function M.list_parsers() end --- Performs a healthcheck for treesitter integration -function M.check_health() +function M.check() local report_info = vim.fn['health#report_info'] local report_ok = vim.fn['health#report_ok'] local report_error = vim.fn['health#report_error'] diff --git a/runtime/plugin/diagnostic.vim b/runtime/plugin/diagnostic.vim deleted file mode 100644 index 2183623ac8..0000000000 --- a/runtime/plugin/diagnostic.vim +++ /dev/null @@ -1,26 +0,0 @@ -" :help vim.diagnostic - -hi default DiagnosticError ctermfg=1 guifg=Red -hi default DiagnosticWarn ctermfg=3 guifg=Orange -hi default DiagnosticInfo ctermfg=4 guifg=LightBlue -hi default DiagnosticHint ctermfg=7 guifg=LightGrey - -hi default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red -hi default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange -hi default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue -hi default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey - -hi default link DiagnosticVirtualTextError DiagnosticError -hi default link DiagnosticVirtualTextWarn DiagnosticWarn -hi default link DiagnosticVirtualTextInfo DiagnosticInfo -hi default link DiagnosticVirtualTextHint DiagnosticHint - -hi default link DiagnosticFloatingError DiagnosticError -hi default link DiagnosticFloatingWarn DiagnosticWarn -hi default link DiagnosticFloatingInfo DiagnosticInfo -hi default link DiagnosticFloatingHint DiagnosticHint - -hi default link DiagnosticSignError DiagnosticError -hi default link DiagnosticSignWarn DiagnosticWarn -hi default link DiagnosticSignInfo DiagnosticInfo -hi default link DiagnosticSignHint DiagnosticHint diff --git a/runtime/syntax/8th.vim b/runtime/syntax/8th.vim index d543489b72..ce27d10a44 100644 --- a/runtime/syntax/8th.vim +++ b/runtime/syntax/8th.vim @@ -1,6 +1,7 @@ " Vim syntax file " Language: 8th -" Version: 19.01d +" Version: 21.08 +" Last Change: 2021 Sep 20 " Maintainer: Ron Aaron <ron@aaron-tech.com> " URL: https://8th-dev.com/ " Filetypes: *.8th @@ -30,246 +31,318 @@ syn match eighthClassWord "\<\S\+:.\+" contains=eighthClasses syn keyword eighthEndOfColonDef ; i; syn keyword eighthDefine var var, -" Built in words +" Built in words: com! -nargs=+ Builtin syn keyword eighthBuiltin <args> -"Builtin ^ < <# <#> = > - -- ,# ; ;; ! ??? / . .# ' () @ * */ \ -Builtin ! G:! #! G:#! ## G:## #> G:#> #if G:#if ' G:' ( G:( (* G:(* (:) G:(:) (code) G:(code) (getc) G:(getc) -Builtin (gets) G:(gets) (interp) G:(interp) (needs) G:(needs) (putc) G:(putc) (puts) G:(puts) (putslim) G:(putslim) -Builtin (say) G:(say) (stat) G:(stat) ) G:) +listener G:+listener +ref G:+ref ,# G:,# -- G:-- -----BEGIN G:-----BEGIN -Builtin -Inf G:-Inf -Inf? G:-Inf? -listener G:-listener -ref G:-ref -rot G:-rot . G:. .# G:.# .needs G:.needs -Builtin .r G:.r .s G:.s .stats G:.stats .ver G:.ver .with G:.with 0; G:0; 2dip G:2dip 2drop G:2drop -Builtin 2dup G:2dup 2over G:2over 2swap G:2swap 3drop G:3drop 4drop G:4drop 8thdt? G:8thdt? 8thver? G:8thver? -Builtin : G:: ; G:; ;; G:;; ;;; G:;;; ;then G:;then ;with G:;with <# G:<# <#> G:<#> >clip G:>clip >json G:>json -Builtin >kind G:>kind >n G:>n >r G:>r >s G:>s ?: G:?: ??? G:??? @ G:@ Inf G:Inf Inf? G:Inf? NaN G:NaN -Builtin NaN? G:NaN? SED-CHECK G:SED-CHECK SED: G:SED: SED: G:SED: \ G:\ ` G:` `` G:`` actor: G:actor: -Builtin again G:again ahead G:ahead and G:and appname G:appname apropos G:apropos argc G:argc args G:args -Builtin array? G:array? assert G:assert base G:base bi G:bi bits G:bits break G:break break? G:break? -Builtin build? G:build? buildver? G:buildver? bye G:bye c# G:c# c/does G:c/does case G:case caseof G:caseof -Builtin chdir G:chdir clip> G:clip> clone G:clone clone-shallow G:clone-shallow cold G:cold compat-level G:compat-level -Builtin compile G:compile compile? G:compile? conflict G:conflict const G:const container? G:container? -Builtin cr G:cr curlang G:curlang curry G:curry curry: G:curry: decimal G:decimal defer: G:defer: deg>rad G:deg>rad -Builtin depth G:depth die G:die dip G:dip drop G:drop dstack G:dstack dump G:dump dup G:dup dup? G:dup? -Builtin else G:else enum: G:enum: eval G:eval eval! G:eval! eval0 G:eval0 execnull G:execnull expect G:expect -Builtin extra! G:extra! extra@ G:extra@ false G:false fnv G:fnv fourth G:fourth free G:free func: G:func: -Builtin getc G:getc getcwd G:getcwd getenv G:getenv gets G:gets handler G:handler header G:header help G:help -Builtin hex G:hex i: G:i: i; G:i; if G:if if; G:if; isa? G:isa? items-used G:items-used jcall G:jcall -Builtin jclass G:jclass jmethod G:jmethod json-nesting G:json-nesting json-pretty G:json-pretty json-throw G:json-throw -Builtin json> G:json> k32 G:k32 keep G:keep l: G:l: last G:last lib G:lib libbin G:libbin libc G:libc +Builtin args #:args b #:b dhm #:dhm exec# #:exec# id2ns #:id2ns id? #:id? idd #:idd key #:key oa #:oa +Builtin oid #:oid okey #:okey with #:with with! #:with! zip #:zip gen-secret 2fa:gen-secret gen-url 2fa:gen-url +Builtin validate-code 2fa:validate-code ! G:! #! G:#! ## G:## #> G:#> #if G:#if ' G:' ( G:( (* G:(* +Builtin (:) G:(:) (code) G:(code) (defer) G:(defer) (dump) G:(dump) (getc) G:(getc) (gets) G:(gets) +Builtin (interp) G:(interp) (log) G:(log) (needs) G:(needs) (parseln) G:(parseln) (putc) G:(putc) (puts) G:(puts) +Builtin (putslim) G:(putslim) (stat) G:(stat) (with) G:(with) ) G:) +hook G:+hook +listener G:+listener +Builtin +ref G:+ref ,# G:,# -- G:-- -----BEGIN G:-----BEGIN -Inf G:-Inf -Inf? G:-Inf? -hook G:-hook +Builtin -listener G:-listener -ref G:-ref -rot G:-rot . G:. .# G:.# .hook G:.hook .needs G:.needs .r G:.r +Builtin .s G:.s .s-truncate G:.s-truncate .stats G:.stats .ver G:.ver .with G:.with 0; G:0; 2dip G:2dip +Builtin 2drop G:2drop 2dup G:2dup 2over G:2over 2swap G:2swap 3drop G:3drop 3rev G:3rev 4drop G:4drop +Builtin 8thdt? G:8thdt? 8thsku G:8thsku 8thver? G:8thver? 8thvernum? G:8thvernum? : G:: ; G:; ;; G:;; +Builtin ;;; G:;;; ;with G:;with <# G:<# <#> G:<#> >clip G:>clip >json G:>json >kind G:>kind >n G:>n +Builtin >r G:>r >s G:>s ?: G:?: @ G:@ BITMAP: G:BITMAP: ENUM: G:ENUM: FLAG: G:FLAG: Inf G:Inf Inf? G:Inf? +Builtin NaN G:NaN NaN? G:NaN? SED-CHECK G:SED-CHECK SED: G:SED: SED: G:SED: \ G:\ _dup G:_dup _swap G:_swap +Builtin actor: G:actor: again G:again ahead G:ahead and G:and appname G:appname apropos G:apropos argc G:argc +Builtin args G:args array? G:array? assert G:assert base G:base bi G:bi bits G:bits break G:break break? G:break? +Builtin breakif G:breakif build? G:build? buildver? G:buildver? bye G:bye c# G:c# c/does G:c/does case: G:case: +Builtin catch G:catch chdir G:chdir clip> G:clip> clone G:clone clone-shallow G:clone-shallow cold G:cold +Builtin compile G:compile compile? G:compile? compiling? G:compiling? conflict G:conflict const G:const +Builtin container? G:container? counting-allocations G:counting-allocations cr G:cr curlang G:curlang +Builtin curry G:curry curry: G:curry: decimal G:decimal default: G:default: defer: G:defer: deferred: G:deferred: +Builtin deg>rad G:deg>rad depth G:depth die G:die dip G:dip drop G:drop dstack G:dstack dump G:dump +Builtin dup G:dup dup>r G:dup>r dup? G:dup? e# G:e# enum: G:enum: error? G:error? eval G:eval eval! G:eval! +Builtin eval0 G:eval0 execnull G:execnull expect G:expect extra! G:extra! extra@ G:extra@ false G:false +Builtin fnv G:fnv fourth G:fourth free G:free func: G:func: getc G:getc getcwd G:getcwd getenv G:getenv +Builtin gets G:gets handler G:handler header G:header help G:help hex G:hex i: G:i: i; G:i; isa? G:isa? +Builtin items-used G:items-used jcall G:jcall jclass G:jclass jmethod G:jmethod json! G:json! json-8th> G:json-8th> +Builtin json-nesting G:json-nesting json-pretty G:json-pretty json-throw G:json-throw json> G:json> +Builtin json@ G:json@ k32 G:k32 keep G:keep l: G:l: last G:last lib G:lib libbin G:libbin libc G:libc Builtin listener@ G:listener@ literal G:literal locals: G:locals: lock G:lock lock-to G:lock-to locked? G:locked? -Builtin log G:log log-async G:log-async log-task G:log-task log-time G:log-time log-time-local G:log-time-local -Builtin long-days G:long-days long-months G:long-months loop G:loop loop- G:loop- map? G:map? mark G:mark -Builtin mark? G:mark? memfree G:memfree mobile? G:mobile? n# G:n# name>os G:name>os name>sem G:name>sem -Builtin ndrop G:ndrop needs G:needs new G:new next-arg G:next-arg nip G:nip noop G:noop not G:not ns G:ns -Builtin ns: G:ns: ns>ls G:ns>ls ns>s G:ns>s ns? G:ns? null G:null null; G:null; null? G:null? number? G:number? -Builtin off G:off on G:on onexit G:onexit only G:only op! G:op! or G:or os G:os os-names G:os-names -Builtin os>long-name G:os>long-name os>name G:os>name over G:over p: G:p: pack G:pack parse G:parse -Builtin parsech G:parsech parseln G:parseln parsews G:parsews pick G:pick poke G:poke pool-clear G:pool-clear -Builtin prior G:prior private G:private process-args G:process-args prompt G:prompt public G:public -Builtin putc G:putc puts G:puts putslim G:putslim quote G:quote r! G:r! r> G:r> r@ G:r@ rad>deg G:rad>deg -Builtin rand G:rand rand-pcg G:rand-pcg rand-pcg-seed G:rand-pcg-seed randbuf G:randbuf randbuf-pcg G:randbuf-pcg -Builtin rdrop G:rdrop recurse G:recurse recurse-stack G:recurse-stack ref@ G:ref@ reg! G:reg! reg@ G:reg@ -Builtin regbin@ G:regbin@ remaining-args G:remaining-args repeat G:repeat reset G:reset roll G:roll -Builtin rop! G:rop! rot G:rot rpick G:rpick rroll G:rroll rstack G:rstack rswap G:rswap rusage G:rusage -Builtin s>ns G:s>ns same? G:same? scriptdir G:scriptdir scriptfile G:scriptfile sem G:sem sem-post G:sem-post -Builtin sem-rm G:sem-rm sem-wait G:sem-wait sem-wait? G:sem-wait? sem>name G:sem>name semi-throw G:semi-throw -Builtin set-wipe G:set-wipe setenv G:setenv settings! G:settings! settings![] G:settings![] settings@ G:settings@ -Builtin settings@? G:settings@? settings@[] G:settings@[] sh G:sh sh$ G:sh$ short-days G:short-days -Builtin short-months G:short-months sleep G:sleep space G:space stack-check G:stack-check stack-size G:stack-size -Builtin step G:step string? G:string? struct: G:struct: swap G:swap syslang G:syslang sysregion G:sysregion +Builtin log G:log log-syslog G:log-syslog log-task G:log-task log-time G:log-time log-time-local G:log-time-local +Builtin long-days G:long-days long-months G:long-months longjmp G:longjmp lookup G:lookup loop G:loop +Builtin loop- G:loop- map? G:map? mark G:mark mark? G:mark? memfree G:memfree mobile? G:mobile? n# G:n# +Builtin name>os G:name>os name>sem G:name>sem ndrop G:ndrop needs G:needs new G:new next-arg G:next-arg +Builtin nip G:nip noop G:noop not G:not nothrow G:nothrow ns G:ns ns: G:ns: ns>ls G:ns>ls ns>s G:ns>s +Builtin ns? G:ns? null G:null null; G:null; null? G:null? number? G:number? of: G:of: off G:off on G:on +Builtin onexit G:onexit only G:only op! G:op! or G:or os G:os os-names G:os-names os>long-name G:os>long-name +Builtin os>name G:os>name over G:over p: G:p: pack G:pack parse G:parse parse-csv G:parse-csv parsech G:parsech +Builtin parseln G:parseln parsews G:parsews pick G:pick poke G:poke pool-clear G:pool-clear pool-clear-all G:pool-clear-all +Builtin prior G:prior private G:private process-args G:process-args process-args-fancy G:process-args-fancy +Builtin process-args-help G:process-args-help process-args-vars G:process-args-vars prompt G:prompt +Builtin public G:public putc G:putc puts G:puts putslim G:putslim quote G:quote r! G:r! r> G:r> r@ G:r@ +Builtin rad>deg G:rad>deg rand-jit G:rand-jit rand-jsf G:rand-jsf rand-native G:rand-native rand-normal G:rand-normal +Builtin rand-pcg G:rand-pcg rand-pcg-seed G:rand-pcg-seed rand-range G:rand-range rand-select G:rand-select +Builtin randbuf-pcg G:randbuf-pcg random G:random rdrop G:rdrop recurse G:recurse recurse-stack G:recurse-stack +Builtin ref@ G:ref@ reg! G:reg! reg@ G:reg@ regbin@ G:regbin@ remaining-args G:remaining-args repeat G:repeat +Builtin required? G:required? requires G:requires reset G:reset roll G:roll rop! G:rop! rot G:rot rpick G:rpick +Builtin rroll G:rroll rstack G:rstack rswap G:rswap rusage G:rusage s>ns G:s>ns same? G:same? scriptdir G:scriptdir +Builtin scriptfile G:scriptfile sem G:sem sem-post G:sem-post sem-rm G:sem-rm sem-wait G:sem-wait sem-wait? G:sem-wait? +Builtin sem>name G:sem>name semi-throw G:semi-throw set-wipe G:set-wipe setenv G:setenv setjmp G:setjmp +Builtin settings! G:settings! settings![] G:settings![] settings@ G:settings@ settings@? G:settings@? +Builtin settings@[] G:settings@[] sh G:sh sh$ G:sh$ short-days G:short-days short-months G:short-months +Builtin sleep G:sleep sleep-until G:sleep-until slog G:slog space G:space stack-check G:stack-check +Builtin stack-size G:stack-size step G:step sthrow G:sthrow string? G:string? struct: G:struct: swap G:swap Builtin tab-hook G:tab-hook tell-conflict G:tell-conflict tempdir G:tempdir tempfilename G:tempfilename -Builtin then G:then third G:third throw G:throw thrownull G:thrownull times G:times tlog G:tlog tri G:tri -Builtin true G:true tuck G:tuck type-check G:type-check typeassert G:typeassert unlock G:unlock unpack G:unpack -Builtin until G:until until! G:until! var G:var var, G:var, while G:while while! G:while! with: G:with: +Builtin third G:third throw G:throw thrownull G:thrownull times G:times tlog G:tlog tri G:tri true G:true +Builtin tuck G:tuck type-check G:type-check typeassert G:typeassert uid G:uid uname G:uname unlock G:unlock +Builtin unpack G:unpack until G:until until! G:until! while G:while while! G:while! with: G:with: word? G:word? Builtin words G:words words-like G:words-like words/ G:words/ xchg G:xchg xor G:xor >auth HTTP:>auth -Builtin sh I:sh tpush I:tpush trace-word I:trace-word call JSONRPC:call auth-string OAuth:auth-string -Builtin gen-nonce OAuth:gen-nonce params OAuth:params call SOAP:call ! a:! + a:+ - a:- 2each a:2each -Builtin 2map a:2map 2map+ a:2map+ 2map= a:2map= = a:= >map a:>map @ a:@ @@ a:@@ bsearch a:bsearch clear a:clear -Builtin close a:close diff a:diff dot a:dot each a:each each-slice a:each-slice exists? a:exists? filter a:filter -Builtin generate a:generate group a:group indexof a:indexof insert a:insert intersect a:intersect join a:join -Builtin len a:len map a:map map+ a:map+ map= a:map= mean a:mean mean&variance a:mean&variance new a:new -Builtin op a:op op! a:op! op= a:op= open a:open pop a:pop push a:push qsort a:qsort randeach a:randeach -Builtin reduce a:reduce reduce+ a:reduce+ rev a:rev shift a:shift shuffle a:shuffle slice a:slice slice+ a:slice+ -Builtin slide a:slide sort a:sort union a:union when a:when when! a:when! x a:x x-each a:x-each xchg a:xchg -Builtin y a:y zip a:zip 8thdir app:8thdir asset app:asset atrun app:atrun atrun app:atrun atrun app:atrun -Builtin basedir app:basedir current app:current datadir app:datadir exename app:exename isgui app:isgui -Builtin main app:main oncrash app:oncrash orientation app:orientation pid app:pid restart app:restart -Builtin resumed app:resumed shared? app:shared? standalone app:standalone subdir app:subdir suspended app:suspended -Builtin sysquit app:sysquit (here) asm:(here) >n asm:>n avail asm:avail c, asm:c, here! asm:here! n> asm:n> -Builtin used asm:used w, asm:w, ! b:! + b:+ / b:/ = b:= >base64 b:>base64 >hex b:>hex >mpack b:>mpack -Builtin @ b:@ append b:append base64> b:base64> bit! b:bit! bit@ b:bit@ clear b:clear compress b:compress -Builtin conv b:conv each b:each each-slice b:each-slice expand b:expand fill b:fill getb b:getb hex> b:hex> -Builtin len b:len mem> b:mem> move b:move mpack-date b:mpack-date mpack-ignore b:mpack-ignore mpack> b:mpack> -Builtin new b:new op b:op rev b:rev search b:search shmem b:shmem slice b:slice splice b:splice ungetb b:ungetb -Builtin writable b:writable xor b:xor +block bc:+block .blocks bc:.blocks add-block bc:add-block block-hash bc:block-hash +Builtin (curry) I:(curry) notimpl I:notimpl sh I:sh trace-word I:trace-word call JSONRPC:call auth-string OAuth:auth-string +Builtin gen-nonce OAuth:gen-nonce params OAuth:params call SOAP:call ! a:! + a:+ - a:- / a:/ 2each a:2each +Builtin 2map a:2map 2map+ a:2map+ 2map= a:2map= = a:= @ a:@ @? a:@? _@ a:_@ all a:all any a:any bsearch a:bsearch +Builtin centroid a:centroid clear a:clear close a:close diff a:diff dot a:dot each a:each each! a:each! +Builtin each-slice a:each-slice exists? a:exists? filter a:filter generate a:generate group a:group +Builtin indexof a:indexof insert a:insert intersect a:intersect join a:join len a:len map a:map map+ a:map+ +Builtin map= a:map= mean a:mean mean&variance a:mean&variance merge a:merge new a:new op! a:op! open a:open +Builtin pop a:pop push a:push qsort a:qsort randeach a:randeach reduce a:reduce reduce+ a:reduce+ remove a:remove +Builtin rev a:rev shift a:shift shuffle a:shuffle slice a:slice slice+ a:slice+ slide a:slide smear a:smear +Builtin sort a:sort union a:union x a:x x-each a:x-each xchg a:xchg y a:y zip a:zip 8thdir app:8thdir +Builtin asset app:asset atrun app:atrun atrun app:atrun atrun app:atrun basedir app:basedir current app:current +Builtin datadir app:datadir exename app:exename lowmem app:lowmem main app:main name app:name oncrash app:oncrash +Builtin opts! app:opts! opts@ app:opts@ orientation app:orientation orientation! app:orientation! pid app:pid +Builtin post-main app:post-main pre-main app:pre-main raise app:raise request-perm app:request-perm +Builtin restart app:restart resumed app:resumed signal app:signal standalone app:standalone subdir app:subdir +Builtin suspended app:suspended sysquit app:sysquit terminated app:terminated trap app:trap (here) asm:(here) +Builtin >n asm:>n avail asm:avail c, asm:c, here! asm:here! n> asm:n> used asm:used w, asm:w, ! b:! +Builtin + b:+ / b:/ 1+ b:1+ 1- b:1- = b:= >base16 b:>base16 >base32 b:>base32 >base64 b:>base64 >base85 b:>base85 +Builtin >hex b:>hex >mpack b:>mpack @ b:@ append b:append base16> b:base16> base32> b:base32> base64> b:base64> +Builtin base85> b:base85> bit! b:bit! bit@ b:bit@ clear b:clear compress b:compress conv b:conv each b:each +Builtin each! b:each! each-slice b:each-slice expand b:expand fill b:fill getb b:getb hex> b:hex> len b:len +Builtin mem> b:mem> move b:move mpack-compat b:mpack-compat mpack-date b:mpack-date mpack-ignore b:mpack-ignore +Builtin mpack> b:mpack> n! b:n! n+ b:n+ n@ b:n@ new b:new op b:op pad b:pad rev b:rev search b:search +Builtin shmem b:shmem slice b:slice splice b:splice ungetb b:ungetb unpad b:unpad writable b:writable +Builtin xor b:xor +block bc:+block .blocks bc:.blocks add-block bc:add-block block-hash bc:block-hash Builtin block@ bc:block@ first-block bc:first-block hash bc:hash last-block bc:last-block load bc:load Builtin new bc:new save bc:save set-sql bc:set-sql validate bc:validate validate-block bc:validate-block Builtin add bloom:add filter bloom:filter in? bloom:in? accept bt:accept ch! bt:ch! ch@ bt:ch@ connect bt:connect -Builtin disconnect bt:disconnect err? bt:err? leconnect bt:leconnect lescan bt:lescan listen bt:listen +Builtin disconnect bt:disconnect init bt:init leconnect bt:leconnect lescan bt:lescan listen bt:listen Builtin on? bt:on? read bt:read scan bt:scan service? bt:service? services? bt:services? write bt:write Builtin * c:* * c:* + c:+ + c:+ = c:= = c:= >ri c:>ri >ri c:>ri abs c:abs abs c:abs arg c:arg arg c:arg -Builtin conj c:conj conj c:conj im c:im n> c:n> new c:new new c:new re c:re >aes128gcm cr:>aes128gcm -Builtin >aes256gcm cr:>aes256gcm >cp cr:>cp >cpe cr:>cpe >decrypt cr:>decrypt >edbox cr:>edbox >encrypt cr:>encrypt -Builtin >nbuf cr:>nbuf >rsabox cr:>rsabox >uuid cr:>uuid CBC cr:CBC CFB cr:CFB CTR cr:CTR ECB cr:ECB -Builtin GCM cr:GCM OFB cr:OFB aad? cr:aad? aes128box-sig cr:aes128box-sig aes128gcm> cr:aes128gcm> -Builtin aes256box-sig cr:aes256box-sig aes256gcm> cr:aes256gcm> aesgcm cr:aesgcm blakehash cr:blakehash -Builtin chacha20box-sig cr:chacha20box-sig chachapoly cr:chachapoly cipher! cr:cipher! cipher@ cr:cipher@ -Builtin cp> cr:cp> cpe> cr:cpe> decrypt cr:decrypt decrypt+ cr:decrypt+ decrypt> cr:decrypt> dh-genkey cr:dh-genkey -Builtin dh-secret cr:dh-secret dh-sign cr:dh-sign dh-verify cr:dh-verify ebox-sig cr:ebox-sig ecc-genkey cr:ecc-genkey -Builtin ecc-secret cr:ecc-secret ecc-sign cr:ecc-sign ecc-verify cr:ecc-verify edbox-sig cr:edbox-sig -Builtin edbox> cr:edbox> encrypt cr:encrypt encrypt+ cr:encrypt+ encrypt> cr:encrypt> ensurekey cr:ensurekey -Builtin err? cr:err? gcm-tag-size cr:gcm-tag-size genkey cr:genkey hash cr:hash hash! cr:hash! hash+ cr:hash+ -Builtin hash>b cr:hash>b hash>s cr:hash>s hash@ cr:hash@ hmac cr:hmac hotp cr:hotp iv? cr:iv? mode cr:mode -Builtin mode@ cr:mode@ randkey cr:randkey restore cr:restore root-certs cr:root-certs rsa_decrypt cr:rsa_decrypt -Builtin rsa_encrypt cr:rsa_encrypt rsa_sign cr:rsa_sign rsa_verify cr:rsa_verify rsabox-sig cr:rsabox-sig -Builtin rsabox> cr:rsabox> rsagenkey cr:rsagenkey save cr:save sbox-sig cr:sbox-sig sha1-hmac cr:sha1-hmac -Builtin shard cr:shard tag? cr:tag? totp cr:totp totp-epoch cr:totp-epoch totp-time-step cr:totp-time-step -Builtin unshard cr:unshard uuid cr:uuid uuid> cr:uuid> validate-pgp-sig cr:validate-pgp-sig (.hebrew) d:(.hebrew) -Builtin (.islamic) d:(.islamic) + d:+ +day d:+day +hour d:+hour +min d:+min +msec d:+msec - d:- .hebrew d:.hebrew -Builtin .islamic d:.islamic .time d:.time / d:/ = d:= >fixed d:>fixed >hebepoch d:>hebepoch >msec d:>msec -Builtin >unix d:>unix >ymd d:>ymd Adar d:Adar Adar2 d:Adar2 Adar2 d:Adar2 Av d:Av Elul d:Elul Fri d:Fri -Builtin Heshvan d:Heshvan Iyar d:Iyar Kislev d:Kislev Mon d:Mon Nissan d:Nissan Sat d:Sat Shevat d:Shevat -Builtin Sivan d:Sivan Sun d:Sun Tammuz d:Tammuz Tevet d:Tevet Thu d:Thu Tishrei d:Tishrei Tue d:Tue -Builtin Wed d:Wed adjust-dst d:adjust-dst between d:between d. d:d. dawn d:dawn days-in-hebrew-year d:days-in-hebrew-year -Builtin displaying-hebrew d:displaying-hebrew do-dawn d:do-dawn do-dusk d:do-dusk do-rise d:do-rise -Builtin doy d:doy dst? d:dst? dstquery d:dstquery dstzones? d:dstzones? dusk d:dusk elapsed-timer d:elapsed-timer -Builtin elapsed-timer-seconds d:elapsed-timer-seconds first-dow d:first-dow fixed> d:fixed> fixed>dow d:fixed>dow -Builtin fixed>hebrew d:fixed>hebrew fixed>islamic d:fixed>islamic format d:format hanukkah d:hanukkah -Builtin hebrew-epoch d:hebrew-epoch hebrew>fixed d:hebrew>fixed hebrewtoday d:hebrewtoday hmonth-name d:hmonth-name -Builtin islamic.epoch d:islamic.epoch islamic>fixed d:islamic>fixed islamictoday d:islamictoday join d:join -Builtin last-day-of-hebrew-month d:last-day-of-hebrew-month last-dow d:last-dow last-month d:last-month -Builtin last-week d:last-week last-year d:last-year latitude d:latitude longitude d:longitude longitude d:longitude -Builtin msec d:msec msec> d:msec> new d:new next-dow d:next-dow next-month d:next-month next-week d:next-week -Builtin next-year d:next-year number>hebrew d:number>hebrew omer d:omer parse d:parse pesach d:pesach +Builtin conj c:conj conj c:conj im c:im n> c:n> new c:new new c:new re c:re >redir con:>redir accept con:accept +Builtin accept-pwd con:accept-pwd ansi? con:ansi? black con:black blue con:blue clreol con:clreol cls con:cls +Builtin cyan con:cyan down con:down free con:free getxy con:getxy gotoxy con:gotoxy green con:green +Builtin key con:key key? con:key? left con:left load-history con:load-history magenta con:magenta onBlack con:onBlack +Builtin onBlue con:onBlue onCyan con:onCyan onGreen con:onGreen onMagenta con:onMagenta onRed con:onRed +Builtin onWhite con:onWhite onYellow con:onYellow print con:print red con:red redir> con:redir> redir? con:redir? +Builtin right con:right save-history con:save-history size? con:size? up con:up white con:white yellow con:yellow +Builtin >aes128gcm cr:>aes128gcm >aes256gcm cr:>aes256gcm >cp cr:>cp >cpe cr:>cpe >decrypt cr:>decrypt +Builtin >edbox cr:>edbox >encrypt cr:>encrypt >nbuf cr:>nbuf >rsabox cr:>rsabox >uuid cr:>uuid CBC cr:CBC +Builtin CFB cr:CFB CTR cr:CTR ECB cr:ECB GCM cr:GCM OFB cr:OFB aad? cr:aad? aes128box-sig cr:aes128box-sig +Builtin aes128gcm> cr:aes128gcm> aes256box-sig cr:aes256box-sig aes256gcm> cr:aes256gcm> aesgcm cr:aesgcm +Builtin blakehash cr:blakehash chacha20box-sig cr:chacha20box-sig chachapoly cr:chachapoly cipher! cr:cipher! +Builtin cipher@ cr:cipher@ cp> cr:cp> cpe> cr:cpe> decrypt cr:decrypt decrypt+ cr:decrypt+ decrypt> cr:decrypt> +Builtin dh-genkey cr:dh-genkey dh-secret cr:dh-secret dh-sign cr:dh-sign dh-verify cr:dh-verify ebox-sig cr:ebox-sig +Builtin ecc-genkey cr:ecc-genkey ecc-secret cr:ecc-secret ecc-sign cr:ecc-sign ecc-verify cr:ecc-verify +Builtin edbox-sig cr:edbox-sig edbox> cr:edbox> encrypt cr:encrypt encrypt+ cr:encrypt+ encrypt> cr:encrypt> +Builtin ensurekey cr:ensurekey gcm-tag-size cr:gcm-tag-size genkey cr:genkey hash cr:hash hash! cr:hash! +Builtin hash+ cr:hash+ hash>b cr:hash>b hash>s cr:hash>s hash@ cr:hash@ hmac cr:hmac hotp cr:hotp iv? cr:iv? +Builtin mode cr:mode mode@ cr:mode@ rand cr:rand randbuf cr:randbuf randkey cr:randkey restore cr:restore +Builtin root-certs cr:root-certs rsa_decrypt cr:rsa_decrypt rsa_encrypt cr:rsa_encrypt rsa_sign cr:rsa_sign +Builtin rsa_verify cr:rsa_verify rsabox-sig cr:rsabox-sig rsabox> cr:rsabox> rsagenkey cr:rsagenkey +Builtin save cr:save sbox-sig cr:sbox-sig sha1-hmac cr:sha1-hmac shard cr:shard tag? cr:tag? totp cr:totp +Builtin totp-epoch cr:totp-epoch totp-time-step cr:totp-time-step unshard cr:unshard uuid cr:uuid uuid> cr:uuid> +Builtin validate-pgp-sig cr:validate-pgp-sig (.hebrew) d:(.hebrew) (.islamic) d:(.islamic) + d:+ +day d:+day +Builtin +hour d:+hour +min d:+min +msec d:+msec - d:- .hebrew d:.hebrew .islamic d:.islamic .time d:.time +Builtin / d:/ = d:= >fixed d:>fixed >hebepoch d:>hebepoch >jdn d:>jdn >msec d:>msec >unix d:>unix >ymd d:>ymd +Builtin ?= d:?= Adar d:Adar Adar2 d:Adar2 Adar2 d:Adar2 Av d:Av Elul d:Elul Fri d:Fri Heshvan d:Heshvan +Builtin Iyar d:Iyar Kislev d:Kislev Mon d:Mon Nissan d:Nissan Sat d:Sat Shevat d:Shevat Sivan d:Sivan +Builtin Sun d:Sun Tammuz d:Tammuz Tevet d:Tevet Thu d:Thu Tishrei d:Tishrei Tue d:Tue Wed d:Wed adjust-dst d:adjust-dst +Builtin approx! d:approx! approx? d:approx? approximates! d:approximates! between d:between d. d:d. +Builtin dawn d:dawn days-in-hebrew-year d:days-in-hebrew-year displaying-hebrew d:displaying-hebrew +Builtin do-dawn d:do-dawn do-dusk d:do-dusk do-rise d:do-rise doy d:doy dst? d:dst? dstquery d:dstquery +Builtin dstzones? d:dstzones? dusk d:dusk elapsed-timer d:elapsed-timer elapsed-timer-seconds d:elapsed-timer-seconds +Builtin first-dow d:first-dow fixed> d:fixed> fixed>dow d:fixed>dow fixed>hebrew d:fixed>hebrew fixed>islamic d:fixed>islamic +Builtin format d:format hanukkah d:hanukkah hebrew-epoch d:hebrew-epoch hebrew>fixed d:hebrew>fixed +Builtin hebrewtoday d:hebrewtoday hmonth-name d:hmonth-name islamic.epoch d:islamic.epoch islamic>fixed d:islamic>fixed +Builtin islamictoday d:islamictoday jdn> d:jdn> join d:join last-day-of-hebrew-month d:last-day-of-hebrew-month +Builtin last-dow d:last-dow last-month d:last-month last-week d:last-week last-year d:last-year latitude d:latitude +Builtin longitude d:longitude longitude d:longitude msec d:msec msec> d:msec> new d:new next-dow d:next-dow +Builtin next-month d:next-month next-week d:next-week next-year d:next-year number>hebrew d:number>hebrew +Builtin omer d:omer parse d:parse parse-approx d:parse-approx parse-range d:parse-range pesach d:pesach Builtin prev-dow d:prev-dow purim d:purim rosh-chodesh? d:rosh-chodesh? rosh-hashanah d:rosh-hashanah Builtin shavuot d:shavuot start-timer d:start-timer sunrise d:sunrise taanit-esther d:taanit-esther -Builtin ticks d:ticks ticks/sec d:ticks/sec timer d:timer tisha-beav d:tisha-beav tzadjust d:tzadjust -Builtin unix> d:unix> updatetz d:updatetz year@ d:year@ ymd d:ymd ymd> d:ymd> yom-haatsmaut d:yom-haatsmaut -Builtin yom-kippur d:yom-kippur add-func db:add-func bind db:bind close db:close col db:col col[] db:col[] -Builtin col{} db:col{} err? db:err? errmsg db:errmsg exec db:exec exec-cb db:exec-cb key db:key mysql? db:mysql? -Builtin odbc? db:odbc? open db:open open? db:open? prepare db:prepare query db:query query-all db:query-all -Builtin rekey db:rekey sqlerrmsg db:sqlerrmsg bp dbg:bp except-task@ dbg:except-task@ go dbg:go line-info dbg:line-info -Builtin prompt dbg:prompt stop dbg:stop trace dbg:trace trace-enter dbg:trace-enter trace-leave dbg:trace-leave -Builtin abspath f:abspath append f:append associate f:associate atime f:atime canwrite? f:canwrite? -Builtin chmod f:chmod close f:close copy f:copy copydir f:copydir create f:create ctime f:ctime dir? f:dir? -Builtin dname f:dname eachbuf f:eachbuf eachline f:eachline enssep f:enssep eof? f:eof? err? f:err? -Builtin exists? f:exists? flush f:flush fname f:fname getb f:getb getc f:getc getline f:getline getmod f:getmod -Builtin glob f:glob glob-nocase f:glob-nocase include f:include launch f:launch link f:link link> f:link> -Builtin link? f:link? mkdir f:mkdir mmap f:mmap mmap-range f:mmap-range mmap-range? f:mmap-range? mtime f:mtime -Builtin mv f:mv open f:open open-ro f:open-ro popen f:popen print f:print read f:read relpath f:relpath -Builtin rglob f:rglob rm f:rm rmdir f:rmdir seek f:seek sep f:sep show f:show size f:size slurp f:slurp -Builtin stderr f:stderr stdin f:stdin stdout f:stdout tell f:tell times f:times trash f:trash ungetb f:ungetb -Builtin ungetc f:ungetc unzip f:unzip unzip-entry f:unzip-entry watch f:watch write f:write writen f:writen -Builtin zip+ f:zip+ zip@ f:zip@ zipentry f:zipentry zipnew f:zipnew zipopen f:zipopen zipsave f:zipsave -Builtin bold font:bold face? font:face? glyph-path font:glyph-path glyph-pos font:glyph-pos info font:info -Builtin italic font:italic ls font:ls measure font:measure new font:new pixels font:pixels pixels? font:pixels? -Builtin points font:points points? font:points? styles font:styles styles? font:styles? underline font:underline -Builtin +child g:+child +kind g:+kind +path g:+path -child g:-child /path g:/path >img g:>img >progress g:>progress -Builtin add-items g:add-items adjustwidth g:adjustwidth allow-orient g:allow-orient arc g:arc arc2 g:arc2 -Builtin autohide g:autohide back g:back bezier g:bezier bg g:bg bg? g:bg? bounds g:bounds bounds? g:bounds? -Builtin box-label g:box-label btn-font g:btn-font bubble g:bubble button-size g:button-size buttons-visible g:buttons-visible -Builtin c-text g:c-text callout g:callout center g:center child g:child clear g:clear clearpath g:clearpath -Builtin clr>n g:clr>n coleven g:coleven colordlg g:colordlg colwidth g:colwidth connectededges g:connectededges -Builtin contrasting g:contrasting cp g:cp curmouse? g:curmouse? default-font g:default-font deselect-row g:deselect-row -Builtin dismiss g:dismiss do g:do draw-fitted-text g:draw-fitted-text draw-text g:draw-text draw-text-at g:draw-text-at -Builtin each g:each edit-on-double-click g:edit-on-double-click editable g:editable editdlg g:editdlg -Builtin empty-text g:empty-text enable g:enable enabled? g:enabled? fade g:fade fb-files g:fb-files -Builtin fcolor g:fcolor fg g:fg fg? g:fg? file-filter g:file-filter file-name g:file-name filedlg g:filedlg -Builtin fill g:fill fillall g:fillall fit-text g:fit-text flex! g:flex! focus g:focus fontdlg g:fontdlg -Builtin forward g:forward fullscreen g:fullscreen get-lasso-items g:get-lasso-items get-tab g:get-tab -Builtin getclr g:getclr getfont g:getfont getimage g:getimage getpath g:getpath getroot g:getroot gradient g:gradient -Builtin gui? g:gui? handle g:handle headerheight g:headerheight hide g:hide image g:image image-at g:image-at -Builtin invalidate g:invalidate ix? g:ix? justify g:justify keyinfo g:keyinfo l-text g:l-text laf g:laf -Builtin laf! g:laf! laf? g:laf? len g:len line-width g:line-width lineto g:lineto list+ g:list+ list- g:list- -Builtin loadcontent g:loadcontent localize g:localize m! g:m! m@ g:m@ menu-font g:menu-font menu-update g:menu-update -Builtin menuenabled g:menuenabled mouse? g:mouse? mousepos? g:mousepos? moveto g:moveto msgdlg g:msgdlg -Builtin multi g:multi name g:name named-skin g:named-skin new g:new new-laf g:new-laf next g:next obj g:obj -Builtin on g:on on? g:on? ontop g:ontop oshandle g:oshandle outlinethickness g:outlinethickness panel-size g:panel-size -Builtin panel-size? g:panel-size? parent g:parent path g:path path>s g:path>s pie g:pie pix! g:pix! -Builtin pop g:pop popmenu g:popmenu pos? g:pos? prev g:prev propval! g:propval! propval@ g:propval@ -Builtin push g:push qbezier g:qbezier quit g:quit r-text g:r-text readonly g:readonly rect g:rect refresh g:refresh -Builtin restore g:restore root g:root root-item-visible g:root-item-visible rotate g:rotate rowheight g:rowheight -Builtin rrect g:rrect s>path g:s>path save g:save say g:say scale g:scale scolor g:scolor scrollthickness g:scrollthickness -Builtin sectionenable g:sectionenable select! g:select! select@ g:select@ selected-rows g:selected-rows -Builtin set-lasso g:set-lasso set-long-press g:set-long-press set-popup-font g:set-popup-font set-range g:set-range -Builtin set-swipe g:set-swipe set-value g:set-value setcursor g:setcursor setfont g:setfont setheader g:setheader -Builtin sethtml g:sethtml setimage g:setimage setname g:setname setroot g:setroot settab g:settab show g:show -Builtin show-line-numbers g:show-line-numbers show-pct g:show-pct showmenu g:showmenu showtooltip g:showtooltip -Builtin size g:size size? g:size? skin g:skin skin-class g:skin-class stackix g:stackix state g:state -Builtin state? g:state? stepsize g:stepsize stroke g:stroke stroke-fill g:stroke-fill style g:style -Builtin tabname g:tabname text g:text text-box-style g:text-box-style text? g:text? textcolor g:textcolor -Builtin textsize g:textsize timer! g:timer! timer@ g:timer@ toback g:toback tofront g:tofront toggle-row g:toggle-row -Builtin tooltip g:tooltip top g:top transition g:transition translate g:translate tree-open g:tree-open -Builtin triangle g:triangle update g:update updateitems g:updateitems url g:url user g:user user! g:user! -Builtin vertical g:vertical view g:view visible? g:visible? vpos! g:vpos! vpos@ g:vpos@ waitcursor g:waitcursor -Builtin winding g:winding xy g:xy xy? g:xy? +edge gr:+edge +edge+w gr:+edge+w +node gr:+node connect gr:connect -Builtin edges gr:edges m! gr:m! m@ gr:m@ neighbors gr:neighbors new gr:new node-edges gr:node-edges -Builtin nodes gr:nodes traverse gr:traverse + h:+ clear h:clear len h:len new h:new peek h:peek pop h:pop -Builtin push h:push unique h:unique arm? hw:arm? camera hw:camera camera-fmt hw:camera-fmt camera-img hw:camera-img -Builtin camera? hw:camera? cpu? hw:cpu? device? hw:device? displays? hw:displays? displaysize? hw:displaysize? -Builtin err? hw:err? gpio hw:gpio gpio! hw:gpio! gpio-mmap hw:gpio-mmap gpio@ hw:gpio@ i2c hw:i2c i2c! hw:i2c! -Builtin i2c!reg hw:i2c!reg i2c@ hw:i2c@ i2c@reg hw:i2c@reg isround? hw:isround? iswatch? hw:iswatch? -Builtin mac? hw:mac? mem? hw:mem? poll hw:poll sensor hw:sensor start hw:start stop hw:stop fetch-full imap:fetch-full -Builtin fetch-uid-mail imap:fetch-uid-mail login imap:login new imap:new select-inbox imap:select-inbox -Builtin >file img:>file copy img:copy crop img:crop data img:data desat img:desat fill img:fill filter img:filter -Builtin flip img:flip from-svg img:from-svg new img:new pix! img:pix! pix@ img:pix@ qr-gen img:qr-gen -Builtin qr-parse img:qr-parse rotate img:rotate scale img:scale scroll img:scroll size img:size countries iso:countries -Builtin find loc:find sort loc:sort ! m:! !? m:!? + m:+ +? m:+? - m:- @ m:@ @? m:@? @@ m:@@ clear m:clear -Builtin data m:data each m:each exists? m:exists? iter m:iter iter-all m:iter-all keys m:keys len m:len -Builtin map m:map new m:new op! m:op! open m:open vals m:vals xchg m:xchg ! mat:! * mat:* + mat:+ = mat:= -Builtin @ mat:@ col mat:col data mat:data det mat:det dim? mat:dim? get-n mat:get-n ident mat:ident -Builtin m. mat:m. minor mat:minor n* mat:n* new mat:new row mat:row same-size? mat:same-size? trans mat:trans -Builtin ! n:! * n:* */ n:*/ + n:+ +! n:+! - n:- / n:/ /mod n:/mod 1+ n:1+ 1- n:1- < n:< = n:= > n:> -Builtin BIGE n:BIGE BIGPI n:BIGPI E n:E PI n:PI ^ n:^ abs n:abs acos n:acos acos n:acos asin n:asin -Builtin asin n:asin atan n:atan atan n:atan atan2 n:atan2 band n:band between n:between bfloat n:bfloat -Builtin bic n:bic bint n:bint binv n:binv bnot n:bnot bor n:bor bxor n:bxor ceil n:ceil clamp n:clamp -Builtin cmp n:cmp comb n:comb cos n:cos cosd n:cosd exp n:exp expmod n:expmod float n:float floor n:floor +Builtin ticks d:ticks ticks/sec d:ticks/sec timer d:timer timer-ctrl d:timer-ctrl tisha-beav d:tisha-beav +Builtin tzadjust d:tzadjust unix> d:unix> unknown d:unknown unknown? d:unknown? updatetz d:updatetz +Builtin year@ d:year@ ymd d:ymd ymd> d:ymd> yom-haatsmaut d:yom-haatsmaut yom-kippur d:yom-kippur add-func db:add-func +Builtin aes! db:aes! begin db:begin bind db:bind bind-exec db:bind-exec bind-exec[] db:bind-exec[] +Builtin close db:close col db:col col[] db:col[] col{} db:col{} commit db:commit each db:each exec db:exec +Builtin exec-cb db:exec-cb exec-name db:exec-name get db:get get-sub db:get-sub key db:key kind? db:kind? +Builtin last-rowid db:last-rowid mysql? db:mysql? odbc? db:odbc? open db:open open? db:open? prep-name db:prep-name +Builtin prepare db:prepare query db:query query-all db:query-all rekey db:rekey rollback db:rollback +Builtin set db:set set-sub db:set-sub sql@ db:sql@ bp dbg:bp except-task@ dbg:except-task@ go dbg:go +Builtin line-info dbg:line-info prompt dbg:prompt stop dbg:stop trace dbg:trace trace-enter dbg:trace-enter +Builtin trace-leave dbg:trace-leave / f:/ abspath f:abspath absrel f:absrel append f:append associate f:associate +Builtin atime f:atime canwrite? f:canwrite? chmod f:chmod close f:close copy f:copy copydir f:copydir +Builtin create f:create ctime f:ctime dir? f:dir? dname f:dname eachbuf f:eachbuf eachline f:eachline +Builtin enssep f:enssep eof? f:eof? exists? f:exists? flush f:flush fname f:fname getb f:getb getc f:getc +Builtin getline f:getline getmod f:getmod glob f:glob glob-nocase f:glob-nocase homedir f:homedir homedir! f:homedir! +Builtin include f:include ioctl f:ioctl join f:join launch f:launch link f:link link> f:link> link? f:link? +Builtin mkdir f:mkdir mmap f:mmap mmap-range f:mmap-range mmap-range? f:mmap-range? mtime f:mtime mv f:mv +Builtin name@ f:name@ open f:open open-ro f:open-ro popen f:popen print f:print read f:read read? f:read? +Builtin relpath f:relpath rglob f:rglob rm f:rm rmdir f:rmdir seek f:seek sep f:sep size f:size slurp f:slurp +Builtin sparse? f:sparse? spit f:spit stderr f:stderr stdin f:stdin stdout f:stdout tell f:tell times f:times +Builtin tmpspit f:tmpspit trash f:trash truncate f:truncate ungetb f:ungetb ungetc f:ungetc unzip f:unzip +Builtin unzip-entry f:unzip-entry watch f:watch write f:write writen f:writen zip+ f:zip+ zip@ f:zip@ +Builtin zipentry f:zipentry zipnew f:zipnew zipopen f:zipopen zipsave f:zipsave atlas! font:atlas! +Builtin atlas@ font:atlas@ default-size font:default-size info font:info ls font:ls measure font:measure +Builtin new font:new oversample font:oversample pixels font:pixels pixels? font:pixels? +edge gr:+edge +Builtin +edge+w gr:+edge+w +node gr:+node connect gr:connect edges gr:edges edges! gr:edges! m! gr:m! +Builtin m@ gr:m@ neighbors gr:neighbors new gr:new node-edges gr:node-edges nodes gr:nodes traverse gr:traverse +Builtin weight! gr:weight! + h:+ clear h:clear cmp! h:cmp! len h:len max! h:max! new h:new peek h:peek +Builtin pop h:pop push h:push unique h:unique arm? hw:arm? camera hw:camera camera-img hw:camera-img +Builtin camera-limits hw:camera-limits camera? hw:camera? cpu? hw:cpu? device? hw:device? displays? hw:displays? +Builtin displaysize? hw:displaysize? finger-match hw:finger-match finger-support hw:finger-support +Builtin gpio hw:gpio gpio! hw:gpio! gpio-mmap hw:gpio-mmap gpio@ hw:gpio@ i2c hw:i2c i2c! hw:i2c! i2c!reg hw:i2c!reg +Builtin i2c@ hw:i2c@ i2c@reg hw:i2c@reg isround? hw:isround? iswatch? hw:iswatch? mac? hw:mac? mem? hw:mem? +Builtin model? hw:model? poll hw:poll sensor hw:sensor start hw:start stop hw:stop uid? hw:uid? fetch-full imap:fetch-full +Builtin fetch-uid-mail imap:fetch-uid-mail login imap:login logout imap:logout new imap:new search imap:search +Builtin select-inbox imap:select-inbox >file img:>file >fmt img:>fmt copy img:copy crop img:crop data img:data +Builtin desat img:desat fill img:fill fillrect img:fillrect filter img:filter flip img:flip from-svg img:from-svg +Builtin new img:new pix! img:pix! pix@ img:pix@ qr-gen img:qr-gen qr-parse img:qr-parse rotate img:rotate +Builtin scale img:scale scroll img:scroll size img:size countries iso:countries find loc:find sort loc:sort +Builtin ! m:! !? m:!? + m:+ +? m:+? - m:- >arr m:>arr @ m:@ @? m:@? _! m:_! _@ m:_@ arr> m:arr> bitmap m:bitmap +Builtin clear m:clear data m:data each m:each exists? m:exists? filter m:filter iter m:iter iter-all m:iter-all +Builtin keys m:keys len m:len map m:map merge m:merge new m:new op! m:op! open m:open slice m:slice +Builtin vals m:vals xchg m:xchg zip m:zip ! mat:! * mat:* + mat:+ = mat:= @ mat:@ affine mat:affine +Builtin col mat:col data mat:data det mat:det dim? mat:dim? get-n mat:get-n ident mat:ident inv mat:inv +Builtin m. mat:m. minor mat:minor n* mat:n* new mat:new new-minor mat:new-minor rotate mat:rotate row mat:row +Builtin same-size? mat:same-size? scale mat:scale shear mat:shear trans mat:trans translate mat:translate +Builtin xform mat:xform 2console md:2console 2html md:2html 2nk md:2nk bounds meta:bounds color meta:color +Builtin console meta:console end meta:end ffi meta:ffi ! n:! * n:* */ n:*/ + n:+ +! n:+! - n:- / n:/ +Builtin /mod n:/mod 1+ n:1+ 1- n:1- < n:< = n:= > n:> BIGE n:BIGE BIGPI n:BIGPI E n:E PI n:PI ^ n:^ +Builtin _mod n:_mod abs n:abs acos n:acos acos n:acos asin n:asin asin n:asin atan n:atan atan n:atan +Builtin atan2 n:atan2 band n:band between n:between bfloat n:bfloat bic n:bic bint n:bint binv n:binv +Builtin bnot n:bnot bor n:bor bxor n:bxor cast n:cast ceil n:ceil clamp n:clamp cmp n:cmp comb n:comb +Builtin cos n:cos cosd n:cosd emod n:emod exp n:exp expm1 n:expm1 expmod n:expmod float n:float floor n:floor Builtin fmod n:fmod frac n:frac gcd n:gcd int n:int invmod n:invmod kind? n:kind? lcm n:lcm ln n:ln -Builtin max n:max median n:median min n:min mod n:mod neg n:neg odd? n:odd? perm n:perm prime? n:prime? -Builtin quantize n:quantize quantize! n:quantize! r+ n:r+ range n:range rot32l n:rot32l rot32r n:rot32r -Builtin round n:round round2 n:round2 running-variance n:running-variance running-variance-finalize n:running-variance-finalize -Builtin sgn n:sgn shl n:shl shr n:shr sin n:sin sind n:sind sqr n:sqr sqrt n:sqrt tan n:tan tand n:tand -Builtin trunc n:trunc ~= n:~= ! net:! >url net:>url @ net:@ DGRAM net:DGRAM INET4 net:INET4 INET6 net:INET6 -Builtin PROTO_TCP net:PROTO_TCP PROTO_UDP net:PROTO_UDP STREAM net:STREAM accept net:accept addrinfo>o net:addrinfo>o -Builtin again? net:again? alloc-and-read net:alloc-and-read alloc-buf net:alloc-buf bind net:bind browse net:browse -Builtin close net:close connect net:connect err>s net:err>s err? net:err? get net:get getaddrinfo net:getaddrinfo -Builtin getpeername net:getpeername head net:head ifaces? net:ifaces? listen net:listen net-socket net:net-socket -Builtin opts net:opts port-is-ssl? net:port-is-ssl? post net:post proxy! net:proxy! read net:read recvfrom net:recvfrom -Builtin s>url net:s>url sendto net:sendto server net:server setsockopt net:setsockopt socket net:socket -Builtin tlshello net:tlshello url> net:url> user-agent net:user-agent wait net:wait write net:write -Builtin MAX ns:MAX cast ptr:cast len ptr:len pack ptr:pack unpack ptr:unpack unpack_orig ptr:unpack_orig +Builtin ln1p n:ln1p max n:max median n:median min n:min mod n:mod neg n:neg odd? n:odd? perm n:perm +Builtin prime? n:prime? quantize n:quantize quantize! n:quantize! r+ n:r+ range n:range rot32l n:rot32l +Builtin rot32r n:rot32r round n:round round2 n:round2 rounding n:rounding running-variance n:running-variance +Builtin running-variance-finalize n:running-variance-finalize sgn n:sgn shl n:shl shr n:shr sin n:sin +Builtin sind n:sind sqr n:sqr sqrt n:sqrt tan n:tan tand n:tand trunc n:trunc ~= n:~= ! net:! !? net:!? +Builtin - net:- >url net:>url @ net:@ @? net:@? DGRAM net:DGRAM INET4 net:INET4 INET6 net:INET6 PROTO_TCP net:PROTO_TCP +Builtin PROTO_UDP net:PROTO_UDP STREAM net:STREAM accept net:accept addrinfo>o net:addrinfo>o again? net:again? +Builtin alloc-and-read net:alloc-and-read alloc-buf net:alloc-buf bind net:bind close net:close closed? net:closed? +Builtin connect net:connect debug? net:debug? delete net:delete get net:get getaddrinfo net:getaddrinfo +Builtin getpeername net:getpeername head net:head ifaces? net:ifaces? listen net:listen map>url net:map>url +Builtin net-socket net:net-socket opts net:opts port-is-ssl? net:port-is-ssl? post net:post proxy! net:proxy! +Builtin put net:put read net:read read-all net:read-all recvfrom net:recvfrom s>url net:s>url sendto net:sendto +Builtin server net:server setsockopt net:setsockopt socket net:socket tlshello net:tlshello url> net:url> +Builtin user-agent net:user-agent wait net:wait write net:write (begin) nk:(begin) (chart-begin) nk:(chart-begin) +Builtin (chart-begin-colored) nk:(chart-begin-colored) (chart-end) nk:(chart-end) (end) nk:(end) (group-begin) nk:(group-begin) +Builtin (group-end) nk:(group-end) (property) nk:(property) >img nk:>img addfont nk:addfont anti-alias nk:anti-alias +Builtin any-clicked? nk:any-clicked? bounds nk:bounds bounds! nk:bounds! button nk:button button-color nk:button-color +Builtin button-label nk:button-label button-set-behavior nk:button-set-behavior button-symbol nk:button-symbol +Builtin button-symbol-label nk:button-symbol-label chart-add-slot nk:chart-add-slot chart-add-slot-colored nk:chart-add-slot-colored +Builtin chart-push nk:chart-push chart-push-slot nk:chart-push-slot checkbox nk:checkbox clicked? nk:clicked? +Builtin close-this! nk:close-this! close-this? nk:close-this? close? nk:close? color-picker nk:color-picker +Builtin combo nk:combo combo-begin-color nk:combo-begin-color combo-begin-label nk:combo-begin-label +Builtin combo-cb nk:combo-cb combo-end nk:combo-end contextual-begin nk:contextual-begin contextual-close nk:contextual-close +Builtin contextual-end nk:contextual-end contextual-item-image-text nk:contextual-item-image-text contextual-item-symbol-text nk:contextual-item-symbol-text +Builtin contextual-item-text nk:contextual-item-text cp! nk:cp! cp@ nk:cp@ display-info nk:display-info +Builtin display@ nk:display@ do nk:do down? nk:down? draw-image nk:draw-image draw-image-at nk:draw-image-at +Builtin draw-image-centered nk:draw-image-centered draw-sub-image nk:draw-sub-image draw-text nk:draw-text +Builtin draw-text-high nk:draw-text-high draw-text-wrap nk:draw-text-wrap edit-focus nk:edit-focus +Builtin edit-string nk:edit-string event nk:event event-boost nk:event-boost event-msec nk:event-msec +Builtin event-wait nk:event-wait fill-arc nk:fill-arc fill-circle nk:fill-circle fill-poly nk:fill-poly +Builtin fill-rect nk:fill-rect fill-rect-color nk:fill-rect-color fill-triangle nk:fill-triangle flags! nk:flags! +Builtin flags@ nk:flags@ fullscreen nk:fullscreen get nk:get get-row-height nk:get-row-height getfont nk:getfont +Builtin getmap nk:getmap gl? nk:gl? grid nk:grid grid-push nk:grid-push group-scroll-ofs nk:group-scroll-ofs +Builtin group-scroll-ofs! nk:group-scroll-ofs! hovered? nk:hovered? image nk:image init nk:init input-button nk:input-button +Builtin input-key nk:input-key input-motion nk:input-motion input-scroll nk:input-scroll input-string nk:input-string +Builtin key-down? nk:key-down? key-pressed? nk:key-pressed? key-released? nk:key-released? label nk:label +Builtin label-colored nk:label-colored label-wrap nk:label-wrap label-wrap-colored nk:label-wrap-colored +Builtin layout-bounds nk:layout-bounds layout-grid-begin nk:layout-grid-begin layout-grid-end nk:layout-grid-end +Builtin layout-push-dynamic nk:layout-push-dynamic layout-push-static nk:layout-push-static layout-push-variable nk:layout-push-variable +Builtin layout-ratio-from-pixel nk:layout-ratio-from-pixel layout-reset-row-height nk:layout-reset-row-height +Builtin layout-row nk:layout-row layout-row-begin nk:layout-row-begin layout-row-dynamic nk:layout-row-dynamic +Builtin layout-row-end nk:layout-row-end layout-row-height nk:layout-row-height layout-row-push nk:layout-row-push +Builtin layout-row-static nk:layout-row-static layout-row-template-begin nk:layout-row-template-begin +Builtin layout-row-template-end nk:layout-row-template-end layout-space-begin nk:layout-space-begin +Builtin layout-space-end nk:layout-space-end layout-space-push nk:layout-space-push layout-widget-bounds nk:layout-widget-bounds +Builtin list-begin nk:list-begin list-end nk:list-end list-new nk:list-new list-range nk:list-range +Builtin m! nk:m! m@ nk:m@ make-style nk:make-style max-vertex-element nk:max-vertex-element measure nk:measure +Builtin measure-font nk:measure-font menu-begin nk:menu-begin menu-close nk:menu-close menu-end nk:menu-end +Builtin menu-item-image nk:menu-item-image menu-item-label nk:menu-item-label menu-item-symbol nk:menu-item-symbol +Builtin menubar-begin nk:menubar-begin menubar-end nk:menubar-end mouse-pos nk:mouse-pos msgdlg nk:msgdlg +Builtin option nk:option plot nk:plot plot-fn nk:plot-fn pop-font nk:pop-font popup-begin nk:popup-begin +Builtin popup-close nk:popup-close popup-end nk:popup-end popup-scroll-ofs nk:popup-scroll-ofs popup-scroll-ofs! nk:popup-scroll-ofs! +Builtin progress nk:progress prop-int nk:prop-int pt>local nk:pt>local pt>screen nk:pt>screen pts>rect nk:pts>rect +Builtin push-font nk:push-font rect-center nk:rect-center rect-intersect nk:rect-intersect rect-ofs nk:rect-ofs +Builtin rect-pad nk:rect-pad rect-shrink nk:rect-shrink rect-union nk:rect-union rect/high nk:rect/high +Builtin rect/wide nk:rect/wide rect>center nk:rect>center rect>local nk:rect>local rect>pos nk:rect>pos +Builtin rect>pts nk:rect>pts rect>screen nk:rect>screen rect>size nk:rect>size released? nk:released? +Builtin render nk:render restore nk:restore rotate nk:rotate save nk:save scale nk:scale scancode? nk:scancode? +Builtin screen-saver nk:screen-saver screen-size nk:screen-size screen-win-close nk:screen-win-close +Builtin selectable nk:selectable set nk:set set-font nk:set-font set-num-vertices nk:set-num-vertices +Builtin setpos nk:setpos setwin nk:setwin slider nk:slider slider-int nk:slider-int space nk:space +Builtin spacing nk:spacing stroke-arc nk:stroke-arc stroke-circle nk:stroke-circle stroke-curve nk:stroke-curve +Builtin stroke-line nk:stroke-line stroke-polygon nk:stroke-polygon stroke-polyline nk:stroke-polyline +Builtin stroke-rect nk:stroke-rect stroke-tri nk:stroke-tri style-from-table nk:style-from-table sw-gl nk:sw-gl +Builtin text? nk:text? tooltip nk:tooltip translate nk:translate tree-pop nk:tree-pop tree-state-push nk:tree-state-push +Builtin use-style nk:use-style vsync nk:vsync widget nk:widget widget-bounds nk:widget-bounds widget-fitting nk:widget-fitting +Builtin widget-high nk:widget-high widget-hovered? nk:widget-hovered? widget-mouse-click-down? nk:widget-mouse-click-down? +Builtin widget-mouse-clicked? nk:widget-mouse-clicked? widget-pos nk:widget-pos widget-size nk:widget-size +Builtin widget-wide nk:widget-wide win nk:win win-bounds nk:win-bounds win-bounds! nk:win-bounds! win-close nk:win-close +Builtin win-closed? nk:win-closed? win-collapse nk:win-collapse win-collapsed? nk:win-collapsed? win-content-bounds nk:win-content-bounds +Builtin win-focus nk:win-focus win-focused? nk:win-focused? win-hidden? nk:win-hidden? win-high nk:win-high +Builtin win-hovered? nk:win-hovered? win-pos nk:win-pos win-scroll-ofs nk:win-scroll-ofs win-scroll-ofs! nk:win-scroll-ofs! +Builtin win-show nk:win-show win-size nk:win-size win-wide nk:win-wide win? nk:win? MAX ns:MAX ! o:! +Builtin + o:+ +? o:+? ??? o:??? @ o:@ class o:class exec o:exec isa o:isa method o:method mutate o:mutate +Builtin new o:new super o:super devname os:devname env os:env lang os:lang mem-arenas os:mem-arenas +Builtin notify os:notify region os:region cast ptr:cast len ptr:len null? ptr:null? pack ptr:pack unpack ptr:unpack +Builtin unpack_orig ptr:unpack_orig publish pubsub:publish qsize pubsub:qsize subscribe pubsub:subscribe Builtin + q:+ clear q:clear len q:len new q:new notify q:notify overwrite q:overwrite peek q:peek pick q:pick -Builtin pop q:pop push q:push shift q:shift size q:size slide q:slide throwing q:throwing wait q:wait -Builtin ++match r:++match +/ r:+/ +match r:+match / r:/ @ r:@ err? r:err? len r:len match r:match new r:new -Builtin rx r:rx str r:str ! s:! * s:* + s:+ - s:- / s:/ /scripts s:/scripts <+ s:<+ = s:= =ic s:=ic -Builtin >base64 s:>base64 >ucs2 s:>ucs2 @ s:@ append s:append base64> s:base64> clear s:clear cmp s:cmp -Builtin cmpi s:cmpi compress s:compress days! s:days! each s:each eachline s:eachline expand s:expand -Builtin fill s:fill fmt s:fmt gershayim s:gershayim globmatch s:globmatch hexupr s:hexupr insert s:insert -Builtin intl s:intl intl! s:intl! lang s:lang lc s:lc len s:len lsub s:lsub ltrim s:ltrim map s:map -Builtin months! s:months! new s:new replace s:replace replace! s:replace! rev s:rev rsearch s:rsearch -Builtin rsub s:rsub rtrim s:rtrim script? s:script? search s:search size s:size slice s:slice strfmap s:strfmap -Builtin strfmt s:strfmt trim s:trim tsub s:tsub uc s:uc ucs2> s:ucs2> utf8? s:utf8? zt s:zt close sio:close -Builtin enum sio:enum open sio:open opts! sio:opts! opts@ sio:opts@ read sio:read write sio:write new smtp:new -Builtin send smtp:send apply-filter snd:apply-filter devices? snd:devices? end-record snd:end-record -Builtin filter snd:filter formats? snd:formats? freq snd:freq gain snd:gain gain? snd:gain? len snd:len -Builtin loop snd:loop mix snd:mix new snd:new pause snd:pause play snd:play played snd:played rate snd:rate -Builtin record snd:record seek snd:seek stop snd:stop stopall snd:stopall unmix snd:unmix volume snd:volume -Builtin volume? snd:volume? + st:+ . st:. clear st:clear len st:len ndrop st:ndrop new st:new op! st:op! -Builtin peek st:peek pick st:pick pop st:pop push st:push roll st:roll shift st:shift size st:size -Builtin slide st:slide swap st:swap throwing st:throwing >buf struct:>buf arr> struct:arr> buf struct:buf -Builtin buf> struct:buf> byte struct:byte double struct:double field! struct:field! field@ struct:field@ -Builtin float struct:float ignore struct:ignore int struct:int long struct:long struct; struct:struct; -Builtin word struct:word ! t:! @ t:@ assign t:assign curtask t:curtask def-queue t:def-queue def-stack t:def-stack -Builtin done? t:done? err! t:err! err? t:err? getq t:getq guitask t:guitask handler t:handler kill t:kill -Builtin list t:list main t:main name! t:name! name@ t:name@ notify t:notify pop t:pop priority t:priority -Builtin push t:push push< t:push< q-notify t:q-notify q-wait t:q-wait qlen t:qlen result t:result task t:task -Builtin task-n t:task-n task-stop t:task-stop wait t:wait ! w:! @ w:@ alias: w:alias: cb w:cb deprecate w:deprecate -Builtin exec w:exec exec? w:exec? ffifail w:ffifail find w:find forget w:forget is w:is undo w:undo -Builtin >s xml:>s >txt xml:>txt parse xml:parse parse-html xml:parse-html parse-stream xml:parse-stream +Builtin pop q:pop push q:push remove q:remove shift q:shift size q:size slide q:slide throwing q:throwing +Builtin wait q:wait ++match r:++match +/ r:+/ +match r:+match / r:/ @ r:@ len r:len match r:match new r:new +Builtin rx r:rx str r:str * rat:* + rat:+ - rat:- / rat:/ >n rat:>n >s rat:>s new rat:new proper rat:proper +Builtin ! s:! * s:* + s:+ - s:- / s:/ /scripts s:/scripts <+ s:<+ = s:= =ic s:=ic >base64 s:>base64 +Builtin >ucs2 s:>ucs2 @ s:@ append s:append base64> s:base64> clear s:clear cmp s:cmp cmpi s:cmpi compress s:compress +Builtin days! s:days! dist s:dist each s:each each! s:each! eachline s:eachline escape s:escape expand s:expand +Builtin fill s:fill fmt s:fmt fold s:fold gershayim s:gershayim globmatch s:globmatch hexupr s:hexupr +Builtin insert s:insert intl s:intl intl! s:intl! lang s:lang lc s:lc lc? s:lc? len s:len lsub s:lsub +Builtin ltrim s:ltrim map s:map months! s:months! new s:new norm s:norm reduce s:reduce repinsert s:repinsert +Builtin replace s:replace replace! s:replace! rev s:rev rsearch s:rsearch rsub s:rsub rtrim s:rtrim +Builtin script? s:script? search s:search size s:size slice s:slice soundex s:soundex strfmap s:strfmap +Builtin strfmt s:strfmt text-wrap s:text-wrap trim s:trim tsub s:tsub uc s:uc uc? s:uc? ucs2> s:ucs2> +Builtin utf8? s:utf8? zt s:zt close sio:close enum sio:enum open sio:open opts! sio:opts! opts@ sio:opts@ +Builtin read sio:read write sio:write @ slv:@ auto slv:auto build slv:build constraint slv:constraint +Builtin dump slv:dump edit slv:edit named-variable slv:named-variable new slv:new relation slv:relation +Builtin reset slv:reset suggest slv:suggest term slv:term update slv:update v[] slv:v[] variable slv:variable +Builtin v{} slv:v{} new smtp:new send smtp:send apply-filter snd:apply-filter devices? snd:devices? +Builtin end-record snd:end-record filter snd:filter formats? snd:formats? freq snd:freq gain snd:gain +Builtin gain? snd:gain? init snd:init len snd:len loop snd:loop loop? snd:loop? mix snd:mix new snd:new +Builtin pause snd:pause play snd:play played snd:played rate snd:rate ready? snd:ready? record snd:record +Builtin resume snd:resume seek snd:seek stop snd:stop stopall snd:stopall volume snd:volume volume? snd:volume? +Builtin + st:+ . st:. clear st:clear len st:len ndrop st:ndrop new st:new op! st:op! peek st:peek pick st:pick +Builtin pop st:pop push st:push roll st:roll shift st:shift size st:size slide st:slide swap st:swap +Builtin throwing st:throwing >buf struct:>buf arr> struct:arr> buf struct:buf buf> struct:buf> byte struct:byte +Builtin double struct:double field! struct:field! field@ struct:field@ float struct:float ignore struct:ignore +Builtin int struct:int long struct:long struct; struct:struct; word struct:word ! t:! @ t:@ by-name t:by-name +Builtin cor t:cor cor-drop t:cor-drop curtask t:curtask def-queue t:def-queue def-stack t:def-stack +Builtin done? t:done? err! t:err! err? t:err? errno? t:errno? getq t:getq handler t:handler handler@ t:handler@ +Builtin kill t:kill list t:list main t:main max-exceptions t:max-exceptions name! t:name! name@ t:name@ +Builtin notify t:notify parent t:parent pop t:pop priority t:priority push t:push q-notify t:q-notify +Builtin q-wait t:q-wait qlen t:qlen result t:result set-affinity t:set-affinity setq t:setq start t:start +Builtin task t:task task-n t:task-n task-stop t:task-stop wait t:wait yield t:yield yield! t:yield! +Builtin add tree:add binary tree:binary bk tree:bk btree tree:btree cmp! tree:cmp! data tree:data del tree:del +Builtin find tree:find iter tree:iter next tree:next nodes tree:nodes parent tree:parent parse tree:parse +Builtin prev tree:prev root tree:root search tree:search trie tree:trie ! w:! (is) w:(is) @ w:@ alias: w:alias: +Builtin cb w:cb deprecate w:deprecate dlcall w:dlcall dlopen w:dlopen dlsym w:dlsym exec w:exec exec? w:exec? +Builtin ffifail w:ffifail find w:find forget w:forget is w:is name w:name undo w:undo >s xml:>s >txt xml:>txt +Builtin md-init xml:md-init md-parse xml:md-parse parse xml:parse parse-html xml:parse-html parse-stream xml:parse-stream Builtin getmsg[] zmq:getmsg[] sendmsg[] zmq:sendmsg[] + " numbers syn keyword eighthMath decimal hex base@ base! syn match eighthInteger '\<-\=[0-9.]*[0-9.]\+\>' + " recognize hex and binary numbers, the '$' and '%' notation is for eighth syn match eighthInteger '\<\$\x*\x\+\>' " *1* --- dont't mess syn match eighthInteger '\<\x*\d\x*\>' " *2* --- this order! @@ -280,20 +353,17 @@ syn match eighthInteger "\<'.\>" syn region eighthString start=+\.\?\"+ skip=+"+ end=+$+ syn keyword jsonNull null syn keyword jsonBool /\(true\|false\)/ - syn region eighthString start=/\<"/ end=/"\>/ +syn region eighthString start=/\<"/ end=/"\>/ syn match jsonObjEntry /"\"[^"]\+\"\ze\s*:/ -"syn region jsonObject start=/{/ end=/}/ contained contains=jsonObjEntry,jsonArray,jsonObject, jsonBool, eighthString -"syn region jsonArray start=/\[/ end=/\]/ contained contains=jsonArray,jsonObject, jsonBool, eighthString - " Include files -" syn match eighthInclude '\<\(libinclude\|include\|needs\)\s\+\S\+' syn region eighthComment start="\zs\\" end="$" contains=eighthTodo " Define the default highlighting. if !exists("did_eighth_syntax_inits") let did_eighth_syntax_inits=1 - " The default methods for highlighting. Can be overridden later. + + " The default methods for highlighting. Can be overriden later. hi def link eighthTodo Todo hi def link eighthOperators Operator hi def link eighthMath Number @@ -320,16 +390,15 @@ if !exists("did_eighth_syntax_inits") hi def link eighthBuiltin Define hi def link eighthClasses Define hi def link eighthClassWord Keyword - hi def link jsonObject Delimiter hi def link jsonObjEntry Label hi def link jsonArray Special - hi def link jsonNull Function - hi def link jsonBool Boolean + hi def link jsonNull Function + hi def link jsonBool Boolean endif let b:current_syntax = "8th" let &cpo = s:cpo_save unlet s:cpo_save -" vim: ts=8:sw=4:nocindent:smartindent: +" vim: ft=vim:ts=8:sw=4:nocindent:smartindent: diff --git a/runtime/syntax/chicken.vim b/runtime/syntax/chicken.vim index 806d08fbb7..f53d872e74 100644 --- a/runtime/syntax/chicken.vim +++ b/runtime/syntax/chicken.vim @@ -1,6 +1,6 @@ " Vim syntax file " Language: Scheme (CHICKEN) -" Last Change: 2021 Jul 30 +" Last Change: 2021 Oct 01 " Author: Evan Hanson <evhan@foldling.org> " Maintainer: Evan Hanson <evhan@foldling.org> " Repository: https://git.foldling.org/vim-scheme.git @@ -37,7 +37,7 @@ if len(s:c) syn region c matchgroup=schemeComment start=/#>/ end=/<#/ contains=@c endif -# SRFI 26 +" SRFI 26 syn match schemeSyntax /\(([ \t\n]*\)\@<=\(cut\|cute\)\>/ syn keyword schemeSyntax and-let* diff --git a/runtime/syntax/nginx.vim b/runtime/syntax/nginx.vim new file mode 100644 index 0000000000..18dd50cbb2 --- /dev/null +++ b/runtime/syntax/nginx.vim @@ -0,0 +1,2307 @@ +" Vim syntax file +" Language: nginx.conf +" Maintainer: Chris Aumann <me@chr4.org> +" Last Change: Apr 15, 2017 + +if exists("b:current_syntax") + finish +end + +let b:current_syntax = "nginx" + +syn match ngxVariable '\$\(\w\+\|{\w\+}\)' +syn match ngxVariableBlock '\$\(\w\+\|{\w\+}\)' contained +syn match ngxVariableString '\$\(\w\+\|{\w\+}\)' contained +syn region ngxBlock start=+^+ end=+{+ skip=+\${\|{{\|{%+ contains=ngxComment,ngxInteger,ngxIPaddr,ngxDirectiveBlock,ngxVariableBlock,ngxString,ngxThirdPartyLuaBlock oneline +syn region ngxString start=+[^:a-zA-Z>!\\@]\z(["']\)+lc=1 end=+\z1+ skip=+\\\\\|\\\z1+ contains=ngxVariableString,ngxSSLCipherInsecure +syn match ngxComment ' *#.*$' + +" These regular expressions where taken (and adapted) from +" http://vim.1045645.n5.nabble.com/IPv6-support-for-quot-dns-quot-zonefile-syntax-highlighting-td1197292.html +syn match ngxInteger '\W\zs\(\d[0-9.]*\|[0-9.]*\d\)\w\?\ze\W' +syn match ngxIPaddr '\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{6}\(\x\{1,4}:\x\{1,4}\|\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[::\(\(\x\{1,4}:\)\{,6}\x\{1,4}\|\(\x\{1,4}:\)\{,5}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{1}:\(\(\x\{1,4}:\)\{,5}\x\{1,4}\|\(\x\{1,4}:\)\{,4}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{2}:\(\(\x\{1,4}:\)\{,4}\x\{1,4}\|\(\x\{1,4}:\)\{,3}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{3}:\(\(\x\{1,4}:\)\{,3}\x\{1,4}\|\(\x\{1,4}:\)\{,2}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{4}:\(\(\x\{1,4}:\)\{,2}\x\{1,4}\|\(\x\{1,4}:\)\{,1}\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{5}:\(\(\x\{1,4}:\)\{,1}\x\{1,4}\|\([0-2]\?\d\{1,2}\.\)\{3}[0-2]\?\d\{1,2}\)\]' +syn match ngxIPaddr '\[\(\x\{1,4}:\)\{6}:\x\{1,4}\]' + +" Highlight wildcard listening signs also as IPaddr +syn match ngxIPaddr '\s\zs\[::]' +syn match ngxIPaddr '\s\zs\*' + +syn keyword ngxBoolean on +syn keyword ngxBoolean off + +syn keyword ngxDirectiveBlock http contained +syn keyword ngxDirectiveBlock mail contained +syn keyword ngxDirectiveBlock events contained +syn keyword ngxDirectiveBlock server contained +syn keyword ngxDirectiveBlock match contained +syn keyword ngxDirectiveBlock types contained +syn keyword ngxDirectiveBlock location contained +syn keyword ngxDirectiveBlock upstream contained +syn keyword ngxDirectiveBlock charset_map contained +syn keyword ngxDirectiveBlock limit_except contained +syn keyword ngxDirectiveBlock if contained +syn keyword ngxDirectiveBlock geo contained +syn keyword ngxDirectiveBlock map contained +syn keyword ngxDirectiveBlock split_clients contained + +syn keyword ngxDirectiveImportant include +syn keyword ngxDirectiveImportant root +syn keyword ngxDirectiveImportant server contained +syn region ngxDirectiveImportantServer matchgroup=ngxDirectiveImportant start=+^\s*\zsserver\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxUpstreamServerOptions,ngxString,ngxIPaddr,ngxBoolean,ngxInteger,ngxTemplateVar +syn keyword ngxDirectiveImportant server_name +syn keyword ngxDirectiveImportant listen contained +syn region ngxDirectiveImportantListen matchgroup=ngxDirectiveImportant start=+listen+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxListenOptions,ngxString,ngxIPaddr,ngxBoolean,ngxInteger,ngxTemplateVar +syn keyword ngxDirectiveImportant internal +syn keyword ngxDirectiveImportant proxy_pass +syn keyword ngxDirectiveImportant memcached_pass +syn keyword ngxDirectiveImportant fastcgi_pass +syn keyword ngxDirectiveImportant scgi_pass +syn keyword ngxDirectiveImportant uwsgi_pass +syn keyword ngxDirectiveImportant try_files +syn keyword ngxDirectiveImportant error_page +syn keyword ngxDirectiveImportant post_action + +syn keyword ngxUpstreamServerOptions weight contained +syn keyword ngxUpstreamServerOptions max_conns contained +syn keyword ngxUpstreamServerOptions max_fails contained +syn keyword ngxUpstreamServerOptions fail_timeout contained +syn keyword ngxUpstreamServerOptions backup contained +syn keyword ngxUpstreamServerOptions down contained +syn keyword ngxUpstreamServerOptions resolve contained +syn keyword ngxUpstreamServerOptions route contained +syn keyword ngxUpstreamServerOptions service contained +syn keyword ngxUpstreamServerOptions default_server contained +syn keyword ngxUpstreamServerOptions slow_start contained + +syn keyword ngxListenOptions default_server contained +syn keyword ngxListenOptions ssl contained +syn keyword ngxListenOptions http2 contained +syn keyword ngxListenOptions spdy contained +syn keyword ngxListenOptions proxy_protocol contained +syn keyword ngxListenOptions setfib contained +syn keyword ngxListenOptions fastopen contained +syn keyword ngxListenOptions backlog contained +syn keyword ngxListenOptions rcvbuf contained +syn keyword ngxListenOptions sndbuf contained +syn keyword ngxListenOptions accept_filter contained +syn keyword ngxListenOptions deferred contained +syn keyword ngxListenOptions bind contained +syn keyword ngxListenOptions ipv6only contained +syn keyword ngxListenOptions reuseport contained +syn keyword ngxListenOptions so_keepalive contained +syn keyword ngxListenOptions keepidle contained + +syn keyword ngxDirectiveControl break +syn keyword ngxDirectiveControl return +syn keyword ngxDirectiveControl rewrite +syn keyword ngxDirectiveControl set + +syn keyword ngxDirectiveDeprecated connections +syn keyword ngxDirectiveDeprecated imap +syn keyword ngxDirectiveDeprecated limit_zone +syn keyword ngxDirectiveDeprecated mysql_test +syn keyword ngxDirectiveDeprecated open_file_cache_retest +syn keyword ngxDirectiveDeprecated optimize_server_names +syn keyword ngxDirectiveDeprecated satisfy_any +syn keyword ngxDirectiveDeprecated so_keepalive + +syn keyword ngxDirective absolute_redirect +syn keyword ngxDirective accept_mutex +syn keyword ngxDirective accept_mutex_delay +syn keyword ngxDirective acceptex_read +syn keyword ngxDirective access_log +syn keyword ngxDirective add_after_body +syn keyword ngxDirective add_before_body +syn keyword ngxDirective add_header +syn keyword ngxDirective addition_types +syn keyword ngxDirective aio +syn keyword ngxDirective aio_write +syn keyword ngxDirective alias +syn keyword ngxDirective allow +syn keyword ngxDirective ancient_browser +syn keyword ngxDirective ancient_browser_value +syn keyword ngxDirective auth_basic +syn keyword ngxDirective auth_basic_user_file +syn keyword ngxDirective auth_http +syn keyword ngxDirective auth_http_header +syn keyword ngxDirective auth_http_pass_client_cert +syn keyword ngxDirective auth_http_timeout +syn keyword ngxDirective auth_jwt +syn keyword ngxDirective auth_jwt_key_file +syn keyword ngxDirective auth_request +syn keyword ngxDirective auth_request_set +syn keyword ngxDirective autoindex +syn keyword ngxDirective autoindex_exact_size +syn keyword ngxDirective autoindex_format +syn keyword ngxDirective autoindex_localtime +syn keyword ngxDirective charset +syn keyword ngxDirective charset_map +syn keyword ngxDirective charset_types +syn keyword ngxDirective chunked_transfer_encoding +syn keyword ngxDirective client_body_buffer_size +syn keyword ngxDirective client_body_in_file_only +syn keyword ngxDirective client_body_in_single_buffer +syn keyword ngxDirective client_body_temp_path +syn keyword ngxDirective client_body_timeout +syn keyword ngxDirective client_header_buffer_size +syn keyword ngxDirective client_header_timeout +syn keyword ngxDirective client_max_body_size +syn keyword ngxDirective connection_pool_size +syn keyword ngxDirective create_full_put_path +syn keyword ngxDirective daemon +syn keyword ngxDirective dav_access +syn keyword ngxDirective dav_methods +syn keyword ngxDirective debug_connection +syn keyword ngxDirective debug_points +syn keyword ngxDirective default_type +syn keyword ngxDirective degradation +syn keyword ngxDirective degrade +syn keyword ngxDirective deny +syn keyword ngxDirective devpoll_changes +syn keyword ngxDirective devpoll_events +syn keyword ngxDirective directio +syn keyword ngxDirective directio_alignment +syn keyword ngxDirective disable_symlinks +syn keyword ngxDirective empty_gif +syn keyword ngxDirective env +syn keyword ngxDirective epoll_events +syn keyword ngxDirective error_log +syn keyword ngxDirective etag +syn keyword ngxDirective eventport_events +syn keyword ngxDirective expires +syn keyword ngxDirective f4f +syn keyword ngxDirective f4f_buffer_size +syn keyword ngxDirective fastcgi_bind +syn keyword ngxDirective fastcgi_buffer_size +syn keyword ngxDirective fastcgi_buffering +syn keyword ngxDirective fastcgi_buffers +syn keyword ngxDirective fastcgi_busy_buffers_size +syn keyword ngxDirective fastcgi_cache +syn keyword ngxDirective fastcgi_cache_bypass +syn keyword ngxDirective fastcgi_cache_key +syn keyword ngxDirective fastcgi_cache_lock +syn keyword ngxDirective fastcgi_cache_lock_age +syn keyword ngxDirective fastcgi_cache_lock_timeout +syn keyword ngxDirective fastcgi_cache_max_range_offset +syn keyword ngxDirective fastcgi_cache_methods +syn keyword ngxDirective fastcgi_cache_min_uses +syn keyword ngxDirective fastcgi_cache_path +syn keyword ngxDirective fastcgi_cache_purge +syn keyword ngxDirective fastcgi_cache_revalidate +syn keyword ngxDirective fastcgi_cache_use_stale +syn keyword ngxDirective fastcgi_cache_valid +syn keyword ngxDirective fastcgi_catch_stderr +syn keyword ngxDirective fastcgi_connect_timeout +syn keyword ngxDirective fastcgi_force_ranges +syn keyword ngxDirective fastcgi_hide_header +syn keyword ngxDirective fastcgi_ignore_client_abort +syn keyword ngxDirective fastcgi_ignore_headers +syn keyword ngxDirective fastcgi_index +syn keyword ngxDirective fastcgi_intercept_errors +syn keyword ngxDirective fastcgi_keep_conn +syn keyword ngxDirective fastcgi_limit_rate +syn keyword ngxDirective fastcgi_max_temp_file_size +syn keyword ngxDirective fastcgi_next_upstream +syn keyword ngxDirective fastcgi_next_upstream_timeout +syn keyword ngxDirective fastcgi_next_upstream_tries +syn keyword ngxDirective fastcgi_no_cache +syn keyword ngxDirective fastcgi_param +syn keyword ngxDirective fastcgi_pass_header +syn keyword ngxDirective fastcgi_pass_request_body +syn keyword ngxDirective fastcgi_pass_request_headers +syn keyword ngxDirective fastcgi_read_timeout +syn keyword ngxDirective fastcgi_request_buffering +syn keyword ngxDirective fastcgi_send_lowat +syn keyword ngxDirective fastcgi_send_timeout +syn keyword ngxDirective fastcgi_split_path_info +syn keyword ngxDirective fastcgi_store +syn keyword ngxDirective fastcgi_store_access +syn keyword ngxDirective fastcgi_temp_file_write_size +syn keyword ngxDirective fastcgi_temp_path +syn keyword ngxDirective flv +syn keyword ngxDirective geoip_city +syn keyword ngxDirective geoip_country +syn keyword ngxDirective geoip_org +syn keyword ngxDirective geoip_proxy +syn keyword ngxDirective geoip_proxy_recursive +syn keyword ngxDirective google_perftools_profiles +syn keyword ngxDirective gunzip +syn keyword ngxDirective gunzip_buffers +syn keyword ngxDirective gzip nextgroup=ngxGzipOn,ngxGzipOff skipwhite +syn keyword ngxGzipOn on contained +syn keyword ngxGzipOff off contained +syn keyword ngxDirective gzip_buffers +syn keyword ngxDirective gzip_comp_level +syn keyword ngxDirective gzip_disable +syn keyword ngxDirective gzip_hash +syn keyword ngxDirective gzip_http_version +syn keyword ngxDirective gzip_min_length +syn keyword ngxDirective gzip_no_buffer +syn keyword ngxDirective gzip_proxied +syn keyword ngxDirective gzip_static +syn keyword ngxDirective gzip_types +syn keyword ngxDirective gzip_vary +syn keyword ngxDirective gzip_window +syn keyword ngxDirective hash +syn keyword ngxDirective health_check +syn keyword ngxDirective health_check_timeout +syn keyword ngxDirective hls +syn keyword ngxDirective hls_buffers +syn keyword ngxDirective hls_forward_args +syn keyword ngxDirective hls_fragment +syn keyword ngxDirective hls_mp4_buffer_size +syn keyword ngxDirective hls_mp4_max_buffer_size +syn keyword ngxDirective http2_chunk_size +syn keyword ngxDirective http2_body_preread_size +syn keyword ngxDirective http2_idle_timeout +syn keyword ngxDirective http2_max_concurrent_streams +syn keyword ngxDirective http2_max_field_size +syn keyword ngxDirective http2_max_header_size +syn keyword ngxDirective http2_max_requests +syn keyword ngxDirective http2_recv_buffer_size +syn keyword ngxDirective http2_recv_timeout +syn keyword ngxDirective if_modified_since +syn keyword ngxDirective ignore_invalid_headers +syn keyword ngxDirective image_filter +syn keyword ngxDirective image_filter_buffer +syn keyword ngxDirective image_filter_interlace +syn keyword ngxDirective image_filter_jpeg_quality +syn keyword ngxDirective image_filter_sharpen +syn keyword ngxDirective image_filter_transparency +syn keyword ngxDirective image_filter_webp_quality +syn keyword ngxDirective imap_auth +syn keyword ngxDirective imap_capabilities +syn keyword ngxDirective imap_client_buffer +syn keyword ngxDirective index +syn keyword ngxDirective iocp_threads +syn keyword ngxDirective ip_hash +syn keyword ngxDirective js_access +syn keyword ngxDirective js_content +syn keyword ngxDirective js_filter +syn keyword ngxDirective js_include +syn keyword ngxDirective js_preread +syn keyword ngxDirective js_set +syn keyword ngxDirective keepalive +syn keyword ngxDirective keepalive_disable +syn keyword ngxDirective keepalive_requests +syn keyword ngxDirective keepalive_timeout +syn keyword ngxDirective kqueue_changes +syn keyword ngxDirective kqueue_events +syn keyword ngxDirective large_client_header_buffers +syn keyword ngxDirective least_conn +syn keyword ngxDirective least_time +syn keyword ngxDirective limit_conn +syn keyword ngxDirective limit_conn_dry_run +syn keyword ngxDirective limit_conn_log_level +syn keyword ngxDirective limit_conn_status +syn keyword ngxDirective limit_conn_zone +syn keyword ngxDirective limit_except +syn keyword ngxDirective limit_rate +syn keyword ngxDirective limit_rate_after +syn keyword ngxDirective limit_req +syn keyword ngxDirective limit_req_dry_run +syn keyword ngxDirective limit_req_log_level +syn keyword ngxDirective limit_req_status +syn keyword ngxDirective limit_req_zone +syn keyword ngxDirective lingering_close +syn keyword ngxDirective lingering_time +syn keyword ngxDirective lingering_timeout +syn keyword ngxDirective load_module +syn keyword ngxDirective lock_file +syn keyword ngxDirective log_format +syn keyword ngxDirective log_not_found +syn keyword ngxDirective log_subrequest +syn keyword ngxDirective map_hash_bucket_size +syn keyword ngxDirective map_hash_max_size +syn keyword ngxDirective master_process +syn keyword ngxDirective max_ranges +syn keyword ngxDirective memcached_bind +syn keyword ngxDirective memcached_buffer_size +syn keyword ngxDirective memcached_connect_timeout +syn keyword ngxDirective memcached_force_ranges +syn keyword ngxDirective memcached_gzip_flag +syn keyword ngxDirective memcached_next_upstream +syn keyword ngxDirective memcached_next_upstream_timeout +syn keyword ngxDirective memcached_next_upstream_tries +syn keyword ngxDirective memcached_read_timeout +syn keyword ngxDirective memcached_send_timeout +syn keyword ngxDirective merge_slashes +syn keyword ngxDirective min_delete_depth +syn keyword ngxDirective modern_browser +syn keyword ngxDirective modern_browser_value +syn keyword ngxDirective mp4 +syn keyword ngxDirective mp4_buffer_size +syn keyword ngxDirective mp4_max_buffer_size +syn keyword ngxDirective mp4_limit_rate +syn keyword ngxDirective mp4_limit_rate_after +syn keyword ngxDirective msie_padding +syn keyword ngxDirective msie_refresh +syn keyword ngxDirective multi_accept +syn keyword ngxDirective ntlm +syn keyword ngxDirective open_file_cache +syn keyword ngxDirective open_file_cache_errors +syn keyword ngxDirective open_file_cache_events +syn keyword ngxDirective open_file_cache_min_uses +syn keyword ngxDirective open_file_cache_valid +syn keyword ngxDirective open_log_file_cache +syn keyword ngxDirective output_buffers +syn keyword ngxDirective override_charset +syn keyword ngxDirective pcre_jit +syn keyword ngxDirective perl +syn keyword ngxDirective perl_modules +syn keyword ngxDirective perl_require +syn keyword ngxDirective perl_set +syn keyword ngxDirective pid +syn keyword ngxDirective pop3_auth +syn keyword ngxDirective pop3_capabilities +syn keyword ngxDirective port_in_redirect +syn keyword ngxDirective post_acceptex +syn keyword ngxDirective postpone_gzipping +syn keyword ngxDirective postpone_output +syn keyword ngxDirective preread_buffer_size +syn keyword ngxDirective preread_timeout +syn keyword ngxDirective protocol nextgroup=ngxMailProtocol skipwhite +syn keyword ngxMailProtocol imap pop3 smtp contained +syn keyword ngxDirective proxy +syn keyword ngxDirective proxy_bind +syn keyword ngxDirective proxy_buffer +syn keyword ngxDirective proxy_buffer_size +syn keyword ngxDirective proxy_buffering +syn keyword ngxDirective proxy_buffers +syn keyword ngxDirective proxy_busy_buffers_size +syn keyword ngxDirective proxy_cache +syn keyword ngxDirective proxy_cache_bypass +syn keyword ngxDirective proxy_cache_convert_head +syn keyword ngxDirective proxy_cache_key +syn keyword ngxDirective proxy_cache_lock +syn keyword ngxDirective proxy_cache_lock_age +syn keyword ngxDirective proxy_cache_lock_timeout +syn keyword ngxDirective proxy_cache_max_range_offset +syn keyword ngxDirective proxy_cache_methods +syn keyword ngxDirective proxy_cache_min_uses +syn keyword ngxDirective proxy_cache_path +syn keyword ngxDirective proxy_cache_purge +syn keyword ngxDirective proxy_cache_revalidate +syn keyword ngxDirective proxy_cache_use_stale +syn keyword ngxDirective proxy_cache_valid +syn keyword ngxDirective proxy_connect_timeout +syn keyword ngxDirective proxy_cookie_domain +syn keyword ngxDirective proxy_cookie_path +syn keyword ngxDirective proxy_download_rate +syn keyword ngxDirective proxy_force_ranges +syn keyword ngxDirective proxy_headers_hash_bucket_size +syn keyword ngxDirective proxy_headers_hash_max_size +syn keyword ngxDirective proxy_hide_header +syn keyword ngxDirective proxy_http_version +syn keyword ngxDirective proxy_ignore_client_abort +syn keyword ngxDirective proxy_ignore_headers +syn keyword ngxDirective proxy_intercept_errors +syn keyword ngxDirective proxy_limit_rate +syn keyword ngxDirective proxy_max_temp_file_size +syn keyword ngxDirective proxy_method +syn keyword ngxDirective proxy_next_upstream contained +syn region ngxDirectiveProxyNextUpstream matchgroup=ngxDirective start=+^\s*\zsproxy_next_upstream\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxProxyNextUpstreamOptions,ngxString,ngxTemplateVar +syn keyword ngxDirective proxy_next_upstream_timeout +syn keyword ngxDirective proxy_next_upstream_tries +syn keyword ngxDirective proxy_no_cache +syn keyword ngxDirective proxy_pass_error_message +syn keyword ngxDirective proxy_pass_header +syn keyword ngxDirective proxy_pass_request_body +syn keyword ngxDirective proxy_pass_request_headers +syn keyword ngxDirective proxy_protocol +syn keyword ngxDirective proxy_protocol_timeout +syn keyword ngxDirective proxy_read_timeout +syn keyword ngxDirective proxy_redirect +syn keyword ngxDirective proxy_request_buffering +syn keyword ngxDirective proxy_responses +syn keyword ngxDirective proxy_send_lowat +syn keyword ngxDirective proxy_send_timeout +syn keyword ngxDirective proxy_set_body +syn keyword ngxDirective proxy_set_header +syn keyword ngxDirective proxy_ssl_certificate +syn keyword ngxDirective proxy_ssl_certificate_key +syn keyword ngxDirective proxy_ssl_ciphers +syn keyword ngxDirective proxy_ssl_crl +syn keyword ngxDirective proxy_ssl_name +syn keyword ngxDirective proxy_ssl_password_file +syn keyword ngxDirective proxy_ssl_protocols nextgroup=ngxSSLProtocol skipwhite +syn keyword ngxDirective proxy_ssl_server_name +syn keyword ngxDirective proxy_ssl_session_reuse +syn keyword ngxDirective proxy_ssl_trusted_certificate +syn keyword ngxDirective proxy_ssl_verify +syn keyword ngxDirective proxy_ssl_verify_depth +syn keyword ngxDirective proxy_store +syn keyword ngxDirective proxy_store_access +syn keyword ngxDirective proxy_temp_file_write_size +syn keyword ngxDirective proxy_temp_path +syn keyword ngxDirective proxy_timeout +syn keyword ngxDirective proxy_upload_rate +syn keyword ngxDirective queue +syn keyword ngxDirective random_index +syn keyword ngxDirective read_ahead +syn keyword ngxDirective real_ip_header +syn keyword ngxDirective real_ip_recursive +syn keyword ngxDirective recursive_error_pages +syn keyword ngxDirective referer_hash_bucket_size +syn keyword ngxDirective referer_hash_max_size +syn keyword ngxDirective request_pool_size +syn keyword ngxDirective reset_timedout_connection +syn keyword ngxDirective resolver +syn keyword ngxDirective resolver_timeout +syn keyword ngxDirective rewrite_log +syn keyword ngxDirective rtsig_overflow_events +syn keyword ngxDirective rtsig_overflow_test +syn keyword ngxDirective rtsig_overflow_threshold +syn keyword ngxDirective rtsig_signo +syn keyword ngxDirective satisfy +syn keyword ngxDirective scgi_bind +syn keyword ngxDirective scgi_buffer_size +syn keyword ngxDirective scgi_buffering +syn keyword ngxDirective scgi_buffers +syn keyword ngxDirective scgi_busy_buffers_size +syn keyword ngxDirective scgi_cache +syn keyword ngxDirective scgi_cache_bypass +syn keyword ngxDirective scgi_cache_key +syn keyword ngxDirective scgi_cache_lock +syn keyword ngxDirective scgi_cache_lock_age +syn keyword ngxDirective scgi_cache_lock_timeout +syn keyword ngxDirective scgi_cache_max_range_offset +syn keyword ngxDirective scgi_cache_methods +syn keyword ngxDirective scgi_cache_min_uses +syn keyword ngxDirective scgi_cache_path +syn keyword ngxDirective scgi_cache_purge +syn keyword ngxDirective scgi_cache_revalidate +syn keyword ngxDirective scgi_cache_use_stale +syn keyword ngxDirective scgi_cache_valid +syn keyword ngxDirective scgi_connect_timeout +syn keyword ngxDirective scgi_force_ranges +syn keyword ngxDirective scgi_hide_header +syn keyword ngxDirective scgi_ignore_client_abort +syn keyword ngxDirective scgi_ignore_headers +syn keyword ngxDirective scgi_intercept_errors +syn keyword ngxDirective scgi_limit_rate +syn keyword ngxDirective scgi_max_temp_file_size +syn keyword ngxDirective scgi_next_upstream +syn keyword ngxDirective scgi_next_upstream_timeout +syn keyword ngxDirective scgi_next_upstream_tries +syn keyword ngxDirective scgi_no_cache +syn keyword ngxDirective scgi_param +syn keyword ngxDirective scgi_pass_header +syn keyword ngxDirective scgi_pass_request_body +syn keyword ngxDirective scgi_pass_request_headers +syn keyword ngxDirective scgi_read_timeout +syn keyword ngxDirective scgi_request_buffering +syn keyword ngxDirective scgi_send_timeout +syn keyword ngxDirective scgi_store +syn keyword ngxDirective scgi_store_access +syn keyword ngxDirective scgi_temp_file_write_size +syn keyword ngxDirective scgi_temp_path +syn keyword ngxDirective secure_link +syn keyword ngxDirective secure_link_md5 +syn keyword ngxDirective secure_link_secret +syn keyword ngxDirective send_lowat +syn keyword ngxDirective send_timeout +syn keyword ngxDirective sendfile +syn keyword ngxDirective sendfile_max_chunk +syn keyword ngxDirective server_name_in_redirect +syn keyword ngxDirective server_names_hash_bucket_size +syn keyword ngxDirective server_names_hash_max_size +syn keyword ngxDirective server_tokens +syn keyword ngxDirective session_log +syn keyword ngxDirective session_log_format +syn keyword ngxDirective session_log_zone +syn keyword ngxDirective set_real_ip_from +syn keyword ngxDirective slice +syn keyword ngxDirective smtp_auth +syn keyword ngxDirective smtp_capabilities +syn keyword ngxDirective smtp_client_buffer +syn keyword ngxDirective smtp_greeting_delay +syn keyword ngxDirective source_charset +syn keyword ngxDirective spdy_chunk_size +syn keyword ngxDirective spdy_headers_comp +syn keyword ngxDirective spdy_keepalive_timeout +syn keyword ngxDirective spdy_max_concurrent_streams +syn keyword ngxDirective spdy_pool_size +syn keyword ngxDirective spdy_recv_buffer_size +syn keyword ngxDirective spdy_recv_timeout +syn keyword ngxDirective spdy_streams_index_size +syn keyword ngxDirective ssi +syn keyword ngxDirective ssi_ignore_recycled_buffers +syn keyword ngxDirective ssi_last_modified +syn keyword ngxDirective ssi_min_file_chunk +syn keyword ngxDirective ssi_silent_errors +syn keyword ngxDirective ssi_types +syn keyword ngxDirective ssi_value_length +syn keyword ngxDirective ssl +syn keyword ngxDirective ssl_buffer_size +syn keyword ngxDirective ssl_certificate +syn keyword ngxDirective ssl_certificate_key +syn keyword ngxDirective ssl_ciphers +syn keyword ngxDirective ssl_client_certificate +syn keyword ngxDirective ssl_crl +syn keyword ngxDirective ssl_dhparam +syn keyword ngxDirective ssl_ecdh_curve +syn keyword ngxDirective ssl_engine +syn keyword ngxDirective ssl_handshake_timeout +syn keyword ngxDirective ssl_password_file +syn keyword ngxDirective ssl_prefer_server_ciphers nextgroup=ngxSSLPreferServerCiphersOff,ngxSSLPreferServerCiphersOn skipwhite +syn keyword ngxSSLPreferServerCiphersOn on contained +syn keyword ngxSSLPreferServerCiphersOff off contained +syn keyword ngxDirective ssl_preread +syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +syn match ngxSSLProtocol 'TLSv1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +syn match ngxSSLProtocol 'TLSv1\.1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +syn match ngxSSLProtocol 'TLSv1\.2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +syn match ngxSSLProtocol 'TLSv1\.3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite + +" Do not enable highlighting of insecure protocols if sslecure is loaded +if !exists('g:loaded_sslsecure') + syn keyword ngxSSLProtocolDeprecated SSLv2 SSLv3 contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +else + syn match ngxSSLProtocol 'SSLv2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite + syn match ngxSSLProtocol 'SSLv3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite +endif + +syn keyword ngxDirective ssl_session_cache +syn keyword ngxDirective ssl_session_ticket_key +syn keyword ngxDirective ssl_session_tickets nextgroup=ngxSSLSessionTicketsOn,ngxSSLSessionTicketsOff skipwhite +syn keyword ngxSSLSessionTicketsOn on contained +syn keyword ngxSSLSessionTicketsOff off contained +syn keyword ngxDirective ssl_session_timeout +syn keyword ngxDirective ssl_stapling +syn keyword ngxDirective ssl_stapling_file +syn keyword ngxDirective ssl_stapling_responder +syn keyword ngxDirective ssl_stapling_verify +syn keyword ngxDirective ssl_trusted_certificate +syn keyword ngxDirective ssl_verify_client +syn keyword ngxDirective ssl_verify_depth +syn keyword ngxDirective starttls +syn keyword ngxDirective state +syn keyword ngxDirective status +syn keyword ngxDirective status_format +syn keyword ngxDirective status_zone +syn keyword ngxDirective sticky contained +syn keyword ngxDirective sticky_cookie_insert contained +syn region ngxDirectiveSticky matchgroup=ngxDirective start=+^\s*\zssticky\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxCookieOptions,ngxString,ngxBoolean,ngxInteger,ngxTemplateVar +syn keyword ngxDirective stub_status +syn keyword ngxDirective sub_filter +syn keyword ngxDirective sub_filter_last_modified +syn keyword ngxDirective sub_filter_once +syn keyword ngxDirective sub_filter_types +syn keyword ngxDirective tcp_nodelay +syn keyword ngxDirective tcp_nopush +syn keyword ngxDirective thread_pool +syn keyword ngxDirective thread_stack_size +syn keyword ngxDirective timeout +syn keyword ngxDirective timer_resolution +syn keyword ngxDirective types_hash_bucket_size +syn keyword ngxDirective types_hash_max_size +syn keyword ngxDirective underscores_in_headers +syn keyword ngxDirective uninitialized_variable_warn +syn keyword ngxDirective upstream_conf +syn keyword ngxDirective use +syn keyword ngxDirective user +syn keyword ngxDirective userid +syn keyword ngxDirective userid_domain +syn keyword ngxDirective userid_expires +syn keyword ngxDirective userid_mark +syn keyword ngxDirective userid_name +syn keyword ngxDirective userid_p3p +syn keyword ngxDirective userid_path +syn keyword ngxDirective userid_service +syn keyword ngxDirective uwsgi_bind +syn keyword ngxDirective uwsgi_buffer_size +syn keyword ngxDirective uwsgi_buffering +syn keyword ngxDirective uwsgi_buffers +syn keyword ngxDirective uwsgi_busy_buffers_size +syn keyword ngxDirective uwsgi_cache +syn keyword ngxDirective uwsgi_cache_bypass +syn keyword ngxDirective uwsgi_cache_key +syn keyword ngxDirective uwsgi_cache_lock +syn keyword ngxDirective uwsgi_cache_lock_age +syn keyword ngxDirective uwsgi_cache_lock_timeout +syn keyword ngxDirective uwsgi_cache_methods +syn keyword ngxDirective uwsgi_cache_min_uses +syn keyword ngxDirective uwsgi_cache_path +syn keyword ngxDirective uwsgi_cache_purge +syn keyword ngxDirective uwsgi_cache_revalidate +syn keyword ngxDirective uwsgi_cache_use_stale +syn keyword ngxDirective uwsgi_cache_valid +syn keyword ngxDirective uwsgi_connect_timeout +syn keyword ngxDirective uwsgi_force_ranges +syn keyword ngxDirective uwsgi_hide_header +syn keyword ngxDirective uwsgi_ignore_client_abort +syn keyword ngxDirective uwsgi_ignore_headers +syn keyword ngxDirective uwsgi_intercept_errors +syn keyword ngxDirective uwsgi_limit_rate +syn keyword ngxDirective uwsgi_max_temp_file_size +syn keyword ngxDirective uwsgi_modifier1 +syn keyword ngxDirective uwsgi_modifier2 +syn keyword ngxDirective uwsgi_next_upstream +syn keyword ngxDirective uwsgi_next_upstream_timeout +syn keyword ngxDirective uwsgi_next_upstream_tries +syn keyword ngxDirective uwsgi_no_cache +syn keyword ngxDirective uwsgi_param +syn keyword ngxDirective uwsgi_pass +syn keyword ngxDirective uwsgi_pass_header +syn keyword ngxDirective uwsgi_pass_request_body +syn keyword ngxDirective uwsgi_pass_request_headers +syn keyword ngxDirective uwsgi_read_timeout +syn keyword ngxDirective uwsgi_request_buffering +syn keyword ngxDirective uwsgi_send_timeout +syn keyword ngxDirective uwsgi_ssl_certificate +syn keyword ngxDirective uwsgi_ssl_certificate_key +syn keyword ngxDirective uwsgi_ssl_ciphers +syn keyword ngxDirective uwsgi_ssl_crl +syn keyword ngxDirective uwsgi_ssl_name +syn keyword ngxDirective uwsgi_ssl_password_file +syn keyword ngxDirective uwsgi_ssl_protocols nextgroup=ngxSSLProtocol skipwhite +syn keyword ngxDirective uwsgi_ssl_server_name +syn keyword ngxDirective uwsgi_ssl_session_reuse +syn keyword ngxDirective uwsgi_ssl_trusted_certificate +syn keyword ngxDirective uwsgi_ssl_verify +syn keyword ngxDirective uwsgi_ssl_verify_depth +syn keyword ngxDirective uwsgi_store +syn keyword ngxDirective uwsgi_store_access +syn keyword ngxDirective uwsgi_string +syn keyword ngxDirective uwsgi_temp_file_write_size +syn keyword ngxDirective uwsgi_temp_path +syn keyword ngxDirective valid_referers +syn keyword ngxDirective variables_hash_bucket_size +syn keyword ngxDirective variables_hash_max_size +syn keyword ngxDirective worker_aio_requests +syn keyword ngxDirective worker_connections +syn keyword ngxDirective worker_cpu_affinity +syn keyword ngxDirective worker_priority +syn keyword ngxDirective worker_processes +syn keyword ngxDirective worker_rlimit_core +syn keyword ngxDirective worker_rlimit_nofile +syn keyword ngxDirective worker_rlimit_sigpending +syn keyword ngxDirective worker_threads +syn keyword ngxDirective working_directory +syn keyword ngxDirective xclient +syn keyword ngxDirective xml_entities +syn keyword ngxDirective xslt_last_modified +syn keyword ngxDirective xslt_param +syn keyword ngxDirective xslt_string_param +syn keyword ngxDirective xslt_stylesheet +syn keyword ngxDirective xslt_types +syn keyword ngxDirective zone + +" Do not enable highlighting of insecure ciphers if sslecure is loaded +if !exists('g:loaded_sslsecure') + " Mark insecure SSL Ciphers (Note: List might not not complete) + " Reference: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html + syn match ngxSSLCipherInsecure '[^!]\zsSSLv3' + syn match ngxSSLCipherInsecure '[^!]\zsSSLv2' + syn match ngxSSLCipherInsecure '[^!]\zsHIGH' + syn match ngxSSLCipherInsecure '[^!]\zsMEDIUM' + syn match ngxSSLCipherInsecure '[^!]\zsLOW' + syn match ngxSSLCipherInsecure '[^!]\zsDEFAULT' + syn match ngxSSLCipherInsecure '[^!]\zsCOMPLEMENTOFDEFAULT' + syn match ngxSSLCipherInsecure '[^!]\zsALL' + syn match ngxSSLCipherInsecure '[^!]\zsCOMPLEMENTOFALL' + + " SHA ciphers are only used in HMAC with all known OpenSSL/ LibreSSL cipher suites and MAC + " usage is still considered safe + " syn match ngxSSLCipherInsecure '[^!]\zsSHA\ze\D' " Match SHA1 without matching SHA256+ + " syn match ngxSSLCipherInsecure '[^!]\zsSHA1' + syn match ngxSSLCipherInsecure '[^!]\zsMD5' + syn match ngxSSLCipherInsecure '[^!]\zsRC2' + syn match ngxSSLCipherInsecure '[^!]\zsRC4' + syn match ngxSSLCipherInsecure '[^!]\zs3DES' + syn match ngxSSLCipherInsecure '[^!3]\zsDES' + syn match ngxSSLCipherInsecure '[^!]\zsaDSS' + syn match ngxSSLCipherInsecure '[^!a]\zsDSS' + syn match ngxSSLCipherInsecure '[^!]\zsPSK' + syn match ngxSSLCipherInsecure '[^!]\zsIDEA' + syn match ngxSSLCipherInsecure '[^!]\zsSEED' + syn match ngxSSLCipherInsecure '[^!]\zsEXP\w*' " Match all EXPORT ciphers + syn match ngxSSLCipherInsecure '[^!]\zsaGOST\w*' " Match all GOST ciphers + syn match ngxSSLCipherInsecure '[^!]\zskGOST\w*' + syn match ngxSSLCipherInsecure '[^!ak]\zsGOST\w*' + syn match ngxSSLCipherInsecure '[^!]\zs[kae]\?FZA' " Not implemented + syn match ngxSSLCipherInsecure '[^!]\zsECB' + syn match ngxSSLCipherInsecure '[^!]\zs[aes]NULL' + + " Anonymous cipher suites should never be used + syn match ngxSSLCipherInsecure '[^!ECa]\zsDH\ze[^E]' " Try to match DH without DHE, EDH, EECDH, etc. + syn match ngxSSLCipherInsecure '[^!EA]\zsECDH\ze[^E]' " Do not match EECDH, ECDHE + syn match ngxSSLCipherInsecure '[^!]\zsADH' + syn match ngxSSLCipherInsecure '[^!]\zskDHE' + syn match ngxSSLCipherInsecure '[^!]\zskEDH' + syn match ngxSSLCipherInsecure '[^!]\zskECDHE' + syn match ngxSSLCipherInsecure '[^!]\zskEECDH' + syn match ngxSSLCipherInsecure '[^!E]\zsAECDH' +endif + +syn keyword ngxProxyNextUpstreamOptions error contained +syn keyword ngxProxyNextUpstreamOptions timeout contained +syn keyword ngxProxyNextUpstreamOptions invalid_header contained +syn keyword ngxProxyNextUpstreamOptions http_500 contained +syn keyword ngxProxyNextUpstreamOptions http_502 contained +syn keyword ngxProxyNextUpstreamOptions http_503 contained +syn keyword ngxProxyNextUpstreamOptions http_504 contained +syn keyword ngxProxyNextUpstreamOptions http_403 contained +syn keyword ngxProxyNextUpstreamOptions http_404 contained +syn keyword ngxProxyNextUpstreamOptions http_429 contained +syn keyword ngxProxyNextUpstreamOptions non_idempotent contained +syn keyword ngxProxyNextUpstreamOptions off contained + +syn keyword ngxStickyOptions cookie contained +syn region ngxStickyOptionsCookie matchgroup=ngxStickyOptions start=+^\s*\zssticky\s\s*cookie\ze\s.*;+ skip=+\\\\\|\\\;+ end=+;+he=e-1 contains=ngxCookieOptions,ngxString,ngxBoolean,ngxInteger,ngxTemplateVar +syn keyword ngxStickyOptions route contained +syn keyword ngxStickyOptions learn contained + +syn keyword ngxCookieOptions expires contained +syn keyword ngxCookieOptions domain contained +syn keyword ngxCookieOptions httponly contained +syn keyword ngxCookieOptions secure contained +syn keyword ngxCookieOptions path contained + +" 3rd party module list: +" https://www.nginx.com/resources/wiki/modules/ + +" Accept Language Module <https://www.nginx.com/resources/wiki/modules/accept_language/> +" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales. +syn keyword ngxDirectiveThirdParty set_from_accept_language + +" Access Key Module (DEPRECATED) <http://wiki.nginx.org/NginxHttpAccessKeyModule> +" Denies access unless the request URL contains an access key. +syn keyword ngxDirectiveDeprecated accesskey +syn keyword ngxDirectiveDeprecated accesskey_arg +syn keyword ngxDirectiveDeprecated accesskey_hashmethod +syn keyword ngxDirectiveDeprecated accesskey_signature + +" Asynchronous FastCGI Module <https://github.com/rsms/afcgi> +" Primarily a modified version of the Nginx FastCGI module which implements multiplexing of connections, allowing a single FastCGI server to handle many concurrent requests. +" syn keyword ngxDirectiveThirdParty fastcgi_bind +" syn keyword ngxDirectiveThirdParty fastcgi_buffer_size +" syn keyword ngxDirectiveThirdParty fastcgi_buffers +" syn keyword ngxDirectiveThirdParty fastcgi_busy_buffers_size +" syn keyword ngxDirectiveThirdParty fastcgi_cache +" syn keyword ngxDirectiveThirdParty fastcgi_cache_key +" syn keyword ngxDirectiveThirdParty fastcgi_cache_methods +" syn keyword ngxDirectiveThirdParty fastcgi_cache_min_uses +" syn keyword ngxDirectiveThirdParty fastcgi_cache_path +" syn keyword ngxDirectiveThirdParty fastcgi_cache_use_stale +" syn keyword ngxDirectiveThirdParty fastcgi_cache_valid +" syn keyword ngxDirectiveThirdParty fastcgi_catch_stderr +" syn keyword ngxDirectiveThirdParty fastcgi_connect_timeout +" syn keyword ngxDirectiveThirdParty fastcgi_hide_header +" syn keyword ngxDirectiveThirdParty fastcgi_ignore_client_abort +" syn keyword ngxDirectiveThirdParty fastcgi_ignore_headers +" syn keyword ngxDirectiveThirdParty fastcgi_index +" syn keyword ngxDirectiveThirdParty fastcgi_intercept_errors +" syn keyword ngxDirectiveThirdParty fastcgi_max_temp_file_size +" syn keyword ngxDirectiveThirdParty fastcgi_next_upstream +" syn keyword ngxDirectiveThirdParty fastcgi_param +" syn keyword ngxDirectiveThirdParty fastcgi_pass +" syn keyword ngxDirectiveThirdParty fastcgi_pass_header +" syn keyword ngxDirectiveThirdParty fastcgi_pass_request_body +" syn keyword ngxDirectiveThirdParty fastcgi_pass_request_headers +" syn keyword ngxDirectiveThirdParty fastcgi_read_timeout +" syn keyword ngxDirectiveThirdParty fastcgi_send_lowat +" syn keyword ngxDirectiveThirdParty fastcgi_send_timeout +" syn keyword ngxDirectiveThirdParty fastcgi_split_path_info +" syn keyword ngxDirectiveThirdParty fastcgi_store +" syn keyword ngxDirectiveThirdParty fastcgi_store_access +" syn keyword ngxDirectiveThirdParty fastcgi_temp_file_write_size +" syn keyword ngxDirectiveThirdParty fastcgi_temp_path +syn keyword ngxDirectiveDeprecated fastcgi_upstream_fail_timeout +syn keyword ngxDirectiveDeprecated fastcgi_upstream_max_fails + +" Akamai G2O Module <https://github.com/kaltura/nginx_mod_akamai_g2o> +" Nginx Module for Authenticating Akamai G2O requests +syn keyword ngxDirectiveThirdParty g2o +syn keyword ngxDirectiveThirdParty g2o_nonce +syn keyword ngxDirectiveThirdParty g2o_key + +" Lua Module <https://github.com/alacner/nginx_lua_module> +" You can be very simple to execute lua code for nginx +syn keyword ngxDirectiveThirdParty lua_file + +" Array Variable Module <https://github.com/openresty/array-var-nginx-module> +" Add support for array-typed variables to nginx config files +syn keyword ngxDirectiveThirdParty array_split +syn keyword ngxDirectiveThirdParty array_join +syn keyword ngxDirectiveThirdParty array_map +syn keyword ngxDirectiveThirdParty array_map_op + +" Nginx Audio Track for HTTP Live Streaming <https://github.com/flavioribeiro/nginx-audio-track-for-hls-module> +" This nginx module generates audio track for hls streams on the fly. +syn keyword ngxDirectiveThirdParty ngx_hls_audio_track +syn keyword ngxDirectiveThirdParty ngx_hls_audio_track_rootpath +syn keyword ngxDirectiveThirdParty ngx_hls_audio_track_output_format +syn keyword ngxDirectiveThirdParty ngx_hls_audio_track_output_header + +" AWS Proxy Module <https://github.com/anomalizer/ngx_aws_auth> +" Nginx module to proxy to authenticated AWS services +syn keyword ngxDirectiveThirdParty aws_access_key +syn keyword ngxDirectiveThirdParty aws_key_scope +syn keyword ngxDirectiveThirdParty aws_signing_key +syn keyword ngxDirectiveThirdParty aws_endpoint +syn keyword ngxDirectiveThirdParty aws_s3_bucket +syn keyword ngxDirectiveThirdParty aws_sign + +" Backtrace module <https://github.com/alibaba/nginx-backtrace> +" A Nginx module to dump backtrace when a worker process exits abnormally +syn keyword ngxDirectiveThirdParty backtrace_log +syn keyword ngxDirectiveThirdParty backtrace_max_stack_size + +" Brotli Module <https://github.com/google/ngx_brotli> +" Nginx module for Brotli compression +syn keyword ngxDirectiveThirdParty brotli_static +syn keyword ngxDirectiveThirdParty brotli +syn keyword ngxDirectiveThirdParty brotli_types +syn keyword ngxDirectiveThirdParty brotli_buffers +syn keyword ngxDirectiveThirdParty brotli_comp_level +syn keyword ngxDirectiveThirdParty brotli_window +syn keyword ngxDirectiveThirdParty brotli_min_length + +" Cache Purge Module <https://github.com/FRiCKLE/ngx_cache_purge> +" Adds ability to purge content from FastCGI, proxy, SCGI and uWSGI caches. +syn keyword ngxDirectiveThirdParty fastcgi_cache_purge +syn keyword ngxDirectiveThirdParty proxy_cache_purge +" syn keyword ngxDirectiveThirdParty scgi_cache_purge +" syn keyword ngxDirectiveThirdParty uwsgi_cache_purge + +" Chunkin Module (DEPRECATED) <http://wiki.nginx.org/NginxHttpChunkinModule> +" HTTP 1.1 chunked-encoding request body support for Nginx. +syn keyword ngxDirectiveDeprecated chunkin +syn keyword ngxDirectiveDeprecated chunkin_keepalive +syn keyword ngxDirectiveDeprecated chunkin_max_chunks_per_buf +syn keyword ngxDirectiveDeprecated chunkin_resume + +" Circle GIF Module <https://github.com/evanmiller/nginx_circle_gif> +" Generates simple circle images with the colors and size specified in the URL. +syn keyword ngxDirectiveThirdParty circle_gif +syn keyword ngxDirectiveThirdParty circle_gif_max_radius +syn keyword ngxDirectiveThirdParty circle_gif_min_radius +syn keyword ngxDirectiveThirdParty circle_gif_step_radius + +" Nginx-Clojure Module <http://nginx-clojure.github.io/index.html> +" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales. +syn keyword ngxDirectiveThirdParty jvm_path +syn keyword ngxDirectiveThirdParty jvm_var +syn keyword ngxDirectiveThirdParty jvm_classpath +syn keyword ngxDirectiveThirdParty jvm_classpath_check +syn keyword ngxDirectiveThirdParty jvm_workers +syn keyword ngxDirectiveThirdParty jvm_options +syn keyword ngxDirectiveThirdParty jvm_handler_type +syn keyword ngxDirectiveThirdParty jvm_init_handler_name +syn keyword ngxDirectiveThirdParty jvm_init_handler_code +syn keyword ngxDirectiveThirdParty jvm_exit_handler_name +syn keyword ngxDirectiveThirdParty jvm_exit_handler_code +syn keyword ngxDirectiveThirdParty handlers_lazy_init +syn keyword ngxDirectiveThirdParty auto_upgrade_ws +syn keyword ngxDirectiveThirdParty content_handler_type +syn keyword ngxDirectiveThirdParty content_handler_name +syn keyword ngxDirectiveThirdParty content_handler_code +syn keyword ngxDirectiveThirdParty rewrite_handler_type +syn keyword ngxDirectiveThirdParty rewrite_handler_name +syn keyword ngxDirectiveThirdParty rewrite_handler_code +syn keyword ngxDirectiveThirdParty access_handler_type +syn keyword ngxDirectiveThirdParty access_handler_name +syn keyword ngxDirectiveThirdParty access_handler_code +syn keyword ngxDirectiveThirdParty header_filter_type +syn keyword ngxDirectiveThirdParty header_filter_name +syn keyword ngxDirectiveThirdParty header_filter_code +syn keyword ngxDirectiveThirdParty content_handler_property +syn keyword ngxDirectiveThirdParty rewrite_handler_property +syn keyword ngxDirectiveThirdParty access_handler_property +syn keyword ngxDirectiveThirdParty header_filter_property +syn keyword ngxDirectiveThirdParty always_read_body +syn keyword ngxDirectiveThirdParty shared_map +syn keyword ngxDirectiveThirdParty write_page_size + +" Upstream Consistent Hash <https://www.nginx.com/resources/wiki/modules/consistent_hash/> +" A load balancer that uses an internal consistent hash ring to select the right backend node. +syn keyword ngxDirectiveThirdParty consistent_hash + +" Nginx Development Kit <https://github.com/simpl/ngx_devel_kit> +" The NDK is an Nginx module that is designed to extend the core functionality of the excellent Nginx webserver in a way that can be used as a basis of other Nginx modules. +" NDK_UPSTREAM_LIST +" This submodule provides a directive that creates a list of upstreams, with optional weighting. This list can then be used by other modules to hash over the upstreams however they choose. +syn keyword ngxDirectiveThirdParty upstream_list + +" Drizzle Module <https://www.nginx.com/resources/wiki/modules/drizzle/> +" Upstream module for talking to MySQL and Drizzle directly +syn keyword ngxDirectiveThirdParty drizzle_server +syn keyword ngxDirectiveThirdParty drizzle_keepalive +syn keyword ngxDirectiveThirdParty drizzle_query +syn keyword ngxDirectiveThirdParty drizzle_pass +syn keyword ngxDirectiveThirdParty drizzle_connect_timeout +syn keyword ngxDirectiveThirdParty drizzle_send_query_timeout +syn keyword ngxDirectiveThirdParty drizzle_recv_cols_timeout +syn keyword ngxDirectiveThirdParty drizzle_recv_rows_timeout +syn keyword ngxDirectiveThirdParty drizzle_buffer_size +syn keyword ngxDirectiveThirdParty drizzle_module_header +syn keyword ngxDirectiveThirdParty drizzle_status + +" Dynamic ETags Module <https://github.com/kali/nginx-dynamic-etags> +" Attempt at handling ETag / If-None-Match on proxied content. +syn keyword ngxDirectiveThirdParty dynamic_etags + +" Echo Module <https://www.nginx.com/resources/wiki/modules/echo/> +" Bringing the power of "echo", "sleep", "time" and more to Nginx's config file +syn keyword ngxDirectiveThirdParty echo +syn keyword ngxDirectiveThirdParty echo_duplicate +syn keyword ngxDirectiveThirdParty echo_flush +syn keyword ngxDirectiveThirdParty echo_sleep +syn keyword ngxDirectiveThirdParty echo_blocking_sleep +syn keyword ngxDirectiveThirdParty echo_reset_timer +syn keyword ngxDirectiveThirdParty echo_read_request_body +syn keyword ngxDirectiveThirdParty echo_location_async +syn keyword ngxDirectiveThirdParty echo_location +syn keyword ngxDirectiveThirdParty echo_subrequest_async +syn keyword ngxDirectiveThirdParty echo_subrequest +syn keyword ngxDirectiveThirdParty echo_foreach_split +syn keyword ngxDirectiveThirdParty echo_end +syn keyword ngxDirectiveThirdParty echo_request_body +syn keyword ngxDirectiveThirdParty echo_exec +syn keyword ngxDirectiveThirdParty echo_status +syn keyword ngxDirectiveThirdParty echo_before_body +syn keyword ngxDirectiveThirdParty echo_after_body + +" Encrypted Session Module <https://github.com/openresty/encrypted-session-nginx-module> +" Encrypt and decrypt nginx variable values +syn keyword ngxDirectiveThirdParty encrypted_session_key +syn keyword ngxDirectiveThirdParty encrypted_session_iv +syn keyword ngxDirectiveThirdParty encrypted_session_expires +syn keyword ngxDirectiveThirdParty set_encrypt_session +syn keyword ngxDirectiveThirdParty set_decrypt_session + +" Enhanced Memcached Module <https://github.com/bpaquet/ngx_http_enhanced_memcached_module> +" This module is based on the standard Nginx Memcached module, with some additonal features +syn keyword ngxDirectiveThirdParty enhanced_memcached_pass +syn keyword ngxDirectiveThirdParty enhanced_memcached_hash_keys_with_md5 +syn keyword ngxDirectiveThirdParty enhanced_memcached_allow_put +syn keyword ngxDirectiveThirdParty enhanced_memcached_allow_delete +syn keyword ngxDirectiveThirdParty enhanced_memcached_stats +syn keyword ngxDirectiveThirdParty enhanced_memcached_flush +syn keyword ngxDirectiveThirdParty enhanced_memcached_flush_namespace +syn keyword ngxDirectiveThirdParty enhanced_memcached_bind +syn keyword ngxDirectiveThirdParty enhanced_memcached_connect_timeout +syn keyword ngxDirectiveThirdParty enhanced_memcached_send_timeout +syn keyword ngxDirectiveThirdParty enhanced_memcached_buffer_size +syn keyword ngxDirectiveThirdParty enhanced_memcached_read_timeout + +" Events Module (DEPRECATED) <http://docs.dutov.org/nginx_modules_events_en.html> +" Provides options for start/stop events. +syn keyword ngxDirectiveDeprecated on_start +syn keyword ngxDirectiveDeprecated on_stop + +" EY Balancer Module <https://github.com/ezmobius/nginx-ey-balancer> +" Adds a request queue to Nginx that allows the limiting of concurrent requests passed to the upstream. +syn keyword ngxDirectiveThirdParty max_connections +syn keyword ngxDirectiveThirdParty max_connections_max_queue_length +syn keyword ngxDirectiveThirdParty max_connections_queue_timeout + +" Upstream Fair Balancer <https://www.nginx.com/resources/wiki/modules/fair_balancer/> +" Sends an incoming request to the least-busy backend server, rather than distributing requests round-robin. +syn keyword ngxDirectiveThirdParty fair +syn keyword ngxDirectiveThirdParty upstream_fair_shm_size + +" Fancy Indexes Module <https://github.com/aperezdc/ngx-fancyindex> +" Like the built-in autoindex module, but fancier. +syn keyword ngxDirectiveThirdParty fancyindex +syn keyword ngxDirectiveThirdParty fancyindex_default_sort +syn keyword ngxDirectiveThirdParty fancyindex_directories_first +syn keyword ngxDirectiveThirdParty fancyindex_css_href +syn keyword ngxDirectiveThirdParty fancyindex_exact_size +syn keyword ngxDirectiveThirdParty fancyindex_name_length +syn keyword ngxDirectiveThirdParty fancyindex_footer +syn keyword ngxDirectiveThirdParty fancyindex_header +syn keyword ngxDirectiveThirdParty fancyindex_show_path +syn keyword ngxDirectiveThirdParty fancyindex_ignore +syn keyword ngxDirectiveThirdParty fancyindex_hide_symlinks +syn keyword ngxDirectiveThirdParty fancyindex_localtime +syn keyword ngxDirectiveThirdParty fancyindex_time_format + +" Form Auth Module <https://github.com/veruu/ngx_form_auth> +" Provides authentication and authorization with credentials submitted via POST request +syn keyword ngxDirectiveThirdParty form_auth +syn keyword ngxDirectiveThirdParty form_auth_pam_service +syn keyword ngxDirectiveThirdParty form_auth_login +syn keyword ngxDirectiveThirdParty form_auth_password +syn keyword ngxDirectiveThirdParty form_auth_remote_user + +" Form Input Module <https://github.com/calio/form-input-nginx-module> +" Reads HTTP POST and PUT request body encoded in "application/x-www-form-urlencoded" and parses the arguments into nginx variables. +syn keyword ngxDirectiveThirdParty set_form_input +syn keyword ngxDirectiveThirdParty set_form_input_multi + +" GeoIP Module (DEPRECATED) <http://wiki.nginx.org/NginxHttp3rdPartyGeoIPModule> +" Country code lookups via the MaxMind GeoIP API. +syn keyword ngxDirectiveDeprecated geoip_country_file + +" GeoIP 2 Module <https://github.com/leev/ngx_http_geoip2_module> +" Creates variables with values from the maxmind geoip2 databases based on the client IP +syn keyword ngxDirectiveThirdParty geoip2 + +" GridFS Module <https://github.com/mdirolf/nginx-gridfs> +" Nginx module for serving files from MongoDB's GridFS +syn keyword ngxDirectiveThirdParty gridfs + +" Headers More Module <https://github.com/openresty/headers-more-nginx-module> +" Set and clear input and output headers...more than "add"! +syn keyword ngxDirectiveThirdParty more_clear_headers +syn keyword ngxDirectiveThirdParty more_clear_input_headers +syn keyword ngxDirectiveThirdParty more_set_headers +syn keyword ngxDirectiveThirdParty more_set_input_headers + +" Health Checks Upstreams Module <https://www.nginx.com/resources/wiki/modules/healthcheck/> +" Polls backends and if they respond with HTTP 200 + an optional request body, they are marked good. Otherwise, they are marked bad. +syn keyword ngxDirectiveThirdParty healthcheck_enabled +syn keyword ngxDirectiveThirdParty healthcheck_delay +syn keyword ngxDirectiveThirdParty healthcheck_timeout +syn keyword ngxDirectiveThirdParty healthcheck_failcount +syn keyword ngxDirectiveThirdParty healthcheck_send +syn keyword ngxDirectiveThirdParty healthcheck_expected +syn keyword ngxDirectiveThirdParty healthcheck_buffer +syn keyword ngxDirectiveThirdParty healthcheck_status + +" HTTP Accounting Module <https://github.com/Lax/ngx_http_accounting_module> +" Add traffic stat function to nginx. Useful for http accounting based on nginx configuration logic +syn keyword ngxDirectiveThirdParty http_accounting +syn keyword ngxDirectiveThirdParty http_accounting_log +syn keyword ngxDirectiveThirdParty http_accounting_id +syn keyword ngxDirectiveThirdParty http_accounting_interval +syn keyword ngxDirectiveThirdParty http_accounting_perturb + +" Nginx Digest Authentication module <https://github.com/atomx/nginx-http-auth-digest> +" Digest Authentication for Nginx +syn keyword ngxDirectiveThirdParty auth_digest +syn keyword ngxDirectiveThirdParty auth_digest_user_file +syn keyword ngxDirectiveThirdParty auth_digest_timeout +syn keyword ngxDirectiveThirdParty auth_digest_expires +syn keyword ngxDirectiveThirdParty auth_digest_replays +syn keyword ngxDirectiveThirdParty auth_digest_shm_size + +" Auth PAM Module <https://github.com/sto/ngx_http_auth_pam_module> +" HTTP Basic Authentication using PAM. +syn keyword ngxDirectiveThirdParty auth_pam +syn keyword ngxDirectiveThirdParty auth_pam_service_name + +" HTTP Auth Request Module <http://nginx.org/en/docs/http/ngx_http_auth_request_module.html> +" Implements client authorization based on the result of a subrequest +" syn keyword ngxDirectiveThirdParty auth_request +" syn keyword ngxDirectiveThirdParty auth_request_set + +" HTTP Concatenation module for Nginx <https://github.com/alibaba/nginx-http-concat> +" A Nginx module for concatenating files in a given context: CSS and JS files usually +syn keyword ngxDirectiveThirdParty concat +syn keyword ngxDirectiveThirdParty concat_types +syn keyword ngxDirectiveThirdParty concat_unique +syn keyword ngxDirectiveThirdParty concat_max_files +syn keyword ngxDirectiveThirdParty concat_delimiter +syn keyword ngxDirectiveThirdParty concat_ignore_file_error + +" HTTP Dynamic Upstream Module <https://github.com/yzprofile/ngx_http_dyups_module> +" Update upstreams' config by restful interface +syn keyword ngxDirectiveThirdParty dyups_interface +syn keyword ngxDirectiveThirdParty dyups_read_msg_timeout +syn keyword ngxDirectiveThirdParty dyups_shm_zone_size +syn keyword ngxDirectiveThirdParty dyups_upstream_conf +syn keyword ngxDirectiveThirdParty dyups_trylock + +" HTTP Footer If Filter Module <https://github.com/flygoast/ngx_http_footer_if_filter> +" The ngx_http_footer_if_filter_module is used to add given content to the end of the response according to the condition specified. +syn keyword ngxDirectiveThirdParty footer_if + +" HTTP Footer Filter Module <https://github.com/alibaba/nginx-http-footer-filter> +" This module implements a body filter that adds a given string to the page footer. +syn keyword ngxDirectiveThirdParty footer +syn keyword ngxDirectiveThirdParty footer_types + +" HTTP Internal Redirect Module <https://github.com/flygoast/ngx_http_internal_redirect> +" Make an internal redirect to the uri specified according to the condition specified. +syn keyword ngxDirectiveThirdParty internal_redirect_if +syn keyword ngxDirectiveThirdParty internal_redirect_if_no_postponed + +" HTTP JavaScript Module <https://github.com/peter-leonov/ngx_http_js_module> +" Embedding SpiderMonkey. Nearly full port on Perl module. +syn keyword ngxDirectiveThirdParty js +syn keyword ngxDirectiveThirdParty js_filter +syn keyword ngxDirectiveThirdParty js_filter_types +syn keyword ngxDirectiveThirdParty js_load +syn keyword ngxDirectiveThirdParty js_maxmem +syn keyword ngxDirectiveThirdParty js_require +syn keyword ngxDirectiveThirdParty js_set +syn keyword ngxDirectiveThirdParty js_utf8 + +" HTTP Push Module (DEPRECATED) <http://pushmodule.slact.net/> +" Turn Nginx into an adept long-polling HTTP Push (Comet) server. +syn keyword ngxDirectiveDeprecated push_buffer_size +syn keyword ngxDirectiveDeprecated push_listener +syn keyword ngxDirectiveDeprecated push_message_timeout +syn keyword ngxDirectiveDeprecated push_queue_messages +syn keyword ngxDirectiveDeprecated push_sender + +" HTTP Redis Module <https://www.nginx.com/resources/wiki/modules/redis/> +" Redis <http://code.google.com/p/redis/> support. +syn keyword ngxDirectiveThirdParty redis_bind +syn keyword ngxDirectiveThirdParty redis_buffer_size +syn keyword ngxDirectiveThirdParty redis_connect_timeout +syn keyword ngxDirectiveThirdParty redis_next_upstream +syn keyword ngxDirectiveThirdParty redis_pass +syn keyword ngxDirectiveThirdParty redis_read_timeout +syn keyword ngxDirectiveThirdParty redis_send_timeout + +" Iconv Module <https://github.com/calio/iconv-nginx-module> +" A character conversion nginx module using libiconv +syn keyword ngxDirectiveThirdParty set_iconv +syn keyword ngxDirectiveThirdParty iconv_buffer_size +syn keyword ngxDirectiveThirdParty iconv_filter + +" IP Blocker Module <https://github.com/tmthrgd/nginx-ip-blocker> +" An efficient shared memory IP blocking system for nginx. +syn keyword ngxDirectiveThirdParty ip_blocker + +" IP2Location Module <https://github.com/chrislim2888/ip2location-nginx> +" Allows user to lookup for geolocation information using IP2Location database +syn keyword ngxDirectiveThirdParty ip2location_database + +" JS Module <https://github.com/peter-leonov/ngx_http_js_module> +" Reflect the nginx functionality in JS +syn keyword ngxDirectiveThirdParty js +syn keyword ngxDirectiveThirdParty js_access +syn keyword ngxDirectiveThirdParty js_load +syn keyword ngxDirectiveThirdParty js_set + +" Limit Upload Rate Module <https://github.com/cfsego/limit_upload_rate> +" Limit client-upload rate when they are sending request bodies to you +syn keyword ngxDirectiveThirdParty limit_upload_rate +syn keyword ngxDirectiveThirdParty limit_upload_rate_after + +" Limit Upstream Module <https://github.com/cfsego/nginx-limit-upstream> +" Limit the number of connections to upstream for NGINX +syn keyword ngxDirectiveThirdParty limit_upstream_zone +syn keyword ngxDirectiveThirdParty limit_upstream_conn +syn keyword ngxDirectiveThirdParty limit_upstream_log_level + +" Log If Module <https://github.com/cfsego/ngx_log_if> +" Conditional accesslog for nginx +syn keyword ngxDirectiveThirdParty access_log_bypass_if + +" Log Request Speed (DEPRECATED) <http://wiki.nginx.org/NginxHttpLogRequestSpeed> +" Log the time it took to process each request. +syn keyword ngxDirectiveDeprecated log_request_speed_filter +syn keyword ngxDirectiveDeprecated log_request_speed_filter_timeout + +" Log ZeroMQ Module <https://github.com/alticelabs/nginx-log-zmq> +" ZeroMQ logger module for nginx +syn keyword ngxDirectiveThirdParty log_zmq_server +syn keyword ngxDirectiveThirdParty log_zmq_endpoint +syn keyword ngxDirectiveThirdParty log_zmq_format +syn keyword ngxDirectiveThirdParty log_zmq_off + +" Lower/UpperCase Module <https://github.com/replay/ngx_http_lower_upper_case> +" This module simply uppercases or lowercases a string and saves it into a new variable. +syn keyword ngxDirectiveThirdParty lower +syn keyword ngxDirectiveThirdParty upper + +" Lua Upstream Module <https://github.com/openresty/lua-upstream-nginx-module> +" Nginx C module to expose Lua API to ngx_lua for Nginx upstreams + +" Lua Module <https://github.com/openresty/lua-nginx-module> +" Embed the Power of Lua into NGINX HTTP servers +syn keyword ngxDirectiveThirdParty lua_use_default_type +syn keyword ngxDirectiveThirdParty lua_malloc_trim +syn keyword ngxDirectiveThirdParty lua_code_cache +syn keyword ngxDirectiveThirdParty lua_regex_cache_max_entries +syn keyword ngxDirectiveThirdParty lua_regex_match_limit +syn keyword ngxDirectiveThirdParty lua_package_path +syn keyword ngxDirectiveThirdParty lua_package_cpath +syn keyword ngxDirectiveThirdParty init_by_lua +syn keyword ngxDirectiveThirdParty init_by_lua_file +syn keyword ngxDirectiveThirdParty init_worker_by_lua +syn keyword ngxDirectiveThirdParty init_worker_by_lua_file +syn keyword ngxDirectiveThirdParty set_by_lua +syn keyword ngxDirectiveThirdParty set_by_lua_file +syn keyword ngxDirectiveThirdParty content_by_lua +syn keyword ngxDirectiveThirdParty content_by_lua_file +syn keyword ngxDirectiveThirdParty rewrite_by_lua +syn keyword ngxDirectiveThirdParty rewrite_by_lua_file +syn keyword ngxDirectiveThirdParty access_by_lua +syn keyword ngxDirectiveThirdParty access_by_lua_file +syn keyword ngxDirectiveThirdParty header_filter_by_lua +syn keyword ngxDirectiveThirdParty header_filter_by_lua_file +syn keyword ngxDirectiveThirdParty body_filter_by_lua +syn keyword ngxDirectiveThirdParty body_filter_by_lua_file +syn keyword ngxDirectiveThirdParty log_by_lua +syn keyword ngxDirectiveThirdParty log_by_lua_file +syn keyword ngxDirectiveThirdParty balancer_by_lua_file +syn keyword ngxDirectiveThirdParty lua_need_request_body +syn keyword ngxDirectiveThirdParty ssl_certificate_by_lua_file +syn keyword ngxDirectiveThirdParty ssl_session_fetch_by_lua_file +syn keyword ngxDirectiveThirdParty ssl_session_store_by_lua_file +syn keyword ngxDirectiveThirdParty lua_shared_dict +syn keyword ngxDirectiveThirdParty lua_socket_connect_timeout +syn keyword ngxDirectiveThirdParty lua_socket_send_timeout +syn keyword ngxDirectiveThirdParty lua_socket_send_lowat +syn keyword ngxDirectiveThirdParty lua_socket_read_timeout +syn keyword ngxDirectiveThirdParty lua_socket_buffer_size +syn keyword ngxDirectiveThirdParty lua_socket_pool_size +syn keyword ngxDirectiveThirdParty lua_socket_keepalive_timeout +syn keyword ngxDirectiveThirdParty lua_socket_log_errors +syn keyword ngxDirectiveThirdParty lua_ssl_ciphers +syn keyword ngxDirectiveThirdParty lua_ssl_crl +syn keyword ngxDirectiveThirdParty lua_ssl_protocols +syn keyword ngxDirectiveThirdParty lua_ssl_trusted_certificate +syn keyword ngxDirectiveThirdParty lua_ssl_verify_depth +syn keyword ngxDirectiveThirdParty lua_http10_buffering +syn keyword ngxDirectiveThirdParty rewrite_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty access_by_lua_no_postpone +syn keyword ngxDirectiveThirdParty lua_transform_underscores_in_response_headers +syn keyword ngxDirectiveThirdParty lua_check_client_abort +syn keyword ngxDirectiveThirdParty lua_max_pending_timers +syn keyword ngxDirectiveThirdParty lua_max_running_timers + +" MD5 Filter Module <https://github.com/kainswor/nginx_md5_filter> +" A content filter for nginx, which returns the md5 hash of the content otherwise returned. +syn keyword ngxDirectiveThirdParty md5_filter + +" Memc Module <https://github.com/openresty/memc-nginx-module> +" An extended version of the standard memcached module that supports set, add, delete, and many more memcached commands. +syn keyword ngxDirectiveThirdParty memc_buffer_size +syn keyword ngxDirectiveThirdParty memc_cmds_allowed +syn keyword ngxDirectiveThirdParty memc_connect_timeout +syn keyword ngxDirectiveThirdParty memc_flags_to_last_modified +syn keyword ngxDirectiveThirdParty memc_next_upstream +syn keyword ngxDirectiveThirdParty memc_pass +syn keyword ngxDirectiveThirdParty memc_read_timeout +syn keyword ngxDirectiveThirdParty memc_send_timeout +syn keyword ngxDirectiveThirdParty memc_upstream_fail_timeout +syn keyword ngxDirectiveThirdParty memc_upstream_max_fails + +" Mod Security Module <https://github.com/SpiderLabs/ModSecurity> +" ModSecurity is an open source, cross platform web application firewall (WAF) engine +syn keyword ngxDirectiveThirdParty ModSecurityConfig +syn keyword ngxDirectiveThirdParty ModSecurityEnabled +syn keyword ngxDirectiveThirdParty pool_context +syn keyword ngxDirectiveThirdParty pool_context_hash_size + +" Mogilefs Module <http://www.grid.net.ru/nginx/mogilefs.en.html> +" MogileFS client for nginx web server. +syn keyword ngxDirectiveThirdParty mogilefs_pass +syn keyword ngxDirectiveThirdParty mogilefs_methods +syn keyword ngxDirectiveThirdParty mogilefs_domain +syn keyword ngxDirectiveThirdParty mogilefs_class +syn keyword ngxDirectiveThirdParty mogilefs_tracker +syn keyword ngxDirectiveThirdParty mogilefs_noverify +syn keyword ngxDirectiveThirdParty mogilefs_connect_timeout +syn keyword ngxDirectiveThirdParty mogilefs_send_timeout +syn keyword ngxDirectiveThirdParty mogilefs_read_timeout + +" Mongo Module <https://github.com/simpl/ngx_mongo> +" Upstream module that allows nginx to communicate directly with MongoDB database. +syn keyword ngxDirectiveThirdParty mongo_auth +syn keyword ngxDirectiveThirdParty mongo_pass +syn keyword ngxDirectiveThirdParty mongo_query +syn keyword ngxDirectiveThirdParty mongo_json +syn keyword ngxDirectiveThirdParty mongo_bind +syn keyword ngxDirectiveThirdParty mongo_connect_timeout +syn keyword ngxDirectiveThirdParty mongo_send_timeout +syn keyword ngxDirectiveThirdParty mongo_read_timeout +syn keyword ngxDirectiveThirdParty mongo_buffering +syn keyword ngxDirectiveThirdParty mongo_buffer_size +syn keyword ngxDirectiveThirdParty mongo_buffers +syn keyword ngxDirectiveThirdParty mongo_busy_buffers_size +syn keyword ngxDirectiveThirdParty mongo_next_upstream + +" MP4 Streaming Lite Module <https://www.nginx.com/resources/wiki/modules/mp4_streaming/> +" Will seek to a certain time within H.264/MP4 files when provided with a 'start' parameter in the URL. +" syn keyword ngxDirectiveThirdParty mp4 + +" NAXSI Module <https://github.com/nbs-system/naxsi> +" NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX +syn keyword ngxDirectiveThirdParty DeniedUrl denied_url +syn keyword ngxDirectiveThirdParty LearningMode learning_mode +syn keyword ngxDirectiveThirdParty SecRulesEnabled rules_enabled +syn keyword ngxDirectiveThirdParty SecRulesDisabled rules_disabled +syn keyword ngxDirectiveThirdParty CheckRule check_rule +syn keyword ngxDirectiveThirdParty BasicRule basic_rule +syn keyword ngxDirectiveThirdParty MainRule main_rule +syn keyword ngxDirectiveThirdParty LibInjectionSql libinjection_sql +syn keyword ngxDirectiveThirdParty LibInjectionXss libinjection_xss + +" Nchan Module <https://nchan.slact.net/> +" Fast, horizontally scalable, multiprocess pub/sub queuing server and proxy for HTTP, long-polling, Websockets and EventSource (SSE) +syn keyword ngxDirectiveThirdParty nchan_channel_id +syn keyword ngxDirectiveThirdParty nchan_channel_id_split_delimiter +syn keyword ngxDirectiveThirdParty nchan_eventsource_event +syn keyword ngxDirectiveThirdParty nchan_longpoll_multipart_response +syn keyword ngxDirectiveThirdParty nchan_publisher +syn keyword ngxDirectiveThirdParty nchan_publisher_channel_id +syn keyword ngxDirectiveThirdParty nchan_publisher_upstream_request +syn keyword ngxDirectiveThirdParty nchan_pubsub +syn keyword ngxDirectiveThirdParty nchan_subscribe_request +syn keyword ngxDirectiveThirdParty nchan_subscriber +syn keyword ngxDirectiveThirdParty nchan_subscriber_channel_id +syn keyword ngxDirectiveThirdParty nchan_subscriber_compound_etag_message_id +syn keyword ngxDirectiveThirdParty nchan_subscriber_first_message +syn keyword ngxDirectiveThirdParty nchan_subscriber_http_raw_stream_separator +syn keyword ngxDirectiveThirdParty nchan_subscriber_last_message_id +syn keyword ngxDirectiveThirdParty nchan_subscriber_message_id_custom_etag_header +syn keyword ngxDirectiveThirdParty nchan_subscriber_timeout +syn keyword ngxDirectiveThirdParty nchan_unsubscribe_request +syn keyword ngxDirectiveThirdParty nchan_websocket_ping_interval +syn keyword ngxDirectiveThirdParty nchan_authorize_request +syn keyword ngxDirectiveThirdParty nchan_max_reserved_memory +syn keyword ngxDirectiveThirdParty nchan_message_buffer_length +syn keyword ngxDirectiveThirdParty nchan_message_timeout +syn keyword ngxDirectiveThirdParty nchan_redis_idle_channel_cache_timeout +syn keyword ngxDirectiveThirdParty nchan_redis_namespace +syn keyword ngxDirectiveThirdParty nchan_redis_pass +syn keyword ngxDirectiveThirdParty nchan_redis_ping_interval +syn keyword ngxDirectiveThirdParty nchan_redis_server +syn keyword ngxDirectiveThirdParty nchan_redis_storage_mode +syn keyword ngxDirectiveThirdParty nchan_redis_url +syn keyword ngxDirectiveThirdParty nchan_store_messages +syn keyword ngxDirectiveThirdParty nchan_use_redis +syn keyword ngxDirectiveThirdParty nchan_access_control_allow_origin +syn keyword ngxDirectiveThirdParty nchan_channel_group +syn keyword ngxDirectiveThirdParty nchan_channel_group_accounting +syn keyword ngxDirectiveThirdParty nchan_group_location +syn keyword ngxDirectiveThirdParty nchan_group_max_channels +syn keyword ngxDirectiveThirdParty nchan_group_max_messages +syn keyword ngxDirectiveThirdParty nchan_group_max_messages_disk +syn keyword ngxDirectiveThirdParty nchan_group_max_messages_memory +syn keyword ngxDirectiveThirdParty nchan_group_max_subscribers +syn keyword ngxDirectiveThirdParty nchan_subscribe_existing_channels_only +syn keyword ngxDirectiveThirdParty nchan_channel_event_string +syn keyword ngxDirectiveThirdParty nchan_channel_events_channel_id +syn keyword ngxDirectiveThirdParty nchan_stub_status +syn keyword ngxDirectiveThirdParty nchan_max_channel_id_length +syn keyword ngxDirectiveThirdParty nchan_max_channel_subscribers +syn keyword ngxDirectiveThirdParty nchan_channel_timeout +syn keyword ngxDirectiveThirdParty nchan_storage_engine + +" Nginx Notice Module <https://github.com/kr/nginx-notice> +" Serve static file to POST requests. +syn keyword ngxDirectiveThirdParty notice +syn keyword ngxDirectiveThirdParty notice_type + +" OCSP Proxy Module <https://github.com/kyprizel/nginx_ocsp_proxy-module> +" Nginx OCSP processing module designed for response caching +syn keyword ngxDirectiveThirdParty ocsp_proxy +syn keyword ngxDirectiveThirdParty ocsp_cache_timeout + +" Eval Module <https://github.com/openresty/nginx-eval-module> +" Module for nginx web server evaluates response of proxy or memcached module into variables. +syn keyword ngxDirectiveThirdParty eval +syn keyword ngxDirectiveThirdParty eval_escalate +syn keyword ngxDirectiveThirdParty eval_buffer_size +syn keyword ngxDirectiveThirdParty eval_override_content_type +syn keyword ngxDirectiveThirdParty eval_subrequest_in_memory + +" OpenSSL Version Module <https://github.com/apcera/nginx-openssl-version> +" Nginx OpenSSL version check at startup +syn keyword ngxDirectiveThirdParty openssl_version_minimum +syn keyword ngxDirectiveThirdParty openssl_builddate_minimum + +" Owner Match Module <https://www.nginx.com/resources/wiki/modules/owner_match/> +" Control access for specific owners and groups of files +syn keyword ngxDirectiveThirdParty omallow +syn keyword ngxDirectiveThirdParty omdeny + +" Accept Language Module <https://www.nginx.com/resources/wiki/modules/accept_language/> +" Parses the Accept-Language header and gives the most suitable locale from a list of supported locales. +syn keyword ngxDirectiveThirdParty pagespeed + +" PHP Memcache Standard Balancer Module <https://github.com/replay/ngx_http_php_memcache_standard_balancer> +" Loadbalancer that is compatible to the standard loadbalancer in the php-memcache module +syn keyword ngxDirectiveThirdParty hash_key + +" PHP Session Module <https://github.com/replay/ngx_http_php_session> +" Nginx module to parse php sessions +syn keyword ngxDirectiveThirdParty php_session_parse +syn keyword ngxDirectiveThirdParty php_session_strip_formatting + +" Phusion Passenger Module <https://www.phusionpassenger.com/library/config/nginx/> +" Passenger is an open source web application server. +syn keyword ngxDirectiveThirdParty passenger_root +syn keyword ngxDirectiveThirdParty passenger_enabled +syn keyword ngxDirectiveThirdParty passenger_base_uri +syn keyword ngxDirectiveThirdParty passenger_document_root +syn keyword ngxDirectiveThirdParty passenger_ruby +syn keyword ngxDirectiveThirdParty passenger_python +syn keyword ngxDirectiveThirdParty passenger_nodejs +syn keyword ngxDirectiveThirdParty passenger_meteor_app_settings +syn keyword ngxDirectiveThirdParty passenger_app_env +syn keyword ngxDirectiveThirdParty passenger_app_root +syn keyword ngxDirectiveThirdParty passenger_app_group_name +syn keyword ngxDirectiveThirdParty passenger_app_type +syn keyword ngxDirectiveThirdParty passenger_startup_file +syn keyword ngxDirectiveThirdParty passenger_restart_dir +syn keyword ngxDirectiveThirdParty passenger_spawn_method +syn keyword ngxDirectiveThirdParty passenger_env_var +syn keyword ngxDirectiveThirdParty passenger_load_shell_envvars +syn keyword ngxDirectiveThirdParty passenger_rolling_restarts +syn keyword ngxDirectiveThirdParty passenger_resist_deployment_errors +syn keyword ngxDirectiveThirdParty passenger_user_switching +syn keyword ngxDirectiveThirdParty passenger_user +syn keyword ngxDirectiveThirdParty passenger_group +syn keyword ngxDirectiveThirdParty passenger_default_user +syn keyword ngxDirectiveThirdParty passenger_default_group +syn keyword ngxDirectiveThirdParty passenger_show_version_in_header +syn keyword ngxDirectiveThirdParty passenger_friendly_error_pages +syn keyword ngxDirectiveThirdParty passenger_disable_security_update_check +syn keyword ngxDirectiveThirdParty passenger_security_update_check_proxy +syn keyword ngxDirectiveThirdParty passenger_max_pool_size +syn keyword ngxDirectiveThirdParty passenger_min_instances +syn keyword ngxDirectiveThirdParty passenger_max_instances +syn keyword ngxDirectiveThirdParty passenger_max_instances_per_app +syn keyword ngxDirectiveThirdParty passenger_pool_idle_time +syn keyword ngxDirectiveThirdParty passenger_max_preloader_idle_time +syn keyword ngxDirectiveThirdParty passenger_force_max_concurrent_requests_per_process +syn keyword ngxDirectiveThirdParty passenger_start_timeout +syn keyword ngxDirectiveThirdParty passenger_concurrency_model +syn keyword ngxDirectiveThirdParty passenger_thread_count +syn keyword ngxDirectiveThirdParty passenger_max_requests +syn keyword ngxDirectiveThirdParty passenger_max_request_time +syn keyword ngxDirectiveThirdParty passenger_memory_limit +syn keyword ngxDirectiveThirdParty passenger_stat_throttle_rate +syn keyword ngxDirectiveThirdParty passenger_core_file_descriptor_ulimit +syn keyword ngxDirectiveThirdParty passenger_app_file_descriptor_ulimit +syn keyword ngxDirectiveThirdParty passenger_pre_start +syn keyword ngxDirectiveThirdParty passenger_set_header +syn keyword ngxDirectiveThirdParty passenger_max_request_queue_size +syn keyword ngxDirectiveThirdParty passenger_request_queue_overflow_status_code +syn keyword ngxDirectiveThirdParty passenger_sticky_sessions +syn keyword ngxDirectiveThirdParty passenger_sticky_sessions_cookie_name +syn keyword ngxDirectiveThirdParty passenger_abort_websockets_on_process_shutdown +syn keyword ngxDirectiveThirdParty passenger_ignore_client_abort +syn keyword ngxDirectiveThirdParty passenger_intercept_errors +syn keyword ngxDirectiveThirdParty passenger_pass_header +syn keyword ngxDirectiveThirdParty passenger_ignore_headers +syn keyword ngxDirectiveThirdParty passenger_headers_hash_bucket_size +syn keyword ngxDirectiveThirdParty passenger_headers_hash_max_size +syn keyword ngxDirectiveThirdParty passenger_buffer_response +syn keyword ngxDirectiveThirdParty passenger_response_buffer_high_watermark +syn keyword ngxDirectiveThirdParty passenger_buffer_size, passenger_buffers, passenger_busy_buffers_size +syn keyword ngxDirectiveThirdParty passenger_socket_backlog +syn keyword ngxDirectiveThirdParty passenger_log_level +syn keyword ngxDirectiveThirdParty passenger_log_file +syn keyword ngxDirectiveThirdParty passenger_file_descriptor_log_file +syn keyword ngxDirectiveThirdParty passenger_debugger +syn keyword ngxDirectiveThirdParty passenger_instance_registry_dir +syn keyword ngxDirectiveThirdParty passenger_data_buffer_dir +syn keyword ngxDirectiveThirdParty passenger_fly_with +syn keyword ngxDirectiveThirdParty union_station_support +syn keyword ngxDirectiveThirdParty union_station_key +syn keyword ngxDirectiveThirdParty union_station_proxy_address +syn keyword ngxDirectiveThirdParty union_station_filter +syn keyword ngxDirectiveThirdParty union_station_gateway_address +syn keyword ngxDirectiveThirdParty union_station_gateway_port +syn keyword ngxDirectiveThirdParty union_station_gateway_cert +syn keyword ngxDirectiveDeprecated rails_spawn_method +syn keyword ngxDirectiveDeprecated passenger_debug_log_file + +" Postgres Module <http://labs.frickle.com/nginx_ngx_postgres/> +" Upstream module that allows nginx to communicate directly with PostgreSQL database. +syn keyword ngxDirectiveThirdParty postgres_server +syn keyword ngxDirectiveThirdParty postgres_keepalive +syn keyword ngxDirectiveThirdParty postgres_pass +syn keyword ngxDirectiveThirdParty postgres_query +syn keyword ngxDirectiveThirdParty postgres_rewrite +syn keyword ngxDirectiveThirdParty postgres_output +syn keyword ngxDirectiveThirdParty postgres_set +syn keyword ngxDirectiveThirdParty postgres_escape +syn keyword ngxDirectiveThirdParty postgres_connect_timeout +syn keyword ngxDirectiveThirdParty postgres_result_timeout + +" Pubcookie Module <https://www.vanko.me/book/page/pubcookie-module-nginx> +" Authorizes users using encrypted cookies +syn keyword ngxDirectiveThirdParty pubcookie_inactive_expire +syn keyword ngxDirectiveThirdParty pubcookie_hard_expire +syn keyword ngxDirectiveThirdParty pubcookie_app_id +syn keyword ngxDirectiveThirdParty pubcookie_dir_depth +syn keyword ngxDirectiveThirdParty pubcookie_catenate_app_ids +syn keyword ngxDirectiveThirdParty pubcookie_app_srv_id +syn keyword ngxDirectiveThirdParty pubcookie_login +syn keyword ngxDirectiveThirdParty pubcookie_login_method +syn keyword ngxDirectiveThirdParty pubcookie_post +syn keyword ngxDirectiveThirdParty pubcookie_domain +syn keyword ngxDirectiveThirdParty pubcookie_granting_cert_file +syn keyword ngxDirectiveThirdParty pubcookie_session_key_file +syn keyword ngxDirectiveThirdParty pubcookie_session_cert_file +syn keyword ngxDirectiveThirdParty pubcookie_crypt_key_file +syn keyword ngxDirectiveThirdParty pubcookie_end_session +syn keyword ngxDirectiveThirdParty pubcookie_encryption +syn keyword ngxDirectiveThirdParty pubcookie_session_reauth +syn keyword ngxDirectiveThirdParty pubcookie_auth_type_names +syn keyword ngxDirectiveThirdParty pubcookie_no_prompt +syn keyword ngxDirectiveThirdParty pubcookie_on_demand +syn keyword ngxDirectiveThirdParty pubcookie_addl_request +syn keyword ngxDirectiveThirdParty pubcookie_no_obscure_cookies +syn keyword ngxDirectiveThirdParty pubcookie_no_clean_creds +syn keyword ngxDirectiveThirdParty pubcookie_egd_device +syn keyword ngxDirectiveThirdParty pubcookie_no_blank +syn keyword ngxDirectiveThirdParty pubcookie_super_debug +syn keyword ngxDirectiveThirdParty pubcookie_set_remote_user + +" Push Stream Module <https://github.com/wandenberg/nginx-push-stream-module> +" A pure stream http push technology for your Nginx setup +syn keyword ngxDirectiveThirdParty push_stream_channels_statistics +syn keyword ngxDirectiveThirdParty push_stream_publisher +syn keyword ngxDirectiveThirdParty push_stream_subscriber +syn keyword ngxDirectiveThirdParty push_stream_shared_memory_size +syn keyword ngxDirectiveThirdParty push_stream_channel_deleted_message_text +syn keyword ngxDirectiveThirdParty push_stream_channel_inactivity_time +syn keyword ngxDirectiveThirdParty push_stream_ping_message_text +syn keyword ngxDirectiveThirdParty push_stream_timeout_with_body +syn keyword ngxDirectiveThirdParty push_stream_message_ttl +syn keyword ngxDirectiveThirdParty push_stream_max_subscribers_per_channel +syn keyword ngxDirectiveThirdParty push_stream_max_messages_stored_per_channel +syn keyword ngxDirectiveThirdParty push_stream_max_channel_id_length +syn keyword ngxDirectiveThirdParty push_stream_max_number_of_channels +syn keyword ngxDirectiveThirdParty push_stream_max_number_of_wildcard_channels +syn keyword ngxDirectiveThirdParty push_stream_wildcard_channel_prefix +syn keyword ngxDirectiveThirdParty push_stream_events_channel_id +syn keyword ngxDirectiveThirdParty push_stream_channels_path +syn keyword ngxDirectiveThirdParty push_stream_store_messages +syn keyword ngxDirectiveThirdParty push_stream_channel_info_on_publish +syn keyword ngxDirectiveThirdParty push_stream_authorized_channels_only +syn keyword ngxDirectiveThirdParty push_stream_header_template_file +syn keyword ngxDirectiveThirdParty push_stream_header_template +syn keyword ngxDirectiveThirdParty push_stream_message_template +syn keyword ngxDirectiveThirdParty push_stream_footer_template +syn keyword ngxDirectiveThirdParty push_stream_wildcard_channel_max_qtd +syn keyword ngxDirectiveThirdParty push_stream_ping_message_interval +syn keyword ngxDirectiveThirdParty push_stream_subscriber_connection_ttl +syn keyword ngxDirectiveThirdParty push_stream_longpolling_connection_ttl +syn keyword ngxDirectiveThirdParty push_stream_websocket_allow_publish +syn keyword ngxDirectiveThirdParty push_stream_last_received_message_time +syn keyword ngxDirectiveThirdParty push_stream_last_received_message_tag +syn keyword ngxDirectiveThirdParty push_stream_last_event_id +syn keyword ngxDirectiveThirdParty push_stream_user_agent +syn keyword ngxDirectiveThirdParty push_stream_padding_by_user_agent +syn keyword ngxDirectiveThirdParty push_stream_allowed_origins +syn keyword ngxDirectiveThirdParty push_stream_allow_connections_to_events_channel + +" rDNS Module <https://github.com/flant/nginx-http-rdns> +" Make a reverse DNS (rDNS) lookup for incoming connection and provides simple access control of incoming hostname by allow/deny rules +syn keyword ngxDirectiveThirdParty rdns +syn keyword ngxDirectiveThirdParty rdns_allow +syn keyword ngxDirectiveThirdParty rdns_deny + +" RDS CSV Module <https://github.com/openresty/rds-csv-nginx-module> +" Nginx output filter module to convert Resty-DBD-Streams (RDS) to Comma-Separated Values (CSV) +syn keyword ngxDirectiveThirdParty rds_csv +syn keyword ngxDirectiveThirdParty rds_csv_row_terminator +syn keyword ngxDirectiveThirdParty rds_csv_field_separator +syn keyword ngxDirectiveThirdParty rds_csv_field_name_header +syn keyword ngxDirectiveThirdParty rds_csv_content_type +syn keyword ngxDirectiveThirdParty rds_csv_buffer_size + +" RDS JSON Module <https://github.com/openresty/rds-json-nginx-module> +" An output filter that formats Resty DBD Streams generated by ngx_drizzle and others to JSON +syn keyword ngxDirectiveThirdParty rds_json +syn keyword ngxDirectiveThirdParty rds_json_buffer_size +syn keyword ngxDirectiveThirdParty rds_json_format +syn keyword ngxDirectiveThirdParty rds_json_root +syn keyword ngxDirectiveThirdParty rds_json_success_property +syn keyword ngxDirectiveThirdParty rds_json_user_property +syn keyword ngxDirectiveThirdParty rds_json_errcode_key +syn keyword ngxDirectiveThirdParty rds_json_errstr_key +syn keyword ngxDirectiveThirdParty rds_json_ret +syn keyword ngxDirectiveThirdParty rds_json_content_type + +" Redis Module <https://www.nginx.com/resources/wiki/modules/redis/> +" Use this module to perform simple caching +syn keyword ngxDirectiveThirdParty redis_pass +syn keyword ngxDirectiveThirdParty redis_bind +syn keyword ngxDirectiveThirdParty redis_connect_timeout +syn keyword ngxDirectiveThirdParty redis_read_timeout +syn keyword ngxDirectiveThirdParty redis_send_timeout +syn keyword ngxDirectiveThirdParty redis_buffer_size +syn keyword ngxDirectiveThirdParty redis_next_upstream +syn keyword ngxDirectiveThirdParty redis_gzip_flag + +" Redis 2 Module <https://github.com/openresty/redis2-nginx-module> +" Nginx upstream module for the Redis 2.0 protocol +syn keyword ngxDirectiveThirdParty redis2_query +syn keyword ngxDirectiveThirdParty redis2_raw_query +syn keyword ngxDirectiveThirdParty redis2_raw_queries +syn keyword ngxDirectiveThirdParty redis2_literal_raw_query +syn keyword ngxDirectiveThirdParty redis2_pass +syn keyword ngxDirectiveThirdParty redis2_connect_timeout +syn keyword ngxDirectiveThirdParty redis2_send_timeout +syn keyword ngxDirectiveThirdParty redis2_read_timeout +syn keyword ngxDirectiveThirdParty redis2_buffer_size +syn keyword ngxDirectiveThirdParty redis2_next_upstream + +" Replace Filter Module <https://github.com/openresty/replace-filter-nginx-module> +" Streaming regular expression replacement in response bodies +syn keyword ngxDirectiveThirdParty replace_filter +syn keyword ngxDirectiveThirdParty replace_filter_types +syn keyword ngxDirectiveThirdParty replace_filter_max_buffered_size +syn keyword ngxDirectiveThirdParty replace_filter_last_modified +syn keyword ngxDirectiveThirdParty replace_filter_skip + +" Roboo Module <https://github.com/yuri-gushin/Roboo> +" HTTP Robot Mitigator + +" RRD Graph Module <https://www.nginx.com/resources/wiki/modules/rrd_graph/> +" This module provides an HTTP interface to RRDtool's graphing facilities. +syn keyword ngxDirectiveThirdParty rrd_graph +syn keyword ngxDirectiveThirdParty rrd_graph_root + +" RTMP Module <https://github.com/arut/nginx-rtmp-module> +" NGINX-based Media Streaming Server +syn keyword ngxDirectiveThirdParty rtmp +" syn keyword ngxDirectiveThirdParty server +" syn keyword ngxDirectiveThirdParty listen +syn keyword ngxDirectiveThirdParty application +" syn keyword ngxDirectiveThirdParty timeout +syn keyword ngxDirectiveThirdParty ping +syn keyword ngxDirectiveThirdParty ping_timeout +syn keyword ngxDirectiveThirdParty max_streams +syn keyword ngxDirectiveThirdParty ack_window +syn keyword ngxDirectiveThirdParty chunk_size +syn keyword ngxDirectiveThirdParty max_queue +syn keyword ngxDirectiveThirdParty max_message +syn keyword ngxDirectiveThirdParty out_queue +syn keyword ngxDirectiveThirdParty out_cork +" syn keyword ngxDirectiveThirdParty allow +" syn keyword ngxDirectiveThirdParty deny +syn keyword ngxDirectiveThirdParty exec_push +syn keyword ngxDirectiveThirdParty exec_pull +syn keyword ngxDirectiveThirdParty exec +syn keyword ngxDirectiveThirdParty exec_options +syn keyword ngxDirectiveThirdParty exec_static +syn keyword ngxDirectiveThirdParty exec_kill_signal +syn keyword ngxDirectiveThirdParty respawn +syn keyword ngxDirectiveThirdParty respawn_timeout +syn keyword ngxDirectiveThirdParty exec_publish +syn keyword ngxDirectiveThirdParty exec_play +syn keyword ngxDirectiveThirdParty exec_play_done +syn keyword ngxDirectiveThirdParty exec_publish_done +syn keyword ngxDirectiveThirdParty exec_record_done +syn keyword ngxDirectiveThirdParty live +syn keyword ngxDirectiveThirdParty meta +syn keyword ngxDirectiveThirdParty interleave +syn keyword ngxDirectiveThirdParty wait_key +syn keyword ngxDirectiveThirdParty wait_video +syn keyword ngxDirectiveThirdParty publish_notify +syn keyword ngxDirectiveThirdParty drop_idle_publisher +syn keyword ngxDirectiveThirdParty sync +syn keyword ngxDirectiveThirdParty play_restart +syn keyword ngxDirectiveThirdParty idle_streams +syn keyword ngxDirectiveThirdParty record +syn keyword ngxDirectiveThirdParty record_path +syn keyword ngxDirectiveThirdParty record_suffix +syn keyword ngxDirectiveThirdParty record_unique +syn keyword ngxDirectiveThirdParty record_append +syn keyword ngxDirectiveThirdParty record_lock +syn keyword ngxDirectiveThirdParty record_max_size +syn keyword ngxDirectiveThirdParty record_max_frames +syn keyword ngxDirectiveThirdParty record_interval +syn keyword ngxDirectiveThirdParty recorder +syn keyword ngxDirectiveThirdParty record_notify +syn keyword ngxDirectiveThirdParty play +syn keyword ngxDirectiveThirdParty play_temp_path +syn keyword ngxDirectiveThirdParty play_local_path +syn keyword ngxDirectiveThirdParty pull +syn keyword ngxDirectiveThirdParty push +syn keyword ngxDirectiveThirdParty push_reconnect +syn keyword ngxDirectiveThirdParty session_relay +syn keyword ngxDirectiveThirdParty on_connect +syn keyword ngxDirectiveThirdParty on_play +syn keyword ngxDirectiveThirdParty on_publish +syn keyword ngxDirectiveThirdParty on_done +syn keyword ngxDirectiveThirdParty on_play_done +syn keyword ngxDirectiveThirdParty on_publish_done +syn keyword ngxDirectiveThirdParty on_record_done +syn keyword ngxDirectiveThirdParty on_update +syn keyword ngxDirectiveThirdParty notify_update_timeout +syn keyword ngxDirectiveThirdParty notify_update_strict +syn keyword ngxDirectiveThirdParty notify_relay_redirect +syn keyword ngxDirectiveThirdParty notify_method +syn keyword ngxDirectiveThirdParty hls +syn keyword ngxDirectiveThirdParty hls_path +syn keyword ngxDirectiveThirdParty hls_fragment +syn keyword ngxDirectiveThirdParty hls_playlist_length +syn keyword ngxDirectiveThirdParty hls_sync +syn keyword ngxDirectiveThirdParty hls_continuous +syn keyword ngxDirectiveThirdParty hls_nested +syn keyword ngxDirectiveThirdParty hls_base_url +syn keyword ngxDirectiveThirdParty hls_cleanup +syn keyword ngxDirectiveThirdParty hls_fragment_naming +syn keyword ngxDirectiveThirdParty hls_fragment_slicing +syn keyword ngxDirectiveThirdParty hls_variant +syn keyword ngxDirectiveThirdParty hls_type +syn keyword ngxDirectiveThirdParty hls_keys +syn keyword ngxDirectiveThirdParty hls_key_path +syn keyword ngxDirectiveThirdParty hls_key_url +syn keyword ngxDirectiveThirdParty hls_fragments_per_key +syn keyword ngxDirectiveThirdParty dash +syn keyword ngxDirectiveThirdParty dash_path +syn keyword ngxDirectiveThirdParty dash_fragment +syn keyword ngxDirectiveThirdParty dash_playlist_length +syn keyword ngxDirectiveThirdParty dash_nested +syn keyword ngxDirectiveThirdParty dash_cleanup +" syn keyword ngxDirectiveThirdParty access_log +" syn keyword ngxDirectiveThirdParty log_format +syn keyword ngxDirectiveThirdParty max_connections +syn keyword ngxDirectiveThirdParty rtmp_stat +syn keyword ngxDirectiveThirdParty rtmp_stat_stylesheet +syn keyword ngxDirectiveThirdParty rtmp_auto_push +syn keyword ngxDirectiveThirdParty rtmp_auto_push_reconnect +syn keyword ngxDirectiveThirdParty rtmp_socket_dir +syn keyword ngxDirectiveThirdParty rtmp_control + +" RTMPT Module <https://github.com/kwojtek/nginx-rtmpt-proxy-module> +" Module for nginx to proxy rtmp using http protocol +syn keyword ngxDirectiveThirdParty rtmpt_proxy_target +syn keyword ngxDirectiveThirdParty rtmpt_proxy_rtmp_timeout +syn keyword ngxDirectiveThirdParty rtmpt_proxy_http_timeout +syn keyword ngxDirectiveThirdParty rtmpt_proxy +syn keyword ngxDirectiveThirdParty rtmpt_proxy_stat +syn keyword ngxDirectiveThirdParty rtmpt_proxy_stylesheet + +" Syntactically Awesome Module <https://github.com/mneudert/sass-nginx-module> +" Providing on-the-fly compiling of Sass files as an NGINX module. +syn keyword ngxDirectiveThirdParty sass_compile +syn keyword ngxDirectiveThirdParty sass_error_log +syn keyword ngxDirectiveThirdParty sass_include_path +syn keyword ngxDirectiveThirdParty sass_indent +syn keyword ngxDirectiveThirdParty sass_is_indented_syntax +syn keyword ngxDirectiveThirdParty sass_linefeed +syn keyword ngxDirectiveThirdParty sass_precision +syn keyword ngxDirectiveThirdParty sass_output_style +syn keyword ngxDirectiveThirdParty sass_source_comments +syn keyword ngxDirectiveThirdParty sass_source_map_embed + +" Secure Download Module <https://www.nginx.com/resources/wiki/modules/secure_download/> +" Enables you to create links which are only valid until a certain datetime is reached +syn keyword ngxDirectiveThirdParty secure_download +syn keyword ngxDirectiveThirdParty secure_download_secret +syn keyword ngxDirectiveThirdParty secure_download_path_mode + +" Selective Cache Purge Module <https://github.com/wandenberg/nginx-selective-cache-purge-module> +" A module to purge cache by GLOB patterns. The supported patterns are the same as supported by Redis. +syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_unix_socket +syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_host +syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_port +syn keyword ngxDirectiveThirdParty selective_cache_purge_redis_database +syn keyword ngxDirectiveThirdParty selective_cache_purge_query + +" Set cconv Module <https://github.com/liseen/set-cconv-nginx-module> +" Cconv rewrite set commands +syn keyword ngxDirectiveThirdParty set_cconv_to_simp +syn keyword ngxDirectiveThirdParty set_cconv_to_trad +syn keyword ngxDirectiveThirdParty set_pinyin_to_normal + +" Set Hash Module <https://github.com/simpl/ngx_http_set_hash> +" Nginx module that allows the setting of variables to the value of a variety of hashes +syn keyword ngxDirectiveThirdParty set_md5 +syn keyword ngxDirectiveThirdParty set_md5_upper +syn keyword ngxDirectiveThirdParty set_murmur2 +syn keyword ngxDirectiveThirdParty set_murmur2_upper +syn keyword ngxDirectiveThirdParty set_sha1 +syn keyword ngxDirectiveThirdParty set_sha1_upper + +" Set Lang Module <https://github.com/simpl/ngx_http_set_lang> +" Provides a variety of ways for setting a variable denoting the langauge that content should be returned in. +syn keyword ngxDirectiveThirdParty set_lang +syn keyword ngxDirectiveThirdParty set_lang_method +syn keyword ngxDirectiveThirdParty lang_cookie +syn keyword ngxDirectiveThirdParty lang_get_var +syn keyword ngxDirectiveThirdParty lang_list +syn keyword ngxDirectiveThirdParty lang_post_var +syn keyword ngxDirectiveThirdParty lang_host +syn keyword ngxDirectiveThirdParty lang_referer + +" Set Misc Module <https://github.com/openresty/set-misc-nginx-module> +" Various set_xxx directives added to nginx's rewrite module +syn keyword ngxDirectiveThirdParty set_if_empty +syn keyword ngxDirectiveThirdParty set_quote_sql_str +syn keyword ngxDirectiveThirdParty set_quote_pgsql_str +syn keyword ngxDirectiveThirdParty set_quote_json_str +syn keyword ngxDirectiveThirdParty set_unescape_uri +syn keyword ngxDirectiveThirdParty set_escape_uri +syn keyword ngxDirectiveThirdParty set_hashed_upstream +syn keyword ngxDirectiveThirdParty set_encode_base32 +syn keyword ngxDirectiveThirdParty set_base32_padding +syn keyword ngxDirectiveThirdParty set_misc_base32_padding +syn keyword ngxDirectiveThirdParty set_base32_alphabet +syn keyword ngxDirectiveThirdParty set_decode_base32 +syn keyword ngxDirectiveThirdParty set_encode_base64 +syn keyword ngxDirectiveThirdParty set_decode_base64 +syn keyword ngxDirectiveThirdParty set_encode_hex +syn keyword ngxDirectiveThirdParty set_decode_hex +syn keyword ngxDirectiveThirdParty set_sha1 +syn keyword ngxDirectiveThirdParty set_md5 +syn keyword ngxDirectiveThirdParty set_hmac_sha1 +syn keyword ngxDirectiveThirdParty set_random +syn keyword ngxDirectiveThirdParty set_secure_random_alphanum +syn keyword ngxDirectiveThirdParty set_secure_random_lcalpha +syn keyword ngxDirectiveThirdParty set_rotate +syn keyword ngxDirectiveThirdParty set_local_today +syn keyword ngxDirectiveThirdParty set_formatted_gmt_time +syn keyword ngxDirectiveThirdParty set_formatted_local_time + +" SFlow Module <https://github.com/sflow/nginx-sflow-module> +" A binary, random-sampling nginx module designed for: lightweight, centralized, continuous, real-time monitoring of very large and very busy web farms. +syn keyword ngxDirectiveThirdParty sflow + +" Shibboleth Module <https://github.com/nginx-shib/nginx-http-shibboleth> +" Shibboleth auth request module for nginx +syn keyword ngxDirectiveThirdParty shib_request +syn keyword ngxDirectiveThirdParty shib_request_set +syn keyword ngxDirectiveThirdParty shib_request_use_headers + +" Slice Module <https://github.com/alibaba/nginx-http-slice> +" Nginx module for serving a file in slices (reverse byte-range) +" syn keyword ngxDirectiveThirdParty slice +syn keyword ngxDirectiveThirdParty slice_arg_begin +syn keyword ngxDirectiveThirdParty slice_arg_end +syn keyword ngxDirectiveThirdParty slice_header +syn keyword ngxDirectiveThirdParty slice_footer +syn keyword ngxDirectiveThirdParty slice_header_first +syn keyword ngxDirectiveThirdParty slice_footer_last + +" SlowFS Cache Module <https://github.com/FRiCKLE/ngx_slowfs_cache/> +" Module adding ability to cache static files. +syn keyword ngxDirectiveThirdParty slowfs_big_file_size +syn keyword ngxDirectiveThirdParty slowfs_cache +syn keyword ngxDirectiveThirdParty slowfs_cache_key +syn keyword ngxDirectiveThirdParty slowfs_cache_min_uses +syn keyword ngxDirectiveThirdParty slowfs_cache_path +syn keyword ngxDirectiveThirdParty slowfs_cache_purge +syn keyword ngxDirectiveThirdParty slowfs_cache_valid +syn keyword ngxDirectiveThirdParty slowfs_temp_path + +" Small Light Module <https://github.com/cubicdaiya/ngx_small_light> +" Dynamic Image Transformation Module For nginx. +syn keyword ngxDirectiveThirdParty small_light +syn keyword ngxDirectiveThirdParty small_light_getparam_mode +syn keyword ngxDirectiveThirdParty small_light_material_dir +syn keyword ngxDirectiveThirdParty small_light_pattern_define +syn keyword ngxDirectiveThirdParty small_light_radius_max +syn keyword ngxDirectiveThirdParty small_light_sigma_max +syn keyword ngxDirectiveThirdParty small_light_imlib2_temp_dir +syn keyword ngxDirectiveThirdParty small_light_buffer + +" Sorted Querystring Filter Module <https://github.com/wandenberg/nginx-sorted-querystring-module> +" Nginx module to expose querystring parameters sorted in a variable to be used on cache_key as example +syn keyword ngxDirectiveThirdParty sorted_querystring_filter_parameter + +" Sphinx2 Module <https://github.com/reeteshranjan/sphinx2-nginx-module> +" Nginx upstream module for Sphinx 2.x +syn keyword ngxDirectiveThirdParty sphinx2_pass +syn keyword ngxDirectiveThirdParty sphinx2_bind +syn keyword ngxDirectiveThirdParty sphinx2_connect_timeout +syn keyword ngxDirectiveThirdParty sphinx2_send_timeout +syn keyword ngxDirectiveThirdParty sphinx2_buffer_size +syn keyword ngxDirectiveThirdParty sphinx2_read_timeout +syn keyword ngxDirectiveThirdParty sphinx2_next_upstream + +" HTTP SPNEGO auth Module <https://github.com/stnoonan/spnego-http-auth-nginx-module> +" This module implements adds SPNEGO support to nginx(http://nginx.org). It currently supports only Kerberos authentication via GSSAPI +syn keyword ngxDirectiveThirdParty auth_gss +syn keyword ngxDirectiveThirdParty auth_gss_keytab +syn keyword ngxDirectiveThirdParty auth_gss_realm +syn keyword ngxDirectiveThirdParty auth_gss_service_name +syn keyword ngxDirectiveThirdParty auth_gss_authorized_principal +syn keyword ngxDirectiveThirdParty auth_gss_allow_basic_fallback + +" SR Cache Module <https://github.com/openresty/srcache-nginx-module> +" Transparent subrequest-based caching layout for arbitrary nginx locations +syn keyword ngxDirectiveThirdParty srcache_fetch +syn keyword ngxDirectiveThirdParty srcache_fetch_skip +syn keyword ngxDirectiveThirdParty srcache_store +syn keyword ngxDirectiveThirdParty srcache_store_max_size +syn keyword ngxDirectiveThirdParty srcache_store_skip +syn keyword ngxDirectiveThirdParty srcache_store_statuses +syn keyword ngxDirectiveThirdParty srcache_store_ranges +syn keyword ngxDirectiveThirdParty srcache_header_buffer_size +syn keyword ngxDirectiveThirdParty srcache_store_hide_header +syn keyword ngxDirectiveThirdParty srcache_store_pass_header +syn keyword ngxDirectiveThirdParty srcache_methods +syn keyword ngxDirectiveThirdParty srcache_ignore_content_encoding +syn keyword ngxDirectiveThirdParty srcache_request_cache_control +syn keyword ngxDirectiveThirdParty srcache_response_cache_control +syn keyword ngxDirectiveThirdParty srcache_store_no_store +syn keyword ngxDirectiveThirdParty srcache_store_no_cache +syn keyword ngxDirectiveThirdParty srcache_store_private +syn keyword ngxDirectiveThirdParty srcache_default_expire +syn keyword ngxDirectiveThirdParty srcache_max_expire + +" SSSD Info Module <https://github.com/veruu/ngx_sssd_info> +" Retrives additional attributes from SSSD for current authentizated user +syn keyword ngxDirectiveThirdParty sssd_info +syn keyword ngxDirectiveThirdParty sssd_info_output_to +syn keyword ngxDirectiveThirdParty sssd_info_groups +syn keyword ngxDirectiveThirdParty sssd_info_group +syn keyword ngxDirectiveThirdParty sssd_info_group_separator +syn keyword ngxDirectiveThirdParty sssd_info_attributes +syn keyword ngxDirectiveThirdParty sssd_info_attribute +syn keyword ngxDirectiveThirdParty sssd_info_attribute_separator + +" Static Etags Module <https://github.com/mikewest/nginx-static-etags> +" Generate etags for static content +syn keyword ngxDirectiveThirdParty FileETag + +" Statsd Module <https://github.com/zebrafishlabs/nginx-statsd> +" An nginx module for sending statistics to statsd +syn keyword ngxDirectiveThirdParty statsd_server +syn keyword ngxDirectiveThirdParty statsd_sample_rate +syn keyword ngxDirectiveThirdParty statsd_count +syn keyword ngxDirectiveThirdParty statsd_timing + +" Sticky Module <https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng> +" Add a sticky cookie to be always forwarded to the same upstream server +" syn keyword ngxDirectiveThirdParty sticky + +" Stream Echo Module <https://github.com/openresty/stream-echo-nginx-module> +" TCP/stream echo module for NGINX (a port of ngx_http_echo_module) +syn keyword ngxDirectiveThirdParty echo +syn keyword ngxDirectiveThirdParty echo_duplicate +syn keyword ngxDirectiveThirdParty echo_flush_wait +syn keyword ngxDirectiveThirdParty echo_sleep +syn keyword ngxDirectiveThirdParty echo_send_timeout +syn keyword ngxDirectiveThirdParty echo_read_bytes +syn keyword ngxDirectiveThirdParty echo_read_line +syn keyword ngxDirectiveThirdParty echo_request_data +syn keyword ngxDirectiveThirdParty echo_discard_request +syn keyword ngxDirectiveThirdParty echo_read_buffer_size +syn keyword ngxDirectiveThirdParty echo_read_timeout +syn keyword ngxDirectiveThirdParty echo_client_error_log_level +syn keyword ngxDirectiveThirdParty echo_lingering_close +syn keyword ngxDirectiveThirdParty echo_lingering_time +syn keyword ngxDirectiveThirdParty echo_lingering_timeout + +" Stream Lua Module <https://github.com/openresty/stream-lua-nginx-module> +" Embed the power of Lua into Nginx stream/TCP Servers. +syn keyword ngxDirectiveThirdParty lua_resolver +syn keyword ngxDirectiveThirdParty lua_resolver_timeout +syn keyword ngxDirectiveThirdParty lua_lingering_close +syn keyword ngxDirectiveThirdParty lua_lingering_time +syn keyword ngxDirectiveThirdParty lua_lingering_timeout + +" Stream Upsync Module <https://github.com/xiaokai-wang/nginx-stream-upsync-module> +" Sync upstreams from consul or others, dynamiclly modify backend-servers attribute(weight, max_fails,...), needn't reload nginx. +syn keyword ngxDirectiveThirdParty upsync +syn keyword ngxDirectiveThirdParty upsync_dump_path +syn keyword ngxDirectiveThirdParty upsync_lb +syn keyword ngxDirectiveThirdParty upsync_show + +" Strip Module <https://github.com/evanmiller/mod_strip> +" Whitespace remover. +syn keyword ngxDirectiveThirdParty strip + +" Subrange Module <https://github.com/Qihoo360/ngx_http_subrange_module> +" Split one big HTTP/Range request to multiple subrange requesets +syn keyword ngxDirectiveThirdParty subrange + +" Substitutions Module <https://www.nginx.com/resources/wiki/modules/substitutions/> +" A filter module which can do both regular expression and fixed string substitutions on response bodies. +syn keyword ngxDirectiveThirdParty subs_filter +syn keyword ngxDirectiveThirdParty subs_filter_types + +" Summarizer Module <https://github.com/reeteshranjan/summarizer-nginx-module> +" Upstream nginx module to get summaries of documents using the summarizer daemon service +syn keyword ngxDirectiveThirdParty smrzr_filename +syn keyword ngxDirectiveThirdParty smrzr_ratio + +" Supervisord Module <https://github.com/FRiCKLE/ngx_supervisord/> +" Module providing nginx with API to communicate with supervisord and manage (start/stop) backends on-demand. +syn keyword ngxDirectiveThirdParty supervisord +syn keyword ngxDirectiveThirdParty supervisord_inherit_backend_status +syn keyword ngxDirectiveThirdParty supervisord_name +syn keyword ngxDirectiveThirdParty supervisord_start +syn keyword ngxDirectiveThirdParty supervisord_stop + +" Tarantool Upstream Module <https://github.com/tarantool/nginx_upstream_module> +" Tarantool NginX upstream module (REST, JSON API, websockets, load balancing) +syn keyword ngxDirectiveThirdParty tnt_pass +syn keyword ngxDirectiveThirdParty tnt_http_methods +syn keyword ngxDirectiveThirdParty tnt_http_rest_methods +syn keyword ngxDirectiveThirdParty tnt_pass_http_request +syn keyword ngxDirectiveThirdParty tnt_pass_http_request_buffer_size +syn keyword ngxDirectiveThirdParty tnt_method +syn keyword ngxDirectiveThirdParty tnt_http_allowed_methods - experemental +syn keyword ngxDirectiveThirdParty tnt_send_timeout +syn keyword ngxDirectiveThirdParty tnt_read_timeout +syn keyword ngxDirectiveThirdParty tnt_buffer_size +syn keyword ngxDirectiveThirdParty tnt_next_upstream +syn keyword ngxDirectiveThirdParty tnt_connect_timeout +syn keyword ngxDirectiveThirdParty tnt_next_upstream +syn keyword ngxDirectiveThirdParty tnt_next_upstream_tries +syn keyword ngxDirectiveThirdParty tnt_next_upstream_timeout + +" TCP Proxy Module <http://yaoweibin.github.io/nginx_tcp_proxy_module/> +" Add the feature of tcp proxy with nginx, with health check and status monitor +syn keyword ngxDirectiveBlock tcp +" syn keyword ngxDirectiveThirdParty server +" syn keyword ngxDirectiveThirdParty listen +" syn keyword ngxDirectiveThirdParty allow +" syn keyword ngxDirectiveThirdParty deny +" syn keyword ngxDirectiveThirdParty so_keepalive +" syn keyword ngxDirectiveThirdParty tcp_nodelay +" syn keyword ngxDirectiveThirdParty timeout +" syn keyword ngxDirectiveThirdParty server_name +" syn keyword ngxDirectiveThirdParty resolver +" syn keyword ngxDirectiveThirdParty resolver_timeout +" syn keyword ngxDirectiveThirdParty upstream +syn keyword ngxDirectiveThirdParty check +syn keyword ngxDirectiveThirdParty check_http_send +syn keyword ngxDirectiveThirdParty check_http_expect_alive +syn keyword ngxDirectiveThirdParty check_smtp_send +syn keyword ngxDirectiveThirdParty check_smtp_expect_alive +syn keyword ngxDirectiveThirdParty check_shm_size +syn keyword ngxDirectiveThirdParty check_status +" syn keyword ngxDirectiveThirdParty ip_hash +" syn keyword ngxDirectiveThirdParty proxy_pass +" syn keyword ngxDirectiveThirdParty proxy_buffer +" syn keyword ngxDirectiveThirdParty proxy_connect_timeout +" syn keyword ngxDirectiveThirdParty proxy_read_timeout +syn keyword ngxDirectiveThirdParty proxy_write_timeout + +" Testcookie Module <https://github.com/kyprizel/testcookie-nginx-module> +" NGINX module for L7 DDoS attack mitigation +syn keyword ngxDirectiveThirdParty testcookie +syn keyword ngxDirectiveThirdParty testcookie_name +syn keyword ngxDirectiveThirdParty testcookie_domain +syn keyword ngxDirectiveThirdParty testcookie_expires +syn keyword ngxDirectiveThirdParty testcookie_path +syn keyword ngxDirectiveThirdParty testcookie_secret +syn keyword ngxDirectiveThirdParty testcookie_session +syn keyword ngxDirectiveThirdParty testcookie_arg +syn keyword ngxDirectiveThirdParty testcookie_max_attempts +syn keyword ngxDirectiveThirdParty testcookie_p3p +syn keyword ngxDirectiveThirdParty testcookie_fallback +syn keyword ngxDirectiveThirdParty testcookie_whitelist +syn keyword ngxDirectiveThirdParty testcookie_pass +syn keyword ngxDirectiveThirdParty testcookie_redirect_via_refresh +syn keyword ngxDirectiveThirdParty testcookie_refresh_template +syn keyword ngxDirectiveThirdParty testcookie_refresh_status +syn keyword ngxDirectiveThirdParty testcookie_deny_keepalive +syn keyword ngxDirectiveThirdParty testcookie_get_only +syn keyword ngxDirectiveThirdParty testcookie_https_location +syn keyword ngxDirectiveThirdParty testcookie_refresh_encrypt_cookie +syn keyword ngxDirectiveThirdParty testcookie_refresh_encrypt_cookie_key +syn keyword ngxDirectiveThirdParty testcookie_refresh_encrypt_iv +syn keyword ngxDirectiveThirdParty testcookie_internal +syn keyword ngxDirectiveThirdParty testcookie_httponly_flag +syn keyword ngxDirectiveThirdParty testcookie_secure_flag + +" Types Filter Module <https://github.com/flygoast/ngx_http_types_filter> +" Change the `Content-Type` output header depending on an extension variable according to a condition specified in the 'if' clause. +syn keyword ngxDirectiveThirdParty types_filter +syn keyword ngxDirectiveThirdParty types_filter_use_default + +" Unzip Module <https://github.com/youzee/nginx-unzip-module> +" Enabling fetching of files that are stored in zipped archives. +syn keyword ngxDirectiveThirdParty file_in_unzip_archivefile +syn keyword ngxDirectiveThirdParty file_in_unzip_extract +syn keyword ngxDirectiveThirdParty file_in_unzip + +" Upload Progress Module <https://www.nginx.com/resources/wiki/modules/upload_progress/> +" An upload progress system, that monitors RFC1867 POST upload as they are transmitted to upstream servers +syn keyword ngxDirectiveThirdParty upload_progress +syn keyword ngxDirectiveThirdParty track_uploads +syn keyword ngxDirectiveThirdParty report_uploads +syn keyword ngxDirectiveThirdParty upload_progress_content_type +syn keyword ngxDirectiveThirdParty upload_progress_header +syn keyword ngxDirectiveThirdParty upload_progress_jsonp_parameter +syn keyword ngxDirectiveThirdParty upload_progress_json_output +syn keyword ngxDirectiveThirdParty upload_progress_jsonp_output +syn keyword ngxDirectiveThirdParty upload_progress_template + +" Upload Module <https://www.nginx.com/resources/wiki/modules/upload/> +" Parses request body storing all files being uploaded to a directory specified by upload_store directive +syn keyword ngxDirectiveThirdParty upload_pass +syn keyword ngxDirectiveThirdParty upload_resumable +syn keyword ngxDirectiveThirdParty upload_store +syn keyword ngxDirectiveThirdParty upload_state_store +syn keyword ngxDirectiveThirdParty upload_store_access +syn keyword ngxDirectiveThirdParty upload_set_form_field +syn keyword ngxDirectiveThirdParty upload_aggregate_form_field +syn keyword ngxDirectiveThirdParty upload_pass_form_field +syn keyword ngxDirectiveThirdParty upload_cleanup +syn keyword ngxDirectiveThirdParty upload_buffer_size +syn keyword ngxDirectiveThirdParty upload_max_part_header_len +syn keyword ngxDirectiveThirdParty upload_max_file_size +syn keyword ngxDirectiveThirdParty upload_limit_rate +syn keyword ngxDirectiveThirdParty upload_max_output_body_len +syn keyword ngxDirectiveThirdParty upload_tame_arrays +syn keyword ngxDirectiveThirdParty upload_pass_args + +" Upstream Fair Module <https://github.com/gnosek/nginx-upstream-fair> +" The fair load balancer module for nginx http://nginx.localdomain.pl +syn keyword ngxDirectiveThirdParty fair +syn keyword ngxDirectiveThirdParty upstream_fair_shm_size + +" Upstream Hash Module (DEPRECATED) <http://wiki.nginx.org/NginxHttpUpstreamRequestHashModule> +" Provides simple upstream load distribution by hashing a configurable variable. +" syn keyword ngxDirectiveDeprecated hash +syn keyword ngxDirectiveDeprecated hash_again + +" Upstream Domain Resolve Module <https://www.nginx.com/resources/wiki/modules/domain_resolve/> +" A load-balancer that resolves an upstream domain name asynchronously. +syn keyword ngxDirectiveThirdParty jdomain + +" Upsync Module <https://github.com/weibocom/nginx-upsync-module> +" Sync upstreams from consul or others, dynamiclly modify backend-servers attribute(weight, max_fails,...), needn't reload nginx +syn keyword ngxDirectiveThirdParty upsync +syn keyword ngxDirectiveThirdParty upsync_dump_path +syn keyword ngxDirectiveThirdParty upsync_lb +syn keyword ngxDirectiveThirdParty upstream_show + +" URL Module <https://github.com/vozlt/nginx-module-url> +" Nginx url encoding converting module +syn keyword ngxDirectiveThirdParty url_encoding_convert +syn keyword ngxDirectiveThirdParty url_encoding_convert_from +syn keyword ngxDirectiveThirdParty url_encoding_convert_to + +" User Agent Module <https://github.com/alibaba/nginx-http-user-agent> +" Match browsers and crawlers +syn keyword ngxDirectiveThirdParty user_agent + +" Upstrema Ketama Chash Module <https://github.com/flygoast/ngx_http_upstream_ketama_chash> +" Nginx load-balancer module implementing ketama consistent hashing. +syn keyword ngxDirectiveThirdParty ketama_chash + +" Video Thumbextractor Module <https://github.com/wandenberg/nginx-video-thumbextractor-module> +" Extract thumbs from a video file +syn keyword ngxDirectiveThirdParty video_thumbextractor +syn keyword ngxDirectiveThirdParty video_thumbextractor_video_filename +syn keyword ngxDirectiveThirdParty video_thumbextractor_video_second +syn keyword ngxDirectiveThirdParty video_thumbextractor_image_width +syn keyword ngxDirectiveThirdParty video_thumbextractor_image_height +syn keyword ngxDirectiveThirdParty video_thumbextractor_only_keyframe +syn keyword ngxDirectiveThirdParty video_thumbextractor_next_time +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_rows +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_cols +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_max_rows +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_max_cols +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_sample_interval +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_color +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_margin +syn keyword ngxDirectiveThirdParty video_thumbextractor_tile_padding +syn keyword ngxDirectiveThirdParty video_thumbextractor_threads +syn keyword ngxDirectiveThirdParty video_thumbextractor_processes_per_worker + +" Eval Module <http://www.grid.net.ru/nginx/eval.en.html> +" Module for nginx web server evaluates response of proxy or memcached module into variables. +syn keyword ngxDirectiveThirdParty eval +syn keyword ngxDirectiveThirdParty eval_escalate +syn keyword ngxDirectiveThirdParty eval_override_content_type + +" VTS Module <https://github.com/vozlt/nginx-module-vts> +" Nginx virtual host traffic status module +syn keyword ngxDirectiveThirdParty vhost_traffic_status +syn keyword ngxDirectiveThirdParty vhost_traffic_status_zone +syn keyword ngxDirectiveThirdParty vhost_traffic_status_display +syn keyword ngxDirectiveThirdParty vhost_traffic_status_display_format +syn keyword ngxDirectiveThirdParty vhost_traffic_status_display_jsonp +syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter +syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter_by_host +syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter_by_set_key +syn keyword ngxDirectiveThirdParty vhost_traffic_status_filter_check_duplicate +syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit +syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit_traffic +syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit_traffic_by_set_key +syn keyword ngxDirectiveThirdParty vhost_traffic_status_limit_check_duplicate + +" XSS Module <https://github.com/openresty/xss-nginx-module> +" Native support for cross-site scripting (XSS) in an nginx. +syn keyword ngxDirectiveThirdParty xss_get +syn keyword ngxDirectiveThirdParty xss_callback_arg +syn keyword ngxDirectiveThirdParty xss_override_status +syn keyword ngxDirectiveThirdParty xss_check_status +syn keyword ngxDirectiveThirdParty xss_input_types + +" ZIP Module <https://www.nginx.com/resources/wiki/modules/zip/> +" ZIP archiver for nginx + +" Contained LUA blocks for embedded syntax highlighting +syn keyword ngxThirdPartyLuaBlock balancer_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock init_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock init_worker_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock set_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock content_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock rewrite_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock access_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock header_filter_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock body_filter_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock log_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock ssl_certificate_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock ssl_session_fetch_by_lua_block contained +syn keyword ngxThirdPartyLuaBlock ssl_session_store_by_lua_block contained + + +" Nested syntax in ERB templating statements +" Subtype needs to be set to '', otherwise recursive errors occur when opening *.nginx files +let b:eruby_subtype = '' +unlet b:current_syntax +syn include @ERB syntax/eruby.vim +syn region ngxTemplate start=+<%[^\=]+ end=+%>+ oneline contains=@ERB +syn region ngxTemplateVar start=+<%=+ end=+%>+ oneline +let b:current_syntax = "nginx" + +" Nested syntax in Jinja templating statements +" This dependend on https://github.com/lepture/vim-jinja +unlet b:current_syntax +try + syn include @JINJA syntax/jinja.vim + syn region ngxTemplate start=+{%+ end=+%}+ oneline contains=@JINJA + syn region ngxTemplateVar start=+{{+ end=+}}+ oneline +catch +endtry +let b:current_syntax = "nginx" + +" Enable nested LUA syntax highlighting +unlet b:current_syntax +syn include @LUA syntax/lua.vim +syn region ngxLua start=+^\s*\w\+_by_lua_block\s*{+ end=+}+me=s-1 contains=ngxBlock,@LUA +let b:current_syntax = "nginx" + + +" Highlight +hi link ngxComment Comment +hi link ngxVariable Identifier +hi link ngxVariableBlock Identifier +hi link ngxVariableString PreProc +hi link ngxString String +hi link ngxIPaddr Delimiter +hi link ngxBoolean Boolean +hi link ngxInteger Number +hi link ngxDirectiveBlock Statement +hi link ngxDirectiveImportant Type +hi link ngxDirectiveControl Keyword +hi link ngxDirectiveDeprecated Error +hi link ngxDirective Function +hi link ngxDirectiveThirdParty Function +hi link ngxListenOptions PreProc +hi link ngxUpstreamServerOptions PreProc +hi link ngxProxyNextUpstreamOptions PreProc +hi link ngxMailProtocol Keyword +hi link ngxSSLProtocol PreProc +hi link ngxSSLProtocolDeprecated Error +hi link ngxStickyOptions ngxDirective +hi link ngxCookieOptions PreProc +hi link ngxTemplateVar Identifier + +hi link ngxSSLSessionTicketsOff ngxBoolean +hi link ngxSSLSessionTicketsOn Error +hi link ngxSSLPreferServerCiphersOn ngxBoolean +hi link ngxSSLPreferServerCiphersOff Error +hi link ngxGzipOff ngxBoolean +hi link ngxGzipOn Error +hi link ngxSSLCipherInsecure Error + +hi link ngxThirdPartyLuaBlock Function diff --git a/runtime/syntax/sml.vim b/runtime/syntax/sml.vim index afff5304e6..53ff12a859 100644 --- a/runtime/syntax/sml.vim +++ b/runtime/syntax/sml.vim @@ -3,19 +3,18 @@ " Filenames: *.sml *.sig " Maintainers: Markus Mottl <markus.mottl@gmail.com> " Fabrizio Zeno Cornelli <zeno@filibusta.crema.unimi.it> -" Last Change: 2019 Oct 01 - Only spell check strings & comments (Chuan Wei Foo) +" Last Change: 2021 Oct 04 " 2015 Aug 31 - Fixed opening of modules (Ramana Kumar) " 2006 Oct 23 - Fixed character highlighting bug (MM) " quit when a syntax file was already loaded if exists("b:current_syntax") + finish +endif " Disable spell checking of syntax. syn spell notoplevel - finish -endif - " SML is case sensitive. syn case match diff --git a/runtime/syntax/tcl.vim b/runtime/syntax/tcl.vim index 64efd6fec4..73b2b3fa11 100644 --- a/runtime/syntax/tcl.vim +++ b/runtime/syntax/tcl.vim @@ -6,9 +6,9 @@ " (previously Matt Neumann <mattneu@purpleturtle.com>) " (previously Allan Kelly <allan@fruitloaf.co.uk>) " Original: Robin Becker <robin@jessikat.demon.co.uk> -" Last Change: 2014-02-12 +" Last Change: 2021 Oct 03 " Version: 1.14 -" URL: http://bitbucket.org/taylor_venable/metasyntax/src/tip/Config/vim/syntax/tcl.vim +" URL: (removed, no longer worked) " quit when a syntax file was already loaded if exists("b:current_syntax") diff --git a/runtime/syntax/tcsh.vim b/runtime/syntax/tcsh.vim index b535d11df8..27c6417fd0 100644 --- a/runtime/syntax/tcsh.vim +++ b/runtime/syntax/tcsh.vim @@ -1,6 +1,7 @@ " tcsh.vim: Vim syntax file for tcsh scripts -" Maintainer: Gautam Iyer <gi1242@gmail.com> -" Modified: Thu 17 Dec 2009 06:05:07 PM EST +" Maintainer: Doug Kearns <dougkearns@NoSpam.com> where NoSpam=gmail +" Author: Gautam Iyer <gi1242+vim@NoSpam.com> where NoSpam=gmail +" Modified: Sun 26 Sep 2021 12:40:55 PM EDT " " Description: We break up each statement into a "command" and an "end" part. " All groups are either a "command" or part of the "end" of a statement (ie diff --git a/runtime/syntax/typescriptcommon.vim b/runtime/syntax/typescriptcommon.vim index 4074f04a35..ef362fc721 100644 --- a/runtime/syntax/typescriptcommon.vim +++ b/runtime/syntax/typescriptcommon.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: TypeScript and TypeScriptReact " Maintainer: Bram Moolenaar, Herrington Darkholme -" Last Change: 2020 Oct 27 +" Last Change: 2021 Sep 22 " Based On: Herrington Darkholme's yats.vim " Changes: See https:github.com/HerringtonDarkholme/yats.vim " Credits: See yats.vim on github @@ -625,7 +625,8 @@ syntax keyword typescriptReadonlyArrayKeyword readonly " extension if get(g:, 'yats_host_keyword', 1) syntax keyword typescriptGlobal containedin=typescriptIdentifierName Function Boolean - syntax keyword typescriptGlobal containedin=typescriptIdentifierName Error EvalError + " use of nextgroup Suggested by Doug Kearns + syntax keyword typescriptGlobal containedin=typescriptIdentifierName Error EvalError nextgroup=typescriptFuncCallArg syntax keyword typescriptGlobal containedin=typescriptIdentifierName InternalError syntax keyword typescriptGlobal containedin=typescriptIdentifierName RangeError ReferenceError syntax keyword typescriptGlobal containedin=typescriptIdentifierName StopIteration diff --git a/runtime/syntax/xpm.vim b/runtime/syntax/xpm.vim index 0667ca28ad..be9f38723e 100644 --- a/runtime/syntax/xpm.vim +++ b/runtime/syntax/xpm.vim @@ -1,19 +1,22 @@ " Vim syntax file " Language: X Pixmap " Maintainer: Ronald Schild <rs@scutum.de> -" Last Change: 2017 Feb 01 +" Last Change: 2021 Oct 04 " Version: 5.4n.1 " Jemma Nelson added termguicolors support +" Dominique Pellé fixed spelling support " quit when a syntax file was already loaded if exists("b:current_syntax") finish endif +syn spell notoplevel + syn keyword xpmType char syn keyword xpmStorageClass static syn keyword xpmTodo TODO FIXME XXX contained -syn region xpmComment start="/\*" end="\*/" contains=xpmTodo +syn region xpmComment start="/\*" end="\*/" contains=xpmTodo,@Spell syn region xpmPixelString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@xpmColors if has("gui_running") || has("termguicolors") && &termguicolors diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py index 36e01153f1..f37e4c9d37 100755 --- a/scripts/gen_vimdoc.py +++ b/scripts/gen_vimdoc.py @@ -91,6 +91,7 @@ CONFIG = { 'vim.c', 'buffer.c', 'window.c', + 'win_config.c', 'tabpage.c', 'ui.c', ], diff --git a/scripts/pvscheck.sh b/scripts/pvscheck.sh index 904ff81700..195a76763f 100755 --- a/scripts/pvscheck.sh +++ b/scripts/pvscheck.sh @@ -373,6 +373,7 @@ run_analysis() {( analyze \ --lic-file PVS-Studio.lic \ --threads "$(get_jobs_num)" \ + --exclude-path src/cjson \ --exclude-path src/xdiff \ --output-file PVS-studio.log \ --file build/compile_commands.json \ diff --git a/scripts/squash_typos.py b/scripts/squash_typos.py index 26be6010a2..b403a9b7c8 100644 --- a/scripts/squash_typos.py +++ b/scripts/squash_typos.py @@ -22,24 +22,40 @@ def get_authors_and_emails_from_pr(): # Get a list of all authors involved in the pull request (including co-authors). authors = subprocess.check_output( - ["gh", "pr", "view", "--json", "commits", "--jq", ".[][].authors.[].name"], + [ + "gh", + "pr", + "view", + os.environ["PR_NUMBER"], + "--json", + "commits", + "--jq", + ".[][].authors.[].name", + ], text=True, ).splitlines() # Get a list of emails of the aforementioned authors. emails = subprocess.check_output( - ["gh", "pr", "view", "--json", "commits", "--jq", ".[][].authors.[].email"], + [ + "gh", + "pr", + "view", + os.environ["PR_NUMBER"], + "--json", + "commits", + "--jq", + ".[][].authors.[].email", + ], text=True, ).splitlines() - authors_and_emails_unique = { - (author, mail) for author, mail in zip(authors, emails) - } + authors_and_emails = [(author, mail) for author, mail in zip(authors, emails)] - return sorted(authors_and_emails_unique) + return authors_and_emails -def rebase_squash_branch_onto_pr(): +def rebase_onto_pr(): """ Rebase current branch onto the PR. @@ -49,9 +65,7 @@ def rebase_squash_branch_onto_pr(): # Check out the pull request. subprocess.call(["gh", "pr", "checkout", os.environ["PR_NUMBER"]]) - # Rebase onto master - default_branch = f"{os.environ['GITHUB_BASE_REF']}" - subprocess.check_call(["git", "rebase", default_branch]) + rebase_onto_master() # Change back to the original branch. subprocess.call(["git", "switch", "-"]) @@ -87,7 +101,7 @@ def rebase_squash_branch_onto_pr(): ) -def rebase_squash_branch_onto_master(): +def rebase_onto_master(): """ Rebase current branch onto the master i.e. make sure current branch is up @@ -99,7 +113,7 @@ def rebase_squash_branch_onto_master(): subprocess.check_call(["git", "rebase", default_branch]) -def squash_all_commits(): +def squash_all_commits(message_body_before): """ Squash all commits on the PR into a single commit. Credit all authors by @@ -111,8 +125,11 @@ def squash_all_commits(): subprocess.call(["git", "reset", "--soft", default_branch]) authors_and_emails = get_authors_and_emails_from_pr() - commit_message_coauthors = "\n" + "\n".join( - [f"Co-authored-by: {i[0]} <{i[1]}>" for i in authors_and_emails] + commit_message_coauthors = ( + "\n" + + "\n".join([f"Co-authored-by: {i[0]} <{i[1]}>" for i in authors_and_emails]) + + "\n" + + message_body_before ) subprocess.call( ["git", "commit", "-m", "chore: typo fixes", "-m", commit_message_coauthors] @@ -164,7 +181,7 @@ def checkout_branch(branch): return False -def get_all_pr_urls(squash_branch_exists): +def get_all_pr_urls(pr_branch_exists): """ Return a list of URLs for the pull requests with the typo fixes. If a @@ -173,7 +190,7 @@ def get_all_pr_urls(squash_branch_exists): """ all_pr_urls = "" - if squash_branch_exists: + if pr_branch_exists: all_pr_urls += subprocess.check_output( ["gh", "pr", "view", "--json", "body", "--jq", ".body"], text=True ) @@ -187,15 +204,21 @@ def get_all_pr_urls(squash_branch_exists): def main(): - squash_branch = "marvim/squash-typos" + pr_branch = "marvim/squash-typos" - squash_branch_exists = checkout_branch(squash_branch) + pr_branch_exists = checkout_branch(pr_branch) - rebase_squash_branch_onto_master() - force_push(squash_branch) + rebase_onto_master() + force_push(pr_branch) + + message_body_before = "\n".join( + subprocess.check_output( + ["git", "log", "--format=%B", "-n1", pr_branch], text=True + ).splitlines()[2:] + ) - rebase_squash_branch_onto_pr() - force_push(squash_branch) + rebase_onto_pr() + force_push(pr_branch) subprocess.call( [ @@ -204,20 +227,37 @@ def main(): "create", "--fill", "--head", - squash_branch, + pr_branch, "--title", "chore: typo fixes (automated)", - ] + ], + text=True, ) - squash_all_commits() - force_push(squash_branch) + squash_all_commits(message_body_before) + force_push(pr_branch) - all_pr_urls = get_all_pr_urls(squash_branch_exists) + all_pr_urls = get_all_pr_urls(pr_branch_exists) subprocess.call(["gh", "pr", "edit", "--add-label", "typo", "--body", all_pr_urls]) subprocess.call(["gh", "pr", "close", os.environ["PR_NUMBER"]]) + squash_url = subprocess.check_output( + ["gh", "pr", "view", "--json", "url", "--jq", ".url"], text=True + ).strip() + subprocess.call( + [ + "gh", + "pr", + "comment", + os.environ["PR_NUMBER"], + "--body", + f"Thank you for your contribution! We collect all typo fixes \ + into a single pull request and merge it once it gets big enough: \ + {squash_url}", + ] + ) + if __name__ == "__main__": main() diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c index 92d07963bd..cf9e82c38e 100644 --- a/src/cjson/lua_cjson.c +++ b/src/cjson/lua_cjson.c @@ -171,10 +171,18 @@ typedef struct { } json_config_t; typedef struct { + /* convert null in json objects to lua nil instead of vim.NIL */ + int luanil_object; + /* convert null in json arrays to lua nil instead of vim.NIL */ + int luanil_array; +} json_options_t; + +typedef struct { const char *data; const char *ptr; strbuf_t *tmp; /* Temporary storage for strings */ json_config_t *cfg; + json_options_t *options; int current_depth; } json_parse_t; @@ -865,7 +873,7 @@ static int json_encode(lua_State *l) /* ===== DECODING ===== */ static void json_process_value(lua_State *l, json_parse_t *json, - json_token_t *token); + json_token_t *token, bool use_luanil); static int hexdigit2int(char hex) { @@ -1296,7 +1304,7 @@ static void json_parse_object_context(lua_State *l, json_parse_t *json) /* Fetch value */ json_next_token(json, &token); - json_process_value(l, json, &token); + json_process_value(l, json, &token, json->options->luanil_object); /* Set key = value */ lua_rawset(l, -3); @@ -1343,7 +1351,7 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json) } for (i = 1; ; i++) { - json_process_value(l, json, &token); + json_process_value(l, json, &token, json->options->luanil_array); lua_rawseti(l, -2, i); /* arr[i] = value */ json_next_token(json, &token); @@ -1362,7 +1370,7 @@ static void json_parse_array_context(lua_State *l, json_parse_t *json) /* Handle the "value" context */ static void json_process_value(lua_State *l, json_parse_t *json, - json_token_t *token) + json_token_t *token, bool use_luanil) { switch (token->type) { case T_STRING: @@ -1381,7 +1389,11 @@ static void json_process_value(lua_State *l, json_parse_t *json, json_parse_array_context(l, json); break;; case T_NULL: - nlua_pushref(l, nlua_nil_ref); + if (use_luanil) { + lua_pushnil(l); + } else { + nlua_pushref(l, nlua_nil_ref); + } break;; default: json_throw_parse_error(l, json, "value", token); @@ -1392,12 +1404,46 @@ static int json_decode(lua_State *l) { json_parse_t json; json_token_t token; + json_options_t options = { .luanil_object = false, .luanil_array = false }; + + size_t json_len; - luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument"); + switch (lua_gettop(l)) { + case 1: + break; + case 2: + luaL_checktype(l, 2, LUA_TTABLE); + lua_getfield(l, 2, "luanil"); + + /* We only handle the luanil option for now */ + if (lua_isnil(l, -1)) { + lua_pop(l, 1); + break; + } + + luaL_checktype(l, -1, LUA_TTABLE); + + lua_getfield(l, -1, "object"); + if (!lua_isnil(l, -1)) { + options.luanil_object = true; + } + lua_pop(l, 1); + + lua_getfield(l, -1, "array"); + if (!lua_isnil(l, -1)) { + options.luanil_array = true; + } + /* Also pop the luanil table */ + lua_pop(l, 2); + break; + default: + return luaL_error (l, "expected 1 or 2 arguments"); + } json.cfg = json_fetch_config(l); json.data = luaL_checklstring(l, 1, &json_len); + json.options = &options; json.current_depth = 0; json.ptr = json.data; @@ -1415,7 +1461,7 @@ static int json_decode(lua_State *l) json.tmp = strbuf_new(json_len); json_next_token(&json, &token); - json_process_value(l, &json, &token); + json_process_value(l, &json, &token, json.options->luanil_object); /* Ensure there is no more input left */ json_next_token(&json, &token); diff --git a/src/mpack/conv.c b/src/mpack/conv.c index 31297a8784..6bd446ca49 100644 --- a/src/mpack/conv.c +++ b/src/mpack/conv.c @@ -301,7 +301,6 @@ MPACK_API double mpack_unpack_number(mpack_token_t t) */ if (!hi) { assert(t.length <= 4); - hi = 0; lo = (~lo & (((mpack_uint32_t)1 << ((t.length * 8) - 1)) - 1)); } else { hi = ~hi; diff --git a/src/mpack/lmpack.c b/src/mpack/lmpack.c index 4b0e132a3a..24d27fd17a 100644 --- a/src/mpack/lmpack.c +++ b/src/mpack/lmpack.c @@ -204,14 +204,14 @@ static void lmpack_pushnil(lua_State *L) static mpack_uint32_t lmpack_objlen(lua_State *L, int *is_array) { size_t len, max; - int isarr, type; + int isarr; lua_Number n; #ifndef NDEBUG int top = lua_gettop(L); assert(top); #endif - if ((type = lua_type(L, -1)) != LUA_TTABLE) { + if ((lua_type(L, -1)) != LUA_TTABLE) { #if LUA_VERSION_NUM >= 502 len = lua_rawlen(L, -1); #elif LUA_VERSION_NUM == 501 @@ -445,7 +445,6 @@ static int lmpack_unpacker_unpack_str(lua_State *L, Unpacker *unpacker, if (rv == MPACK_NOMEM) { unpacker->parser = lmpack_grow_parser(unpacker->parser); if (!unpacker->parser) { - unpacker->unpacking = 0; return luaL_error(L, "failed to grow Unpacker capacity"); } } @@ -799,7 +798,6 @@ static int lmpack_packer_pack(lua_State *L) if (result == MPACK_NOMEM) { packer->parser = lmpack_grow_parser(packer->parser); if (!packer->parser) { - packer->packing = 0; return luaL_error(L, "Failed to grow Packer capacity"); } } diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 34d7f6e32d..569c0c9771 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -418,7 +418,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Buffer buffer, Integer start, Integ try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); if (!MODIFIABLE(buf)) { api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); @@ -624,7 +624,8 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In if (replacement.size == 1) { firstlen += last_part_len; } - char *first = xmallocz(firstlen), *last = NULL; + char *first = xmallocz(firstlen); + char *last = NULL; memcpy(first, str_at_start, (size_t)start_col); memcpy(first+start_col, first_item.data, first_item.size); memchrsub(first+start_col, NUL, NL, first_item.size); @@ -637,7 +638,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In memcpy(last+last_item.size, str_at_end+end_col, last_part_len); } - char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL; + char **lines = xcalloc(new_len, sizeof(char *)); lines[0] = first; new_byte += (bcount_t)(first_item.size); for (size_t i = 1; i < new_len-1; i++) { @@ -656,7 +657,7 @@ void nvim_buf_set_text(uint64_t channel_id, Buffer buffer, Integer start_row, In try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); if (!MODIFIABLE(buf)) { api_set_error(err, kErrorTypeException, "Buffer is not 'modifiable'"); @@ -1108,14 +1109,97 @@ Boolean nvim_buf_is_valid(Buffer buffer) return ret; } -/// Return a tuple (row,col) representing the position of the named mark. +/// Deletes a named mark in the buffer. See |mark-motions|. +/// +/// @note only deletes marks set in the buffer, if the mark is not set +/// in the buffer it will return false. +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @return true if the mark was deleted, else false. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_del_mark()| +Boolean nvim_buf_del_mark(Buffer buffer, String name, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return res; + } + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + + pos_T *pos = getmark_buf(buf, *name.data, false); + + // pos point to NULL when there's no mark with name + if (pos == NULL) { + api_set_error(err, kErrorTypeValidation, "Invalid mark name: '%c'", + *name.data); + return res; + } + + // pos->lnum is 0 when the mark is not valid in the buffer, or is not set. + if (pos->lnum != 0) { + // since the mark belongs to the buffer delete it. + res = set_mark(buf, name, 0, 0, err); + } + + return res; +} + +/// Sets a named mark in the given buffer, all marks are allowed +/// file/uppercase, visual, last change, etc. See |mark-motions|. +/// +/// Marks are (1,0)-indexed. |api-indexing| +/// +/// @note Passing 0 as line deletes the mark +/// +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @param line Line number +/// @param col Column/row number +/// @return true if the mark was set, else false. +/// @see |nvim_buf_del_mark()| +/// @see |nvim_buf_get_mark()| +Boolean nvim_buf_set_mark(Buffer buffer, String name, + Integer line, Integer col, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return res; + } + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + + res = set_mark(buf, name, line, col, err); + + return res; +} + +/// Returns a tuple (row,col) representing the position of the named mark. See +/// |mark-motions|. /// /// Marks are (1,0)-indexed. |api-indexing| /// /// @param buffer Buffer handle, or 0 for current buffer /// @param name Mark name /// @param[out] err Error details, if any -/// @return (row, col) tuple +/// @return (row, col) tuple, (0, 0) if the mark is not set, or is an +/// uppercase/file mark set in another buffer. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_buf_del_mark()| ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) FUNC_API_SINCE(1) { @@ -1257,7 +1341,7 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, if (extmark.row < 0) { return rv; } - return extmark_to_array(extmark, false, (bool)details); + return extmark_to_array(extmark, false, details); } /// Gets extmarks in "traversal order" from a |charwise| region defined by @@ -1478,17 +1562,18 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer Dict(set_extmark) *opts, Error *err) FUNC_API_SINCE(7) { + Decoration decor = DECORATION_INIT; + buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { - return 0; + goto error; } if (!ns_initialized((uint64_t)ns_id)) { api_set_error(err, kErrorTypeValidation, "Invalid ns_id"); - return 0; + goto error; } - uint64_t id = 0; if (opts->id.type == kObjectTypeInteger && opts->id.data.integer > 0) { id = (uint64_t)opts->id.data.integer; @@ -1525,8 +1610,6 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer goto error; } - Decoration decor = DECORATION_INIT; - if (HAS_KEY(opts->hl_group)) { decor.hl_id = object_to_hl_id(opts->hl_group, "hl_group", err); if (ERROR_SET(err)) { @@ -1658,7 +1741,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer if (line < 0 || line > buf->b_ml.ml_line_count) { api_set_error(err, kErrorTypeValidation, "line value outside range"); - return 0; + goto error; } else if (line < buf->b_ml.ml_line_count) { len = ephemeral ? MAXCOL : STRLEN(ml_get_buf(buf, (linenr_T)line+1, false)); } @@ -1667,7 +1750,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col = (Integer)len; } else if (col < -1 || col > (Integer)len) { api_set_error(err, kErrorTypeValidation, "col value outside range"); - return 0; + goto error; } if (col2 >= 0) { @@ -1900,7 +1983,7 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err) } try_start(); aco_save_T aco; - aucmd_prepbuf(&aco, (buf_T *)buf); + aucmd_prepbuf(&aco, buf); Array args = ARRAY_DICT_INIT; Object res = nlua_call_ref(fun, NULL, args, true, err); diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 332fc0ba96..907d09e5b7 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -165,6 +165,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A /// @param lines Array of lines /// @param[out] err Error details, if any void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { // "lnum" will be the index of the line after inserting, // no matter if it is negative or not @@ -184,6 +185,7 @@ void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *er /// @param[out] err Error details, if any /// @return Line string String buffer_get_line(Buffer buffer, Integer index, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { String rv = { .size = 0 }; @@ -212,6 +214,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) /// @param line Contents of the new line /// @param[out] err Error details, if any void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Object l = STRING_OBJ(line); Array array = { .items = &l, .size = 1 }; @@ -230,6 +233,7 @@ void buffer_set_line(Buffer buffer, Integer index, String line, Error *err) /// @param index line index /// @param[out] err Error details, if any void buffer_del_line(Buffer buffer, Integer index, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Array array = ARRAY_DICT_INIT; index = convert_index(index); @@ -255,6 +259,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, Boolean include_start, Boolean include_end, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; @@ -278,6 +283,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, /// @param[out] err Error details, if any void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start, Boolean include_end, ArrayOf(String) replacement, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { start = convert_index(start) + !include_start; end = convert_index(end) + include_end; @@ -298,6 +304,7 @@ void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean in /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -317,6 +324,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object buffer_del_var(Buffer buffer, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -340,6 +348,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err) /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object window_set_var(Window window, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -359,6 +368,7 @@ Object window_set_var(Window window, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object window_del_var(Window window, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -382,6 +392,7 @@ Object window_del_var(Window window, String name, Error *err) /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -401,6 +412,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) /// @param[out] err Error details, if any /// @return Old value Object tabpage_del_var(Tabpage tabpage, String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -417,6 +429,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err) /// OR if previous value was `v:null`. /// @return Old value or nil if there was no previous value. Object vim_set_var(String name, Object value, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { return dict_set_var(&globvardict, name, value, false, true, err); } @@ -424,6 +437,7 @@ Object vim_set_var(String name, Object value, Error *err) /// @deprecated /// @see nvim_del_var Object vim_del_var(String name, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { return dict_set_var(&globvardict, name, NIL, true, true, err); } diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 8346e01558..663d1e16b5 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -1,15 +1,15 @@ #ifndef NVIM_API_PRIVATE_DEFS_H #define NVIM_API_PRIVATE_DEFS_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <string.h> #include "nvim/func_attr.h" #include "nvim/types.h" -#define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL} -#define STRING_INIT {.data = NULL, .size = 0} +#define ARRAY_DICT_INIT { .size = 0, .capacity = 0, .items = NULL } +#define STRING_INIT { .data = NULL, .size = 0 } #define OBJECT_INIT { .type = kObjectTypeNil } #define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL } #define REMOTE_TYPE(type) typedef handle_T type diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c index 5e93ccce17..ee0cdc4c07 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -15,6 +15,7 @@ #include "nvim/api/ui.h" #include "nvim/api/vim.h" #include "nvim/api/window.h" +#include "nvim/api/win_config.h" #include "nvim/log.h" #include "nvim/map.h" #include "nvim/msgpack_rpc/helpers.h" diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 24fac0a916..d03a61d1cc 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -25,6 +25,7 @@ #include "nvim/lua/executor.h" #include "nvim/map.h" #include "nvim/map_defs.h" +#include "nvim/mark.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/msgpack_rpc/helpers.h" @@ -396,7 +397,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object return; } - stringval = (char *)value.data.string.data; + stringval = value.data.string.data; } const sctx_T save_current_sctx = current_sctx; @@ -817,13 +818,6 @@ Array string_to_array(const String input, bool crlf) void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String rhs, Dict(keymap) *opts, Error *err) { - char *err_msg = NULL; // the error message to report, if any - char *err_arg = NULL; // argument for the error message format string - ErrorType err_type = kErrorTypeNone; - - char_u *lhs_buf = NULL; - char_u *rhs_buf = NULL; - bool global = (buffer == -1); if (global) { buffer = 0; @@ -857,17 +851,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String CPO_TO_CPO_FLAGS, &parsed_args); if (parsed_args.lhs_len > MAXMAPLEN) { - err_msg = "LHS exceeds maximum map length: %s"; - err_arg = lhs.data; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "LHS exceeds maximum map length: %s", lhs.data); + goto fail_and_free; } if (mode.size > 1) { - err_msg = "Shortname is too long: %s"; - err_arg = mode.data; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Shortname is too long: %s", mode.data); + goto fail_and_free; } int mode_val; // integer value of the mapping mode, to be passed to do_map() char_u *p = (char_u *)((mode.size) ? mode.data : "m"); @@ -879,18 +869,14 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String && mode.size > 0) { // get_map_mode() treats unrecognized mode shortnames as ":map". // This is an error unless the given shortname was empty string "". - err_msg = "Invalid mode shortname: \"%s\""; - err_arg = (char *)p; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Invalid mode shortname: \"%s\"", (char *)p); + goto fail_and_free; } } if (parsed_args.lhs_len == 0) { - err_msg = "Invalid (empty) LHS"; - err_arg = ""; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Invalid (empty) LHS"); + goto fail_and_free; } bool is_noremap = parsed_args.noremap; @@ -903,16 +889,13 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String // the given RHS was nonempty and not a <Nop>, but was parsed as if it // were empty? assert(false && "Failed to parse nonempty RHS!"); - err_msg = "Parsing of nonempty RHS failed: %s"; - err_arg = rhs.data; - err_type = kErrorTypeException; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, "Parsing of nonempty RHS failed: %s", rhs.data); + goto fail_and_free; } } else if (is_unmap && parsed_args.rhs_len) { - err_msg = "Gave nonempty RHS in unmap command: %s"; - err_arg = (char *)parsed_args.rhs; - err_type = kErrorTypeValidation; - goto fail_with_message; + api_set_error(err, kErrorTypeValidation, + "Gave nonempty RHS in unmap command: %s", parsed_args.rhs); + goto fail_and_free; } // buf_do_map() reads noremap/unmap as its own argument. @@ -941,19 +924,7 @@ void modify_keymap(Buffer buffer, bool is_unmap, String mode, String lhs, String goto fail_and_free; } // switch - xfree(lhs_buf); - xfree(rhs_buf); - xfree(parsed_args.rhs); - xfree(parsed_args.orig_rhs); - - return; - -fail_with_message: - api_set_error(err, err_type, err_msg, err_arg); - fail_and_free: - xfree(lhs_buf); - xfree(rhs_buf); xfree(parsed_args.rhs); xfree(parsed_args.orig_rhs); return; @@ -1648,361 +1619,6 @@ const char *describe_ns(NS ns_id) return "(UNKNOWN PLUGIN)"; } -static bool parse_float_anchor(String anchor, FloatAnchor *out) -{ - if (anchor.size == 0) { - *out = (FloatAnchor)0; - } - char *str = anchor.data; - if (striequal(str, "NW")) { - *out = 0; // NW is the default - } else if (striequal(str, "NE")) { - *out = kFloatAnchorEast; - } else if (striequal(str, "SW")) { - *out = kFloatAnchorSouth; - } else if (striequal(str, "SE")) { - *out = kFloatAnchorSouth | kFloatAnchorEast; - } else { - return false; - } - return true; -} - -static bool parse_float_relative(String relative, FloatRelative *out) -{ - char *str = relative.data; - if (striequal(str, "editor")) { - *out = kFloatRelativeEditor; - } else if (striequal(str, "win")) { - *out = kFloatRelativeWindow; - } else if (striequal(str, "cursor")) { - *out = kFloatRelativeCursor; - } else { - return false; - } - return true; -} - -static bool parse_float_bufpos(Array bufpos, lpos_T *out) -{ - if (bufpos.size != 2 - || bufpos.items[0].type != kObjectTypeInteger - || bufpos.items[1].type != kObjectTypeInteger) { - return false; - } - out->lnum = bufpos.items[0].data.integer; - out->col = (colnr_T)bufpos.items[1].data.integer; - return true; -} - -static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) -{ - struct { - const char *name; - schar_T chars[8]; - bool shadow_color; - } defaults[] = { - { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false }, - { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false }, - { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true }, - { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false }, - { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false }, - { NULL, { { NUL } }, false }, - }; - - schar_T *chars = fconfig->border_chars; - int *hl_ids = fconfig->border_hl_ids; - - fconfig->border = true; - - if (style.type == kObjectTypeArray) { - Array arr = style.data.array; - size_t size = arr.size; - if (!size || size > 8 || (size & (size-1))) { - api_set_error(err, kErrorTypeValidation, - "invalid number of border chars"); - return; - } - for (size_t i = 0; i < size; i++) { - Object iytem = arr.items[i]; - String string; - int hl_id = 0; - if (iytem.type == kObjectTypeArray) { - Array iarr = iytem.data.array; - if (!iarr.size || iarr.size > 2) { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - if (iarr.items[0].type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - string = iarr.items[0].data.string; - if (iarr.size == 2) { - hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err); - if (ERROR_SET(err)) { - return; - } - } - } else if (iytem.type == kObjectTypeString) { - string = iytem.data.string; - } else { - api_set_error(err, kErrorTypeValidation, "invalid border char"); - return; - } - if (string.size - && mb_string2cells_len((char_u *)string.data, string.size) > 1) { - api_set_error(err, kErrorTypeValidation, - "border chars must be one cell"); - return; - } - size_t len = MIN(string.size, sizeof(*chars)-1); - if (len) { - memcpy(chars[i], string.data, len); - } - chars[i][len] = NUL; - hl_ids[i] = hl_id; - } - while (size < 8) { - memcpy(chars+size, chars, sizeof(*chars) * size); - memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size); - size <<= 1; - } - if ((chars[7][0] && chars[1][0] && !chars[0][0]) - || (chars[1][0] && chars[3][0] && !chars[2][0]) - || (chars[3][0] && chars[5][0] && !chars[4][0]) - || (chars[5][0] && chars[7][0] && !chars[6][0])) { - api_set_error(err, kErrorTypeValidation, - "corner between used edges must be specified"); - } - } else if (style.type == kObjectTypeString) { - String str = style.data.string; - if (str.size == 0 || strequal(str.data, "none")) { - fconfig->border = false; - return; - } - for (size_t i = 0; defaults[i].name; i++) { - if (strequal(str.data, defaults[i].name)) { - memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars)); - memset(hl_ids, 0, 8 * sizeof(*hl_ids)); - if (defaults[i].shadow_color) { - int hl_blend = SYN_GROUP_STATIC("FloatShadow"); - int hl_through = SYN_GROUP_STATIC("FloatShadowThrough"); - hl_ids[2] = hl_through; - hl_ids[3] = hl_blend; - hl_ids[4] = hl_blend; - hl_ids[5] = hl_blend; - hl_ids[6] = hl_through; - } - return; - } - } - api_set_error(err, kErrorTypeValidation, - "invalid border style \"%s\"", str.data); - } -} - -bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf, bool new_win, - Error *err) -{ - bool has_relative = false, relative_is_win = false; - if (config->relative.type == kObjectTypeString) { - // ignore empty string, to match nvim_win_get_config - if (config->relative.data.string.size > 0) { - if (!parse_float_relative(config->relative.data.string, &fconfig->relative)) { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'relative' key"); - return false; - } - - if (!(HAS_KEY(config->row) && HAS_KEY(config->col)) && !HAS_KEY(config->bufpos)) { - api_set_error(err, kErrorTypeValidation, - "'relative' requires 'row'/'col' or 'bufpos'"); - return false; - } - - has_relative = true; - fconfig->external = false; - if (fconfig->relative == kFloatRelativeWindow) { - relative_is_win = true; - fconfig->bufpos.lnum = -1; - } - } - } else if (HAS_KEY(config->relative)) { - api_set_error(err, kErrorTypeValidation, "'relative' key must be String"); - return false; - } - - if (config->anchor.type == kObjectTypeString) { - if (!parse_float_anchor(config->anchor.data.string, &fconfig->anchor)) { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'anchor' key"); - return false; - } - } else if (HAS_KEY(config->anchor)) { - api_set_error(err, kErrorTypeValidation, "'anchor' key must be String"); - return false; - } - - if (HAS_KEY(config->row)) { - if (!has_relative) { - api_set_error(err, kErrorTypeValidation, "non-float cannot have 'row'"); - return false; - } else if (config->row.type == kObjectTypeInteger) { - fconfig->row = (double)config->row.data.integer; - } else if (config->row.type == kObjectTypeFloat) { - fconfig->row = config->row.data.floating; - } else { - api_set_error(err, kErrorTypeValidation, - "'row' key must be Integer or Float"); - return false; - } - } - - if (HAS_KEY(config->col)) { - if (!has_relative) { - api_set_error(err, kErrorTypeValidation, "non-float cannot have 'col'"); - return false; - } else if (config->col.type == kObjectTypeInteger) { - fconfig->col = (double)config->col.data.integer; - } else if (config->col.type == kObjectTypeFloat) { - fconfig->col = config->col.data.floating; - } else { - api_set_error(err, kErrorTypeValidation, - "'col' key must be Integer or Float"); - return false; - } - } - - if (HAS_KEY(config->bufpos)) { - if (!has_relative) { - api_set_error(err, kErrorTypeValidation, "non-float cannot have 'bufpos'"); - return false; - } else if (config->bufpos.type == kObjectTypeArray) { - if (!parse_float_bufpos(config->bufpos.data.array, &fconfig->bufpos)) { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'bufpos' key"); - return false; - } - - if (!HAS_KEY(config->row)) { - fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1; - } - if (!HAS_KEY(config->col)) { - fconfig->col = 0; - } - } else { - api_set_error(err, kErrorTypeValidation, "'bufpos' key must be Array"); - return false; - } - } - - if (config->width.type == kObjectTypeInteger && config->width.data.integer > 0) { - fconfig->width = (int)config->width.data.integer; - } else if (HAS_KEY(config->width)) { - api_set_error(err, kErrorTypeValidation, "'width' key must be a positive Integer"); - return false; - } else if (!reconf) { - api_set_error(err, kErrorTypeValidation, "Must specify 'width'"); - return false; - } - - if (config->height.type == kObjectTypeInteger && config->height.data.integer > 0) { - fconfig->height = (int)config->height.data.integer; - } else if (HAS_KEY(config->height)) { - api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer"); - return false; - } else if (!reconf) { - api_set_error(err, kErrorTypeValidation, "Must specify 'height'"); - return false; - } - - if (relative_is_win) { - fconfig->window = curwin->handle; - if (config->win.type == kObjectTypeInteger || config->win.type == kObjectTypeWindow) { - if (config->win.data.integer > 0) { - fconfig->window = (Window)config->win.data.integer; - } - } else if (HAS_KEY(config->win)) { - api_set_error(err, kErrorTypeValidation, "'win' key must be Integer or Window"); - return false; - } - } else { - if (HAS_KEY(config->win)) { - api_set_error(err, kErrorTypeValidation, "'win' key is only valid with relative='win'"); - return false; - } - } - - if (HAS_KEY(config->external)) { - fconfig->external = api_object_to_bool(config->external, "'external' key", false, err); - if (ERROR_SET(err)) { - return false; - } - if (has_relative && fconfig->external) { - api_set_error(err, kErrorTypeValidation, - "Only one of 'relative' and 'external' must be used"); - return false; - } - if (fconfig->external && !ui_has(kUIMultigrid)) { - api_set_error(err, kErrorTypeValidation, - "UI doesn't support external windows"); - return false; - } - } - - if (!reconf && (!has_relative && !fconfig->external)) { - api_set_error(err, kErrorTypeValidation, - "One of 'relative' and 'external' must be used"); - return false; - } - - - if (HAS_KEY(config->focusable)) { - fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err); - if (ERROR_SET(err)) { - return false; - } - } - - if (config->zindex.type == kObjectTypeInteger && config->zindex.data.integer > 0) { - fconfig->zindex = (int)config->zindex.data.integer; - } else if (HAS_KEY(config->zindex)) { - api_set_error(err, kErrorTypeValidation, "'zindex' key must be a positive Integer"); - return false; - } - - if (HAS_KEY(config->border)) { - parse_border_style(config->border, fconfig, err); - if (ERROR_SET(err)) { - return false; - } - } - - if (config->style.type == kObjectTypeString) { - if (config->style.data.string.data[0] == NUL) { - fconfig->style = kWinStyleUnused; - } else if (striequal(config->style.data.string.data, "minimal")) { - fconfig->style = kWinStyleMinimal; - } else { - api_set_error(err, kErrorTypeValidation, "Invalid value of 'style' key"); - } - } else if (HAS_KEY(config->style)) { - api_set_error(err, kErrorTypeValidation, "'style' key must be String"); - return false; - } - - if (HAS_KEY(config->noautocmd)) { - if (!new_win) { - api_set_error(err, kErrorTypeValidation, "Invalid key: 'noautocmd'"); - return false; - } - fconfig->noautocmd = api_object_to_bool(config->noautocmd, "'noautocmd' key", false, err); - if (ERROR_SET(err)) { - return false; - } - } - - return true; -} - bool api_dict_to_keydict(void *rv, field_hash hashy, Dictionary dict, Error *err) { for (size_t i = 0; i < dict.size; i++) { @@ -2026,3 +1642,42 @@ void api_free_keydict(void *dict, KeySetLink *table) } } +/// Set a named mark +/// buffer and mark name must be validated already +/// @param buffer Buffer to set the mark on +/// @param name Mark name +/// @param line Line number +/// @param col Column/row number +/// @return true if the mark was set, else false +bool set_mark(buf_T *buf, String name, Integer line, Integer col, Error *err) +{ + buf = buf == NULL ? curbuf : buf; + // If line == 0 the marks is being deleted + bool res = false; + bool deleting = false; + if (line == 0) { + col = 0; + deleting = true; + } else { + if (col > MAXCOL) { + api_set_error(err, kErrorTypeValidation, "Column value outside range"); + return res; + } + if (line < 1 || line > buf->b_ml.ml_line_count) { + api_set_error(err, kErrorTypeValidation, "Line value outside range"); + return res; + } + } + pos_T pos = { line, (int)col, (int)col }; + res = setmark_pos(*name.data, &pos, buf->handle); + if (!res) { + if (deleting) { + api_set_error(err, kErrorTypeException, + "Failed to delete named mark: %c", *name.data); + } else { + api_set_error(err, kErrorTypeException, + "Failed to set named mark: %c", *name.data); + } + } + return res; +} diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 2cdd80bffe..dc9452e832 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -4,12 +4,12 @@ #include <stdbool.h> #include "nvim/api/private/defs.h" -#include "nvim/vim.h" -#include "nvim/getchar.h" -#include "nvim/memory.h" #include "nvim/decoration.h" #include "nvim/ex_eval.h" +#include "nvim/getchar.h" #include "nvim/lib/kvec.h" +#include "nvim/memory.h" +#include "nvim/vim.h" #define OBJECT_OBJ(o) o @@ -76,7 +76,7 @@ name.size = fixsize; \ name.items = name##__items; \ -#define STATIC_CSTR_AS_STRING(s) ((String) {.data = s, .size = sizeof(s) - 1}) +#define STATIC_CSTR_AS_STRING(s) ((String) { .data = s, .size = sizeof(s) - 1 }) /// Create a new String instance, putting data in allocated memory /// @@ -137,7 +137,7 @@ typedef struct { msg_list = &private_msg_list; \ private_msg_list = NULL; \ code \ - msg_list = saved_msg_list; /* Restore the exception context. */ \ + msg_list = saved_msg_list; /* Restore the exception context. */ \ } while (0) #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index 9b200dcba2..d86aecc318 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -40,7 +40,6 @@ typedef struct { static PMap(uint64_t) connected_uis = MAP_INIT; void remote_ui_disconnect(uint64_t channel_id) - FUNC_API_NOEXPORT { UI *ui = pmap_get(uint64_t)(&connected_uis, channel_id); if (!ui) { @@ -57,7 +56,6 @@ void remote_ui_disconnect(uint64_t channel_id) /// Wait until ui has connected on stdio channel. void remote_ui_wait_for_attach(void) - FUNC_API_NOEXPORT { Channel *channel = find_channel(CHAN_STDIO); if (!channel) { @@ -172,6 +170,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona /// @deprecated void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err) + FUNC_API_DEPRECATED_SINCE(1) { Dictionary opts = ARRAY_DICT_INIT; PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb)); diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index f80d605d9a..9b39b18c4e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -59,7 +59,6 @@ #endif void api_vim_free_all_mem(void) - FUNC_API_NOEXPORT { String name; handle_T id; @@ -264,7 +263,6 @@ void nvim__set_hl_ns(Integer ns_id, Error *err) } static void on_redraw_event(void **argv) - FUNC_API_NOEXPORT { redraw_all_later(NOT_VALID); } @@ -1221,7 +1219,7 @@ fail: /// buffer in a configured window before calling this. For instance, for a /// floating display, first create an empty buffer using |nvim_create_buf()|, /// then display it using |nvim_open_win()|, and then call this function. -/// Then |nvim_chan_send()| cal be called immediately to process sequences +/// Then |nvim_chan_send()| can be called immediately to process sequences /// in a virtual terminal having the intended size. /// /// @param buffer the buffer to use (expected to be empty) @@ -1305,156 +1303,6 @@ void nvim_chan_send(Integer chan, String data, Error *err) } } -/// Open a new window. -/// -/// Currently this is used to open floating and external windows. -/// Floats are windows that are drawn above the split layout, at some anchor -/// position in some other window. Floats can be drawn internally or by external -/// GUI with the |ui-multigrid| extension. External windows are only supported -/// with multigrid GUIs, and are displayed as separate top-level windows. -/// -/// For a general overview of floats, see |api-floatwin|. -/// -/// Exactly one of `external` and `relative` must be specified. The `width` and -/// `height` of the new window must be specified. -/// -/// With relative=editor (row=0,col=0) refers to the top-left corner of the -/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right -/// corner. Fractional values are allowed, but the builtin implementation -/// (used by non-multigrid UIs) will always round down to nearest integer. -/// -/// Out-of-bounds values, and configurations that make the float not fit inside -/// the main editor, are allowed. The builtin implementation truncates values -/// so floats are fully within the main screen grid. External GUIs -/// could let floats hover outside of the main window like a tooltip, but -/// this should not be used to specify arbitrary WM screen positions. -/// -/// Example (Lua): window-relative float -/// <pre> -/// vim.api.nvim_open_win(0, false, -/// {relative='win', row=3, col=3, width=12, height=3}) -/// </pre> -/// -/// Example (Lua): buffer-relative float (travels as buffer is scrolled) -/// <pre> -/// vim.api.nvim_open_win(0, false, -/// {relative='win', width=12, height=3, bufpos={100,10}}) -/// </pre> -/// -/// @param buffer Buffer to display, or 0 for current buffer -/// @param enter Enter the window (make it the current window) -/// @param config Map defining the window configuration. Keys: -/// - `relative`: Sets the window layout to "floating", placed at (row,col) -/// coordinates relative to: -/// - "editor" The global editor grid -/// - "win" Window given by the `win` field, or current window. -/// - "cursor" Cursor position in current window. -/// - `win`: |window-ID| for relative="win". -/// - `anchor`: Decides which corner of the float to place at (row,col): -/// - "NW" northwest (default) -/// - "NE" northeast -/// - "SW" southwest -/// - "SE" southeast -/// - `width`: Window width (in character cells). Minimum of 1. -/// - `height`: Window height (in character cells). Minimum of 1. -/// - `bufpos`: Places float relative to buffer text (only when -/// relative="win"). Takes a tuple of zero-indexed [line, column]. -/// `row` and `col` if given are applied relative to this -/// position, else they default to: -/// - `row=1` and `col=0` if `anchor` is "NW" or "NE" -/// - `row=0` and `col=0` if `anchor` is "SW" or "SE" -/// (thus like a tooltip near the buffer text). -/// - `row`: Row position in units of "screen cell height", may be fractional. -/// - `col`: Column position in units of "screen cell width", may be -/// fractional. -/// - `focusable`: Enable focus by user actions (wincmds, mouse events). -/// Defaults to true. Non-focusable windows can be entered by -/// |nvim_set_current_win()|. -/// - `external`: GUI should display the window as an external -/// top-level window. Currently accepts no other positioning -/// configuration together with this. -/// - `zindex`: Stacking order. floats with higher `zindex` go on top on -/// floats with lower indices. Must be larger than zero. The -/// following screen elements have hard-coded z-indices: -/// - 100: insert completion popupmenu -/// - 200: message scrollback -/// - 250: cmdline completion popupmenu (when wildoptions+=pum) -/// The default value for floats are 50. In general, values below 100 are -/// recommended, unless there is a good reason to overshadow builtin -/// elements. -/// - `style`: Configure the appearance of the window. Currently only takes -/// one non-empty value: -/// - "minimal" Nvim will display the window with many UI options -/// disabled. This is useful when displaying a temporary -/// float where the text should not be edited. Disables -/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', -/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' -/// is changed to `auto` and 'colorcolumn' is cleared. The -/// end-of-buffer region is hidden by setting `eob` flag of -/// 'fillchars' to a space char, and clearing the -/// |EndOfBuffer| region in 'winhighlight'. -/// - `border`: Style of (optional) window border. This can either be a string -/// or an array. The string values are -/// - "none": No border (default). -/// - "single": A single line box. -/// - "double": A double line box. -/// - "rounded": Like "single", but with rounded corners ("╭" etc.). -/// - "solid": Adds padding by a single whitespace cell. -/// - "shadow": A drop shadow effect by blending with the background. -/// - If it is an array, it should have a length of eight or any divisor of -/// eight. The array will specifify the eight chars building up the border -/// in a clockwise fashion starting with the top-left corner. As an -/// example, the double box style could be specified as -/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. -/// If the number of chars are less than eight, they will be repeated. Thus -/// an ASCII border could be specified as -/// [ "/", "-", "\\", "|" ], -/// or all chars the same as -/// [ "x" ]. -/// An empty string can be used to turn off a specific border, for instance, -/// [ "", "", "", ">", "", "", "", "<" ] -/// will only make vertical borders but not horizontal ones. -/// By default, `FloatBorder` highlight is used, which links to `VertSplit` -/// when not defined. It could also be specified by character: -/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]. -/// - `noautocmd`: If true then no buffer-related autocommand events such as -/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from -/// calling this function. -/// -/// @param[out] err Error details, if any -/// -/// @return Window handle, or 0 on error -Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err) - FUNC_API_SINCE(6) - FUNC_API_CHECK_TEXTLOCK -{ - FloatConfig fconfig = FLOAT_CONFIG_INIT; - if (!parse_float_config(config, &fconfig, false, true, err)) { - return 0; - } - win_T *wp = win_new_float(NULL, fconfig, err); - if (!wp) { - return 0; - } - if (enter) { - win_enter(wp, false); - } - // autocmds in win_enter or win_set_buf below may close the window - if (win_valid(wp) && buffer > 0) { - win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); - } - if (!win_valid(wp)) { - api_set_error(err, kErrorTypeException, "Window was closed immediately"); - return 0; - } - - if (fconfig.style == kWinStyleMinimal) { - win_set_minimal_style(wp); - didset_window_options(wp); - } - return wp->handle; -} - /// Gets the current list of tabpage handles. /// /// @return List of tabpage handles @@ -1510,7 +1358,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) } } -/// Creates a new *namespace*, or gets an existing one. +/// Creates a new \*namespace\* or gets an existing one. /// /// Namespaces are used for buffer highlights and virtual text, see /// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. @@ -2931,3 +2779,106 @@ void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts, Erro error: decor_provider_clear(p); } + +/// Deletes a uppercase/file named mark. See |mark-motions|. +/// +/// @note fails with error if a lowercase or buffer local named mark is used. +/// @param name Mark name +/// @return true if the mark was deleted, else false. +/// @see |nvim_buf_del_mark()| +/// @see |nvim_get_mark()| +Boolean nvim_del_mark(String name, Error *err) + FUNC_API_SINCE(8) +{ + bool res = false; + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return res; + } + // Only allow file/uppercase marks + // TODO(muniter): Refactor this ASCII_ISUPPER macro to a proper function + if (ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data)) { + res = set_mark(NULL, name, 0, 0, err); + } else { + api_set_error(err, kErrorTypeValidation, + "Only file/uppercase marks allowed, invalid mark name: '%c'", + *name.data); + } + return res; +} + +/// Return a tuple (row, col, buffer, buffername) representing the position of +/// the uppercase/file named mark. See |mark-motions|. +/// +/// Marks are (1,0)-indexed. |api-indexing| +/// +/// @note fails with error if a lowercase or buffer local named mark is used. +/// @param name Mark name +/// @return 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is +/// not set. +/// @see |nvim_buf_set_mark()| +/// @see |nvim_del_mark()| +Array nvim_get_mark(String name, Error *err) + FUNC_API_SINCE(8) +{ + Array rv = ARRAY_DICT_INIT; + + if (name.size != 1) { + api_set_error(err, kErrorTypeValidation, + "Mark name must be a single character"); + return rv; + } else if (!(ASCII_ISUPPER(*name.data) || ascii_isdigit(*name.data))) { + api_set_error(err, kErrorTypeValidation, + "Only file/uppercase marks allowed, invalid mark name: '%c'", + *name.data); + return rv; + } + + xfmark_T mark = get_global_mark(*name.data); + pos_T pos = mark.fmark.mark; + bool allocated = false; + int bufnr; + char *filename; + + // Marks are from an open buffer it fnum is non zero + if (mark.fmark.fnum != 0) { + bufnr = mark.fmark.fnum; + filename = (char *)buflist_nr2name(bufnr, true, true); + allocated = true; + // Marks comes from shada + } else { + filename = (char *)mark.fname; + bufnr = 0; + } + + bool exists = filename != NULL; + Integer row; + Integer col; + + if (!exists || pos.lnum <= 0) { + if (allocated) { + xfree(filename); + allocated = false; + } + filename = ""; + bufnr = 0; + row = 0; + col = 0; + } else { + row = pos.lnum; + col = pos.col; + } + + ADD(rv, INTEGER_OBJ(row)); + ADD(rv, INTEGER_OBJ(col)); + ADD(rv, INTEGER_OBJ(bufnr)); + ADD(rv, STRING_OBJ(cstr_to_string(filename))); + + if (allocated) { + xfree(filename); + } + + return rv; +} + diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c new file mode 100644 index 0000000000..d82e7e8a03 --- /dev/null +++ b/src/nvim/api/win_config.c @@ -0,0 +1,639 @@ +// 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 <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" +#include "nvim/api/win_config.h" +#include "nvim/ascii.h" +#include "nvim/option.h" +#include "nvim/screen.h" +#include "nvim/strings.h" +#include "nvim/syntax.h" +#include "nvim/ui.h" +#include "nvim/window.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/win_config.c.generated.h" +#endif + + +/// Open a new window. +/// +/// Currently this is used to open floating and external windows. +/// Floats are windows that are drawn above the split layout, at some anchor +/// position in some other window. Floats can be drawn internally or by external +/// GUI with the |ui-multigrid| extension. External windows are only supported +/// with multigrid GUIs, and are displayed as separate top-level windows. +/// +/// For a general overview of floats, see |api-floatwin|. +/// +/// Exactly one of `external` and `relative` must be specified. The `width` and +/// `height` of the new window must be specified. +/// +/// With relative=editor (row=0,col=0) refers to the top-left corner of the +/// screen-grid and (row=Lines-1,col=Columns-1) refers to the bottom-right +/// corner. Fractional values are allowed, but the builtin implementation +/// (used by non-multigrid UIs) will always round down to nearest integer. +/// +/// Out-of-bounds values, and configurations that make the float not fit inside +/// the main editor, are allowed. The builtin implementation truncates values +/// so floats are fully within the main screen grid. External GUIs +/// could let floats hover outside of the main window like a tooltip, but +/// this should not be used to specify arbitrary WM screen positions. +/// +/// Example (Lua): window-relative float +/// <pre> +/// vim.api.nvim_open_win(0, false, +/// {relative='win', row=3, col=3, width=12, height=3}) +/// </pre> +/// +/// Example (Lua): buffer-relative float (travels as buffer is scrolled) +/// <pre> +/// vim.api.nvim_open_win(0, false, +/// {relative='win', width=12, height=3, bufpos={100,10}}) +/// </pre> +/// +/// @param buffer Buffer to display, or 0 for current buffer +/// @param enter Enter the window (make it the current window) +/// @param config Map defining the window configuration. Keys: +/// - `relative`: Sets the window layout to "floating", placed at (row,col) +/// coordinates relative to: +/// - "editor" The global editor grid +/// - "win" Window given by the `win` field, or current window. +/// - "cursor" Cursor position in current window. +/// - `win`: |window-ID| for relative="win". +/// - `anchor`: Decides which corner of the float to place at (row,col): +/// - "NW" northwest (default) +/// - "NE" northeast +/// - "SW" southwest +/// - "SE" southeast +/// - `width`: Window width (in character cells). Minimum of 1. +/// - `height`: Window height (in character cells). Minimum of 1. +/// - `bufpos`: Places float relative to buffer text (only when +/// relative="win"). Takes a tuple of zero-indexed [line, column]. +/// `row` and `col` if given are applied relative to this +/// position, else they default to: +/// - `row=1` and `col=0` if `anchor` is "NW" or "NE" +/// - `row=0` and `col=0` if `anchor` is "SW" or "SE" +/// (thus like a tooltip near the buffer text). +/// - `row`: Row position in units of "screen cell height", may be fractional. +/// - `col`: Column position in units of "screen cell width", may be +/// fractional. +/// - `focusable`: Enable focus by user actions (wincmds, mouse events). +/// Defaults to true. Non-focusable windows can be entered by +/// |nvim_set_current_win()|. +/// - `external`: GUI should display the window as an external +/// top-level window. Currently accepts no other positioning +/// configuration together with this. +/// - `zindex`: Stacking order. floats with higher `zindex` go on top on +/// floats with lower indices. Must be larger than zero. The +/// following screen elements have hard-coded z-indices: +/// - 100: insert completion popupmenu +/// - 200: message scrollback +/// - 250: cmdline completion popupmenu (when wildoptions+=pum) +/// The default value for floats are 50. In general, values below 100 are +/// recommended, unless there is a good reason to overshadow builtin +/// elements. +/// - `style`: Configure the appearance of the window. Currently only takes +/// one non-empty value: +/// - "minimal" Nvim will display the window with many UI options +/// disabled. This is useful when displaying a temporary +/// float where the text should not be edited. Disables +/// 'number', 'relativenumber', 'cursorline', 'cursorcolumn', +/// 'foldcolumn', 'spell' and 'list' options. 'signcolumn' +/// is changed to `auto` and 'colorcolumn' is cleared. The +/// end-of-buffer region is hidden by setting `eob` flag of +/// 'fillchars' to a space char, and clearing the +/// |EndOfBuffer| region in 'winhighlight'. +/// - `border`: Style of (optional) window border. This can either be a string +/// or an array. The string values are +/// - "none": No border (default). +/// - "single": A single line box. +/// - "double": A double line box. +/// - "rounded": Like "single", but with rounded corners ("╭" etc.). +/// - "solid": Adds padding by a single whitespace cell. +/// - "shadow": A drop shadow effect by blending with the background. +/// - If it is an array, it should have a length of eight or any divisor of +/// eight. The array will specifify the eight chars building up the border +/// in a clockwise fashion starting with the top-left corner. As an +/// example, the double box style could be specified as +/// [ "╔", "═" ,"╗", "║", "╝", "═", "╚", "║" ]. +/// If the number of chars are less than eight, they will be repeated. Thus +/// an ASCII border could be specified as +/// [ "/", "-", "\\", "|" ], +/// or all chars the same as +/// [ "x" ]. +/// An empty string can be used to turn off a specific border, for instance, +/// [ "", "", "", ">", "", "", "", "<" ] +/// will only make vertical borders but not horizontal ones. +/// By default, `FloatBorder` highlight is used, which links to `VertSplit` +/// when not defined. It could also be specified by character: +/// [ {"+", "MyCorner"}, {"x", "MyBorder"} ]. +/// - `noautocmd`: If true then no buffer-related autocommand events such as +/// |BufEnter|, |BufLeave| or |BufWinEnter| may fire from +/// calling this function. +/// +/// @param[out] err Error details, if any +/// +/// @return Window handle, or 0 on error +Window nvim_open_win(Buffer buffer, Boolean enter, Dict(float_config) *config, Error *err) + FUNC_API_SINCE(6) + FUNC_API_CHECK_TEXTLOCK +{ + FloatConfig fconfig = FLOAT_CONFIG_INIT; + if (!parse_float_config(config, &fconfig, false, true, err)) { + return 0; + } + win_T *wp = win_new_float(NULL, fconfig, err); + if (!wp) { + return 0; + } + if (enter) { + win_enter(wp, false); + } + // autocmds in win_enter or win_set_buf below may close the window + if (win_valid(wp) && buffer > 0) { + win_set_buf(wp->handle, buffer, fconfig.noautocmd, err); + } + if (!win_valid(wp)) { + api_set_error(err, kErrorTypeException, "Window was closed immediately"); + return 0; + } + + if (fconfig.style == kWinStyleMinimal) { + win_set_minimal_style(wp); + didset_window_options(wp); + } + return wp->handle; +} + +/// Configures window layout. Currently only for floating and external windows +/// (including changing a split window to those layouts). +/// +/// When reconfiguring a floating window, absent option keys will not be +/// changed. `row`/`col` and `relative` must be reconfigured together. +/// +/// @see |nvim_open_win()| +/// +/// @param window Window handle, or 0 for current window +/// @param config Map defining the window configuration, +/// see |nvim_open_win()| +/// @param[out] err Error details, if any +void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err) + FUNC_API_SINCE(6) +{ + win_T *win = find_window_by_handle(window, err); + if (!win) { + return; + } + bool new_float = !win->w_floating; + // reuse old values, if not overridden + FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; + + if (!parse_float_config(config, &fconfig, !new_float, false, err)) { + return; + } + if (new_float) { + if (!win_new_float(win, fconfig, err)) { + return; + } + redraw_later(win, NOT_VALID); + } else { + win_config_float(win, fconfig); + win->w_pos_changed = true; + } + if (fconfig.style == kWinStyleMinimal) { + win_set_minimal_style(win); + didset_window_options(win); + } +} + +/// Gets window configuration. +/// +/// The returned value may be given to |nvim_open_win()|. +/// +/// `relative` is empty for normal windows. +/// +/// @param window Window handle, or 0 for current window +/// @param[out] err Error details, if any +/// @return Map defining the window configuration, see |nvim_open_win()| +Dictionary nvim_win_get_config(Window window, Error *err) + FUNC_API_SINCE(6) +{ + Dictionary rv = ARRAY_DICT_INIT; + + win_T *wp = find_window_by_handle(window, err); + if (!wp) { + return rv; + } + + FloatConfig *config = &wp->w_float_config; + + PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable)); + PUT(rv, "external", BOOLEAN_OBJ(config->external)); + + if (wp->w_floating) { + PUT(rv, "width", INTEGER_OBJ(config->width)); + PUT(rv, "height", INTEGER_OBJ(config->height)); + if (!config->external) { + if (config->relative == kFloatRelativeWindow) { + PUT(rv, "win", INTEGER_OBJ(config->window)); + if (config->bufpos.lnum >= 0) { + Array pos = ARRAY_DICT_INIT; + ADD(pos, INTEGER_OBJ(config->bufpos.lnum)); + ADD(pos, INTEGER_OBJ(config->bufpos.col)); + PUT(rv, "bufpos", ARRAY_OBJ(pos)); + } + } + PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor]))); + PUT(rv, "row", FLOAT_OBJ(config->row)); + PUT(rv, "col", FLOAT_OBJ(config->col)); + PUT(rv, "zindex", INTEGER_OBJ(config->zindex)); + } + if (config->border) { + Array border = ARRAY_DICT_INIT; + for (size_t i = 0; i < 8; i++) { + Array tuple = ARRAY_DICT_INIT; + + String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); + + int hi_id = config->border_hl_ids[i]; + char_u *hi_name = syn_id2name(hi_id); + if (hi_name[0]) { + ADD(tuple, STRING_OBJ(s)); + ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); + ADD(border, ARRAY_OBJ(tuple)); + } else { + ADD(border, STRING_OBJ(s)); + } + } + PUT(rv, "border", ARRAY_OBJ(border)); + } + } + + const char *rel = (wp->w_floating && !config->external + ? float_relative_str[config->relative] : ""); + PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel))); + + return rv; +} + +static bool parse_float_anchor(String anchor, FloatAnchor *out) +{ + if (anchor.size == 0) { + *out = (FloatAnchor)0; + } + char *str = anchor.data; + if (striequal(str, "NW")) { + *out = 0; // NW is the default + } else if (striequal(str, "NE")) { + *out = kFloatAnchorEast; + } else if (striequal(str, "SW")) { + *out = kFloatAnchorSouth; + } else if (striequal(str, "SE")) { + *out = kFloatAnchorSouth | kFloatAnchorEast; + } else { + return false; + } + return true; +} + +static bool parse_float_relative(String relative, FloatRelative *out) +{ + char *str = relative.data; + if (striequal(str, "editor")) { + *out = kFloatRelativeEditor; + } else if (striequal(str, "win")) { + *out = kFloatRelativeWindow; + } else if (striequal(str, "cursor")) { + *out = kFloatRelativeCursor; + } else { + return false; + } + return true; +} + +static bool parse_float_bufpos(Array bufpos, lpos_T *out) +{ + if (bufpos.size != 2 + || bufpos.items[0].type != kObjectTypeInteger + || bufpos.items[1].type != kObjectTypeInteger) { + return false; + } + out->lnum = bufpos.items[0].data.integer; + out->col = (colnr_T)bufpos.items[1].data.integer; + return true; +} + +static void parse_border_style(Object style, FloatConfig *fconfig, Error *err) +{ + struct { + const char *name; + schar_T chars[8]; + bool shadow_color; + } defaults[] = { + { "double", { "╔", "═", "╗", "║", "╝", "═", "╚", "║" }, false }, + { "single", { "┌", "─", "┐", "│", "┘", "─", "└", "│" }, false }, + { "shadow", { "", "", " ", " ", " ", " ", " ", "" }, true }, + { "rounded", { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, false }, + { "solid", { " ", " ", " ", " ", " ", " ", " ", " " }, false }, + { NULL, { { NUL } }, false }, + }; + + schar_T *chars = fconfig->border_chars; + int *hl_ids = fconfig->border_hl_ids; + + fconfig->border = true; + + if (style.type == kObjectTypeArray) { + Array arr = style.data.array; + size_t size = arr.size; + if (!size || size > 8 || (size & (size-1))) { + api_set_error(err, kErrorTypeValidation, + "invalid number of border chars"); + return; + } + for (size_t i = 0; i < size; i++) { + Object iytem = arr.items[i]; + String string; + int hl_id = 0; + if (iytem.type == kObjectTypeArray) { + Array iarr = iytem.data.array; + if (!iarr.size || iarr.size > 2) { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + if (iarr.items[0].type != kObjectTypeString) { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + string = iarr.items[0].data.string; + if (iarr.size == 2) { + hl_id = object_to_hl_id(iarr.items[1], "border char highlight", err); + if (ERROR_SET(err)) { + return; + } + } + } else if (iytem.type == kObjectTypeString) { + string = iytem.data.string; + } else { + api_set_error(err, kErrorTypeValidation, "invalid border char"); + return; + } + if (string.size + && mb_string2cells_len((char_u *)string.data, string.size) > 1) { + api_set_error(err, kErrorTypeValidation, + "border chars must be one cell"); + return; + } + size_t len = MIN(string.size, sizeof(*chars)-1); + if (len) { + memcpy(chars[i], string.data, len); + } + chars[i][len] = NUL; + hl_ids[i] = hl_id; + } + while (size < 8) { + memcpy(chars+size, chars, sizeof(*chars) * size); + memcpy(hl_ids+size, hl_ids, sizeof(*hl_ids) * size); + size <<= 1; + } + if ((chars[7][0] && chars[1][0] && !chars[0][0]) + || (chars[1][0] && chars[3][0] && !chars[2][0]) + || (chars[3][0] && chars[5][0] && !chars[4][0]) + || (chars[5][0] && chars[7][0] && !chars[6][0])) { + api_set_error(err, kErrorTypeValidation, + "corner between used edges must be specified"); + } + } else if (style.type == kObjectTypeString) { + String str = style.data.string; + if (str.size == 0 || strequal(str.data, "none")) { + fconfig->border = false; + return; + } + for (size_t i = 0; defaults[i].name; i++) { + if (strequal(str.data, defaults[i].name)) { + memcpy(chars, defaults[i].chars, sizeof(defaults[i].chars)); + memset(hl_ids, 0, 8 * sizeof(*hl_ids)); + if (defaults[i].shadow_color) { + int hl_blend = SYN_GROUP_STATIC("FloatShadow"); + int hl_through = SYN_GROUP_STATIC("FloatShadowThrough"); + hl_ids[2] = hl_through; + hl_ids[3] = hl_blend; + hl_ids[4] = hl_blend; + hl_ids[5] = hl_blend; + hl_ids[6] = hl_through; + } + return; + } + } + api_set_error(err, kErrorTypeValidation, + "invalid border style \"%s\"", str.data); + } +} + +static bool parse_float_config(Dict(float_config) *config, FloatConfig *fconfig, bool reconf, + bool new_win, Error *err) +{ + bool has_relative = false, relative_is_win = false; + if (config->relative.type == kObjectTypeString) { + // ignore empty string, to match nvim_win_get_config + if (config->relative.data.string.size > 0) { + if (!parse_float_relative(config->relative.data.string, &fconfig->relative)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'relative' key"); + return false; + } + + if (!(HAS_KEY(config->row) && HAS_KEY(config->col)) && !HAS_KEY(config->bufpos)) { + api_set_error(err, kErrorTypeValidation, + "'relative' requires 'row'/'col' or 'bufpos'"); + return false; + } + + has_relative = true; + fconfig->external = false; + if (fconfig->relative == kFloatRelativeWindow) { + relative_is_win = true; + fconfig->bufpos.lnum = -1; + } + } + } else if (HAS_KEY(config->relative)) { + api_set_error(err, kErrorTypeValidation, "'relative' key must be String"); + return false; + } + + if (config->anchor.type == kObjectTypeString) { + if (!parse_float_anchor(config->anchor.data.string, &fconfig->anchor)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'anchor' key"); + return false; + } + } else if (HAS_KEY(config->anchor)) { + api_set_error(err, kErrorTypeValidation, "'anchor' key must be String"); + return false; + } + + if (HAS_KEY(config->row)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'row'"); + return false; + } else if (config->row.type == kObjectTypeInteger) { + fconfig->row = (double)config->row.data.integer; + } else if (config->row.type == kObjectTypeFloat) { + fconfig->row = config->row.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'row' key must be Integer or Float"); + return false; + } + } + + if (HAS_KEY(config->col)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'col'"); + return false; + } else if (config->col.type == kObjectTypeInteger) { + fconfig->col = (double)config->col.data.integer; + } else if (config->col.type == kObjectTypeFloat) { + fconfig->col = config->col.data.floating; + } else { + api_set_error(err, kErrorTypeValidation, + "'col' key must be Integer or Float"); + return false; + } + } + + if (HAS_KEY(config->bufpos)) { + if (!has_relative) { + api_set_error(err, kErrorTypeValidation, "non-float cannot have 'bufpos'"); + return false; + } else if (config->bufpos.type == kObjectTypeArray) { + if (!parse_float_bufpos(config->bufpos.data.array, &fconfig->bufpos)) { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'bufpos' key"); + return false; + } + + if (!HAS_KEY(config->row)) { + fconfig->row = (fconfig->anchor & kFloatAnchorSouth) ? 0 : 1; + } + if (!HAS_KEY(config->col)) { + fconfig->col = 0; + } + } else { + api_set_error(err, kErrorTypeValidation, "'bufpos' key must be Array"); + return false; + } + } + + if (config->width.type == kObjectTypeInteger && config->width.data.integer > 0) { + fconfig->width = (int)config->width.data.integer; + } else if (HAS_KEY(config->width)) { + api_set_error(err, kErrorTypeValidation, "'width' key must be a positive Integer"); + return false; + } else if (!reconf) { + api_set_error(err, kErrorTypeValidation, "Must specify 'width'"); + return false; + } + + if (config->height.type == kObjectTypeInteger && config->height.data.integer > 0) { + fconfig->height = (int)config->height.data.integer; + } else if (HAS_KEY(config->height)) { + api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer"); + return false; + } else if (!reconf) { + api_set_error(err, kErrorTypeValidation, "Must specify 'height'"); + return false; + } + + if (relative_is_win) { + fconfig->window = curwin->handle; + if (config->win.type == kObjectTypeInteger || config->win.type == kObjectTypeWindow) { + if (config->win.data.integer > 0) { + fconfig->window = (Window)config->win.data.integer; + } + } else if (HAS_KEY(config->win)) { + api_set_error(err, kErrorTypeValidation, "'win' key must be Integer or Window"); + return false; + } + } else { + if (HAS_KEY(config->win)) { + api_set_error(err, kErrorTypeValidation, "'win' key is only valid with relative='win'"); + return false; + } + } + + if (HAS_KEY(config->external)) { + fconfig->external = api_object_to_bool(config->external, "'external' key", false, err); + if (ERROR_SET(err)) { + return false; + } + if (has_relative && fconfig->external) { + api_set_error(err, kErrorTypeValidation, + "Only one of 'relative' and 'external' must be used"); + return false; + } + if (fconfig->external && !ui_has(kUIMultigrid)) { + api_set_error(err, kErrorTypeValidation, + "UI doesn't support external windows"); + return false; + } + } + + if (!reconf && (!has_relative && !fconfig->external)) { + api_set_error(err, kErrorTypeValidation, + "One of 'relative' and 'external' must be used"); + return false; + } + + + if (HAS_KEY(config->focusable)) { + fconfig->focusable = api_object_to_bool(config->focusable, "'focusable' key", false, err); + if (ERROR_SET(err)) { + return false; + } + } + + if (config->zindex.type == kObjectTypeInteger && config->zindex.data.integer > 0) { + fconfig->zindex = (int)config->zindex.data.integer; + } else if (HAS_KEY(config->zindex)) { + api_set_error(err, kErrorTypeValidation, "'zindex' key must be a positive Integer"); + return false; + } + + if (HAS_KEY(config->border)) { + parse_border_style(config->border, fconfig, err); + if (ERROR_SET(err)) { + return false; + } + } + + if (config->style.type == kObjectTypeString) { + if (config->style.data.string.data[0] == NUL) { + fconfig->style = kWinStyleUnused; + } else if (striequal(config->style.data.string.data, "minimal")) { + fconfig->style = kWinStyleMinimal; + } else { + api_set_error(err, kErrorTypeValidation, "Invalid value of 'style' key"); + } + } else if (HAS_KEY(config->style)) { + api_set_error(err, kErrorTypeValidation, "'style' key must be String"); + return false; + } + + if (HAS_KEY(config->noautocmd)) { + if (!new_win) { + api_set_error(err, kErrorTypeValidation, "Invalid key: 'noautocmd'"); + return false; + } + fconfig->noautocmd = api_object_to_bool(config->noautocmd, "'noautocmd' key", false, err); + if (ERROR_SET(err)) { + return false; + } + } + + return true; +} diff --git a/src/nvim/api/win_config.h b/src/nvim/api/win_config.h new file mode 100644 index 0000000000..9271c35f23 --- /dev/null +++ b/src/nvim/api/win_config.h @@ -0,0 +1,11 @@ +#ifndef NVIM_API_WIN_CONFIG_H +#define NVIM_API_WIN_CONFIG_H + +#include <stdint.h> + +#include "nvim/api/private/defs.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "api/win_config.h.generated.h" +#endif +#endif // NVIM_API_WIN_CONFIG_H diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 95eae1af2d..6e68c057dc 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -373,117 +373,6 @@ Boolean nvim_win_is_valid(Window window) } -/// Configures window layout. Currently only for floating and external windows -/// (including changing a split window to those layouts). -/// -/// When reconfiguring a floating window, absent option keys will not be -/// changed. `row`/`col` and `relative` must be reconfigured together. -/// -/// @see |nvim_open_win()| -/// -/// @param window Window handle, or 0 for current window -/// @param config Map defining the window configuration, -/// see |nvim_open_win()| -/// @param[out] err Error details, if any -void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err) - FUNC_API_SINCE(6) -{ - win_T *win = find_window_by_handle(window, err); - if (!win) { - return; - } - bool new_float = !win->w_floating; - // reuse old values, if not overridden - FloatConfig fconfig = new_float ? FLOAT_CONFIG_INIT : win->w_float_config; - - if (!parse_float_config(config, &fconfig, !new_float, false, err)) { - return; - } - if (new_float) { - if (!win_new_float(win, fconfig, err)) { - return; - } - redraw_later(win, NOT_VALID); - } else { - win_config_float(win, fconfig); - win->w_pos_changed = true; - } - if (fconfig.style == kWinStyleMinimal) { - win_set_minimal_style(win); - didset_window_options(win); - } -} - -/// Gets window configuration. -/// -/// The returned value may be given to |nvim_open_win()|. -/// -/// `relative` is empty for normal windows. -/// -/// @param window Window handle, or 0 for current window -/// @param[out] err Error details, if any -/// @return Map defining the window configuration, see |nvim_open_win()| -Dictionary nvim_win_get_config(Window window, Error *err) - FUNC_API_SINCE(6) -{ - Dictionary rv = ARRAY_DICT_INIT; - - win_T *wp = find_window_by_handle(window, err); - if (!wp) { - return rv; - } - - FloatConfig *config = &wp->w_float_config; - - PUT(rv, "focusable", BOOLEAN_OBJ(config->focusable)); - PUT(rv, "external", BOOLEAN_OBJ(config->external)); - - if (wp->w_floating) { - PUT(rv, "width", INTEGER_OBJ(config->width)); - PUT(rv, "height", INTEGER_OBJ(config->height)); - if (!config->external) { - if (config->relative == kFloatRelativeWindow) { - PUT(rv, "win", INTEGER_OBJ(config->window)); - if (config->bufpos.lnum >= 0) { - Array pos = ARRAY_DICT_INIT; - ADD(pos, INTEGER_OBJ(config->bufpos.lnum)); - ADD(pos, INTEGER_OBJ(config->bufpos.col)); - PUT(rv, "bufpos", ARRAY_OBJ(pos)); - } - } - PUT(rv, "anchor", STRING_OBJ(cstr_to_string(float_anchor_str[config->anchor]))); - PUT(rv, "row", FLOAT_OBJ(config->row)); - PUT(rv, "col", FLOAT_OBJ(config->col)); - PUT(rv, "zindex", INTEGER_OBJ(config->zindex)); - } - if (config->border) { - Array border = ARRAY_DICT_INIT; - for (size_t i = 0; i < 8; i++) { - Array tuple = ARRAY_DICT_INIT; - - String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T)); - - int hi_id = config->border_hl_ids[i]; - char_u *hi_name = syn_id2name(hi_id); - if (hi_name[0]) { - ADD(tuple, STRING_OBJ(s)); - ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name))); - ADD(border, ARRAY_OBJ(tuple)); - } else { - ADD(border, STRING_OBJ(s)); - } - } - PUT(rv, "border", ARRAY_OBJ(border)); - } - } - - const char *rel = (wp->w_floating && !config->external - ? float_relative_str[config->relative] : ""); - PUT(rv, "relative", STRING_OBJ(cstr_to_string(rel))); - - return rv; -} - /// Closes the window and hide the buffer it contains (like |:hide| with a /// |window-ID|). /// diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 20dd94622f..6d91632dcd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2553,8 +2553,6 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T if (wip->wi_next) { wip->wi_next->wi_prev = wip; } - - return; } diff --git a/src/nvim/change.c b/src/nvim/change.c index 4ac5edeaa9..2450c56838 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -413,7 +413,11 @@ void deleted_lines(linenr_T lnum, long count) /// be triggered to display the cursor. void deleted_lines_mark(linenr_T lnum, long count) { - mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count, + // if we deleted the entire buffer, we need to implicity add a new empty line + bool made_empty = (count > 0) && curbuf->b_ml.ml_flags & ML_EMPTY; + + mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, + -count + (made_empty?1:0), kExtmarkUndo); changed_lines(lnum, 0, lnum + count, -count, true); } @@ -625,7 +629,7 @@ void ins_char_bytes(char_u *buf, size_t charlen) // Copy bytes before the cursor. if (col > 0) { - memmove(newp, oldp, (size_t)col); + memmove(newp, oldp, col); } // Copy bytes after the changed character(s). diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 30243a3102..db0a2ff64c 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -87,7 +87,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error) break; case kChannelStreamProc: - proc = (Process *)&chan->stream.proc; + proc = &chan->stream.proc; if (part == kChannelPartStdin || close_main) { stream_may_close(&proc->in); } @@ -335,7 +335,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader chan->stream.uv = libuv_process_init(&main_loop, chan); } - Process *proc = (Process *)&chan->stream.proc; + Process *proc = &chan->stream.proc; proc->argv = argv; proc->cb = channel_process_exit_cb; proc->events = chan->events; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index f899ebf57c..d2f95ad81c 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -412,7 +412,7 @@ char *transstr(const char *const s, bool untab) { // Compute the length of the result, taking account of unprintable // multi-byte characters. - const size_t len = transstr_len((const char *)s, untab) + 1; + const size_t len = transstr_len(s, untab) + 1; char *const buf = xmalloc(len); transstr_buf(s, buf, len, untab); return buf; diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 5c43b2498e..3a7bd21c70 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1110,7 +1110,7 @@ static int diff_file(diffio_T *dio) // Build the diff command and execute it. Always use -a, binary // differences are of no use. Ignore errors, diff returns // non-zero when differences have been found. - vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s", + vim_snprintf(cmd, len, "diff %s%s%s%s%s%s%s%s %s", diff_a_works == kFalse ? "" : "-a ", "", (diff_flags & DIFF_IWHITE) ? "-b " : "", diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 768b82b464..a281c09042 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -514,8 +514,8 @@ int var_redir_start(char_u *name, int append) ga_init(&redir_ga, (int)sizeof(char), 500); // Parse the variable name (can be a dict or list entry). - redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, false, false, - 0, FNE_CHECK_START); + redir_endp = get_lval(redir_varname, NULL, redir_lval, false, false, + 0, FNE_CHECK_START); if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) { clear_lval(redir_lval); @@ -597,8 +597,8 @@ void var_redir_stop(void) tv.vval.v_string = redir_ga.ga_data; // Call get_lval() again, if it's inside a Dict or List it may // have changed. - redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, - false, false, 0, FNE_CHECK_START); + redir_endp = get_lval(redir_varname, NULL, redir_lval, + false, false, 0, FNE_CHECK_START); if (redir_endp != NULL && redir_lval->ll_name != NULL) { set_var_lval(redir_lval, redir_endp, &tv, false, false, "."); } @@ -1711,7 +1711,7 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) if (tofree != NULL) { name = tofree; } - if (get_var_tv((const char *)name, len, &tv, NULL, true, false) + if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) { error = true; } else { @@ -2023,7 +2023,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, lval_T *const lp, co } lp->ll_exp_name = (char *)make_expanded_name(name, expr_start, expr_end, - (char_u *)p); + p); lp->ll_name = lp->ll_exp_name; if (lp->ll_exp_name == NULL) { /* Report an invalid expression in braces, unless the @@ -2419,7 +2419,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, co // handle +=, -=, *=, /=, %= and .= di = NULL; - if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name), + if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, lp->ll_name, TV_CSTRING) @@ -3004,12 +3004,12 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit) hashitem_T *hi = hash_find(ht, (const char_u *)varname); if (HASHITEM_EMPTY(hi)) { - hi = find_hi_in_scoped_ht((const char *)name, &ht); + hi = find_hi_in_scoped_ht(name, &ht); } if (hi != NULL && !HASHITEM_EMPTY(hi)) { dictitem_T *const di = TV_DICT_HI2DI(hi); - if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING) - || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING) + if (var_check_fixed(di->di_flags, name, TV_CSTRING) + || var_check_ro(di->di_flags, name, TV_CSTRING) || var_check_lock(d->dv_lock, name, TV_CSTRING)) { return FAIL; } @@ -3069,7 +3069,7 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, exarg_T *e ret = FAIL; } else { // Normal name or expanded name. - dictitem_T *const di = find_var((const char *)lp->ll_name, lp->ll_name_len, NULL, + dictitem_T *const di = find_var(lp->ll_name, lp->ll_name_len, NULL, true); if (di == NULL) { ret = FAIL; @@ -4348,7 +4348,7 @@ static int call_func_rettv(char_u **const arg, typval_T *const rettv, const bool funcexe.selfdict = selfdict; funcexe.basetv = basetv; const int ret = get_func_tv(funcname, is_lua ? *arg - funcname : -1, rettv, - (char_u **)arg, &funcexe); + arg, &funcexe); // Clear the funcref afterwards, so that deleting it while // evaluating the arguments is possible (see test55). @@ -9444,7 +9444,7 @@ static void set_var_const(const char *name, const size_t name_len, typval_T *con // Search in parent scope which is possible to reference from lambda if (v == NULL) { - v = find_var_in_scoped_ht((const char *)name, name_len, true); + v = find_var_in_scoped_ht(name, name_len, true); } if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) { @@ -9654,7 +9654,7 @@ bool var_check_func_name(const char *const name, const bool new_var) // Don't allow hiding a function. When "v" is not NULL we might be // assigning another function to the same var, the type is checked // below. - if (new_var && function_exists((const char *)name, false)) { + if (new_var && function_exists(name, false)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), name); return false; @@ -11325,7 +11325,7 @@ bool var_exists(const char *var) // get_name_len() takes care of expanding curly braces const char *name = var; - const int len = get_name_len((const char **)&var, &tofree, true, false); + const int len = get_name_len(&var, &tofree, true, false); if (len > 0) { typval_T tv; diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h index 77fc4c78c2..f1be5a1f69 100644 --- a/src/nvim/eval/decode.h +++ b/src/nvim/eval/decode.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVAL_DECODE_H #define NVIM_EVAL_DECODE_H -#include <stddef.h> - #include <msgpack.h> +#include <stddef.h> #include "nvim/eval/typval.h" #include "nvim/globals.h" diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 1c0afc89f5..5ef0045659 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -268,9 +268,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s || TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL); for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) { assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL); - const char ch = (char)( - TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]); - *p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch); + const char ch = (char)(TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]); + *p++ = (char)(ch == (char)NL ? (char)NUL : ch); } if (p < buf_end) { state->li = TV_LIST_ITEM_NEXT(state->list, state->li); diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h index 596bb49ae0..8755ff48ac 100644 --- a/src/nvim/eval/encode.h +++ b/src/nvim/eval/encode.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVAL_ENCODE_H #define NVIM_EVAL_ENCODE_H -#include <stddef.h> - #include <msgpack.h> +#include <stddef.h> #include "nvim/eval.h" #include "nvim/garray.h" @@ -49,8 +48,7 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list) .offset = 0, .li_length = (TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string == NULL ? 0 - : STRLEN(TV_LIST_ITEM_TV( - tv_list_first(list))->vval.v_string)), + : STRLEN(TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string)), }; } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b53b50e766..709ef8e5b6 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3747,7 +3747,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (cur->conceal_char) { char buf[MB_MAXBYTES + 1]; - buf[utf_char2bytes((int)cur->conceal_char, (char_u *)buf)] = NUL; + buf[utf_char2bytes(cur->conceal_char, (char_u *)buf)] = NUL; tv_dict_add_str(dict, S_LEN("conceal"), buf); } @@ -5155,7 +5155,7 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_trailing)); } else { if (lv.ll_tv == NULL) { - di = find_var((const char *)lv.ll_name, lv.ll_name_len, NULL, true); + di = find_var(lv.ll_name, lv.ll_name_len, NULL, true); if (di != NULL) { // Consider a variable locked when: // 1. the variable itself is locked @@ -5236,7 +5236,7 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - Process *proc = (Process *)&data->stream.proc; + Process *proc = &data->stream.proc; rettv->vval.v_number = proc->pid; } @@ -5534,7 +5534,7 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) // Ignore return code, but show error later. (void)channel_close(data->id, kChannelPartRpc, &error); } - process_stop((Process *)&data->stream.proc); + process_stop(&data->stream.proc); rettv->vval.v_number = 1; if (error) { EMSG(error); @@ -5990,7 +5990,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr) FUNC_ATTR_NONNULL_ALL { - const char *const str = (const char *)tv_get_string_chk(&argvars[0]); + const char *const str = tv_get_string_chk(&argvars[0]); if (str == NULL) { return; } @@ -6141,7 +6141,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, } } - match = vim_regexec_nl(®match, str, (colnr_T)startcol); + match = vim_regexec_nl(®match, str, startcol); if (match && --nth <= 0) { break; @@ -6352,7 +6352,7 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr) : 0)); if (id >= 1 && id <= 3) { - matchitem_T *const m = (matchitem_T *)get_match(curwin, id); + matchitem_T *const m = get_match(curwin, id); if (m != NULL) { tv_list_append_string(rettv->vval.v_list, @@ -6999,7 +6999,7 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { tv_list_alloc_ret(rettv, (end - start) / stride); for (i = start; stride > 0 ? i <= end : i >= end; i += stride) { - tv_list_append_number(rettv->vval.v_list, (varnumber_T)i); + tv_list_append_number(rettv->vval.v_list, i); } } } @@ -7302,7 +7302,7 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (list == NULL) { return; } - tv_dict_add_list(dict, S_LEN("regcontents"), list); + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); char buf[NUMBUFLEN + 2]; buf[0] = NUL; @@ -7321,14 +7321,15 @@ static void f_getreginfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) case kMTUnknown: abort(); } - tv_dict_add_str(dict, S_LEN("regtype"), buf); + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); buf[0] = get_register_name(get_unname_register()); buf[1] = NUL; if (regname == '"') { - tv_dict_add_str(dict, S_LEN("points_to"), buf); + (void)tv_dict_add_str(dict, S_LEN("points_to"), buf); } else { - tv_dict_add_bool(dict, S_LEN("isunnamed"), regname == buf[0] ? kBoolVarTrue : kBoolVarFalse); + (void)tv_dict_add_bool(dict, S_LEN("isunnamed"), + regname == buf[0] ? kBoolVarTrue : kBoolVarFalse); } } @@ -11364,7 +11365,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && *new_cwd != NUL) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir_executable((const char *)cwd)) { + if (!os_isdir_executable(cwd)) { EMSG2(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 075b50a366..cfc95ba167 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2861,7 +2861,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, const boo char buf2[NUMBUFLEN]; const char *s1 = tv_get_string_buf(tv1, buf1); const char *s2 = tv_get_string_buf(tv2, buf2); - return mb_strcmp_ic((bool)ic, s1, s2) == 0; + return mb_strcmp_ic(ic, s1, s2) == 0; } case VAR_BOOL: return tv1->vval.v_bool == tv2->vval.v_bool; @@ -3260,7 +3260,7 @@ const char *tv_get_string(const typval_T *const tv) const char *tv_get_string_buf(const typval_T *const tv, char *const buf) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { - const char *const res = (const char *)tv_get_string_buf_chk(tv, buf); + const char *const res = tv_get_string_buf_chk(tv, buf); return res != NULL ? res : ""; } diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 5aecaccee9..a28feffd0b 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -1,23 +1,23 @@ #ifndef NVIM_EVAL_TYPVAL_H #define NVIM_EVAL_TYPVAL_H +#include <assert.h> #include <inttypes.h> +#include <stdbool.h> #include <stddef.h> #include <string.h> -#include <stdbool.h> -#include <assert.h> -#include "nvim/types.h" -#include "nvim/hashtab.h" -#include "nvim/garray.h" -#include "nvim/mbyte.h" #include "nvim/func_attr.h" -#include "nvim/lib/queue.h" -#include "nvim/profile.h" // for proftime_T -#include "nvim/pos.h" // for linenr_T +#include "nvim/garray.h" #include "nvim/gettext.h" -#include "nvim/message.h" +#include "nvim/hashtab.h" +#include "nvim/lib/queue.h" #include "nvim/macros.h" +#include "nvim/mbyte.h" +#include "nvim/message.h" +#include "nvim/pos.h" // for linenr_T +#include "nvim/profile.h" // for proftime_T +#include "nvim/types.h" #ifdef LOG_LIST_ACTIONS # include "nvim/memory.h" #endif @@ -156,8 +156,8 @@ typedef enum { typedef struct listitem_S listitem_T; struct listitem_S { - listitem_T *li_next; ///< Next item in list. - listitem_T *li_prev; ///< Previous item in list. + listitem_T *li_next; ///< Next item in list. + listitem_T *li_prev; ///< Previous item in list. typval_T li_tv; ///< Item value. }; @@ -195,25 +195,25 @@ typedef struct { } staticList10_T; #define TV_LIST_STATIC10_INIT { \ - .sl_list = { \ - .lv_first = NULL, \ - .lv_last = NULL, \ - .lv_refcount = 0, \ - .lv_len = 0, \ - .lv_watch = NULL, \ - .lv_idx_item = NULL, \ - .lv_lock = VAR_FIXED, \ - .lv_used_next = NULL, \ - .lv_used_prev = NULL, \ - }, \ - } + .sl_list = { \ + .lv_first = NULL, \ + .lv_last = NULL, \ + .lv_refcount = 0, \ + .lv_len = 0, \ + .lv_watch = NULL, \ + .lv_idx_item = NULL, \ + .lv_lock = VAR_FIXED, \ + .lv_used_next = NULL, \ + .lv_used_prev = NULL, \ + }, \ +} #define TV_DICTITEM_STRUCT(...) \ - struct { \ - typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ - uint8_t di_flags; /* Flags. */ \ - char_u di_key[__VA_ARGS__]; /* Key value. */ \ - } + struct { \ + typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ + uint8_t di_flags; /* Flags. */ \ + char_u di_key[__VA_ARGS__]; /* Key value. */ \ + } /// Structure to hold a scope dictionary /// @@ -321,40 +321,40 @@ struct funccall_S { /// Structure to hold info for a user function. struct ufunc { - int uf_varargs; ///< variable nr of arguments - int uf_flags; - int uf_calls; ///< nr of active calls - bool uf_cleared; ///< func_clear() was already called - garray_T uf_args; ///< arguments - garray_T uf_def_args; ///< default argument expressions - garray_T uf_lines; ///< function lines - int uf_profiling; ///< true when func is being profiled - int uf_prof_initialized; + int uf_varargs; ///< variable nr of arguments + int uf_flags; + int uf_calls; ///< nr of active calls + bool uf_cleared; ///< func_clear() was already called + garray_T uf_args; ///< arguments + garray_T uf_def_args; ///< default argument expressions + garray_T uf_lines; ///< function lines + int uf_profiling; ///< true when func is being profiled + int uf_prof_initialized; // Managing cfuncs - cfunc_T uf_cb; ///< C function extension callback + cfunc_T uf_cb; ///< C function extension callback cfunc_free_T uf_cb_free; ///< C function extension free callback - void *uf_cb_state; ///< State of C function extension. + void *uf_cb_state; ///< State of C function extension. // Profiling the function as a whole. - int uf_tm_count; ///< nr of calls - proftime_T uf_tm_total; ///< time spent in function + children - proftime_T uf_tm_self; ///< time spent in function itself - proftime_T uf_tm_children; ///< time spent in children this call + int uf_tm_count; ///< nr of calls + proftime_T uf_tm_total; ///< time spent in function + children + proftime_T uf_tm_self; ///< time spent in function itself + proftime_T uf_tm_children; ///< time spent in children this call // Profiling the function per line. - int *uf_tml_count; ///< nr of times line was executed - proftime_T *uf_tml_total; ///< time spent in a line + children - proftime_T *uf_tml_self; ///< time spent in a line itself - proftime_T uf_tml_start; ///< start time for current line - proftime_T uf_tml_children; ///< time spent in children for this line - proftime_T uf_tml_wait; ///< start wait time for current line - int uf_tml_idx; ///< index of line being timed; -1 if none - int uf_tml_execed; ///< line being timed was executed - sctx_T uf_script_ctx; ///< SCTX where function was defined, - ///< used for s: variables - int uf_refcount; ///< reference count, see func_name_refcount() - funccall_T *uf_scoped; ///< l: local variables for closure - char_u uf_name[]; ///< Name of function (actual size equals name); - ///< can start with <SNR>123_ - ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) + int *uf_tml_count; ///< nr of times line was executed + proftime_T *uf_tml_total; ///< time spent in a line + children + proftime_T *uf_tml_self; ///< time spent in a line itself + proftime_T uf_tml_start; ///< start time for current line + proftime_T uf_tml_children; ///< time spent in children for this line + proftime_T uf_tml_wait; ///< start wait time for current line + int uf_tml_idx; ///< index of line being timed; -1 if none + int uf_tml_execed; ///< line being timed was executed + sctx_T uf_script_ctx; ///< SCTX where function was defined, + ///< used for s: variables + int uf_refcount; ///< reference count, see func_name_refcount() + funccall_T *uf_scoped; ///< l: local variables for closure + char_u uf_name[]; ///< Name of function (actual size equals name); + ///< can start with <SNR>123_ + ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) }; struct partial_S { @@ -452,10 +452,8 @@ static inline void list_log(const list_T *const l, /// @param[in] li1 List item 1. /// @param[in] li2 List item 2, often used for integers and not list items. /// @param[in] action Logged action. -static inline void list_log(const list_T *const l, - const listitem_T *const li1, - const listitem_T *const li2, - const char *const action) +static inline void list_log(const list_T *const l, const listitem_T *const li1, + const listitem_T *const li2, const char *const action) { ListLog *tgt; if (list_log_first == NULL) { @@ -484,7 +482,7 @@ static inline void list_log(const list_T *const l, /// Convert a hashitem pointer to a dictitem pointer #define TV_DICT_HI2DI(hi) \ - ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) + ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key))) static inline void tv_list_ref(list_T *const l) REAL_FATTR_ALWAYS_INLINE; @@ -538,8 +536,7 @@ static inline VarLockStatus tv_list_locked(const list_T *const l) /// /// @param[out] l List to modify. /// @param[in] lock New lock status. -static inline void tv_list_set_lock(list_T *const l, - const VarLockStatus lock) +static inline void tv_list_set_lock(list_T *const l, const VarLockStatus lock) { if (l == NULL) { assert(lock == VAR_FIXED); @@ -554,8 +551,7 @@ static inline void tv_list_set_lock(list_T *const l, /// /// @param[out] l List to modify. /// @param[in] copyid New copyID. -static inline void tv_list_set_copyid(list_T *const l, - const int copyid) +static inline void tv_list_set_copyid(list_T *const l, const int copyid) FUNC_ATTR_NONNULL_ALL { l->lv_copyID = copyid; @@ -793,10 +789,10 @@ static inline void tv_init(typval_T *const tv) } #define TV_INITIAL_VALUE \ - ((typval_T) { \ - .v_type = VAR_UNKNOWN, \ - .v_lock = VAR_UNLOCKED, \ - }) + ((typval_T) { \ + .v_type = VAR_UNKNOWN, \ + .v_lock = VAR_UNLOCKED, \ + }) /// Empty string /// @@ -815,16 +811,16 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define _TV_LIST_ITER_MOD(modifier, l, li, code) \ - do { \ - modifier list_T *const l_ = (l); \ - list_log(l_, NULL, NULL, "iter" #modifier); \ - if (l_ != NULL) { \ - for (modifier listitem_T *li = l_->lv_first; \ - li != NULL; li = li->li_next) { \ - code \ - } \ + do { \ + modifier list_T *const l_ = (l); \ + list_log(l_, NULL, NULL, "iter" #modifier); \ + if (l_ != NULL) { \ + for (modifier listitem_T *li = l_->lv_first; \ + li != NULL; li = li->li_next) { \ + code \ } \ - } while (0) + } \ + } while (0) /// Iterate over a list /// @@ -835,7 +831,7 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define TV_LIST_ITER(l, li, code) \ - _TV_LIST_ITER_MOD(, l, li, code) + _TV_LIST_ITER_MOD(, l, li, code) /// Iterate over a list /// @@ -846,7 +842,7 @@ extern bool tv_in_free_unref_items; /// @param li Name of the variable with current listitem_T entry. /// @param code Cycle body. #define TV_LIST_ITER_CONST(l, li, code) \ - _TV_LIST_ITER_MOD(const, l, li, code) + _TV_LIST_ITER_MOD(const, l, li, code) // Below macros are macros to avoid duplicating code for functionally identical // const and non-const function variants. @@ -883,14 +879,14 @@ extern bool tv_in_free_unref_items; /// @param di Name of the variable with current dictitem_T entry. /// @param code Cycle body. #define TV_DICT_ITER(d, di, code) \ - HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \ + HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \ + { \ + dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \ { \ - dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \ - { \ - code \ - } \ + code \ } \ - }) + } \ + }) static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) @@ -907,8 +903,7 @@ bool emsgf(const char *const fmt, ...); /// @param[out] ret_f Location where resulting float is stored. /// /// @return true in case of success, false if tv is not a number or float. -static inline bool tv_get_float_chk(const typval_T *const tv, - float_T *const ret_f) +static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) { if (tv->v_type == VAR_FLOAT) { *ret_f = tv->vval.v_float; diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index cd1be1eecc..ece51cb046 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -240,15 +240,15 @@ /// /// This name will only be used by one of the above macros which are defined by /// the caller. Functions defined here do not use first argument directly. -#include <stddef.h> -#include <inttypes.h> #include <assert.h> +#include <inttypes.h> +#include <stddef.h> -#include "nvim/lib/kvec.h" -#include "nvim/eval/typval.h" #include "nvim/eval/encode.h" -#include "nvim/func_attr.h" +#include "nvim/eval/typval.h" #include "nvim/eval/typval_encode.h" +#include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" /// Dummy variable used because some macros need lvalue /// @@ -257,12 +257,12 @@ const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL; static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - void *const val, int *const val_copyID, - const MPConvStack *const mpstack, const int copyID, - const MPConvStackValType conv_type, - const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + void *const val, int *const val_copyID, + const MPConvStack *const mpstack, const int copyID, + const MPConvStackValType conv_type, + const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE; /// Function for checking whether container references itself @@ -280,11 +280,9 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( /// /// @return NOTDONE in case of success, what to return in case of failure. static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - void *const val, int *const val_copyID, - const MPConvStack *const mpstack, const int copyID, - const MPConvStackValType conv_type, - const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, void *const val, int *const val_copyID, + const MPConvStack *const mpstack, const int copyID, const MPConvStackValType conv_type, + const char *const objname) { if (*val_copyID == copyID) { TYPVAL_ENCODE_CONV_RECURSE(val, conv_type); @@ -295,11 +293,11 @@ static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( } static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, - typval_T *const tv, const int copyID, - const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT; + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, + typval_T *const tv, const int copyID, + const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT; /// Convert single value /// @@ -319,42 +317,35 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( /// /// @return OK in case of success, FAIL in case of failure. static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv, - typval_T *const tv, const int copyID, - const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, MPConvStack *const mpstack, + MPConvStackVal *const cur_mpsv, typval_T *const tv, const int copyID, const char *const objname) { switch (tv->v_type) { - case VAR_STRING: { - TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv)); - break; - } - case VAR_NUMBER: { - TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number); - break; - } - case VAR_FLOAT: { - TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); - break; - } - case VAR_BLOB: { - TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, - tv_blob_len(tv->vval.v_blob)); - break; - } - case VAR_FUNC: { - TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); - TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); - TYPVAL_ENCODE_CONV_FUNC_END(tv); - break; - } - case VAR_PARTIAL: { - partial_T *const pt = tv->vval.v_partial; - (void)pt; - TYPVAL_ENCODE_CONV_FUNC_START( // -V547 - tv, (pt == NULL ? NULL : partial_name(pt))); - _mp_push(*mpstack, ((MPConvStackVal) { // -V779 + case VAR_STRING: + TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv)); + break; + case VAR_NUMBER: + TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number); + break; + case VAR_FLOAT: + TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); + break; + case VAR_BLOB: + TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, + tv_blob_len(tv->vval.v_blob)); + break; + case VAR_FUNC: + TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); + TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); + TYPVAL_ENCODE_CONV_FUNC_END(tv); + break; + case VAR_PARTIAL: { + partial_T *const pt = tv->vval.v_partial; + (void)pt; + TYPVAL_ENCODE_CONV_FUNC_START( // -V547 + tv, (pt == NULL ? NULL : partial_name(pt))); + _mp_push(*mpstack, ((MPConvStackVal) { // -V779 .type = kMPConvPartial, .tv = tv, .saved_copyID = copyID - 1, @@ -365,19 +356,19 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); + break; + } + case VAR_LIST: { + if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) { + TYPVAL_ENCODE_CONV_EMPTY_LIST(tv); break; } - case VAR_LIST: { - if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) { - TYPVAL_ENCODE_CONV_EMPTY_LIST(tv); - break; - } - const int saved_copyID = tv_list_copyid(tv->vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID, - kMPConvList); - TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list)); - assert(saved_copyID != copyID); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv_list_copyid(tv->vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID, + kMPConvList); + TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list)); + assert(saved_copyID != copyID); + _mp_push(*mpstack, ((MPConvStackVal) { .type = kMPConvList, .tv = tv, .saved_copyID = saved_copyID, @@ -388,159 +379,151 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack)); + TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack)); + break; + } + case VAR_BOOL: + switch (tv->vval.v_bool) { + case kBoolVarTrue: + case kBoolVarFalse: + TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue); break; } - case VAR_BOOL: { - switch (tv->vval.v_bool) { - case kBoolVarTrue: - case kBoolVarFalse: { - TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue); - break; - } - } + break; + case VAR_SPECIAL: + switch (tv->vval.v_special) { + case kSpecialVarNull: + TYPVAL_ENCODE_CONV_NIL(tv); // -V1037 break; } - case VAR_SPECIAL: { - switch (tv->vval.v_special) { - case kSpecialVarNull: { - TYPVAL_ENCODE_CONV_NIL(tv); // -V1037 + break; + case VAR_DICT: { + if (tv->vval.v_dict == NULL + || tv->vval.v_dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); + break; + } + const dictitem_T *type_di; + const dictitem_T *val_di; + if (TYPVAL_ENCODE_ALLOW_SPECIALS + && tv->vval.v_dict->dv_hashtab.ht_used == 2 + && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict, + S_LEN("_TYPE"))) != NULL + && type_di->di_tv.v_type == VAR_LIST + && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict, + S_LEN("_VAL"))) != NULL) { + size_t i; + for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { + if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { break; } } - break; - } - case VAR_DICT: { - if (tv->vval.v_dict == NULL - || tv->vval.v_dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); - break; + if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { + goto _convert_one_value_regular_dict; } - const dictitem_T *type_di; - const dictitem_T *val_di; - if (TYPVAL_ENCODE_ALLOW_SPECIALS - && tv->vval.v_dict->dv_hashtab.ht_used == 2 - && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict, - S_LEN("_TYPE"))) != NULL - && type_di->di_tv.v_type == VAR_LIST - && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict, - S_LEN("_VAL"))) != NULL) { - size_t i; - for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { - if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { - break; - } + switch ((MessagePackType)i) { + case kMPNil: + TYPVAL_ENCODE_CONV_NIL(tv); + break; + case kMPBoolean: + if (val_di->di_tv.v_type != VAR_NUMBER) { + goto _convert_one_value_regular_dict; } - if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { + TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number); + break; + case kMPInteger: { + const list_T *val_list; + varnumber_T sign; + varnumber_T highest_bits; + varnumber_T high_bits; + varnumber_T low_bits; + // List of 4 integers; first is signed (should be 1 or -1, but + // this is not checked), second is unsigned and have at most + // one (sign is -1) or two (sign is 1) non-zero bits (number of + // bits is not checked), other unsigned and have at most 31 + // non-zero bits (number of bits is not checked). + if (val_di->di_tv.v_type != VAR_LIST + || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) { goto _convert_one_value_regular_dict; } - switch ((MessagePackType)i) { - case kMPNil: { - TYPVAL_ENCODE_CONV_NIL(tv); - break; - } - case kMPBoolean: { - if (val_di->di_tv.v_type != VAR_NUMBER) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number); - break; - } - case kMPInteger: { - const list_T *val_list; - varnumber_T sign; - varnumber_T highest_bits; - varnumber_T high_bits; - varnumber_T low_bits; - // List of 4 integers; first is signed (should be 1 or -1, but - // this is not checked), second is unsigned and have at most - // one (sign is -1) or two (sign is 1) non-zero bits (number of - // bits is not checked), other unsigned and have at most 31 - // non-zero bits (number of bits is not checked). - if (val_di->di_tv.v_type != VAR_LIST - || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) { - goto _convert_one_value_regular_dict; - } - const listitem_T *const sign_li = tv_list_first(val_list); - if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER - || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const sign_li = tv_list_first(val_list); + if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER + || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const highest_bits_li = ( - TV_LIST_ITEM_NEXT(val_list, sign_li)); - if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER - || ((highest_bits - = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const highest_bits_li = ( + TV_LIST_ITEM_NEXT(val_list, sign_li)); + if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER + || ((highest_bits + = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const high_bits_li = ( - TV_LIST_ITEM_NEXT(val_list, highest_bits_li)); - if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER - || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const high_bits_li = ( + TV_LIST_ITEM_NEXT(val_list, highest_bits_li)); + if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER + || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const listitem_T *const low_bits_li = tv_list_last(val_list); - if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER - || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number) - < 0)) { - goto _convert_one_value_regular_dict; - } + const listitem_T *const low_bits_li = tv_list_last(val_list); + if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER + || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number) + < 0)) { + goto _convert_one_value_regular_dict; + } - const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62) - | (uint64_t)(((uint64_t)high_bits) << 31) - | (uint64_t)low_bits); - if (sign > 0) { - TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number); - } else { - TYPVAL_ENCODE_CONV_NUMBER(tv, -number); - } - break; - } - case kMPFloat: { - if (val_di->di_tv.v_type != VAR_FLOAT) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float); - break; - } - case kMPString: - case kMPBinary: { - const bool is_string = ((MessagePackType)i == kMPString); - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - size_t len; - char *buf; - if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, - &buf)) { - goto _convert_one_value_regular_dict; - } - if (is_string) { - TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len); - } else { // -V523 - TYPVAL_ENCODE_CONV_STRING(tv, buf, len); - } - xfree(buf); - break; - } - case kMPArray: { - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, - lv_copyID, copyID, - kMPConvList); - TYPVAL_ENCODE_CONV_LIST_START( - tv, tv_list_len(val_di->di_tv.vval.v_list)); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(*mpstack, ((MPConvStackVal) { + const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62) + | (uint64_t)(((uint64_t)high_bits) << 31) + | (uint64_t)low_bits); + if (sign > 0) { + TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number); + } else { + TYPVAL_ENCODE_CONV_NUMBER(tv, -number); + } + break; + } + case kMPFloat: + if (val_di->di_tv.v_type != VAR_FLOAT) { + goto _convert_one_value_regular_dict; + } + TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float); + break; + case kMPString: + case kMPBinary: { + const bool is_string = ((MessagePackType)i == kMPString); + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + size_t len; + char *buf; + if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, + &buf)) { + goto _convert_one_value_regular_dict; + } + if (is_string) { + TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len); + } else { // -V523 + TYPVAL_ENCODE_CONV_STRING(tv, buf, len); + } + xfree(buf); + break; + } + case kMPArray: { + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, + lv_copyID, copyID, + kMPConvList); + TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(val_di->di_tv.vval.v_list)); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvList, .saved_copyID = saved_copyID, @@ -551,31 +534,31 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - break; - } - case kMPMap: { - if (val_di->di_tv.v_type != VAR_LIST) { - goto _convert_one_value_regular_dict; - } - list_T *const val_list = val_di->di_tv.vval.v_list; - if (val_list == NULL || tv_list_len(val_list) == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501 - tv, TYPVAL_ENCODE_NODICT_VAR); - break; - } - TV_LIST_ITER_CONST(val_list, li, { + break; + } + case kMPMap: { + if (val_di->di_tv.v_type != VAR_LIST) { + goto _convert_one_value_regular_dict; + } + list_T *const val_list = val_di->di_tv.vval.v_list; + if (val_list == NULL || tv_list_len(val_list) == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501 + tv, TYPVAL_ENCODE_NODICT_VAR); + break; + } + TV_LIST_ITER_CONST(val_list, li, { if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST || tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) != 2) { goto _convert_one_value_regular_dict; } }); - const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID, - kMPConvPairs); - TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR, - tv_list_len(val_list)); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list); + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID, + kMPConvPairs); + TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR, + tv_list_len(val_list)); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvPairs, .saved_copyID = saved_copyID, @@ -586,46 +569,45 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( }, }, })); - break; - } - case kMPExt: { - const list_T *val_list; - varnumber_T type; - if (val_di->di_tv.v_type != VAR_LIST - || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2 - || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type - != VAR_NUMBER) - || ((type - = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number) - > INT8_MAX) - || type < INT8_MIN - || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type - != VAR_LIST)) { - goto _convert_one_value_regular_dict; - } - size_t len; - char *buf; - if (!( - encode_vim_list_to_buf( - TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len, - &buf))) { - goto _convert_one_value_regular_dict; - } - TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type); - xfree(buf); - break; - } + break; + } + case kMPExt: { + const list_T *val_list; + varnumber_T type; + if (val_di->di_tv.v_type != VAR_LIST + || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2 + || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type + != VAR_NUMBER) + || ((type + = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number) + > INT8_MAX) + || type < INT8_MIN + || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type + != VAR_LIST)) { + goto _convert_one_value_regular_dict; + } + size_t len; + char *buf; + if (!( + encode_vim_list_to_buf(TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len, + &buf))) { + goto _convert_one_value_regular_dict; } + TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type); + xfree(buf); break; } + } + break; + } _convert_one_value_regular_dict: {} - const int saved_copyID = tv->vval.v_dict->dv_copyID; - _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID, - kMPConvDict); - TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict, - tv->vval.v_dict->dv_hashtab.ht_used); - assert(saved_copyID != copyID); - _mp_push(*mpstack, ((MPConvStackVal) { + const int saved_copyID = tv->vval.v_dict->dv_copyID; + _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID, + kMPConvDict); + TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict, + tv->vval.v_dict->dv_hashtab.ht_used); + assert(saved_copyID != copyID); + _mp_push(*mpstack, ((MPConvStackVal) { .tv = tv, .type = kMPConvDict, .saved_copyID = saved_copyID, @@ -638,14 +620,13 @@ _convert_one_value_regular_dict: {} }, }, })); - TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict, - _mp_last(*mpstack)); - break; - } - case VAR_UNKNOWN: { - internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()"); - return FAIL; - } + TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict, + _mp_last(*mpstack)); + break; + } + case VAR_UNKNOWN: + internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()"); + return FAIL; } typval_encode_stop_converting_one_item: return OK; @@ -654,9 +635,9 @@ typval_encode_stop_converting_one_item: } TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - typval_T *const tv, const char *const objname) - REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT; + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, + typval_T *const tv, const char *const objname) +REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT; /// Convert the whole typval /// @@ -668,8 +649,8 @@ TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( /// /// @return OK in case of success, FAIL in case of failure. TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE( - TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, - typval_T *const top_tv, const char *const objname) + TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, typval_T *const top_tv, + const char *const objname) { const int copyID = get_copyID(); MPConvStack mpstack; @@ -687,125 +668,121 @@ typval_encode_stop_converting_one_item: MPConvStackVal *cur_mpsv = &_mp_last(mpstack); typval_T *tv = NULL; switch (cur_mpsv->type) { - case kMPConvDict: { - if (!cur_mpsv->data.d.todo) { - (void)_mp_pop(mpstack); - cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID; - TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp); - continue; - } else if (cur_mpsv->data.d.todo - != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { - TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, - *cur_mpsv->data.d.dictp); - } - while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { - cur_mpsv->data.d.hi++; - } - dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi); - cur_mpsv->data.d.todo--; + case kMPConvDict: { + if (!cur_mpsv->data.d.todo) { + (void)_mp_pop(mpstack); + cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID; + TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp); + continue; + } else if (cur_mpsv->data.d.todo + != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { + TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, + *cur_mpsv->data.d.dictp); + } + while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { cur_mpsv->data.d.hi++; - TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0], - strlen((char *)&di->di_key[0])); - TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, - *cur_mpsv->data.d.dictp); - tv = &di->di_tv; - break; } - case kMPConvList: { - if (cur_mpsv->data.l.li == NULL) { - (void)_mp_pop(mpstack); - tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); - TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv); - continue; - } else if (cur_mpsv->data.l.li - != tv_list_first(cur_mpsv->data.l.list)) { - TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv); - } - tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li); - cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, - cur_mpsv->data.l.li); - break; + dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi); + cur_mpsv->data.d.todo--; + cur_mpsv->data.d.hi++; + TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0], + strlen((char *)&di->di_key[0])); + TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, + *cur_mpsv->data.d.dictp); + tv = &di->di_tv; + break; + } + case kMPConvList: + if (cur_mpsv->data.l.li == NULL) { + (void)_mp_pop(mpstack); + tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); + TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv); + continue; + } else if (cur_mpsv->data.l.li + != tv_list_first(cur_mpsv->data.l.list)) { + TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv); } - case kMPConvPairs: { - if (cur_mpsv->data.l.li == NULL) { - (void)_mp_pop(mpstack); - tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); - TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); - continue; - } else if (cur_mpsv->data.l.li - != tv_list_first(cur_mpsv->data.l.list)) { - TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS( - cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); - } - const list_T *const kv_pair = ( - TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list); - TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK( - encode_vim_to__error_ret, *TV_LIST_ITEM_TV(tv_list_first(kv_pair))); - if ( - _TYPVAL_ENCODE_CONVERT_ONE_VALUE( - TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv, - TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname) - == FAIL) { - goto encode_vim_to__error_ret; - } - TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, - TYPVAL_ENCODE_NODICT_VAR); - tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)); - cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, - cur_mpsv->data.l.li); - break; + tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li); + cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, + cur_mpsv->data.l.li); + break; + case kMPConvPairs: { + if (cur_mpsv->data.l.li == NULL) { + (void)_mp_pop(mpstack); + tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID); + TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); + continue; + } else if (cur_mpsv->data.l.li + != tv_list_first(cur_mpsv->data.l.list)) { + TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR); } - case kMPConvPartial: { - partial_T *const pt = cur_mpsv->data.p.pt; - tv = cur_mpsv->tv; - (void)tv; - switch (cur_mpsv->data.p.stage) { - case kMPConvPartialArgs: { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, - pt == NULL ? 0 : pt->pt_argc); - cur_mpsv->data.p.stage = kMPConvPartialSelf; - if (pt != NULL && pt->pt_argc > 0) { - TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc); - _mp_push(mpstack, ((MPConvStackVal) { - .type = kMPConvPartialList, - .tv = NULL, - .saved_copyID = copyID - 1, - .data = { - .a = { - .arg = pt->pt_argv, - .argv = pt->pt_argv, - .todo = (size_t)pt->pt_argc, - }, + const list_T *const kv_pair = ( + TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list); + TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(encode_vim_to__error_ret, + *TV_LIST_ITEM_TV(tv_list_first(kv_pair))); + if ( + _TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv, + TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname) + == FAIL) { + goto encode_vim_to__error_ret; + } + TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv, + TYPVAL_ENCODE_NODICT_VAR); + tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)); + cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list, + cur_mpsv->data.l.li); + break; + } + case kMPConvPartial: { + partial_T *const pt = cur_mpsv->data.p.pt; + tv = cur_mpsv->tv; + (void)tv; + switch (cur_mpsv->data.p.stage) { + case kMPConvPartialArgs: + TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, + pt == NULL ? 0 : pt->pt_argc); + cur_mpsv->data.p.stage = kMPConvPartialSelf; + if (pt != NULL && pt->pt_argc > 0) { + TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc); + _mp_push(mpstack, ((MPConvStackVal) { + .type = kMPConvPartialList, + .tv = NULL, + .saved_copyID = copyID - 1, + .data = { + .a = { + .arg = pt->pt_argv, + .argv = pt->pt_argv, + .todo = (size_t)pt->pt_argc, }, - })); + }, + })); + } + break; + case kMPConvPartialSelf: { + cur_mpsv->data.p.stage = kMPConvPartialEnd; + dict_T *const dict = pt == NULL ? NULL : pt->pt_dict; + if (dict != NULL) { + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used); + if (dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); + continue; + } + const int saved_copyID = dict->dv_copyID; + const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, + dict, &dict->dv_copyID, + &mpstack, copyID, kMPConvDict, + objname); + if (te_csr_ret != NOTDONE) { + if (te_csr_ret == FAIL) { + goto encode_vim_to__error_ret; + } else { + continue; } - break; } - case kMPConvPartialSelf: { - cur_mpsv->data.p.stage = kMPConvPartialEnd; - dict_T *const dict = pt == NULL ? NULL : pt->pt_dict; - if (dict != NULL) { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used); - if (dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); - continue; - } - const int saved_copyID = dict->dv_copyID; - const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( - TYPVAL_ENCODE_FIRST_ARG_NAME, - dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict, - objname); - if (te_csr_ret != NOTDONE) { - if (te_csr_ret == FAIL) { - goto encode_vim_to__error_ret; - } else { - continue; - } - } - TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, - dict->dv_hashtab.ht_used); - assert(saved_copyID != copyID && saved_copyID != copyID - 1); - _mp_push(mpstack, ((MPConvStackVal) { + TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, + dict->dv_hashtab.ht_used); + assert(saved_copyID != copyID && saved_copyID != copyID - 1); + _mp_push(mpstack, ((MPConvStackVal) { .type = kMPConvDict, .tv = NULL, .saved_copyID = saved_copyID, @@ -818,33 +795,31 @@ typval_encode_stop_converting_one_item: }, }, })); - TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict, - _mp_last(mpstack)); - } else { - TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); - } - break; - } - case kMPConvPartialEnd: { - TYPVAL_ENCODE_CONV_FUNC_END(tv); - (void)_mp_pop(mpstack); - break; - } + TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict, + _mp_last(mpstack)); + } else { + TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); } - continue; + break; } - case kMPConvPartialList: { - if (!cur_mpsv->data.a.todo) { - (void)_mp_pop(mpstack); - TYPVAL_ENCODE_CONV_LIST_END(NULL); - continue; - } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) { - TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL); - } - tv = cur_mpsv->data.a.arg++; - cur_mpsv->data.a.todo--; + case kMPConvPartialEnd: + TYPVAL_ENCODE_CONV_FUNC_END(tv); + (void)_mp_pop(mpstack); break; } + continue; + } + case kMPConvPartialList: + if (!cur_mpsv->data.a.todo) { + (void)_mp_pop(mpstack); + TYPVAL_ENCODE_CONV_LIST_END(NULL); + continue; + } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) { + TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL); + } + tv = cur_mpsv->data.a.arg++; + cur_mpsv->data.a.todo--; + break; } assert(tv != NULL); if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h index 3475f6d8b3..d5cf431870 100644 --- a/src/nvim/eval/typval_encode.h +++ b/src/nvim/eval/typval_encode.h @@ -5,14 +5,14 @@ #ifndef NVIM_EVAL_TYPVAL_ENCODE_H #define NVIM_EVAL_TYPVAL_ENCODE_H -#include <stddef.h> +#include <assert.h> #include <inttypes.h> +#include <stddef.h> #include <string.h> -#include <assert.h> -#include "nvim/lib/kvec.h" #include "nvim/eval/typval.h" #include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" /// Type of the stack entry typedef enum { @@ -87,7 +87,7 @@ static inline size_t tv_strlen(const typval_T *const tv) assert(tv->v_type == VAR_STRING); return (tv->vval.v_string == NULL ? 0 - : strlen((char *) tv->vval.v_string)); + : strlen((char *)tv->vval.v_string)); } /// Code for checking whether container references itself @@ -100,19 +100,19 @@ static inline size_t tv_strlen(const typval_T *const tv) /// @param conv_type Type of the conversion, @see MPConvStackValType. #define _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val, copyID_attr, copyID, \ conv_type) \ - do { \ - const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( \ - TYPVAL_ENCODE_FIRST_ARG_NAME, \ - (val), &(val)->copyID_attr, mpstack, copyID, conv_type, objname); \ - if (te_csr_ret != NOTDONE) { \ - return te_csr_ret; \ - } \ - } while (0) + do { \ + const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, \ + (val), &(val)->copyID_attr, mpstack, \ + copyID, conv_type, objname); \ + if (te_csr_ret != NOTDONE) { \ + return te_csr_ret; \ + } \ + } while (0) #define _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) \ - pref##name##suf + pref##name##suf #define _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, name, suf) \ - _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) + _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) /// Construct function name, possibly using macros /// @@ -125,22 +125,22 @@ static inline size_t tv_strlen(const typval_T *const tv) /// /// @return Concat: pref + #TYPVAL_ENCODE_NAME + suf. #define _TYPVAL_ENCODE_FUNC_NAME(pref, suf) \ - _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf) + _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf) /// Self reference checker function name #define _TYPVAL_ENCODE_CHECK_SELF_REFERENCE \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference) /// Entry point function name #define _TYPVAL_ENCODE_ENCODE \ - _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, ) + _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, ) /// Name of the …convert_one_value function #define _TYPVAL_ENCODE_CONVERT_ONE_VALUE \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value) /// Name of the dummy const dict_T *const variable #define TYPVAL_ENCODE_NODICT_VAR \ - _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var) + _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var) #endif // NVIM_EVAL_TYPVAL_ENCODE_H diff --git a/src/nvim/eval/userfunc.h b/src/nvim/eval/userfunc.h index 3f111343d2..ed86aaad4a 100644 --- a/src/nvim/eval/userfunc.h +++ b/src/nvim/eval/userfunc.h @@ -8,7 +8,7 @@ typedef struct { dict_T *fd_dict; ///< Dictionary used. char_u *fd_newkey; ///< New key in "dict" in allocated memory. - dictitem_T *fd_di; ///< Dictionary item used. + dictitem_T *fd_di; ///< Dictionary item used. } funcdict_T; typedef struct funccal_entry funccal_entry_T; diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index fdd4f17d5c..cf079681d0 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -11,7 +11,7 @@ typedef struct message { argv_callback handler; void *argv[EVENT_HANDLER_MAX_ARGC]; } Event; -typedef void(*event_scheduler)(Event event, void *data); +typedef void (*event_scheduler)(Event event, void *data); #define VA_EVENT_INIT(event, h, a) \ do { \ diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index f5dd23ac8b..03cf7e489a 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -2,12 +2,11 @@ #define NVIM_EVENT_LOOP_H #include <stdint.h> - #include <uv.h> +#include "nvim/event/multiqueue.h" #include "nvim/lib/klist.h" #include "nvim/os/time.h" -#include "nvim/event/multiqueue.h" typedef void * WatcherPtr; @@ -65,7 +64,7 @@ typedef struct loop { break; \ } else if (remaining > 0) { \ uint64_t now = os_hrtime(); \ - remaining -= (int) ((now - before) / 1000000); \ + remaining -= (int)((now - before) / 1000000); \ before = now; \ if (remaining <= 0) { \ break; \ diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 20c02e4900..2b22cd95dc 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -1,10 +1,10 @@ #ifndef NVIM_EVENT_PROCESS_H #define NVIM_EVENT_PROCESS_H +#include "nvim/eval/typval.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/eval/typval.h" typedef enum { kProcessTypeUv, diff --git a/src/nvim/event/rstream.h b/src/nvim/event/rstream.h index f30ad79ee5..77418c59a2 100644 --- a/src/nvim/event/rstream.h +++ b/src/nvim/event/rstream.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stddef.h> - #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index a5c33a66a2..02e816b4be 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -3,7 +3,6 @@ #include <stdbool.h> #include <stddef.h> - #include <uv.h> #include "nvim/event/loop.h" @@ -18,7 +17,7 @@ typedef struct stream Stream; /// @param data User-defined data /// @param eof If the stream reached EOF. typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count, - void *data, bool eof); + void *data, bool eof); /// Type of function called when the Stream has information about a write /// request. diff --git a/src/nvim/event/wstream.h b/src/nvim/event/wstream.h index 9008de0d97..d599d29913 100644 --- a/src/nvim/event/wstream.h +++ b/src/nvim/event/wstream.h @@ -1,9 +1,8 @@ #ifndef NVIM_EVENT_WSTREAM_H #define NVIM_EVENT_WSTREAM_H -#include <stdint.h> #include <stdbool.h> - +#include <stdint.h> #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index bbc1dd9717..3bfbb42d87 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -702,11 +702,11 @@ void ex_sort(exarg_T *eap) mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, kExtmarkNOOP); } - extmark_splice(curbuf, eap->line1-1, 0, - count, 0, old_count, - lnum - eap->line2, 0, new_count, kExtmarkUndo); - if (change_occurred || deleted != 0) { + extmark_splice(curbuf, eap->line1-1, 0, + count, 0, old_count, + lnum - eap->line2, 0, new_count, kExtmarkUndo); + changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index a9990df58f..f4f07e0680 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -230,7 +230,22 @@ static int compl_match_arraysize; static int compl_startcol; static int compl_selected; +/// |:checkhealth| completion items +/// +/// Regenerates on every new command line prompt, to accomodate changes on the +/// runtime files. +typedef struct { + garray_T names; // healthcheck names + unsigned last_gen; // last_prompt_id where names were generated +} CheckhealthComp; + +/// Cookie used when converting filepath to name +struct healthchecks_cookie { + garray_T *names; // global healthchecks + bool is_lua; // true if the current entry is a Lua healthcheck +}; +static CheckhealthComp healthchecks = { GA_INIT(sizeof(char_u *), 10), 0 }; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_getln.c.generated.h" @@ -273,6 +288,68 @@ static void init_incsearch_state(incsearch_state_T *s) save_viewstate(&s->old_viewstate); } +/// Completion for |:checkhealth| command. +/// +/// Given to ExpandGeneric() to obtain all available heathcheck names. +/// @param[in] idx Index of the healthcheck item. +/// @param[in] xp Not used. +static char_u *get_healthcheck_names(expand_T *xp, int idx) +{ + // Generate the first time or on new prompt. + if (healthchecks.last_gen == 0 || healthchecks.last_gen != last_prompt_id) { + ga_clear_strings(&healthchecks.names); + char *patterns[3] = { "autoload/health/**.vim", "lua/**/**/health/init.lua", // NOLINT + "lua/**/**/health.lua" }; // NOLINT + for (int i = 0; i < 3; i++) { + struct healthchecks_cookie hcookie = { .names = &healthchecks.names, .is_lua = i != 0 }; + do_in_runtimepath((char_u *)patterns[i], DIP_ALL, get_healthcheck_cb, &hcookie); + + if (healthchecks.names.ga_len > 0) { + ga_remove_duplicate_strings(&healthchecks.names); + } + } + // Tracked to regenerate items on next prompt. + healthchecks.last_gen = last_prompt_id; + } + return idx < + (int)healthchecks.names.ga_len ? ((char_u **)(healthchecks.names.ga_data))[idx] : NULL; +} + +/// Transform healthcheck file path into it's name. +/// +/// Used as a callback for do_in_runtimepath +/// @param[in] path Expanded path to a possible healthcheck. +/// @param[out] cookie Array where names will be inserted. +static void get_healthcheck_cb(char_u *path, void *cookie) +{ + if (path != NULL) { + struct healthchecks_cookie *hcookie = (struct healthchecks_cookie *)cookie; + char *pattern; + char *sub = "\\1"; + char_u *res; + + if (hcookie->is_lua) { + // Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp" + pattern = ".*lua[\\/]\\(.\\{-}\\)[\\/]health\\([\\/]init\\)\\?\\.lua$"; + } else { + // Vim: transform "../autoload/health/provider.vim" into "provider" + pattern = ".*[\\/]\\([^\\/]*\\)\\.vim$"; + } + + res = do_string_sub(path, (char_u *)pattern, (char_u *)sub, NULL, (char_u *)"g"); + if (hcookie->is_lua && res != NULL) { + // Replace slashes with dots as represented by the healthcheck plugin. + char_u *ares = do_string_sub(res, (char_u *)"[\\/]", (char_u *)".", NULL, (char_u *)"g"); + xfree(res); + res = ares; + } + + if (res != NULL) { + GA_APPEND(char_u *, hcookie->names, res); + } + } +} + // Return true when 'incsearch' highlighting is to be done. // Sets search_first_line and search_last_line to the address range. static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_state_T *s, @@ -3037,7 +3114,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) line->cmdindent, line->level); if (line->special_char) { - ui_call_cmdline_special_char(cchar_to_string((char)(line->special_char)), + ui_call_cmdline_special_char(cchar_to_string(line->special_char), line->special_shift, line->level); } @@ -3135,7 +3212,7 @@ void putcmdline(char c, int shift) } msg_no_more = false; } else if (ccline.redraw_state != kCmdRedrawAll) { - ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift, + ui_call_cmdline_special_char(cchar_to_string(c), shift, ccline.level); } cursorcmd(); @@ -4902,10 +4979,6 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ** char *directories[] = { "syntax", "indent", "ftplugin", NULL }; return ExpandRTDir(pat, DIP_LUA, num_file, file, directories); } - if (xp->xp_context == EXPAND_CHECKHEALTH) { - char *directories[] = { "autoload/health", NULL }; - return ExpandRTDir(pat, 0, num_file, file, directories); - } if (xp->xp_context == EXPAND_USER_LIST) { return ExpandUserList(xp, num_file, file); } @@ -4982,6 +5055,7 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char_u ** { EXPAND_ENV_VARS, get_env_name, true, true }, { EXPAND_USER, get_users, true, false }, { EXPAND_ARGLIST, get_arglist_name, true, false }, + { EXPAND_CHECKHEALTH, get_healthcheck_names, true, false }, }; int i; diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index cf01c305d7..dc73e34111 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -723,7 +723,7 @@ void extmark_move_region(buf_T *buf, int start_row, colnr_T start_col, bcount_t uint64_t src2ns(Integer *src_id) { if (*src_id == 0) { - *src_id = (Integer)nvim_create_namespace((String)STRING_INIT); + *src_id = nvim_create_namespace((String)STRING_INIT); } if (*src_id < 0) { return UINT64_MAX; diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 6ed2e5dab8..e38a0af0ec 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -33,6 +33,10 @@ local function_names = {} local c_grammar = require('generators.c_grammar') +local function startswith(String,Start) + return string.sub(String,1,string.len(Start))==Start +end + -- read each input file, parse and append to the api metadata for i = 6, #arg do local full_path = arg[i] @@ -47,7 +51,8 @@ for i = 6, #arg do local tmp = c_grammar.grammar:match(input:read('*all')) for j = 1, #tmp do local fn = tmp[j] - if not fn.noexport then + local public = startswith(fn.name, "nvim_") or fn.deprecated_since + if public and not fn.noexport then functions[#functions + 1] = tmp[j] function_names[fn.name] = true if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then @@ -76,10 +81,6 @@ local function shallowcopy(orig) return copy end -local function startswith(String,Start) - return string.sub(String,1,string.len(Start))==Start -end - -- Export functions under older deprecated names. -- These will be removed eventually. local deprecated_aliases = require("api.dispatch_deprecated") @@ -108,9 +109,10 @@ for _,f in ipairs(shallowcopy(functions)) do f.lua = f.lua_only or not f.remote_only f.eval = (not f.lua_only) and (not f.remote_only) else + f.deprecated_since = tonumber(f.deprecated_since) + assert(f.deprecated_since == 1) f.remote = true f.since = 0 - f.deprecated_since = 1 end f.method = ismethod local newname = deprecated_aliases[f.name] diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 15acd73aa5..a53742b17b 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -293,7 +293,6 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle buf->bh_curr->b_next = p; buf->bh_curr = p; } - return; } /* @@ -523,7 +522,7 @@ void restoreRedobuff(save_redo_T *save_redo) void AppendToRedobuff(const char *s) { if (!block_redo) { - add_buff(&redobuff, (const char *)s, -1L); + add_buff(&redobuff, s, -1L); } } @@ -2861,7 +2860,7 @@ int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev, buf_T } char_u *lhs = (char_u *)&args->lhs; - char_u *rhs = (char_u *)args->rhs; + char_u *rhs = args->rhs; char_u *orig_rhs = args->orig_rhs; // check arguments and translate function keys diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 76dcb58236..f236b966ca 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -1294,7 +1294,7 @@ static int cs_kill(exarg_T *eap) } } } else { - cs_kill_execute((size_t)i, stok); + cs_kill_execute(i, stok); } } @@ -1559,8 +1559,8 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, assert(totmatches > 0); buf = xmalloc(CSREAD_BUFSIZE); - matches = xmalloc(sizeof(char *) * (size_t)totmatches); - cntxts = xmalloc(sizeof(char *) * (size_t)totmatches); + matches = xmalloc(sizeof(char *) * totmatches); + cntxts = xmalloc(sizeof(char *) * totmatches); for (size_t i = 0; i < csinfo_size; i++) { if (nummatches_a[i] < 1) { diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index fd4cfc4c31..ca3c4f604a 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -1303,6 +1303,12 @@ void nlua_init_types(lua_State *const lstate) void nlua_pop_keydict(lua_State *L, void *retval, field_hash hashy, Error *err) { + if (!lua_istable(L, -1)) { + api_set_error(err, kErrorTypeValidation, "Expected lua table"); + lua_pop(L, -1); + return; + } + lua_pushnil(L); // [dict, nil] while (lua_next(L, -2)) { // [dict, key, value] diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h index 43a7e06019..1c9e60e4b2 100644 --- a/src/nvim/lua/converter.h +++ b/src/nvim/lua/converter.h @@ -6,8 +6,8 @@ #include <stdint.h> #include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" #include "nvim/eval.h" +#include "nvim/func_attr.h" typedef struct { LuaRef func_ref; diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h index ea774ac2e3..a1f66bd02b 100644 --- a/src/nvim/lua/executor.h +++ b/src/nvim/lua/executor.h @@ -1,13 +1,13 @@ #ifndef NVIM_LUA_EXECUTOR_H #define NVIM_LUA_EXECUTOR_H -#include <lua.h> #include <lauxlib.h> +#include <lua.h> #include "nvim/api/private/defs.h" -#include "nvim/func_attr.h" #include "nvim/eval/typval.h" #include "nvim/ex_cmds_defs.h" +#include "nvim/func_attr.h" #include "nvim/lua/converter.h" // Generated by msgpack-gen.lua @@ -19,12 +19,12 @@ EXTERN LuaRef nlua_empty_dict_ref INIT(= LUA_NOREF); EXTERN int nlua_refcount INIT(= 0); #define set_api_error(s, err) \ - do { \ - Error *err_ = (err); \ - err_->type = kErrorTypeException; \ - err_->set = true; \ - memcpy(&err_->msg[0], s, sizeof(s)); \ - } while (0) + do { \ + Error *err_ = (err); \ + err_->type = kErrorTypeException; \ + err_->set = true; \ + memcpy(&err_->msg[0], s, sizeof(s)); \ + } while (0) #define NLUA_CLEAR_REF(x) \ do { \ diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index 37929093e3..bd978cc8ab 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -30,6 +30,7 @@ typedef struct { TSQueryCursor *cursor; int predicated_match; + int max_match_id; } TSLua_cursor; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -1055,6 +1056,8 @@ static int query_next_match(lua_State *L) static int query_next_capture(lua_State *L) { + // Upvalues are: + // [ cursor, node, query, current_match ] TSLua_cursor *ud = lua_touserdata(L, lua_upvalueindex(1)); TSQueryCursor *cursor = ud->cursor; @@ -1078,9 +1081,13 @@ static int query_next_capture(lua_State *L) lua_pushinteger(L, capture.index+1); // [index] push_node(L, capture.node, lua_upvalueindex(2)); // [index, node] + // Now check if we need to run the predicates uint32_t n_pred; ts_query_predicates_for_pattern(query, match.pattern_index, &n_pred); - if (n_pred > 0 && capture_index == 0) { + + if (n_pred > 0 && (ud->max_match_id < (int)match.id)) { + ud->max_match_id = match.id; + lua_pushvalue(L, lua_upvalueindex(4)); // [index, node, match] set_match(L, &match, lua_upvalueindex(2)); lua_pushinteger(L, match.pattern_index+1); @@ -1127,6 +1134,7 @@ static int node_rawquery(lua_State *L) TSLua_cursor *ud = lua_newuserdata(L, sizeof(*ud)); // [udata] ud->cursor = cursor; ud->predicated_match = -1; + ud->max_match_id = -1; lua_getfield(L, LUA_REGISTRYINDEX, TS_META_QUERYCURSOR); lua_setmetatable(L, -2); // [udata] diff --git a/src/nvim/lua/treesitter.h b/src/nvim/lua/treesitter.h index 812166f67b..b69fb9dfae 100644 --- a/src/nvim/lua/treesitter.h +++ b/src/nvim/lua/treesitter.h @@ -1,9 +1,9 @@ #ifndef NVIM_LUA_TREESITTER_H #define NVIM_LUA_TREESITTER_H +#include <lauxlib.h> #include <lua.h> #include <lualib.h> -#include <lauxlib.h> #include "tree_sitter/api.h" diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index 7a209f2d79..5ca4cc82a5 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -433,6 +433,7 @@ function vim.notify(msg, log_level, _opts) end +---@private function vim.register_keystroke_callback() error('vim.register_keystroke_callback is deprecated, instead use: vim.on_key') end diff --git a/src/nvim/lua/xdiff.h b/src/nvim/lua/xdiff.h index cae7c98e81..b172d2f922 100644 --- a/src/nvim/lua/xdiff.h +++ b/src/nvim/lua/xdiff.h @@ -1,9 +1,9 @@ #ifndef NVIM_LUA_XDIFF_H #define NVIM_LUA_XDIFF_H +#include <lauxlib.h> #include <lua.h> #include <lualib.h> -#include <lauxlib.h> #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/xdiff.h.generated.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index f801351d2d..069c253bff 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -345,7 +345,8 @@ int main(int argc, char **argv) // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) { - p_lpl = false; + // When using --clean we still want to load plugins + p_lpl = params.clean; } // Execute --cmd arguments. diff --git a/src/nvim/mark.c b/src/nvim/mark.c index b296bf39cf..835c2adbe5 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -1036,9 +1036,10 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo } sign_mark_adjust(line1, line2, amount, amount_after); - if (op != kExtmarkNOOP) { - extmark_adjust(curbuf, line1, line2, amount, amount_after, op); - } + } + + if (op != kExtmarkNOOP) { + extmark_adjust(curbuf, line1, line2, amount, amount_after, op); } // previous context mark @@ -1637,6 +1638,15 @@ void get_buf_local_marks(const buf_T *buf, list_T *l) add_mark(l, "'>", &buf->b_visual.vi_end, buf->b_fnum, NULL); } +/// Get a global mark +/// +/// @param[in] Name of named mark +/// @param[out] Global/file mark +xfmark_T get_global_mark(char name) +{ + return namedfm[mark_global_index(name)]; +} + /// Get information about global marks ('A' to 'Z' and '0' to '9') /// /// @param[out] l List to store global marks diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index ebe4478bc8..e62f91e698 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -837,8 +837,8 @@ bool marktree_splice(MarkTree *b, int start_line, int start_col, int old_extent_ int old_extent_col, int new_extent_line, int new_extent_col) { mtpos_t start = { start_line, start_col }; - mtpos_t old_extent = { (int)old_extent_line, old_extent_col }; - mtpos_t new_extent = { (int)new_extent_line, new_extent_col }; + mtpos_t old_extent = { old_extent_line, old_extent_col }; + mtpos_t new_extent = { new_extent_line, new_extent_col }; bool may_delete = (old_extent.row != 0 || old_extent.col != 0); bool same_line = old_extent.row == 0 && new_extent.row == 0; diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 69598bbdda..20ae5a4042 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1272,7 +1272,6 @@ theend: apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf); apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf); } - return; } /// Find the names of swap files in current directory and the directory given @@ -2798,7 +2797,6 @@ void ml_clearmarked(void) } lowest_marked = 0; - return; } size_t ml_flush_deleted_bytes(buf_T *buf, size_t *codepoints, size_t *codeunits) diff --git a/src/nvim/menu.c b/src/nvim/menu.c index de8503f9d0..85e062009a 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -857,7 +857,7 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) MSG_PUTS(" "); } if (menu->priority) { - msg_outnum((long)menu->priority); + msg_outnum(menu->priority); MSG_PUTS(" "); } // Same highlighting as for directories!? diff --git a/src/nvim/message.c b/src/nvim/message.c index ed673b52d3..cc4319b8da 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2363,7 +2363,7 @@ void msg_reset_scroll(void) // 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); } } } else { @@ -3191,7 +3191,7 @@ static void redir_write(const char *const str, const ptrdiff_t maxlen) size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; if (capture_ga) { - ga_concat_len(capture_ga, (const char *)str, len); + ga_concat_len(capture_ga, str, len); } if (redir_reg) { write_reg_contents(redir_reg, s, len, true); diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index cf463fd40a..f02c000e82 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -236,6 +236,11 @@ retnomove: redraw_curbuf_later(INVERTED); // delete the inversion } + if (grid == 0) { + row -= curwin->w_grid_alloc.comp_row+curwin->w_grid.row_offset; + col -= curwin->w_grid_alloc.comp_col+curwin->w_grid.col_offset; + } + // When clicking beyond the end of the window, scroll the screen. // Scroll by however many rows outside the window we are. if (row < 0) { @@ -476,7 +481,7 @@ win_T *mouse_find_win(int *gridp, int *rowp, int *colp) static win_T *mouse_find_grid_win(int *gridp, int *rowp, int *colp) { if (*gridp == msg_grid.handle) { - // rowp += msg_grid_pos; // PVS: dead store #11612 + *rowp += msg_grid_pos; *gridp = DEFAULT_GRID_HANDLE; } else if (*gridp > 1) { win_T *wp = get_win_by_grid_handle(*gridp); @@ -677,8 +682,8 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; -#define incr() nudge++; ptr_end += utfc_ptr2len(ptr_end) -#define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end) +#define INCR() nudge++; ptr_end += utfc_ptr2len(ptr_end) +#define DECR() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { cwidth = win_chartabsize(curwin, ptr, vcol); @@ -687,7 +692,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // A tab will "absorb" any previous adjustments. cwidth = MIN(cwidth, nudge); while (cwidth > 0) { - decr(); + DECR(); cwidth--; } } @@ -695,20 +700,20 @@ static int mouse_adjust_click(win_T *wp, int row, int col) matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); if (matchid != 0) { if (wp->w_p_cole == 3) { - incr(); + INCR(); } else { if (!(row > 0 && ptr == ptr_row_offset) && (wp->w_p_cole == 1 || (wp->w_p_cole == 2 && (wp->w_p_lcs_chars.conceal != NUL || syn_get_sub_char() != NUL)))) { // At least one placeholder character will be displayed. - decr(); + DECR(); } prev_matchid = matchid; while (prev_matchid == matchid && *ptr != NUL) { - incr(); + INCR(); ptr += utfc_ptr2len(ptr); matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line)); } diff --git a/src/nvim/move.c b/src/nvim/move.c index c4f8e81fa3..918e0a5c4f 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2104,7 +2104,6 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) } else { *lp = loff2; // 2 lines overlap } - return; } // Scroll 'scroll' lines up or down. diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h index 90e1c7d48b..eb0de47437 100644 --- a/src/nvim/msgpack_rpc/channel.h +++ b/src/nvim/msgpack_rpc/channel.h @@ -5,10 +5,10 @@ #include <uv.h> #include "nvim/api/private/defs.h" -#include "nvim/event/socket.h" +#include "nvim/channel.h" #include "nvim/event/process.h" +#include "nvim/event/socket.h" #include "nvim/vim.h" -#include "nvim/channel.h" #define METHOD_MAXLEN 512 diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h index de328af1ce..6647779db9 100644 --- a/src/nvim/msgpack_rpc/channel_defs.h +++ b/src/nvim/msgpack_rpc/channel_defs.h @@ -1,13 +1,13 @@ #ifndef NVIM_MSGPACK_RPC_CHANNEL_DEFS_H #define NVIM_MSGPACK_RPC_CHANNEL_DEFS_H +#include <msgpack.h> #include <stdbool.h> #include <uv.h> -#include <msgpack.h> #include "nvim/api/private/defs.h" -#include "nvim/event/socket.h" #include "nvim/event/process.h" +#include "nvim/event/socket.h" #include "nvim/vim.h" typedef struct Channel Channel; diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index 549016e751..f805858904 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -22,42 +22,6 @@ static msgpack_zone zone; static msgpack_sbuffer sbuffer; -#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \ - static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \ - Integer *const arg) \ - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \ - { \ - if (obj->type != MSGPACK_OBJECT_EXT \ - || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \ - return false; \ - } \ - \ - msgpack_object data; \ - msgpack_unpack_return ret = msgpack_unpack(obj->via.ext.ptr, \ - obj->via.ext.size, \ - NULL, \ - &zone, \ - &data); \ - \ - if (ret != MSGPACK_UNPACK_SUCCESS) { \ - return false; \ - } \ - \ - *arg = (handle_T)data.via.i64; \ - return true; \ - } \ - \ - static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \ - FUNC_ATTR_NONNULL_ARG(2) \ - { \ - msgpack_packer pac; \ - msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \ - msgpack_pack_int64(&pac, (handle_T)o); \ - msgpack_pack_ext(res, sbuffer.size, \ - kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \ - msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \ - msgpack_sbuffer_clear(&sbuffer); \ - } void msgpack_rpc_helpers_init(void) { @@ -65,10 +29,6 @@ void msgpack_rpc_helpers_init(void) msgpack_sbuffer_init(&sbuffer); } -HANDLE_TYPE_CONVERSION_IMPL(Buffer, buffer) -HANDLE_TYPE_CONVERSION_IMPL(Window, window) -HANDLE_TYPE_CONVERSION_IMPL(Tabpage, tabpage) - typedef struct { const msgpack_object *mobj; Object *aobj; @@ -226,28 +186,18 @@ case type: { \ break; } case MSGPACK_OBJECT_EXT: - switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) { - case kObjectTypeBuffer: - cur.aobj->type = kObjectTypeBuffer; - ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeWindow: - cur.aobj->type = kObjectTypeWindow; - ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeTabpage: - cur.aobj->type = kObjectTypeTabpage; - ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer); - break; - case kObjectTypeNil: - case kObjectTypeBoolean: - case kObjectTypeInteger: - case kObjectTypeFloat: - case kObjectTypeString: - case kObjectTypeArray: - case kObjectTypeDictionary: - case kObjectTypeLuaRef: - break; + if (0 <= cur.mobj->via.ext.type && cur.mobj->via.ext.type <= EXT_OBJECT_TYPE_MAX) { + cur.aobj->type = (ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT); + msgpack_object data; + msgpack_unpack_return status = msgpack_unpack(cur.mobj->via.ext.ptr, cur.mobj->via.ext.size, + NULL, &zone, &data); + + if (status != MSGPACK_UNPACK_SUCCESS || data.type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + ret = false; + break; + } + cur.aobj->data.integer = (handle_T)data.via.i64; + ret = true; } break; #undef STR_CASE @@ -349,6 +299,17 @@ void msgpack_rpc_from_string(const String result, msgpack_packer *res) } } +static void msgpack_rpc_from_handle(ObjectType type, Integer o, msgpack_packer *res) + FUNC_ATTR_NONNULL_ARG(3) +{ + msgpack_packer pac; + msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); + msgpack_pack_int64(&pac, (handle_T)o); + msgpack_pack_ext(res, sbuffer.size, (int8_t)(type - EXT_OBJECT_TYPE_SHIFT)); + msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); + msgpack_sbuffer_clear(&sbuffer); +} + typedef struct { const Object *aobj; bool container; @@ -393,13 +354,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res) msgpack_rpc_from_string(cur.aobj->data.string, res); break; case kObjectTypeBuffer: - msgpack_rpc_from_buffer(cur.aobj->data.integer, res); - break; case kObjectTypeWindow: - msgpack_rpc_from_window(cur.aobj->data.integer, res); - break; case kObjectTypeTabpage: - msgpack_rpc_from_tabpage(cur.aobj->data.integer, res); + msgpack_rpc_from_handle(cur.aobj->type, cur.aobj->data.integer, res); break; case kObjectTypeArray: { const size_t size = cur.aobj->data.array.size; diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h index 0e4cd1be6d..e5fd92374d 100644 --- a/src/nvim/msgpack_rpc/helpers.h +++ b/src/nvim/msgpack_rpc/helpers.h @@ -1,13 +1,12 @@ #ifndef NVIM_MSGPACK_RPC_HELPERS_H #define NVIM_MSGPACK_RPC_HELPERS_H -#include <stdint.h> -#include <stdbool.h> - #include <msgpack.h> +#include <stdbool.h> +#include <stdint.h> -#include "nvim/event/wstream.h" #include "nvim/api/private/defs.h" +#include "nvim/event/wstream.h" /// Value by which objects represented as EXT type are shifted /// @@ -15,6 +14,7 @@ /// buffer/window/tabpage block inside ObjectType enum. This block yet cannot be /// split or reordered. #define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer +#define EXT_OBJECT_TYPE_MAX (kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT) #ifdef INCLUDE_GENERATED_DECLARATIONS # include "msgpack_rpc/helpers.h.generated.h" diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 1d737ee9fc..0668924237 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2817,17 +2817,17 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) tv_list_append_string(list, (const char *)reg->y_array[i], -1); } tv_list_set_lock(list, VAR_FIXED); - tv_dict_add_list(dict, S_LEN("regcontents"), list); + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); // Register type. char buf[NUMBUFLEN+2]; format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf)); - tv_dict_add_str(dict, S_LEN("regtype"), buf); + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); // Name of requested register, or empty string for unnamed operation. buf[0] = (char)oap->regname; buf[1] = NUL; - tv_dict_add_str(dict, S_LEN("regname"), buf); + (void)tv_dict_add_str(dict, S_LEN("regname"), buf); // Motion type: inclusive or exclusive. tv_dict_add_bool(dict, S_LEN("inclusive"), @@ -2836,11 +2836,11 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) // Kind of operation: yank, delete, change). buf[0] = (char)get_op_char(oap->op_type); buf[1] = NUL; - tv_dict_add_str(dict, S_LEN("operator"), buf); + (void)tv_dict_add_str(dict, S_LEN("operator"), buf); // Selection type: visual or not. - tv_dict_add_bool(dict, S_LEN("visual"), - oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); + (void)tv_dict_add_bool(dict, S_LEN("visual"), + oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse); tv_dict_set_keys_readonly(dict); textlock++; diff --git a/src/nvim/option.c b/src/nvim/option.c index 5646a62cd4..a9bff8285c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3899,7 +3899,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va // when 'buflisted' changes, trigger autocommands apply_autocmds(curbuf->b_p_bl ? EVENT_BUFADD : EVENT_BUFDELETE, NULL, NULL, true, curbuf); - } else if ((int *)varp == (int *)&curbuf->b_p_swf) { + } else if ((int *)varp == &curbuf->b_p_swf) { // when 'swf' is set, create swapfile, when reset remove swapfile if (curbuf->b_p_swf && p_uc) { ml_open_file(curbuf); // create the swap file @@ -6509,8 +6509,6 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags) break; } } - - return; } int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file) diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index bbf70a4830..9675cfbb0f 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -134,7 +134,7 @@ bool os_isdir(const char_u *name) bool os_isdir_executable(const char *name) FUNC_ATTR_NONNULL_ALL { - int32_t mode = os_getperm((const char *)name); + int32_t mode = os_getperm(name); if (mode < 0) { return false; } diff --git a/src/nvim/os/input.h b/src/nvim/os/input.h index d571965408..7026781407 100644 --- a/src/nvim/os/input.h +++ b/src/nvim/os/input.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_INPUT_H #define NVIM_OS_INPUT_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include "nvim/api/private/defs.h" #include "nvim/event/multiqueue.h" diff --git a/src/nvim/os/os.h b/src/nvim/os/os.h index 3e89e5a94a..bff2936f8e 100644 --- a/src/nvim/os/os.h +++ b/src/nvim/os/os.h @@ -9,11 +9,11 @@ #include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS +# include "os/env.h.generated.h" # include "os/fs.h.generated.h" # include "os/mem.h.generated.h" -# include "os/env.h.generated.h" -# include "os/users.h.generated.h" # include "os/stdpaths.h.generated.h" +# include "os/users.h.generated.h" #endif #endif // NVIM_OS_OS_H diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h index 1b7859b0d3..8049b3b80e 100644 --- a/src/nvim/os/os_defs.h +++ b/src/nvim/os/os_defs.h @@ -16,7 +16,7 @@ #define BASENAMELEN (NAME_MAX - 5) // Use the system path length if it makes sense. -# define DEFAULT_MAXPATHL 4096 +#define DEFAULT_MAXPATHL 4096 #if defined(PATH_MAX) && (PATH_MAX > DEFAULT_MAXPATHL) # define MAXPATHL PATH_MAX #else diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 2c9cb699fc..18e2e02b81 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -46,29 +46,3 @@ void os_replace_stdout_and_stderr_to_conout(void) const int conerr_fd = _open_osfhandle((intptr_t)conout_handle, 0); assert(conerr_fd == STDERR_FILENO); } - -void os_set_vtp(bool enable) -{ - static TriState is_legacy = kNone; - if (is_legacy == kNone) { - uv_tty_vtermstate_t state; - uv_tty_get_vterm_state(&state); - is_legacy = (state == UV_TTY_UNSUPPORTED) ? kTrue : kFalse; - } - if (!is_legacy && !os_has_vti()) { - uv_tty_set_vterm_state(enable ? UV_TTY_SUPPORTED : UV_TTY_UNSUPPORTED); - } -} - -static bool os_has_vti(void) -{ - static TriState has_vti = kNone; - if (has_vti == kNone) { - HANDLE handle = (HANDLE)_get_osfhandle(input_global_fd()); - DWORD dwMode; - if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) { - has_vti = !!(dwMode & ENABLE_VIRTUAL_TERMINAL_INPUT) ? kTrue : kFalse; - } - } - return has_vti == kTrue; -} diff --git a/src/nvim/os/process.h b/src/nvim/os/process.h index 1722d56bd3..faa4762cf1 100644 --- a/src/nvim/os/process.h +++ b/src/nvim/os/process.h @@ -2,6 +2,7 @@ #define NVIM_OS_PROCESS_H #include <stddef.h> + #include "nvim/api/private/defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/os/time.h b/src/nvim/os/time.h index ad4886446a..1b6c667dbb 100644 --- a/src/nvim/os/time.h +++ b/src/nvim/os/time.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_TIME_H #define NVIM_OS_TIME_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <time.h> typedef uint64_t Timestamp; diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h index 60a2dfa882..4ed3b51694 100644 --- a/src/nvim/os/unix_defs.h +++ b/src/nvim/os/unix_defs.h @@ -1,8 +1,8 @@ #ifndef NVIM_OS_UNIX_DEFS_H #define NVIM_OS_UNIX_DEFS_H -#include <unistd.h> #include <sys/param.h> +#include <unistd.h> // POSIX.1-2008 says that NAME_MAX should be in here #include <limits.h> diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h index 66d72de08d..efef77be7b 100644 --- a/src/nvim/os/win_defs.h +++ b/src/nvim/os/win_defs.h @@ -7,11 +7,14 @@ // winsock2.h must be first to avoid incompatibilities // with winsock.h (included by windows.h) + +// uncrustify:off #include <winsock2.h> -#include <windows.h> -#include <sys/stat.h> +// uncrustify:on #include <io.h> #include <stdio.h> +#include <sys/stat.h> +#include <windows.h> // Windows does not have S_IFLNK but libuv defines it // and sets the flag for us when calling uv_fs_stat. diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index eb0ba874f4..046e6dbd12 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1823,7 +1823,7 @@ static int qf_add_entry(qf_list_T *qfl, char_u *dir, char_u *fname, char_u *modu if (type != 1 && !vim_isprintc(type)) { // only printable chars allowed type = 0; } - qfp->qf_type = (char_u)type; + qfp->qf_type = type; qfp->qf_valid = valid; lastp = &qfl->qf_last; diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index e1669a8c19..c47bffd426 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -332,10 +332,10 @@ int do_in_path_and_pp(char_u *path, char_u *name, int flags, DoInRuntimepathCB c return done; } -static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, - char *entry, bool after) +static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, char *entry, + bool after) { - handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string((char *)entry)); + handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string(entry)); if (h == 0) { char *allocated = xstrdup(entry); map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1); @@ -776,7 +776,7 @@ static bool pack_has_entries(char_u *buf) { int num_files; char_u **files; - char_u *(pat[]) = { (char_u *)buf }; + char_u *(pat[]) = { buf }; if (gen_expand_wildcards(1, pat, &num_files, &files, EW_DIR) == OK) { FreeWild(num_files, files); } diff --git a/src/nvim/shada.c b/src/nvim/shada.c index bf245bec51..2610df666b 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -65,26 +65,6 @@ KHASH_SET_INIT_INT64(bufset) KHASH_MAP_INIT_STR(fnamebufs, buf_T *) KHASH_SET_INIT_STR(strset) -#define copy_option_part(src, dest, ...) \ - ((char *)copy_option_part((char_u **)src, (char_u *)dest, __VA_ARGS__)) -#define find_shada_parameter(...) \ - ((const char *)find_shada_parameter(__VA_ARGS__)) -#define home_replace_save(a, b) \ - ((char *)home_replace_save(a, (char_u *)b)) -#define home_replace(a, b, c, d, e) \ - home_replace(a, (char_u *)b, (char_u *)c, d, e) -#define vim_rename(a, b) \ - (vim_rename((char_u *)a, (char_u *)b)) -#define mb_strnicmp(a, b, c) \ - (mb_strnicmp((char_u *)a, (char_u *)b, c)) -#define path_try_shorten_fname(b) \ - ((char *)path_try_shorten_fname((char_u *)b)) -#define buflist_new(ffname, sfname, ...) \ - (buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__)) -#define os_isdir(f) (os_isdir((char_u *)f)) -#define regtilde(s, m) ((char *)regtilde((char_u *)s, m)) -#define path_tail_with_sep(f) ((char *)path_tail_with_sep((char_u *)f)) - #define SEARCH_KEY_MAGIC "sm" #define SEARCH_KEY_SMARTCASE "sc" #define SEARCH_KEY_HAS_LINE_OFFSET "sl" @@ -624,20 +604,6 @@ static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, co } } -/// Iterate over HMLList in backward direction -/// -/// @param hmll Pointer to the list. -/// @param cur_entry Name of the variable to iterate over, must be already -/// defined. -/// @param code Code to execute on each iteration. -/// -/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`). -#define HMLL_ITER_BACK(hmll, cur_entry, code) \ - for (cur_entry = (hmll)->last; cur_entry != NULL; \ - cur_entry = cur_entry->prev) { \ - code \ - } - /// Free linked list /// /// @param[in] hmll List to free. @@ -981,11 +947,12 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry, } } HMLListEntry *insert_after; - HMLL_ITER_BACK(hmll, insert_after, { + // Iterate over HMLList in backward direction + for (insert_after = hmll->last; insert_after != NULL; insert_after = insert_after->prev) { if (insert_after->data.timestamp <= entry.timestamp) { break; } - }) + } hmll_insert(hmll, insert_after, entry, can_free_entry); } @@ -1271,7 +1238,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) // string is close to useless: you can only use it with :& or :~ and // that’s all because s//~ is not available until the first call to // regtilde. Vim was not calling this for some reason. - (void)regtilde(cur_entry.data.sub_string.sub, p_magic); + (void)(char *)regtilde((char_u *)cur_entry.data.sub_string.sub, p_magic); // Do not free shada entry: its allocated memory was saved above. break; case kSDItemHistoryEntry: @@ -1361,9 +1328,11 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) } case kSDItemBufferList: for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) { - char *const sfname = path_try_shorten_fname(cur_entry.data.buffer_list.buffers[i].fname); - buf_T *const buf = buflist_new(cur_entry.data.buffer_list.buffers[i].fname, sfname, 0, - BLN_LISTED); + char *const sfname = + (char *)path_try_shorten_fname((char_u *)cur_entry.data.buffer_list.buffers[i].fname); + buf_T *const buf = + buflist_new((char_u *)cur_entry.data.buffer_list.buffers[i].fname, (char_u *)sfname, 0, + BLN_LISTED); if (buf != NULL) { RESET_FMARK(&buf->b_last_cursor, cur_entry.data.buffer_list.buffers[i].pos, 0); @@ -1502,7 +1471,7 @@ static char *shada_filename(const char *file) if (p_shadafile != NULL && *p_shadafile != NUL) { file = p_shadafile; } else { - if ((file = find_shada_parameter('n')) == NULL || *file == NUL) { + if ((file = (char *)find_shada_parameter('n')) == NULL || *file == NUL) { file = shada_get_default_file(); } // XXX It used to be one level lower, so that whatever is in @@ -1522,14 +1491,6 @@ static char *shada_filename(const char *file) msgpack_pack_str(spacker, sizeof(s) - 1); \ msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \ } while (0) -#define PACK_STRING(s) \ - do { \ - const String s_ = (s); \ - msgpack_pack_str(spacker, s_.size); \ - if (s_.size) { \ - msgpack_pack_str_body(spacker, s_.data, s_.size); \ - } \ - } while (0) #define PACK_BIN(s) \ do { \ const String s_ = (s); \ @@ -1810,7 +1771,11 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, ShadaEntr case kSDItemHeader: msgpack_pack_map(spacker, entry.data.header.size); for (size_t i = 0; i < entry.data.header.size; i++) { - PACK_STRING(entry.data.header.items[i].key); + const String s = entry.data.header.items[i].key; + msgpack_pack_str(spacker, s.size); + if (s.size) { + msgpack_pack_str_body(spacker, s.data, s.size); + } const Object obj = entry.data.header.items[i].value; switch (obj.type) { case kObjectTypeString: @@ -1856,7 +1821,6 @@ shada_pack_entry_error: msgpack_sbuffer_destroy(&sbuf); return ret; } -#undef PACK_STRING /// Write single ShaDa entry and free it afterwards /// @@ -2437,7 +2401,7 @@ static inline void shada_initialize_registers(WriteMergerState *const wms, int m .data = { .reg = { .contents = (char **)reg.y_array, - .contents_size = (size_t)reg.y_size, + .contents_size = reg.y_size, .type = reg.y_type, .width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0), .additional_data = reg.additional_data, @@ -2694,7 +2658,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef .timestamp = sub.timestamp, .data = { .sub_string = { - .sub = (char *)sub.sub, + .sub = sub.sub, .additional_elements = sub.additional_elements, } } @@ -2957,7 +2921,6 @@ shada_write_exit: return ret; } -#undef IGNORE_BUF #undef PACK_STATIC_STR /// Write ShaDa file to a given location @@ -3037,11 +3000,11 @@ shada_write_file_open: {} } if (nomerge) { shada_write_file_nomerge: {} - char *const tail = path_tail_with_sep(fname); + char *const tail = (char *)path_tail_with_sep((char_u *)fname); if (tail != fname) { const char tail_save = *tail; *tail = NUL; - if (!os_isdir(fname)) { + if (!os_isdir((char_u *)fname)) { int ret; char *failed_dir; if ((ret = os_mkdir_recurse(fname, 0700, &failed_dir)) != 0) { @@ -3092,7 +3055,7 @@ shada_write_file_nomerge: {} // overwrite a user’s viminfo file after a "su root", with a // viminfo file that the user can't read. FileInfo old_info; - if (os_fileinfo((char *)fname, &old_info)) { + if (os_fileinfo(fname, &old_info)) { if (getuid() == ROOT_UID) { if (old_info.stat.st_uid != ROOT_UID || old_info.stat.st_gid != getgid()) { @@ -3116,7 +3079,7 @@ shada_write_file_nomerge: {} } } #endif - if (vim_rename(tempname, fname) == -1) { + if (vim_rename((char_u *)tempname, (char_u *)fname) == -1) { EMSG3(_(RNERR "Can't rename ShaDa file from %s to %s!"), tempname, fname); } else { @@ -3424,8 +3387,7 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, const sizeof(*un.data.via.map.ptr)); \ ad_ga.ga_len++; \ } -#define CONVERTED(str, len) (xmemdupz((str), (len))) -#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size) +#define BIN_CONVERTED(b) (xmemdupz((b.ptr), (b.size))) #define SET_ADDITIONAL_DATA(tgt, name) \ do { \ if (ad_ga.ga_len) { \ @@ -3982,7 +3944,6 @@ shada_read_next_item_error: goto shada_read_next_item_end; } #undef BIN_CONVERTED -#undef CONVERTED #undef CHECK_KEY #undef BOOLEAN_KEY #undef CONVERTED_STRING_KEY @@ -4015,13 +3976,13 @@ static bool shada_removable(const char *name) char part[MAXPATHL + 1]; bool retval = false; - char *new_name = home_replace_save(NULL, name); + char *new_name = (char *)home_replace_save(NULL, (char_u *)name); for (p = (char *)p_shada; *p; ) { - (void)copy_option_part(&p, part, ARRAY_SIZE(part), ", "); + (void)(char *)copy_option_part((char_u **)&p, (char_u *)part, ARRAY_SIZE(part), ", "); if (part[0] == 'r') { - home_replace(NULL, part + 1, NameBuff, MAXPATHL, true); + home_replace(NULL, (char_u *)(part + 1), (char_u *)NameBuff, MAXPATHL, true); size_t n = STRLEN(NameBuff); - if (mb_strnicmp(NameBuff, new_name, n) == 0) { + if (mb_strnicmp((char_u *)NameBuff, (char_u *)new_name, n) == 0) { retval = true; break; } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 3e56ad561b..9ed421c8a0 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2924,8 +2924,8 @@ void spell_suggest(int count) // Get the list of suggestions. Limit to 'lines' - 2 or the number in // 'spellsuggest', whatever is smaller. - if (sps_limit > (int)Rows - 2) { - limit = (int)Rows - 2; + if (sps_limit > Rows - 2) { + limit = Rows - 2; } else { limit = sps_limit; } @@ -6073,7 +6073,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) wordlen = 0; for (const char_u *s = inword; *s != NUL; ) { const char_u *t = s; - c = mb_cptr2char_adv((const char_u **)&s); + c = mb_cptr2char_adv(&s); if (slang->sl_rem_accents) { if (utf_class(c) == 0) { if (did_white) { diff --git a/src/nvim/state.c b/src/nvim/state.c index 04271d750c..4eb0073873 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -195,6 +195,8 @@ char *get_mode(void) || restart_edit == 'V') { buf[1] = 'i'; buf[2] = (char)restart_edit; + } else if (curbuf->terminal) { + buf[1] = 't'; } } diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index d2c94d9fe8..49f54dcfe1 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6217,6 +6217,26 @@ static const char *highlight_init_both[] = { "default link Delimiter Special", "default link SpecialComment Special", "default link Debug Special", + "default DiagnosticError ctermfg=1 guifg=Red", + "default DiagnosticWarn ctermfg=3 guifg=Orange", + "default DiagnosticInfo ctermfg=4 guifg=LightBlue", + "default DiagnosticHint ctermfg=7 guifg=LightGrey", + "default DiagnosticUnderlineError cterm=underline gui=underline guisp=Red", + "default DiagnosticUnderlineWarn cterm=underline gui=underline guisp=Orange", + "default DiagnosticUnderlineInfo cterm=underline gui=underline guisp=LightBlue", + "default DiagnosticUnderlineHint cterm=underline gui=underline guisp=LightGrey", + "default link DiagnosticVirtualTextError DiagnosticError", + "default link DiagnosticVirtualTextWarn DiagnosticWarn", + "default link DiagnosticVirtualTextInfo DiagnosticInfo", + "default link DiagnosticVirtualTextHint DiagnosticHint", + "default link DiagnosticFloatingError DiagnosticError", + "default link DiagnosticFloatingWarn DiagnosticWarn", + "default link DiagnosticFloatingInfo DiagnosticInfo", + "default link DiagnosticFloatingHint DiagnosticHint", + "default link DiagnosticSignError DiagnosticError", + "default link DiagnosticSignWarn DiagnosticWarn", + "default link DiagnosticSignInfo DiagnosticInfo", + "default link DiagnosticSignHint DiagnosticHint", NULL }; diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 6f19a9209e..fb025265f2 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -358,11 +358,21 @@ void terminal_enter(void) // Disable these options in terminal-mode. They are nonsense because cursor is // placed at end of buffer to "follow" output. #11072 win_T *save_curwin = curwin; - int save_w_p_cul = curwin->w_p_cul; + bool save_w_p_cul = curwin->w_p_cul; + char_u *save_w_p_culopt = NULL; + char_u save_w_p_culopt_flags = curwin->w_p_culopt_flags; int save_w_p_cuc = curwin->w_p_cuc; long save_w_p_so = curwin->w_p_so; long save_w_p_siso = curwin->w_p_siso; - curwin->w_p_cul = false; + if (curwin->w_p_cul && curwin->w_p_culopt_flags & CULOPT_NBR) { + if (strcmp((char *)curwin->w_p_culopt, "number")) { + save_w_p_culopt = curwin->w_p_culopt; + curwin->w_p_culopt = (char_u *)xstrdup("number"); + } + curwin->w_p_culopt_flags = CULOPT_NBR; + } else { + curwin->w_p_cul = false; + } curwin->w_p_cuc = false; curwin->w_p_so = 0; curwin->w_p_siso = 0; @@ -386,9 +396,16 @@ void terminal_enter(void) if (save_curwin == curwin) { // save_curwin may be invalid (window closed)! curwin->w_p_cul = save_w_p_cul; + if (save_w_p_culopt) { + xfree(curwin->w_p_culopt); + curwin->w_p_culopt = save_w_p_culopt; + } + curwin->w_p_culopt_flags = save_w_p_culopt_flags; curwin->w_p_cuc = save_w_p_cuc; curwin->w_p_so = save_w_p_so; curwin->w_p_siso = save_w_p_siso; + } else if (save_w_p_culopt) { + xfree(save_w_p_culopt); } // draw the unfocused cursor @@ -1224,7 +1241,7 @@ static bool send_mouse_event(Terminal *term, int c) mouse_action(term, button, row, col - offset, drag, 0); size_t len = vterm_output_read(term->vt, term->textbuf, sizeof(term->textbuf)); - terminal_send(term, term->textbuf, (size_t)len); + terminal_send(term, term->textbuf, len); return false; } diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 9eb64f68ef..52e6ba64cc 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -259,7 +259,7 @@ let s:filename_checks = { \ 'jgraph': ['file.jgr'], \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'], \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'], - \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'], + \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb', '.babelrc', '.eslintrc', '.prettierrc', '.firebaserc'], \ 'jsonc': ['file.jsonc'], \ 'jsp': ['file.jsp'], \ 'julia': ['file.jl'], @@ -492,7 +492,7 @@ let s:filename_checks = { \ 'tak': ['file.tak'], \ 'taskdata': ['pending.data', 'completed.data', 'undo.data'], \ 'taskedit': ['file.task'], - \ 'tcl': ['file.tcl', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl'], + \ 'tcl': ['file.tcl', 'file.tm', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl', '.tclshrc', 'tclsh.rc', '.wishrc'], \ 'teraterm': ['file.ttl'], \ 'terminfo': ['file.ti'], \ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'], @@ -554,6 +554,7 @@ let s:filename_checks = { \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl', 'file.wpl', 'any/etc/blkid.tab', 'any/etc/blkid.tab.old', 'any/etc/xdg/menus/file.menu'], \ 'xmodmap': ['anyXmodmap', 'Xmodmap', 'some-Xmodmap', 'some-xmodmap', 'some-xmodmap-file', 'xmodmap', 'xmodmap-file'], \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'], + \ 'xpm': ['file.xpm'], \ 'xpm2': ['file.xpm2'], \ 'xquery': ['file.xq', 'file.xql', 'file.xqm', 'file.xquery', 'file.xqy'], \ 'xs': ['file.xs'], @@ -568,7 +569,6 @@ let s:filename_checks = { \ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file', 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'], \ \ 'help': [$VIMRUNTIME . '/doc/help.txt'], - \ 'xpm': ['file.xpm'], \ } let s:filename_case_checks = { @@ -918,4 +918,17 @@ func Test_m_file() call delete('Xfile.m') filetype off endfunc + +func Test_xpm_file() + filetype on + + call writefile(['this is XPM2'], 'file.xpm') + split file.xpm + call assert_equal('xpm2', &filetype) + bwipe! + + call delete('file.xpm') + filetype off +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index a80c3e9bf2..a0e9f780c6 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -711,6 +711,14 @@ func Test_mode() call assert_equal('c-cv', g:current_modes) " How to test Ex mode? + if has('terminal') + term + call feedkeys("\<C-W>N", 'xt') + call assert_equal('n', mode()) + call assert_equal('nt', mode(1)) + call feedkeys("aexit\<CR>", 'xt') + endif + bwipe! iunmap <F2> xunmap <F2> diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim index d34448e09e..cdf688b857 100644 --- a/src/nvim/testdir/test_method.vim +++ b/src/nvim/testdir/test_method.vim @@ -1,5 +1,7 @@ " Tests for ->method() +source check.vim + func Test_list_method() let l = [1, 2, 3] call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4)) @@ -118,6 +120,7 @@ func Test_method_funcref() endfunc func Test_method_float() + CheckFeature float eval 1.234->string()->assert_equal('1.234') eval -1.234->string()->assert_equal('-1.234') endfunc diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index ed76455189..2a8ea32a88 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -2,8 +2,8 @@ #define NVIM_TUI_INPUT_H #include <stdbool.h> - #include <termkey.h> + #include "nvim/event/stream.h" #include "nvim/event/time.h" diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h index 8d77dc7225..8c328496c1 100644 --- a/src/nvim/tui/terminfo_defs.h +++ b/src/nvim/tui/terminfo_defs.h @@ -1,6 +1,8 @@ // 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 +// uncrustify:off + // // Generated by scripts/update_terminfo.sh and ncurses 6.1.20180127 // @@ -2274,3 +2276,6 @@ static const int8_t xterm_256colour_terminfo[] = { 30,2,37,0,38,0,15,0,-99,1,2,6,120,116,101,114,109,45,50,53,54,99,111,108,111,114,124,120,116,101,114,109,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,102,0,-1,-1,106,0,110,0,120,0,124,0,-1,-1,-1,-1,-128,0,-124,0,-119,0,-114,0,-1,-1,-96,0,-91,0,-86,0,-1,-1,-81,0,-76,0,-71,0,-66,0,-57,0,-53,0,-46,0,-1,-1,-28,0,-23,0,-17,0,-11,0,-1,-1,-1,-1,-1,-1,7,1,-1,-1,-1,-1,-1,-1,25,1,-1,-1,29,1,-1,-1,-1,-1,-1,-1,31,1,-1,-1,36,1,-1,-1,-1,-1,-1,-1,-1,-1,40,1,44,1,50,1,54,1,58,1,62,1,68,1,74,1,80,1,86,1,92,1,96,1,-1,-1,101,1,-1,-1,105,1,110,1,115,1,119,1,126,1,-1,-1,-123,1,-119,1,-111,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-103,1,-94,1,-1,-1,-1,-1,-85,1,-76,1,-67,1,-58,1,-49,1,-40,1,-31,1,-22,1,-13,1,-4,1,-1,-1,-1,-1,-1,-1,5,2,9,2,14,2,19,2,39,2,48,2,-1,-1,-1,-1,66,2,69,2,80,2,83,2,85,2,88,2,-75,2,-1,-1,-72,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-70,2,-1,-1,-1,-1,-1,-1,-1,-1,-66,2,-1,-1,-13,2,-1,-1,-1,-1,-9,2,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,3,7,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,3,-1,-1,-1,-1,18,3,-1,-1,-1,-1,-1,-1,-1,-1,25,3,32,3,39,3,-1,-1,-1,-1,46,3,-1,-1,53,3,-1,-1,-1,-1,-1,-1,60,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,67,3,73,3,79,3,86,3,93,3,100,3,107,3,115,3,123,3,-125,3,-117,3,-109,3,-101,3,-93,3,-85,3,-78,3,-71,3,-64,3,-57,3,-49,3,-41,3,-33,3,-25,3,-17,3,-9,3,-1,3,7,4,14,4,21,4,28,4,35,4,43,4,51,4,59,4,67,4,75,4,83,4,91,4,99,4,106,4,113,4,120,4,127,4,-121,4,-113,4,-105,4,-97,4,-89,4,-81,4,-73,4,-65,4,-58,4,-51,4,-44,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-39,4,-28,4,-23,4,-4,4,0,5,9,5,16,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,110,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,115,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,121,5,-1,-1,-1,-1,-1,-1,125,5,-68,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-4,5,-1,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,63,49,50,59,50,53,104,0,27,91,80,0,27,91,77,0,27,40,48,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,27,91,50,50,59,48,59,48,116,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,40,66,27,91,109,0,27,91,63,49,48,52,57,108,27,91,50,51,59,48,59,48,116,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,63,49,48,51,52,108,0,27,91,63,49,48,51,52,104,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,105,0,27,91,52,105,0,27,91,53,105,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,99,27,93,49,48,52,7,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,37,63,37,112,57,37,116,27,40,48,37,101,27,40,66,37,59,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,55,37,116,59,56,37,59,109,0,27,72,0,9,0,27,79,69,0,96,96,97,97,102,102,103,103,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,79,70,0,27,79,77,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,51,109,0,27,91,50,51,109,0,27,91,60,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,108,0,27,109,0,3,0,1,0,73,0,-106,0,115,3,1,0,1,0,-1,-1,-1,-1,0,0,7,0,-1,-1,19,0,24,0,-1,-1,42,0,48,0,-1,-1,58,0,-1,-1,-1,-1,90,0,97,0,104,0,111,0,118,0,125,0,-124,0,-117,0,-110,0,-103,0,-96,0,-89,0,-82,0,-75,0,-68,0,-61,0,-1,-1,-54,0,-47,0,-40,0,-33,0,-26,0,-1,-1,-19,0,-12,0,-5,0,2,1,9,1,16,1,23,1,30,1,37,1,44,1,51,1,58,1,65,1,72,1,79,1,86,1,93,1,100,1,107,1,114,1,121,1,-128,1,-121,1,-114,1,-107,1,-100,1,-93,1,-86,1,-79,1,-72,1,-65,1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-52,1,-47,1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,93,49,49,50,7,0,27,93,49,50,59,37,112,49,37,115,7,0,27,91,51,74,0,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,91,63,49,48,48,54,59,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,27,91,60,37,112,49,37,100,59,37,112,50,37,100,59,37,112,51,37,100,59,37,63,37,112,52,37,116,77,37,101,109,37,59,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT }; #endif // NVIM_TUI_TERMINFO_DEFS_H + +// uncrustify:on + diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 803ff23cea..612eaf6667 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1019,22 +1019,8 @@ static void tui_mouse_on(UI *ui) { TUIData *data = ui->data; if (!data->mouse_enabled) { -#ifdef WIN32 - // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of - // libuv. For this reason, vtp (vterm) state of libuv is temporarily - // disabled because the control sequence needs to be processed by libuv - // instead of Windows vtp. - // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode - flush_buf(ui); - os_set_vtp(false); -#endif unibi_out_ext(ui, data->unibi_ext.enable_mouse); data->mouse_enabled = true; -#ifdef WIN32 - flush_buf(ui); - os_set_vtp(true); -#endif } } @@ -1042,22 +1028,8 @@ static void tui_mouse_off(UI *ui) { TUIData *data = ui->data; if (data->mouse_enabled) { -#ifdef WIN32 - // Windows versions with vtp(ENABLE_VIRTUAL_TERMINAL_PROCESSING) and - // no vti(ENABLE_VIRTUAL_TERMINAL_INPUT) will need to use mouse tracking of - // libuv. For this reason, vtp (vterm) state of libuv is temporarily - // disabled because the control sequence needs to be processed by libuv - // instead of Windows vtp. - // ref. https://docs.microsoft.com/en-us/windows/console/setconsolemode - flush_buf(ui); - os_set_vtp(false); -#endif unibi_out_ext(ui, data->unibi_ext.disable_mouse); data->mouse_enabled = false; -#ifdef WIN32 - flush_buf(ui); - os_set_vtp(true); -#endif } } diff --git a/src/nvim/undo.c b/src/nvim/undo.c index af214815f8..500845ec72 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1407,7 +1407,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT FileInfo file_info_orig; FileInfo file_info_undo; if (os_fileinfo((const char *)orig_name, &file_info_orig) - && os_fileinfo((char *)file_name, &file_info_undo) + && os_fileinfo(file_name, &file_info_undo) && file_info_orig.stat.st_uid != file_info_undo.stat.st_uid && file_info_undo.stat.st_uid != getuid()) { if (p_verbose > 0) { @@ -1420,7 +1420,7 @@ void u_read_undo(char *name, const char_u *hash, const char_u *orig_name FUNC_AT } #endif } else { - file_name = (char *)name; + file_name = name; } if (p_verbose > 0) { @@ -3085,6 +3085,8 @@ void u_undoline(void) oldp = u_save_line(curbuf->b_u_line_lnum); ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true); changed_bytes(curbuf->b_u_line_lnum, 0); + extmark_splice_cols(curbuf, (int)curbuf->b_u_line_lnum-1, 0, (colnr_T)STRLEN(oldp), + (colnr_T)STRLEN(curbuf->b_u_line_ptr), kExtmarkUndo); xfree(curbuf->b_u_line_ptr); curbuf->b_u_line_ptr = oldp; diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h index 838a742271..325df643e7 100644 --- a/src/nvim/viml/parser/expressions.h +++ b/src/nvim/viml/parser/expressions.h @@ -1,13 +1,13 @@ #ifndef NVIM_VIML_PARSER_EXPRESSIONS_H #define NVIM_VIML_PARSER_EXPRESSIONS_H +#include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include <stdbool.h> +#include "nvim/eval/typval.h" #include "nvim/types.h" #include "nvim/viml/parser/parser.h" -#include "nvim/eval/typval.h" // Defines whether to ignore case: // == kCCStrategyUseOption @@ -80,7 +80,7 @@ typedef enum { } ExprAssignmentType; #define EXPR_OPT_SCOPE_LIST \ - ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) + ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal }) /// All possible variable scopes typedef enum { @@ -96,11 +96,11 @@ typedef enum { } ExprVarScope; #define EXPR_VAR_SCOPE_LIST \ - ((char[]) { \ - kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ - kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ - kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ - }) + ((char[]) { \ + kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \ + kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \ + kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \ + }) /// Lexer token typedef struct { diff --git a/src/nvim/viml/parser/parser.h b/src/nvim/viml/parser/parser.h index 7ac49709d8..b2933c3781 100644 --- a/src/nvim/viml/parser/parser.h +++ b/src/nvim/viml/parser/parser.h @@ -1,12 +1,12 @@ #ifndef NVIM_VIML_PARSER_PARSER_H #define NVIM_VIML_PARSER_PARSER_H +#include <assert.h> #include <stdbool.h> #include <stddef.h> -#include <assert.h> -#include "nvim/lib/kvec.h" #include "nvim/func_attr.h" +#include "nvim/lib/kvec.h" #include "nvim/mbyte.h" #include "nvim/memory.h" @@ -82,9 +82,9 @@ typedef struct { } ParserState; static inline void viml_parser_init( - ParserState *const ret_pstate, - const ParserLineGetter get_line, void *const cookie, - ParserHighlight *const colors) + ParserState *const ret_pstate, + const ParserLineGetter get_line, void *const cookie, + ParserHighlight *const colors) REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1, 2); /// Initialize a new parser state instance @@ -94,10 +94,8 @@ static inline void viml_parser_init( /// @param[in] cookie Argument for the get_line function. /// @param[in] colors Where to save highlighting. May be NULL if it is not /// needed. -static inline void viml_parser_init( - ParserState *const ret_pstate, - const ParserLineGetter get_line, void *const cookie, - ParserHighlight *const colors) +static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line, + void *const cookie, ParserHighlight *const colors) { *ret_pstate = (ParserState) { .reader = { @@ -194,8 +192,7 @@ static inline void viml_parser_advance(ParserState *const pstate, /// /// @param pstate Parser state to advance. /// @param[in] len Number of bytes to advance. -static inline void viml_parser_advance(ParserState *const pstate, - const size_t len) +static inline void viml_parser_advance(ParserState *const pstate, const size_t len) { assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1); const ParserLine pline = kv_last(pstate->reader.lines); @@ -219,10 +216,8 @@ static inline void viml_parser_highlight(ParserState *const pstate, /// @param[in] start Start position of the highlight. /// @param[in] len Highlighting chunk length. /// @param[in] group Highlight group. -static inline void viml_parser_highlight(ParserState *const pstate, - const ParserPosition start, - const size_t len, - const char *const group) +static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start, + const size_t len, const char *const group) { if (pstate->colors == NULL || len == 0) { return; @@ -231,9 +226,9 @@ static inline void viml_parser_highlight(ParserState *const pstate, || kv_Z(*pstate->colors, 0).start.line < start.line || kv_Z(*pstate->colors, 0).end_col <= start.col); kvi_push(*pstate->colors, ((ParserHighlightChunk) { - .start = start, - .end_col = start.col + len, - .group = group, + .start = start, + .end_col = start.col + len, + .group = group, })); } diff --git a/src/uncrustify.cfg b/src/uncrustify.cfg index db0c50ff22..0e1e1de87f 100644 --- a/src/uncrustify.cfg +++ b/src/uncrustify.cfg @@ -1,4 +1,4 @@ -# Uncrustify-0.73.0-195-1f883c691 +# Uncrustify-0.73.0-199-0dfafb273 # # General options @@ -44,12 +44,12 @@ disable_processing_nl_cont = false # true/false # file. # # Default: *INDENT-OFF* -disable_processing_cmt = "uncrustify:indent-off" # string +disable_processing_cmt = "uncrustify:off" # string # Specify the marker used in comments to (re)enable processing in a file. # # Default: *INDENT-ON* -enable_processing_cmt = "uncrustify:indent-on" # string +enable_processing_cmt = "uncrustify:on" # string # Enable parsing of digraphs. enable_digraphs = false # true/false @@ -472,9 +472,13 @@ sp_after_class_colon = ignore # ignore/add/remove/force/not_defined sp_before_class_colon = ignore # ignore/add/remove/force/not_defined # Add or remove space after class constructor ':'. +# +# Default: add sp_after_constr_colon = ignore # ignore/add/remove/force/not_defined # Add or remove space before class constructor ':'. +# +# Default: add sp_before_constr_colon = ignore # ignore/add/remove/force/not_defined # Add or remove space before case ':'. @@ -1103,11 +1107,16 @@ indent_class_on_colon = false # true/false # Whether to indent the stuff after a leading class initializer colon. indent_constr_colon = false # true/false -# Virtual indent from the ':' for member initializers. +# Virtual indent from the ':' for leading member initializers. # # Default: 2 indent_ctor_init_leading = 2 # unsigned number +# Virtual indent from the ':' for following member initializers. +# +# Default: 2 +indent_ctor_init_following = 2 # unsigned number + # Additional indent for constructor initializer list. # Negative values decrease indent down to the first column. indent_ctor_init = 0 # number @@ -3298,5 +3307,5 @@ set QUESTION REAL_FATTR_CONST set QUESTION REAL_FATTR_NONNULL_ALL set QUESTION REAL_FATTR_PURE set QUESTION REAL_FATTR_WARN_UNUSED_RESULT -# option(s) with 'not default' value: 62 +# option(s) with 'not default' value: 64 # diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua index 81fad206da..01fcfab543 100644 --- a/test/functional/api/buffer_spec.lua +++ b/test/functional/api/buffer_spec.lua @@ -707,4 +707,59 @@ describe('api/buf', function() eq({3, 0}, curbuf('get_mark', 'v')) end) end) + + describe('nvim_buf_set_mark', function() + it('works with buffer local marks', function() + curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) + eq(true, curbufmeths.set_mark('z', 1, 1)) + eq({1, 1}, curbufmeths.get_mark('z')) + end) + it('works with file/uppercase marks', function() + curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) + eq(true, curbufmeths.set_mark('Z', 3, 1)) + eq({3, 1}, curbufmeths.get_mark('Z')) + end) + it('fails when invalid marks names are used', function() + eq(false, pcall(curbufmeths.set_mark, '!', 1, 0)) + eq(false, pcall(curbufmeths.set_mark, 'fail', 1, 0)) + end) + it('fails when invalid buffer number is used', function() + eq(false, pcall(meths.buf_set_mark, 99, 'a', 1, 1)) + end) + end) + + describe('nvim_buf_del_mark', function() + it('works with buffer local marks', function() + curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) + curbufmeths.set_mark('z', 3, 1) + eq(true, curbufmeths.del_mark('z')) + eq({0, 0}, curbufmeths.get_mark('z')) + end) + it('works with file/uppercase marks', function() + curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) + curbufmeths.set_mark('Z', 3, 3) + eq(true, curbufmeths.del_mark('Z')) + eq({0, 0}, curbufmeths.get_mark('Z')) + end) + it('returns false in marks not set in this buffer', function() + local abuf = meths.create_buf(false,true) + bufmeths.set_lines(abuf, -1, -1, true, {'a', 'bit of', 'text'}) + bufmeths.set_mark(abuf, 'A', 2, 2) + eq(false, curbufmeths.del_mark('A')) + eq({2, 2}, bufmeths.get_mark(abuf, 'A')) + end) + it('returns false if mark was not deleted', function() + curbufmeths.set_lines(-1, -1, true, {'a', 'bit of', 'text'}) + curbufmeths.set_mark('z', 3, 1) + eq(true, curbufmeths.del_mark('z')) + eq(false, curbufmeths.del_mark('z')) -- Mark was already deleted + end) + it('fails when invalid marks names are used', function() + eq(false, pcall(curbufmeths.del_mark, '!')) + eq(false, pcall(curbufmeths.del_mark, 'fail')) + end) + it('fails when invalid buffer number is used', function() + eq(false, pcall(meths.buf_del_mark, 99, 'a')) + end) + end) end) diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 6bcf8dd91f..6b644ed519 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -2267,4 +2267,59 @@ describe('API', function() ]]} end) end) + + describe('nvim_del_mark', function() + it('works', function() + local buf = meths.create_buf(false,true) + meths.buf_set_lines(buf, -1, -1, true, {'a', 'bit of', 'text'}) + eq(true, meths.buf_set_mark(buf, 'F', 2, 2)) + eq(true, meths.del_mark('F')) + eq({0, 0}, meths.buf_get_mark(buf, 'F')) + end) + it('fails when invalid marks are used', function() + eq(false, pcall(meths.del_mark, 'f')) + eq(false, pcall(meths.del_mark, '!')) + eq(false, pcall(meths.del_mark, 'fail')) + end) + end) + describe('nvim_get_mark', function() + it('works', function() + local buf = meths.create_buf(false,true) + meths.buf_set_lines(buf, -1, -1, true, {'a', 'bit of', 'text'}) + meths.buf_set_mark(buf, 'F', 2, 2) + meths.buf_set_name(buf, "mybuf") + local mark = meths.get_mark('F') + -- Compare the path tail ony + assert(string.find(mark[4], "mybuf$")) + eq({2, 2, buf.id, mark[4]}, mark) + end) + it('fails when invalid marks are used', function() + eq(false, pcall(meths.del_mark, 'f')) + eq(false, pcall(meths.del_mark, '!')) + eq(false, pcall(meths.del_mark, 'fail')) + end) + it('returns the expected when mark is not set', function() + eq(true, meths.del_mark('A')) + eq({0, 0, 0, ''}, meths.get_mark('A')) + end) + it('works with deleted buffers', function() + local fname = tmpname() + write_file(fname, 'a\nbit of\text') + nvim("command", "edit " .. fname) + local buf = meths.get_current_buf() + + meths.buf_set_mark(buf, 'F', 2, 2) + nvim("command", "new") -- Create new buf to avoid :bd failing + nvim("command", "bd! " .. buf.id) + os.remove(fname) + + local mark = meths.get_mark('F') + -- To avoid comparing relative vs absolute path + local mfname = mark[4] + local tail_patt = [[[\/][^\/]*$]] + -- tail of paths should be equals + eq(fname:match(tail_patt), mfname:match(tail_patt)) + eq({2, 2, buf.id, mark[4]}, mark) + end) + end) end) diff --git a/test/functional/fixtures/autoload/health/full_render.vim b/test/functional/fixtures/autoload/health/full_render.vim new file mode 100644 index 0000000000..2064b8606e --- /dev/null +++ b/test/functional/fixtures/autoload/health/full_render.vim @@ -0,0 +1,8 @@ +function! health#full_render#check() + call health#report_start("report 1") + call health#report_ok("life is fine") + call health#report_warn("no what installed", ["pip what", "make what"]) + call health#report_start("report 2") + call health#report_info("stuff is stable") + call health#report_error("why no hardcopy", [":h :hardcopy", ":h :TOhtml"]) +endfunction diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index 8e03d9a46e..9abf478070 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -246,6 +246,35 @@ function tests.capabilities_for_client_supports_method() } end +function tests.check_forward_request_cancelled() + skeleton { + on_init = function(_) + return { capabilities = {} } + end; + body = function() + expect_request("error_code_test", function() + return {code = -32800}, nil, {method = "error_code_test", client_id=1} + end) + notify('finish') + end; + } +end + +function tests.check_forward_content_modified() + skeleton { + on_init = function(_) + return { capabilities = {} } + end; + body = function() + expect_request("error_code_test", function() + return {code = -32801}, nil, {method = "error_code_test", client_id=1} + end) + expect_notification('finish') + notify('finish') + end; + } +end + function tests.basic_finish() skeleton { on_init = function(params) diff --git a/test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim b/test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim new file mode 100644 index 0000000000..de05f56e9e --- /dev/null +++ b/test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim @@ -0,0 +1,3 @@ +function! health#success1#check() + call health#report_start("If you see this I'm broken") +endfunction diff --git a/test/functional/fixtures/lua/test_plug/health/init.lua b/test/functional/fixtures/lua/test_plug/health/init.lua new file mode 100644 index 0000000000..d07632cff4 --- /dev/null +++ b/test/functional/fixtures/lua/test_plug/health/init.lua @@ -0,0 +1,11 @@ +local M = {} +local health = require("health") + +M.check = function() + health.report_start("report 1") + health.report_ok("everything is fine") + health.report_start("report 2") + health.report_ok("nothing to see here") +end + +return M diff --git a/test/functional/fixtures/lua/test_plug/submodule/health.lua b/test/functional/fixtures/lua/test_plug/submodule/health.lua new file mode 100644 index 0000000000..d07632cff4 --- /dev/null +++ b/test/functional/fixtures/lua/test_plug/submodule/health.lua @@ -0,0 +1,11 @@ +local M = {} +local health = require("health") + +M.check = function() + health.report_start("report 1") + health.report_ok("everything is fine") + health.report_start("report 2") + health.report_ok("nothing to see here") +end + +return M diff --git a/test/functional/fixtures/lua/test_plug/submodule_failed/health.lua b/test/functional/fixtures/lua/test_plug/submodule_failed/health.lua new file mode 100644 index 0000000000..3a8af6ebb2 --- /dev/null +++ b/test/functional/fixtures/lua/test_plug/submodule_failed/health.lua @@ -0,0 +1,12 @@ +local M = {} +local health = require("health") + +M.check = function() + health.report_start("report 1") + health.report_ok("everything is fine") + health.report_warn("About to add a number to nil") + local a = nil + 2 + return a +end + +return M diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua index fdf79d55b2..8551c3d2a0 100644 --- a/test/functional/lua/api_spec.lua +++ b/test/functional/lua/api_spec.lua @@ -194,6 +194,10 @@ describe('luaeval(vim.api.…)', function() exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]])) eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type', exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]])) + + eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table', + exc_exec([[call luaeval("vim.api.nvim_set_keymap('', '', '', '')")]])) + -- TODO: check for errors with Tabpage argument -- TODO: check for errors with Window argument -- TODO: check for errors with Buffer argument diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 073927bf22..c83a50b78b 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -1050,6 +1050,102 @@ describe('lua: nvim_buf_attach on_bytes', function() } end) + it("sends updates on U", function() + feed("ggiAAA<cr>BBB") + feed("<esc>gg$a CCC") + + local check_events = setup_eventcheck(verify, nil) + + feed("ggU") + + check_events { + { "test1", "bytes", 1, 6, 0, 7, 7, 0, 0, 0, 0, 3, 3 }; + } + end) + + it("delete in completely empty buffer", function() + local check_events = setup_eventcheck(verify, nil) + + command "delete" + check_events { } + end) + + it("delete the only line of a buffer", function() + local check_events = setup_eventcheck(verify, {"AAA"}) + + command "delete" + check_events { + { "test1", "bytes", 1, 3, 0, 0, 0, 1, 0, 4, 1, 0, 1 }; + } + end) + + it("delete the last line of a buffer with two lines", function() + local check_events = setup_eventcheck(verify, {"AAA", "BBB"}) + + command "2delete" + check_events { + { "test1", "bytes", 1, 3, 1, 0, 4, 1, 0, 4, 0, 0, 0 }; + } + end) + + it(":sort lines", function() + local check_events = setup_eventcheck(verify, {"CCC", "BBB", "AAA"}) + + command "%sort" + check_events { + { "test1", "bytes", 1, 3, 0, 0, 0, 3, 0, 12, 3, 0, 12 }; + } + end) + + it("handles already sorted lines", function() + local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"}) + + command "%sort" + check_events { } + end) + + local function test_lockmarks(mode) + local description = (mode ~= "") and mode or "(baseline)" + it("test_lockmarks " .. description .. " %delete _", function() + local check_events = setup_eventcheck(verify, {"AAA", "BBB", "CCC"}) + + command(mode .. " %delete _") + check_events { + { "test1", "bytes", 1, 3, 0, 0, 0, 3, 0, 12, 1, 0, 1 }; + } + end) + + it("test_lockmarks " .. description .. " append()", function() + local check_events = setup_eventcheck(verify) + + command(mode .. " call append(0, 'CCC')") + check_events { + { "test1", "bytes", 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 4 }; + } + + command(mode .. " call append(1, 'BBBB')") + check_events { + { "test1", "bytes", 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 5 }; + } + + command(mode .. " call append(2, '')") + check_events { + { "test1", "bytes", 1, 4, 2, 0, 9, 0, 0, 0, 1, 0, 1 }; + } + + command(mode .. " $delete _") + check_events { + { "test1", "bytes", 1, 5, 3, 0, 10, 1, 0, 1, 0, 0, 0 }; + } + + eq("CCC|BBBB|", table.concat(meths.buf_get_lines(0, 0, -1, true), "|")) + end) + end + + -- check that behavior is identical with and without "lockmarks" + test_lockmarks "" + test_lockmarks "lockmarks" + teardown(function() os.remove "Xtest-reload" os.remove "Xtest-undofile" diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index 45aa4915cd..a08c8d8681 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -1013,6 +1013,44 @@ describe('vim.diagnostic', function() return lines ]]) end) + + it('respects severity_sort', function() + exec_lua [[vim.api.nvim_win_set_buf(0, diagnostic_bufnr)]] + + eq({"1. Syntax error", "2. Info", "3. Error", "4. Warning"}, exec_lua [[ + local diagnostics = { + make_error("Syntax error", 0, 1, 0, 3), + make_info('Info', 0, 3, 0, 4), + make_error('Error', 0, 2, 0, 2), + make_warning('Warning', 0, 0, 0, 1), + } + + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics) + + vim.diagnostic.config({severity_sort = false}) + + local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics { show_header = false } + local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) + + eq({"1. Syntax error", "2. Error", "3. Warning", "4. Info"}, exec_lua [[ + vim.diagnostic.config({severity_sort = true}) + local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics { show_header = false } + local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) + + eq({"1. Info", "2. Warning", "3. Error", "4. Syntax error"}, exec_lua [[ + vim.diagnostic.config({severity_sort = { reverse = true } }) + local popup_bufnr, winnr = vim.diagnostic.show_line_diagnostics { show_header = false } + local lines = vim.api.nvim_buf_get_lines(popup_bufnr, 0, -1, false) + vim.api.nvim_win_close(winnr, true) + return lines + ]]) + end) end) describe('setloclist()', function() diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index a066cfbc10..8651a38025 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -237,29 +237,34 @@ describe('lua stdlib', function() end) it("vim.split", function() - local split = function(str, sep, plain) - return exec_lua('return vim.split(...)', str, sep, plain) + local split = function(str, sep, kwargs) + return exec_lua('return vim.split(...)', str, sep, kwargs) end local tests = { - { "a,b", ",", false, { 'a', 'b' } }, - { ":aa::bb:", ":", false, { '', 'aa', '', 'bb', '' } }, - { "::ee::ff:", ":", false, { '', '', 'ee', '', 'ff', '' } }, - { "ab", ".", false, { '', '', '' } }, - { "a1b2c", "[0-9]", false, { 'a', 'b', 'c' } }, - { "xy", "", false, { 'x', 'y' } }, - { "here be dragons", " ", false, { "here", "be", "dragons"} }, - { "axaby", "ab?", false, { '', 'x', 'y' } }, - { "f v2v v3v w2w ", "([vw])2%1", false, { 'f ', ' v3v ', ' ' } }, - { "", "", false, {} }, - { "", "a", false, { '' } }, - { "x*yz*oo*l", "*", true, { 'x', 'yz', 'oo', 'l' } }, + { "a,b", ",", false, false, { 'a', 'b' } }, + { ":aa::bb:", ":", false, false, { '', 'aa', '', 'bb', '' } }, + { ":aa::bb:", ":", false, true, { 'aa', '', 'bb' } }, + { "::ee::ff:", ":", false, false, { '', '', 'ee', '', 'ff', '' } }, + { "::ee::ff:", ":", false, true, { 'ee', '', 'ff' } }, + { "ab", ".", false, false, { '', '', '' } }, + { "a1b2c", "[0-9]", false, false, { 'a', 'b', 'c' } }, + { "xy", "", false, false, { 'x', 'y' } }, + { "here be dragons", " ", false, false, { "here", "be", "dragons"} }, + { "axaby", "ab?", false, false, { '', 'x', 'y' } }, + { "f v2v v3v w2w ", "([vw])2%1", false, false, { 'f ', ' v3v ', ' ' } }, + { "", "", false, false, {} }, + { "", "a", false, false, { '' } }, + { "x*yz*oo*l", "*", true, false, { 'x', 'yz', 'oo', 'l' } }, } for _, t in ipairs(tests) do - eq(t[4], split(t[1], t[2], t[3])) + eq(t[5], split(t[1], t[2], {plain=t[3], trimempty=t[4]})) end + -- Test old signature + eq({'x', 'yz', 'oo', 'l'}, split("x*yz*oo*l", "*", true)) + local loops = { { "abc", ".-" }, } @@ -283,9 +288,8 @@ describe('lua stdlib', function() vim/shared.lua:0: in function <vim/shared.lua:0>]]), pcall_err(split, 'string', 1)) eq(dedent([[ - Error executing lua: vim/shared.lua:0: plain: expected boolean, got number + Error executing lua: vim/shared.lua:0: kwargs: expected table, got number stack traceback: - vim/shared.lua:0: in function 'gsplit' vim/shared.lua:0: in function <vim/shared.lua:0>]]), pcall_err(split, 'string', 'string', 1)) end) diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 85c67be8f9..45fcf945f4 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -1,4 +1,5 @@ local helpers = require('test.functional.helpers')(after_each) +local global_helpers = require('test.helpers') local Screen = require('test.functional.ui.screen') local clear = helpers.clear @@ -35,6 +36,7 @@ describe(':checkhealth', function() clear() eq('nvim', getcompletion('nvim', 'checkhealth')[1]) eq('provider', getcompletion('prov', 'checkhealth')[1]) + eq('vim.lsp', getcompletion('vim.ls', 'checkhealth')[1]) end) end) @@ -48,42 +50,34 @@ describe('health.vim', function() command("set runtimepath+=test/functional/fixtures") end) - it("health#report_*()", function() - helpers.source([[ - let g:health_report = execute([ - \ "call health#report_start('Check Bar')", - \ "call health#report_ok('Bar status')", - \ "call health#report_ok('Other Bar status')", - \ "call health#report_warn('Zub')", - \ "call health#report_start('Baz')", - \ "call health#report_warn('Zim', ['suggestion 1', 'suggestion 2'])" - \ ]) - ]]) - local result = helpers.eval("g:health_report") - - helpers.eq(helpers.dedent([[ - - - ## Check Bar - - OK: Bar status - - OK: Other Bar status - - WARNING: Zub - - ## Baz - - WARNING: Zim + describe(":checkhealth", function() + it("functions health#report_*() render correctly", function() + command("checkhealth full_render") + helpers.expect([[ + + full_render: health#full_render#check + ======================================================================== + ## report 1 + - OK: life is fine + - WARNING: no what installed - ADVICE: - - suggestion 1 - - suggestion 2]]), - result) - end) + - pip what + - make what + ## report 2 + - INFO: stuff is stable + - ERROR: why no hardcopy + - ADVICE: + - :help |:hardcopy| + - :help |:TOhtml| + ]]) + end) - describe(":checkhealth", function() it("concatenates multiple reports", function() - command("checkhealth success1 success2") + command("checkhealth success1 success2 test_plug") helpers.expect([[ - health#success1#check + success1: health#success1#check ======================================================================== ## report 1 - OK: everything is fine @@ -91,25 +85,111 @@ describe('health.vim', function() ## report 2 - OK: nothing to see here - health#success2#check + success2: health#success2#check ======================================================================== ## another 1 - OK: ok + + test_plug: require("test_plug.health").check() + ======================================================================== + ## report 1 + - OK: everything is fine + + ## report 2 + - OK: nothing to see here + ]]) + end) + + it("lua plugins, skips vimscript healthchecks with the same name", function() + command("checkhealth test_plug") + -- Existing file in test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim + -- and the Lua healthcheck is used instead. + helpers.expect([[ + + test_plug: require("test_plug.health").check() + ======================================================================== + ## report 1 + - OK: everything is fine + + ## report 2 + - OK: nothing to see here ]]) end) + it("lua plugins submodules", function() + command("checkhealth test_plug.submodule") + helpers.expect([[ + + test_plug.submodule: require("test_plug.submodule.health").check() + ======================================================================== + ## report 1 + - OK: everything is fine + + ## report 2 + - OK: nothing to see here + ]]) + end) + + it("lua plugins submodules with expression '*'", function() + command("checkhealth test_plug*") + local buf_lines = helpers.curbuf('get_lines', 0, -1, true) + -- avoid dealing with path separators + local received = table.concat(buf_lines, '\n', 1, #buf_lines - 2) + local expected = helpers.dedent([[ + + test_plug: require("test_plug.health").check() + ======================================================================== + ## report 1 + - OK: everything is fine + + ## report 2 + - OK: nothing to see here + + test_plug.submodule: require("test_plug.submodule.health").check() + ======================================================================== + ## report 1 + - OK: everything is fine + + ## report 2 + - OK: nothing to see here + + test_plug.submodule_failed: require("test_plug.submodule_failed.health").check() + ======================================================================== + - ERROR: Failed to run healthcheck for "test_plug.submodule_failed" plugin. Exception: + function health#check, line 24]]) + eq(expected, received) + end) + it("gracefully handles broken healthcheck", function() command("checkhealth broken") helpers.expect([[ - health#broken#check + broken: health#broken#check ======================================================================== - ERROR: Failed to run healthcheck for "broken" plugin. Exception: - function health#check[21]..health#broken#check, line 1 + function health#check[24]..health#broken#check, line 1 caused an error ]]) end) + it("gracefully handles broken lua healthcheck", function() + command("checkhealth test_plug.submodule_failed") + local buf_lines = helpers.curbuf('get_lines', 0, -1, true) + local received = table.concat(buf_lines, '\n', 1, #buf_lines - 2) + -- avoid dealing with path separators + local lua_err = "attempt to perform arithmetic on a nil value" + local last_line = buf_lines[#buf_lines - 1] + assert(string.find(last_line, lua_err) ~= nil, "Lua error not present") + + local expected = global_helpers.dedent([[ + + test_plug.submodule_failed: require("test_plug.submodule_failed.health").check() + ======================================================================== + - ERROR: Failed to run healthcheck for "test_plug.submodule_failed" plugin. Exception: + function health#check, line 24]]) + eq(expected, received) + end) + it("highlights OK, ERROR", function() local screen = Screen.new(72, 10) screen:attach() @@ -126,11 +206,11 @@ describe('health.vim', function() command("set laststatus=0") screen:expect{grid=[[ ^ | - {Heading:health#foo#check} | + {Heading:foo: } | {Bar:========================================================================}| {Bullet: -} {Error:ERROR:} No healthcheck found for "foo" plugin. | | - {Heading:health#success1#check} | + {Heading:success1: health#success1#check} | {Bar:========================================================================}| {Heading2:##}{Heading: report 1} | {Bullet: -} {Ok:OK:} everything is fine | @@ -140,9 +220,10 @@ describe('health.vim', function() it("gracefully handles invalid healthcheck", function() command("checkhealth non_existent_healthcheck") + -- luacheck: ignore 613 helpers.expect([[ - health#non_existent_healthcheck#check + non_existent_healthcheck: ======================================================================== - ERROR: No healthcheck found for "non_existent_healthcheck" plugin. ]]) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 8f9b194690..026e6815dc 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -480,6 +480,55 @@ describe('LSP', function() } end) + it('should not forward RequestCancelled to callback', function() + local expected_handlers = { + {NIL, {}, {method="finish", client_id=1}}; + } + local client + test_rpc_server { + test_name = "check_forward_request_cancelled"; + on_init = function(_client) + _client.request("error_code_test") + client = _client + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + eq(0, #expected_handlers, "did not call expected handler") + end; + on_handler = function(err, _, ctx) + eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + if ctx.method == 'finish' then client.stop() end + end; + } + end) + + it('should forward ContentModified to callback', function() + local expected_handlers = { + {NIL, {}, {method="finish", client_id=1}}; + {{code = -32801}, NIL, {method = "error_code_test", client_id=1}}; + } + local client + test_rpc_server { + test_name = "check_forward_content_modified"; + on_init = function(_client) + _client.request("error_code_test") + client = _client + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + eq(0, #expected_handlers, "did not call expected handler") + end; + on_handler = function(err, _, ctx) + eq(table.remove(expected_handlers), {err, _, ctx}, "expected handler") + -- if ctx.method == 'error_code_test' then client.notify("finish") end + if ctx.method ~= 'finish' then client.notify('finish') end + if ctx.method == 'finish' then client.stop() end + end; + } + end) + it('should not send didOpen if the buffer closes before init', function() local expected_handlers = { {NIL, {}, {method="shutdown", client_id=1}}; diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index 103ae59b8e..7dcca231ee 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -22,14 +22,28 @@ describe(':terminal buffer', function() it('terminal-mode forces various options', function() feed([[<C-\><C-N>]]) - command('setlocal cursorline cursorcolumn scrolloff=4 sidescrolloff=7') - eq({ 1, 1, 4, 7 }, eval('[&l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')) - eq('n', eval('mode()')) + command('setlocal cursorline cursorlineopt=both cursorcolumn scrolloff=4 sidescrolloff=7') + eq({ 'both', 1, 1, 4, 7 }, eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')) + eq('nt', eval('mode(1)')) -- Enter terminal-mode ("insert" mode in :terminal). feed('i') - eq('t', eval('mode()')) - eq({ 0, 0, 0, 0 }, eval('[&l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')) + eq('t', eval('mode(1)')) + eq({ 'number', 1, 0, 0, 0 }, eval('[&l:cursorlineopt, &l:cursorline, &l:cursorcolumn, &l:scrolloff, &l:sidescrolloff]')) + end) + + it('terminal-mode does not change cursorlineopt if cursorline is disabled', function() + feed([[<C-\><C-N>]]) + command('setlocal nocursorline cursorlineopt=both') + feed('i') + eq({ 0, 'both' }, eval('[&l:cursorline, &l:cursorlineopt]')) + end) + + it('terminal-mode disables cursorline when cursorlineopt is only set to "line', function() + feed([[<C-\><C-N>]]) + command('setlocal cursorline cursorlineopt=line') + feed('i') + eq({ 0, 'line' }, eval('[&l:cursorline, &l:cursorlineopt]')) end) describe('when a new file is edited', function() diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index 707c355069..065dd72485 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -96,19 +96,28 @@ describe(':terminal', function() eq(3, #jumps) end) + it('nvim_get_mode() in :terminal', function() + command(':terminal') + eq({ blocking=false, mode='nt' }, nvim('get_mode')) + feed('i') + eq({ blocking=false, mode='t' }, nvim('get_mode')) + feed([[<C-\><C-N>]]) + eq({ blocking=false, mode='nt' }, nvim('get_mode')) + end) + it(':stopinsert RPC request exits terminal-mode #7807', function() command(':terminal') feed('i[tui] insert-mode') eq({ blocking=false, mode='t' }, nvim('get_mode')) command('stopinsert') - eq({ blocking=false, mode='n' }, nvim('get_mode')) + eq({ blocking=false, mode='nt' }, nvim('get_mode')) end) it(':stopinsert in normal mode doesn\'t break insert mode #9889', function() command(':terminal') - eq({ blocking=false, mode='n' }, nvim('get_mode')) + eq({ blocking=false, mode='nt' }, nvim('get_mode')) command(':stopinsert') - eq({ blocking=false, mode='n' }, nvim('get_mode')) + eq({ blocking=false, mode='nt' }, nvim('get_mode')) feed('a') eq({ blocking=false, mode='t' }, nvim('get_mode')) end) diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index 0eb5901b3b..3d8441b93c 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -33,16 +33,16 @@ describe(':terminal mouse', function() describe('when the terminal has focus', function() it('will exit focus on mouse-scroll', function() - eq('t', eval('mode()')) + eq('t', eval('mode(1)')) feed('<ScrollWheelUp><0,0>') - eq('n', eval('mode()')) + eq('nt', eval('mode(1)')) end) it('will exit focus on <C-\\> + mouse-scroll', function() - eq('t', eval('mode()')) + eq('t', eval('mode(1)')) feed('<C-\\>') feed('<ScrollWheelUp><0,0>') - eq('n', eval('mode()')) + eq('nt', eval('mode(1)')) end) describe('with mouse events enabled by the program', function() @@ -94,7 +94,7 @@ describe(':terminal mouse', function() -- When the display area such as a number is clicked, it returns to the -- normal mode. feed('<LeftMouse><3,0>') - eq('n', eval('mode()')) + eq('nt', eval('mode(1)')) screen:expect([[ {7: 11 }^line28 | {7: 12 }line29 | diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index 188afa1e84..c92107082e 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -111,7 +111,7 @@ describe(':terminal', function() command('terminal') feed('a<Cmd>wincmd j<CR>') eq(2, eval("winnr()")) - eq('t', eval('mode()')) + eq('t', eval('mode(1)')) end) end) diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index e57c63bb0f..6c2c4b398a 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -46,6 +46,7 @@ describe('float window', function() [24] = {foreground = Screen.colors.Black, background = Screen.colors.Grey80}; [25] = {blend = 100, background = Screen.colors.Gray0}; [26] = {blend = 80, background = Screen.colors.Gray0}; + [27] = {background = Screen.colors.LightGray}; } it('behavior', function() @@ -6174,6 +6175,132 @@ describe('float window', function() end) end) + it("left drag changes visual selection in float window", function() + local buf = meths.create_buf(false,false) + meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar'}) + meths.open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=5}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 5 + {1:foo }| + {1:bar }| + {2:~ }| + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1}; + [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2}; + }} + meths.input_mouse('left', 'press', '', 5, 0, 0) + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 5 + {1:^foo }| + {1:bar }| + {2:~ }| + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1}; + [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2}; + }} + meths.input_mouse('left', 'drag', '', 5, 1, 2) + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + {3:-- VISUAL --} | + ## grid 5 + {27:foo}{1: }| + {27:ba}{1:^r }| + {2:~ }| + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1}; + [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 2}; + }} + else + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }{1:foo }{0: }| + {0:~ }{1:bar }{0: }| + {0:~ }{2:~ }{0: }| + {0:~ }| + | + ]]} + + meths.input_mouse('left', 'press', '', 0, 2, 5) + screen:expect{grid=[[ + | + {0:~ }| + {0:~ }{1:^foo }{0: }| + {0:~ }{1:bar }{0: }| + {0:~ }{2:~ }{0: }| + {0:~ }| + | + ]]} + + meths.input_mouse('left', 'drag', '', 0, 3, 7) + screen:expect{grid=[[ + | + {0:~ }| + {0:~ }{27:foo}{1: }{0: }| + {0:~ }{27:ba}{1:^r }{0: }| + {0:~ }{2:~ }{0: }| + {0:~ }| + {3:-- VISUAL --} | + ]]} + end + end) + it("'winblend' option", function() screen:try_resize(50,9) screen:set_default_attr_ids({ diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index d3fe38ef52..baacef358f 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -585,6 +585,69 @@ describe('ui/mouse/input', function() ]]) end) + it('left drag changes visual selection in split layout', function() + screen:try_resize(53,14) + command('set mouse=a') + command('vsplit') + command('wincmd l') + command('below split') + command('enew') + feed('ifoo\nbar<esc>') + + screen:expect{grid=[[ + testing {4:│}testing | + mouse {4:│}mouse | + support and selection {4:│}support and selection | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│[No Name] [+] }| + {0:~ }{4:│}foo{0:$} | + {0:~ }{4:│}ba^r{0:$} | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {4:[No Name] [+] }{5:[No Name] [+] }| + | + ]]} + + meths.input_mouse('left', 'press', '', 0, 6, 27) + screen:expect{grid=[[ + testing {4:│}testing | + mouse {4:│}mouse | + support and selection {4:│}support and selection | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│[No Name] [+] }| + {0:~ }{4:│}^foo{0:$} | + {0:~ }{4:│}bar{0:$} | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {4:[No Name] [+] }{5:[No Name] [+] }| + | + ]]} + meths.input_mouse('left', 'drag', '', 0, 7, 30) + + screen:expect{grid=[[ + testing {4:│}testing | + mouse {4:│}mouse | + support and selection {4:│}support and selection | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│[No Name] [+] }| + {0:~ }{4:│}{1:foo}{3:$} | + {0:~ }{4:│}{1:bar}{0:^$} | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {4:[No Name] [+] }{5:[No Name] [+] }| + {2:-- VISUAL --} | + ]]} + end) + it('two clicks will select the word and enter VISUAL', function() feed('<LeftMouse><2,2><LeftMouse><2,2>') screen:expect([[ diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index 8dc9644ae5..29ff0daa8d 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -144,14 +144,8 @@ endif() include(ExternalProject) -if(WIN32) - # "nvim" branch of https://github.com/neovim/libuv - set(LIBUV_URL https://github.com/neovim/libuv/archive/b899d12b0d56d217f31222da83f8c398355b69ef.tar.gz) - set(LIBUV_SHA256 eb7e37b824887e1b31a4e31d1d9bad4c03d8b98532d9cce5f67a3b70495a4b2a) -else() - set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.42.0.tar.gz) - set(LIBUV_SHA256 371e5419708f6aaeb8656671f89400b92a9bba6443369af1bb70bcd6e4b3c764) -endif() +set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.42.0.tar.gz) +set(LIBUV_SHA256 371e5419708f6aaeb8656671f89400b92a9bba6443369af1bb70bcd6e4b3c764) set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/cpp-3.0.0/msgpack-3.0.0.tar.gz) set(MSGPACK_SHA256 bfbb71b7c02f806393bc3cbc491b40523b89e64f83860c58e3e54af47de176e4) @@ -209,8 +203,8 @@ set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc891 set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/5aa0bbb.tar.gz) set(TREESITTER_C_SHA256 a5dcb37460d83002dfae7f9a208170ddbc9a047f231b9d6b75da7d36d707db2f) -set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.20.0.tar.gz) -set(TREESITTER_SHA256 4a8070b9de17c3b8096181fe8530320ab3e8cca685d8bee6a3e8d164b5fb47da) +set(TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/7890a29db0b186b7b21a0a95d99fa6c562b8316b.tar.gz) +set(TREESITTER_SHA256 634006b0336a5eef1b07d2f80a4d4f8ac1522bf15759ec3e5dda0032a734fb19) if(USE_BUNDLED_UNIBILIUM) include(BuildUnibilium) |