diff options
93 files changed, 3017 insertions, 1444 deletions
diff --git a/.clang-format b/.clang-format index ff61915aac..c86f5a3ddf 100644 --- a/.clang-format +++ b/.clang-format @@ -1,6 +1,6 @@ BasedOnStyle: Google Language: Cpp -ColumnLimit: 80 +ColumnLimit: 100 IndentWidth: 2 TabWidth: 2 UseTab: Never diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..35b9e23489 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Question + url: https://neovim.discourse.group/ + about: Please ask and answer questions about Neovim on Discourse. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b89730434..f75320048b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,7 @@ on: push: branches: '**' pull_request: + types: [opened, synchronize, reopened, ready_for_review] branches: - 'master' - 'release-[0-9]+.[0-9]+' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ff7562bf20..c6d3eaf42b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,10 +28,14 @@ jobs: run: | sudo apt-get update sudo apt-get install -y autoconf automake build-essential cmake gcc-11 gettext gperf libtool-bin locales ninja-build pkg-config unzip + - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name != 'nightly') + run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV + - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') + run: printf 'NVIM_BUILD_TYPE=RelWithDebInfo\n' >> $GITHUB_ENV - name: Build release id: build run: | - CC=gcc-11 make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH=" + CC=gcc-11 make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH=" printf '::set-output name=version::%s\n' "$(./build/bin/nvim --version | head -n 3 | sed -z 's/\n/%0A/g')" printf '::set-output name=release::%s\n' "$(./build/bin/nvim --version | head -n 1)" make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-linux64" install @@ -80,9 +84,13 @@ jobs: brew update >/dev/null brew upgrade brew install automake ninja + - if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name != 'nightly') + run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV + - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') + run: printf 'NVIM_BUILD_TYPE=RelWithDebInfo\n' >> $GITHUB_ENV - name: Build release run: | - make CMAKE_BUILD_TYPE=Release CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11" + make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11" make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-osx64" install - name: Create package run: | diff --git a/.github/workflows/squash-typos.yml b/.github/workflows/squash-typos.yml index 6f5e24a9b6..6779589dc6 100644 --- a/.github/workflows/squash-typos.yml +++ b/.github/workflows/squash-typos.yml @@ -1,7 +1,7 @@ name: Squash Typo Pull Requests on: - pull_request: + pull_request_target: types: labeled concurrency: group: ${{ github.workflow }} @@ -21,7 +21,6 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 - ref: master - uses: actions/setup-python@v2 - name: Setup git config @@ -30,3 +29,5 @@ jobs: git config --global user.email 'marvim@users.noreply.github.com' - run: python scripts/squash_typos.py + env: + PR_NUMBER: ${{ github.event.number }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 56b200050f..7e362ddd82 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ Developer guidelines Pull requests (PRs) --------------------- -- To avoid duplicate work, create a `[WIP]` pull request as soon as possible. +- To avoid duplicate work, create a draft pull request as soon as possible. - Your PR must include **test coverage.** See [test/README.md][run-tests]. - Avoid cosmetic changes to unrelated files in the same commit. - Use a [feature branch][git-feature-branch] instead of the master branch. @@ -62,16 +62,22 @@ Pull requests (PRs) - During a squash/fixup, use `exec make -C build unittest` between each pick/edit/reword. -### Stages: WIP, RFC, RDY +### Stages: Draft and Ready for review -Pull requests have three stages: `[WIP]` (Work In Progress), `[RFC]` (Request -For Comment) and `[RDY]` (Ready). +Pull requests have two stages: Draft and Ready for review. -1. `[RFC]` is assumed by default, **do not** put "RFC" in the PR title (it adds - noise to merge commit messages). -2. Add `[WIP]` to the PR title if you are _not_ requesting feedback and the work - is still in flux. -3. Add `[RDY]` to the PR title if you are _done_ and only waiting on merge. +1. [Create a Draft PR][pr-draft] while you are _not_ requesting feedback as + you are still working on the PR. +2. [Change your PR to ready][pr-ready] when the PR is ready for review. + +You can convert the state of your PR back to Draft (or Ready for review) at any +time. You can also skip the Draft stage if your PR is ready for review from the +beginning. + +Do __not__ add any labels like `[RFC]` or `[WIP]` in the title to indicate the +state of your PR: this just adds noise. Non-Draft PRs are assumed to be open +for comments by default; if you want feedback from specific people, `@`-ping +them in a comment. ### Commit messages @@ -284,3 +290,5 @@ as context, use the `-W` argument as well. [complexity:low]: https://github.com/neovim/neovim/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%3Alow [master error list]: https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint/errors.json [wiki-contribute-help]: https://github.com/neovim/neovim/wiki/contribute-%3Ahelp +[pr-draft]: https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request +[pr-ready]: https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request diff --git a/cmake/FindLibLUV.cmake b/cmake/FindLibLUV.cmake index af25c2ddaa..23b62b66d3 100644 --- a/cmake/FindLibLUV.cmake +++ b/cmake/FindLibLUV.cmake @@ -15,7 +15,7 @@ find_path(LIBLUV_INCLUDE_DIR luv/luv.h PATHS ${PC_LIBLUV_INCLUDEDIR} ${PC_LIBLUV_INCLUDE_DIRS}) # Explicitly look for luv.so. #10407 -list(APPEND LIBLUV_NAMES luv luv_a libluv_a luv${CMAKE_SHARED_LIBRARY_SUFFIX}) +list(APPEND LIBLUV_NAMES luv_a luv libluv_a luv${CMAKE_SHARED_LIBRARY_SUFFIX}) find_library(LIBLUV_LIBRARY NAMES ${LIBLUV_NAMES} HINTS ${PC_LIBLUV_LIBDIR} ${PC_LIBLUV_LIBRARY_DIRS}) diff --git a/contrib/flake.nix b/contrib/flake.nix index c601377cd0..d07067a7a1 100644 --- a/contrib/flake.nix +++ b/contrib/flake.nix @@ -106,9 +106,10 @@ clang-tools # for clangd to find the correct headers ]; - shellHook = '' + shellHook = oa.shellHook + '' export NVIM_PYTHON_LOG_LEVEL=DEBUG export NVIM_LOG_FILE=/tmp/nvim.log + export ASAN_SYMBOLIZER_PATH=${pkgs.llvm_11}/bin/llvm-symbolizer # ASAN_OPTIONS=detect_leaks=1 export ASAN_OPTIONS="log_path=./test.log:abort_on_error=1" @@ -118,6 +119,10 @@ # when running the functionaltests mkdir -p outputs/out/share/nvim/syntax touch outputs/out/share/nvim/syntax/syntax.vim + + # for treesitter functionaltests + mkdir -p runtime/parser + cp -f ${pkgs.tree-sitter.builtGrammars.tree-sitter-c}/parser runtime/parser/c.so ''; }); }); diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index 6be87af8a9..aed3acab67 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -986,9 +986,9 @@ inside of strings can change! Also see 'softtabstop' option. > *Y* ["x]Y yank [count] lines [into register x] (synonym for - yy, |linewise|). If you like "Y" to work from the - cursor to the end of line (which is more logical, - but not Vi-compatible) use ":map Y y$". + yy, |linewise|). + *Y-default* + Mapped to "y$" by default. |default-mappings| *zy* ["x]zy{motion} Yank {motion} text [into register x]. Only differs diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt index c8a4168ab2..bb00c77ca8 100644 --- a/runtime/doc/insert.txt +++ b/runtime/doc/insert.txt @@ -68,12 +68,18 @@ CTRL-A Insert previously inserted text. CTRL-W Delete the word before the cursor (see |i_backspacing| about joining lines). See the section "word motions", |word-motions|, for the definition of a word. + *i_CTRL-W-default* + By default, sets a new undo point before deleting. + |default-mappings| *i_CTRL-U* CTRL-U Delete all entered characters before the cursor in the current line. If there are no newly entered characters and 'backspace' is not empty, delete all characters before the cursor in the current line. See |i_backspacing| about joining lines. + *i_CTRL-U-default* + By default, sets a new undo point before deleting. + |default-mappings| *i_CTRL-I* *i_<Tab>* *i_Tab* <Tab> or CTRL-I Insert a tab. If the 'expandtab' option is on, the equivalent number of spaces is inserted (use CTRL-V <Tab> to diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 7e589c095b..4d32be97d3 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -766,15 +766,6 @@ get_log_path() *vim.lsp.get_log_path()* Return: ~ (String) Path to logfile. -init({client}, {bufnr}) *vim.lsp.init()* - client_id → state - - state pending_change?: function that the timer starts to - trigger didChange pending_changes: list of tables with the - pending changesets; for incremental_sync only - use_incremental_sync: bool buffers?: table (bufnr → lines); - for incremental sync only timer?: uv_timer - omnifunc({findstart}, {base}) *vim.lsp.omnifunc()* Implements 'omnifunc' compatible LSP completion. @@ -828,9 +819,9 @@ start_client({config}) *vim.lsp.start_client()* table. Parameters: ~ - {root_dir} (required, string) Directory where - the LSP server will base its rootUri - on initialization. + {root_dir} (string) Directory where the LSP + server will base its rootUri on + initialization. {cmd} (required, string or list treated like |jobstart()|) Base command that initiates the LSP client. @@ -1267,7 +1258,7 @@ enable({bufnr}, {client_id}) *vim.lsp.diagnostic.enable()* the given client. The default is to enable diagnostics for all attached clients. -get({bufnr}, {client_id}) *vim.lsp.diagnostic.get()* +get({bufnr}, {client_id}, {predicate}) *vim.lsp.diagnostic.get()* Return associated diagnostics for bufnr Parameters: ~ @@ -1275,6 +1266,8 @@ get({bufnr}, {client_id}) *vim.lsp.diagnostic.get()* {client_id} number|nil If nil, then return all of the diagnostics. Else, return just the diagnostics associated with the client_id. + {predicate} function|nil Optional function for filtering + diagnostics get_all({client_id}) *vim.lsp.diagnostic.get_all()* Get all diagnostics for clients @@ -1319,18 +1312,18 @@ get_line_diagnostics({bufnr}, {line_nr}, {opts}, {client_id}) Get the diagnostics by line Parameters: ~ - {bufnr} number The buffer number - {line_nr} number The line number - {opts} table|nil Configuration keys - • severity: (DiagnosticSeverity, default nil) - • Only return diagnostics with this - severity. Overrides severity_limit - - • severity_limit: (DiagnosticSeverity, default nil) - • Limit severity of diagnostics found. E.g. - "Warning" means { "Error", "Warning" } - will be valid. - {client_id} number the client id + {bufnr} number|nil The buffer number + {line_nr} number|nil The line number + {opts} table|nil Configuration keys + • severity: (DiagnosticSeverity, default nil) + • Only return diagnostics with this + severity. Overrides severity_limit + + • severity_limit: (DiagnosticSeverity, default nil) + • Limit severity of diagnostics found. + E.g. "Warning" means { "Error", + "Warning" } will be valid. + {client_id|nil} number the client id Return: ~ table Table with map of line number to list of @@ -1665,9 +1658,9 @@ set_virtual_text({diagnostics}, {bufnr}, {client_id}, {diagnostic_ns}, {opts}) E.g. "Warning" means { "Error", "Warning" } will be valid. - *vim.lsp.diagnostic.show_line_diagnostics()* -show_line_diagnostics({opts}, {bufnr}, {line_nr}, {client_id}) - Open a floating window with the diagnostics from {line_nr} + *vim.lsp.diagnostic.show_diagnostics()* +show_diagnostics({opts}, {diagnostics}) + Open a floating window with the provided diagnostics The floating window can be customized with the following highlight groups: > @@ -1679,20 +1672,52 @@ show_line_diagnostics({opts}, {bufnr}, {line_nr}, {client_id}) < Parameters: ~ + {opts} table Configuration table + • show_header (boolean, default true): Show + "Diagnostics:" header + • all opts for + |vim.lsp.util.open_floating_preview()| + can be used here + {diagnostics} table: The diagnostics to display + + Return: ~ + table {popup_bufnr, win_id} + + *vim.lsp.diagnostic.show_line_diagnostics()* +show_line_diagnostics({opts}, {buf_nr}, {line_nr}, {client_id}) + Parameters: ~ {opts} table Configuration table - • show_header (boolean, default true): Show - "Diagnostics:" header. - • Plus all the opts for + • all opts for |vim.lsp.diagnostic.get_line_diagnostics()| - and |vim.lsp.util.open_floating_preview()| - can be used here. - {bufnr} number The buffer number - {line_nr} number The line number + and |show_diagnostics()| can be used here + {buf_nr} number|nil The buffer number + {line_nr} number|nil The line number {client_id} number|nil the client id Return: ~ table {popup_bufnr, win_id} + *vim.lsp.diagnostic.show_position_diagnostics()* +show_position_diagnostics({opts}, {buf_nr}, {position}) + Parameters: ~ + {opts} table|nil Configuration keys + • severity: (DiagnosticSeverity, default nil) + • Only return diagnostics with this + severity. Overrides severity_limit + + • severity_limit: (DiagnosticSeverity, default nil) + • Limit severity of diagnostics found. E.g. + "Warning" means { "Error", "Warning" } + will be valid. + + • all opts for |show_diagnostics()| can be + used here + {buf_nr} number|nil The buffer number + {position} table|nil The (0,0)-indexed position + + Return: ~ + table {popup_bufnr, win_id} + ============================================================================== Lua module: vim.lsp.codelens *lsp-codelens* diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index f0ce15ac0f..10b849aa3e 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3078,7 +3078,7 @@ A jump table for the options with a short description can be found at |Q_op|. See |help-translated|. *'hidden'* *'hid'* *'nohidden'* *'nohid'* -'hidden' 'hid' boolean (default off) +'hidden' 'hid' boolean (default on) global When off a buffer is unloaded when it is |abandon|ed. When on a buffer becomes hidden when it is |abandon|ed. If the buffer is still @@ -3213,7 +3213,7 @@ A jump table for the options with a short description can be found at |Q_op|. option to a valid keymap name. *'inccommand'* *'icm'* -'inccommand' 'icm' string (default "") +'inccommand' 'icm' string (default "nosplit") global "nosplit": Shows the effects of a command incrementally, as you type. @@ -3498,7 +3498,7 @@ A jump table for the options with a short description can be found at |Q_op|. |jumplist-stack| *'joinspaces'* *'js'* *'nojoinspaces'* *'nojs'* -'joinspaces' 'js' boolean (default on) +'joinspaces' 'js' boolean (default off) global Insert two spaces after a '.', '?' and '!' with a join command. Otherwise only one space is inserted. @@ -6116,7 +6116,7 @@ A jump table for the options with a short description can be found at |Q_op|. specify special kinds of buffers. See |special-buffers|. *'switchbuf'* *'swb'* -'switchbuf' 'swb' string (default "") +'switchbuf' 'swb' string (default "uselast") global This option controls the behavior when switching between buffers. Possible values (comma separated list): @@ -6700,7 +6700,7 @@ A jump table for the options with a short description can be found at |Q_op|. security reasons. *'viewoptions'* *'vop'* -'viewoptions' 'vop' string (default: "folds,options,cursor,curdir") +'viewoptions' 'vop' string (default: "folds,cursor,curdir") global Changes the effect of the |:mkview| command. It is a comma separated list of words. Each word enables saving and restoring something: diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index ec91b6e29a..162909ce45 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -14,6 +14,10 @@ Various commands *various* *CTRL-L* CTRL-L Clears and redraws the screen. The redraw may happen later, after processing typeahead. + *CTRL-L-default* + By default, also clears search highlighting + |:nohlsearch| and updates diffs |:diffupdate|. + |default-mappings| *:mod* *:mode* :mod[e] Clears and redraws the screen. diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 2c53620049..166c0c17aa 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -41,9 +41,11 @@ the differences. - 'fillchars' defaults (in effect) to "vert:│,fold:·,sep:│" - 'formatoptions' defaults to "tcqj" - 'fsync' is disabled +- 'hidden' is enabled - 'history' defaults to 10000 (the maximum) - 'hlsearch' is enabled - 'incsearch' is enabled +- 'joinspaces' is disabled - 'langnoremap' is enabled - 'langremap' is disabled - 'laststatus' defaults to 2 (statusline is always shown) @@ -56,12 +58,13 @@ the differences. - 'sidescroll' defaults to 1 - 'smarttab' is enabled - 'startofline' is disabled +- 'switchbuf' defaults to "uselast" - 'tabpagemax' defaults to 50 - 'tags' defaults to "./tags;,tags" - 'ttimeoutlen' defaults to 50 - 'ttyfast' is always set -- 'viewoptions' includes "unix,slash" - 'undodir' defaults to ~/.local/share/nvim/undo (|xdg|), auto-created +- 'viewoptions' includes "unix,slash", excludes "options" - 'viminfo' includes "!" - 'wildmenu' is enabled - 'wildoptions' defaults to "pum,tagfile" @@ -72,6 +75,14 @@ the differences. - |g:vimsyn_embed| defaults to "l" to enable Lua highlighting + +Default Mappings: *default-mappings* + +nnoremap Y y$ +nnoremap <C-L> <Cmd>nohlsearch<Bar>diffupdate<CR><C-L> +inoremap <C-U> <C-G>u<C-U> +inoremap <C-W> <C-G>u<C-W> + ============================================================================== 3. New Features *nvim-features* @@ -150,6 +161,7 @@ Commands: |:drop| is always available |:Man| is available by default, with many improvements such as completion |:sign-define| accepts a `numhl` argument, to highlight the line number + |:match| can be invoked before highlight group is defined Events: |Signal| @@ -167,6 +179,7 @@ Functions: |msgpackdump()|, |msgpackparse()| provide msgpack de/serialization |stdpath()| |system()|, |systemlist()| can run {cmd} directly (without 'shell') + |matchadd()| can be called before highlight group is defined Highlight groups: |highlight-blend| controls blend level for a highlight group diff --git a/runtime/filetype.vim b/runtime/filetype.vim index f012c7cb4b..9c75a49ac1 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -870,6 +870,9 @@ au BufNewFile,BufRead *.ipynb setf json " JSONC au BufNewFile,BufRead *.jsonc setf jsonc +" Julia +au BufNewFile,BufRead *.jl setf julia + " Kixtart au BufNewFile,BufRead *.kix setf kix diff --git a/runtime/ftplugin/julia.vim b/runtime/ftplugin/julia.vim new file mode 100644 index 0000000000..32e364e436 --- /dev/null +++ b/runtime/ftplugin/julia.vim @@ -0,0 +1,92 @@ +" Vim filetype plugin file +" Language: Julia +" Maintainer: Carlo Baldassi <carlobaldassi@gmail.com> +" Homepage: https://github.com/JuliaEditorSupport/julia-vim +" Last Change: 2014 may 29 +" adapted from upstream 2021 Aug 4 + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let s:save_cpo = &cpo +set cpo-=C + +setlocal include=^\\s*\\%(reload\\\|include\\)\\> +setlocal suffixesadd=.jl +setlocal comments=:# +setlocal commentstring=#\ %s +setlocal cinoptions+=#1 +setlocal define=^\\s*macro\\> +setlocal fo-=t fo+=croql + +let b:julia_vim_loaded = 1 + +let b:undo_ftplugin = "setlocal include< suffixesadd< comments< commentstring<" + \ . " define< fo< shiftwidth< expandtab< indentexpr< indentkeys< cinoptions< completefunc<" + \ . " | unlet! b:julia_vim_loaded" + +" MatchIt plugin support +if exists("loaded_matchit") + let b:match_ignorecase = 0 + + " note: begin_keywords must contain all blocks, in order + " for nested-structures-skipping to work properly + " note: 'mutable struct' and 'struct' are defined separately because + " using \? puts the cursor on 'struct' instead of 'mutable' for some reason + let b:julia_begin_keywords = '\%(\.\s*\|@\)\@<!\<\%(function\|macro\|begin\|mutable\s\+struct\|\%(mutable\s\+\)\@<!struct\|\%(abstract\|primitive\)\s\+type\|let\|do\|\%(bare\)\?module\|quote\|if\|for\|while\|try\)\>' + " note: the following regex not only recognizes macros, but also local/global keywords. + " the purpose is recognizing things like `@inline myfunction()` + " or `global myfunction(...)` etc, for matchit and block movement functionality + let s:macro_regex = '\%(@\%([#(]\@!\S\)\+\|\<\%(local\|global\)\)\s\+' + let s:nomacro = '\%(' . s:macro_regex . '\)\@<!' + let s:yesmacro = s:nomacro . '\%('. s:macro_regex . '\)\+' + let b:julia_begin_keywordsm = '\%(' . s:yesmacro . b:julia_begin_keywords . '\)\|' + \ . '\%(' . s:nomacro . b:julia_begin_keywords . '\)' + let b:julia_end_keywords = '\<end\>' + + " note: this function relies heavily on the syntax file + function! JuliaGetMatchWords() + let [l,c] = [line('.'),col('.')] + let attr = synIDattr(synID(l, c, 1),"name") + let c1 = c + while attr == 'juliaMacro' || expand('<cword>') =~# '\<\%(global\|local\)\>' + normal! W + if line('.') > l || col('.') == c1 + call cursor(l, c) + return '' + endif + let attr = synIDattr(synID(l, col('.'), 1),"name") + let c1 = col('.') + endwhile + call cursor(l, c) + if attr == 'juliaConditional' + return b:julia_begin_keywordsm . ':\<\%(elseif\|else\)\>:' . b:julia_end_keywords + elseif attr =~# '\<\%(juliaRepeat\|juliaRepKeyword\)\>' + return b:julia_begin_keywordsm . ':\<\%(break\|continue\)\>:' . b:julia_end_keywords + elseif attr == 'juliaBlKeyword' + return b:julia_begin_keywordsm . ':' . b:julia_end_keywords + elseif attr == 'juliaException' + return b:julia_begin_keywordsm . ':\<\%(catch\|finally\)\>:' . b:julia_end_keywords + endif + return '\<\>:\<\>' + endfunction + + let b:match_words = 'JuliaGetMatchWords()' + + " we need to skip everything within comments, strings and + " the 'begin' and 'end' keywords when they are used as a range rather than as + " the delimiter of a block + let b:match_skip = 'synIDattr(synID(line("."),col("."),0),"name") =~# ' + \ . '"\\<julia\\%(Comprehension\\%(For\\|If\\)\\|RangeKeyword\\|Comment\\%([LM]\\|Delim\\)\\|\\%([bs]\\|Shell\\|Printf\\|Doc\\)\\?String\\|StringPrefixed\\|DocStringM\\(Raw\\)\\?\\|RegEx\\|SymbolS\\?\\|Dotted\\)\\>"' + + let b:undo_ftplugin = b:undo_ftplugin + \ . " | unlet! b:match_words b:match_skip b:match_ignorecase" + \ . " | unlet! b:julia_begin_keywords b:julia_end_keywords" + \ . " | delfunction JuliaGetMatchWords" + +endif + +let &cpo = s:save_cpo +unlet s:save_cpo diff --git a/runtime/indent/julia.vim b/runtime/indent/julia.vim new file mode 100644 index 0000000000..a90cff49e4 --- /dev/null +++ b/runtime/indent/julia.vim @@ -0,0 +1,491 @@ +" Vim indent file +" Language: Julia +" Maintainer: Carlo Baldassi <carlobaldassi@gmail.com> +" Homepage: https://github.com/JuliaEditorSupport/julia-vim +" Last Change: 2016 jun 16 +" Notes: originally based on Bram Molenaar's indent file for vim + +setlocal autoindent + +setlocal indentexpr=GetJuliaIndent() +setlocal indentkeys+==end,=else,=catch,=finally,),],} +setlocal indentkeys-=0# +setlocal indentkeys-=: +setlocal indentkeys-=0{ +setlocal indentkeys-=0} +setlocal nosmartindent + +" Only define the function once. +if exists("*GetJuliaIndent") + finish +endif + +let s:skipPatternsBasic = '\<julia\%(Comment\%([LM]\|Delim\)\)\>' +let s:skipPatterns = '\<julia\%(Comprehension\%(For\|If\)\|RangeKeyword\|Comment\%([LM]\|Delim\)\|\%([bs]\|Shell\|Printf\|Doc\)\?String\|StringPrefixed\|DocStringM\(Raw\)\?\|RegEx\|SymbolS\?\|Macro\|Dotted\)\>' + +function JuliaMatch(lnum, str, regex, st, ...) + let s = a:st + let e = a:0 > 0 ? a:1 : -1 + let basic_skip = a:0 > 1 ? a:2 : 'all' + let skip = basic_skip ==# 'basic' ? s:skipPatternsBasic : s:skipPatterns + while 1 + let f = match(a:str, '\C' . a:regex, s) + if e >= 0 && f >= e + return -1 + endif + if f >= 0 + let attr = synIDattr(synID(a:lnum,f+1,1),"name") + let attrT = synIDattr(synID(a:lnum,f+1,0),"name") + if attr =~# skip || attrT =~# skip + let s = f+1 + continue + endif + endif + break + endwhile + return f +endfunction + +function GetJuliaNestingStruct(lnum, ...) + " Auxiliary function to inspect the block structure of a line + let line = getline(a:lnum) + let s = a:0 > 0 ? a:1 : 0 + let e = a:0 > 1 ? a:2 : -1 + let blocks_stack = [] + let num_closed_blocks = 0 + while 1 + let fb = JuliaMatch(a:lnum, line, '\<\%(if\|else\%(if\)\?\|while\|for\|try\|catch\|finally\|\%(staged\)\?function\|macro\|begin\|mutable\s\+struct\|\%(mutable\s\+\)\@<!struct\|\%(abstract\|primitive\)\s\+type\|let\|\%(bare\)\?module\|quote\|do\)\>', s, e) + let fe = JuliaMatch(a:lnum, line, '\<end\>', s, e) + + if fb < 0 && fe < 0 + " No blocks found + break + end + + if fb >= 0 && (fb < fe || fe < 0) + " The first occurrence is an opening block keyword + " Note: some keywords (elseif,else,catch,finally) are both + " closing blocks and opening new ones + + let i = JuliaMatch(a:lnum, line, '\<if\>', s) + if i >= 0 && i == fb + let s = i+1 + call add(blocks_stack, 'if') + continue + endif + let i = JuliaMatch(a:lnum, line, '\<elseif\>', s) + if i >= 0 && i == fb + let s = i+1 + if len(blocks_stack) > 0 && blocks_stack[-1] == 'if' + let blocks_stack[-1] = 'elseif' + elseif (len(blocks_stack) > 0 && blocks_stack[-1] != 'elseif') || len(blocks_stack) == 0 + call add(blocks_stack, 'elseif') + let num_closed_blocks += 1 + endif + continue + endif + let i = JuliaMatch(a:lnum, line, '\<else\>', s) + if i >= 0 && i == fb + let s = i+1 + if len(blocks_stack) > 0 && blocks_stack[-1] =~# '\<\%(else\)\=if\>' + let blocks_stack[-1] = 'else' + else + call add(blocks_stack, 'else') + let num_closed_blocks += 1 + endif + continue + endif + + let i = JuliaMatch(a:lnum, line, '\<try\>', s) + if i >= 0 && i == fb + let s = i+1 + call add(blocks_stack, 'try') + continue + endif + let i = JuliaMatch(a:lnum, line, '\<catch\>', s) + if i >= 0 && i == fb + let s = i+1 + if len(blocks_stack) > 0 && blocks_stack[-1] == 'try' + let blocks_stack[-1] = 'catch' + else + call add(blocks_stack, 'catch') + let num_closed_blocks += 1 + endif + continue + endif + let i = JuliaMatch(a:lnum, line, '\<finally\>', s) + if i >= 0 && i == fb + let s = i+1 + if len(blocks_stack) > 0 && (blocks_stack[-1] == 'try' || blocks_stack[-1] == 'catch') + let blocks_stack[-1] = 'finally' + else + call add(blocks_stack, 'finally') + let num_closed_blocks += 1 + endif + continue + endif + + let i = JuliaMatch(a:lnum, line, '\<\%(bare\)\?module\>', s) + if i >= 0 && i == fb + let s = i+1 + if i == 0 + call add(blocks_stack, 'col1module') + else + call add(blocks_stack, 'other') + endif + continue + endif + + let i = JuliaMatch(a:lnum, line, '\<\%(while\|for\|function\|macro\|begin\|\%(mutable\s\+\)\?struct\|\%(abstract\|primitive\)\s\+type\|let\|quote\|do\)\>', s) + if i >= 0 && i == fb + if match(line, '\C\<\%(mutable\|abstract\|primitive\)', i) != -1 + let s = i+11 + else + let s = i+1 + endif + call add(blocks_stack, 'other') + continue + endif + + " Note: it should be impossible to get here + break + + else + " The first occurrence is an 'end' + + let s = fe+1 + if len(blocks_stack) == 0 + let num_closed_blocks += 1 + else + call remove(blocks_stack, -1) + endif + continue + + endif + + " Note: it should be impossible to get here + break + endwhile + let num_open_blocks = len(blocks_stack) - count(blocks_stack, 'col1module') + return [num_open_blocks, num_closed_blocks] +endfunction + +function GetJuliaNestingBrackets(lnum, c) + " Auxiliary function to inspect the brackets structure of a line + let line = getline(a:lnum)[0 : (a:c - 1)] + let s = 0 + let brackets_stack = [] + let last_closed_bracket = -1 + while 1 + let fb = JuliaMatch(a:lnum, line, '[([{]', s) + let fe = JuliaMatch(a:lnum, line, '[])}]', s) + + if fb < 0 && fe < 0 + " No brackets found + break + end + + if fb >= 0 && (fb < fe || fe < 0) + " The first occurrence is an opening bracket + + let i = JuliaMatch(a:lnum, line, '(', s) + if i >= 0 && i == fb + let s = i+1 + call add(brackets_stack, ['par',i]) + continue + endif + + let i = JuliaMatch(a:lnum, line, '\[', s) + if i >= 0 && i == fb + let s = i+1 + call add(brackets_stack, ['sqbra',i]) + continue + endif + + let i = JuliaMatch(a:lnum, line, '{', s) + if i >= 0 && i == fb + let s = i+1 + call add(brackets_stack, ['curbra',i]) + continue + endif + + " Note: it should be impossible to get here + break + + else + " The first occurrence is a closing bracket + + let i = JuliaMatch(a:lnum, line, ')', s) + if i >= 0 && i == fe + let s = i+1 + if len(brackets_stack) > 0 && brackets_stack[-1][0] == 'par' + call remove(brackets_stack, -1) + else + let last_closed_bracket = i + 1 + endif + continue + endif + + let i = JuliaMatch(a:lnum, line, ']', s) + if i >= 0 && i == fe + let s = i+1 + if len(brackets_stack) > 0 && brackets_stack[-1][0] == 'sqbra' + call remove(brackets_stack, -1) + else + let last_closed_bracket = i + 1 + endif + continue + endif + + let i = JuliaMatch(a:lnum, line, '}', s) + if i >= 0 && i == fe + let s = i+1 + if len(brackets_stack) > 0 && brackets_stack[-1][0] == 'curbra' + call remove(brackets_stack, -1) + else + let last_closed_bracket = i + 1 + endif + continue + endif + + " Note: it should be impossible to get here + break + + endif + + " Note: it should be impossible to get here + break + endwhile + let first_open_bracket = -1 + let last_open_bracket = -1 + let infuncargs = 0 + if len(brackets_stack) > 0 + let first_open_bracket = brackets_stack[0][1] + let last_open_bracket = brackets_stack[-1][1] + if brackets_stack[-1][0] == 'par' && IsFunctionArgPar(a:lnum, last_open_bracket+1) + let infuncargs = 1 + endif + endif + return [first_open_bracket, last_open_bracket, last_closed_bracket, infuncargs] +endfunction + +let s:bracketBlocks = '\<julia\%(\%(\%(Printf\)\?Par\|SqBra\%(Idx\)\?\|CurBra\)Block\|ParBlockInRange\|StringVars\%(Par\|SqBra\|CurBra\)\|Dollar\%(Par\|SqBra\)\|QuotedParBlockS\?\)\>' + +function IsInBrackets(lnum, c) + let stack = map(synstack(a:lnum, a:c), 'synIDattr(v:val, "name")') + call filter(stack, 'v:val =~# s:bracketBlocks') + return len(stack) > 0 +endfunction + +function IsInDocString(lnum) + let stack = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') + call filter(stack, 'v:val =~# "\\<juliaDocString\\(Delim\\|M\\\(Raw\\)\\?\\)\\?\\>"') + return len(stack) > 0 +endfunction + +function IsInContinuationImportLine(lnum) + let stack = map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') + call filter(stack, 'v:val =~# "\\<juliaImportLine\\>"') + if len(stack) == 0 + return 0 + endif + return JuliaMatch(a:lnum, getline(a:lnum), '\<\%(import\|using\|export\)\>', indent(a:lnum)) == -1 +endfunction + +function IsFunctionArgPar(lnum, c) + if a:c == 0 + return 0 + endif + let stack = map(synstack(a:lnum, a:c-1), 'synIDattr(v:val, "name")') + return len(stack) >= 2 && stack[-2] ==# 'juliaFunctionDef' +endfunction + +function JumpToMatch(lnum, last_closed_bracket) + " we use the % command to skip back (tries to ues matchit if possible, + " otherwise resorts to vim's default, which is buggy but better than + " nothing) + call cursor(a:lnum, a:last_closed_bracket) + let percmap = maparg("%", "n") + if exists("g:loaded_matchit") && percmap =~# 'Match\%(it\|_wrapper\)' + normal % + else + normal! % + end +endfunction + +" Auxiliary function to find a line which does not start in the middle of a +" multiline bracketed expression, to be used as reference for block +" indentation. +function LastBlockIndent(lnum) + let lnum = a:lnum + let ind = 0 + while lnum > 0 + let ind = indent(lnum) + if ind == 0 + return [lnum, 0] + endif + if !IsInBrackets(lnum, 1) + break + endif + let lnum = prevnonblank(lnum - 1) + endwhile + return [max([lnum,1]), ind] +endfunction + +function GetJuliaIndent() + " Do not alter doctrings indentation + if IsInDocString(v:lnum) + return -1 + endif + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " At the start of the file use zero indent. + if lnum == 0 + return 0 + endif + + let ind = -1 + let st = -1 + let lim = -1 + + " Multiline bracketed expressions take precedence + let align_brackets = get(g:, "julia_indent_align_brackets", 1) + let align_funcargs = get(g:, "julia_indent_align_funcargs", 0) + let c = len(getline(lnum)) + 1 + while IsInBrackets(lnum, c) + let [first_open_bracket, last_open_bracket, last_closed_bracket, infuncargs] = GetJuliaNestingBrackets(lnum, c) + + " First scenario: the previous line has a hanging open bracket: + " set the indentation to match the opening bracket (plus an extra space) + " unless we're in a function arguments list or alignment is disabled, in + " which case we just add an extra indent + if last_open_bracket != -1 + if (!infuncargs && align_brackets) || (infuncargs && align_funcargs) + let st = last_open_bracket + let ind = virtcol([lnum, st + 1]) + else + let ind = indent(lnum) + shiftwidth() + endif + + " Second scenario: some multiline bracketed expression was closed in the + " previous line. But since we know we are still in a bracketed expression, + " we need to find the line where the bracket was opened + elseif last_closed_bracket != -1 + call JumpToMatch(lnum, last_closed_bracket) + if line(".") == lnum + " something wrong here, give up + let ind = indent(lnum) + else + let lnum = line(".") + let c = col(".") - 1 + if c == 0 + " uhm, give up + let ind = 0 + else + " we skipped a bracket set, keep searching for an opening bracket + let lim = c + continue + endif + endif + + " Third scenario: nothing special: keep the indentation + else + let ind = indent(lnum) + endif + + " Does the current line start with a closing bracket? Then depending on + " the situation we align it with the opening one, or we let the rest of + " the code figure it out (the case in which we're closing a function + " argument list is special-cased) + if JuliaMatch(v:lnum, getline(v:lnum), '[])}]', indent(v:lnum)) == indent(v:lnum) && ind > 0 + if !align_brackets && !align_funcargs + call JumpToMatch(v:lnum, indent(v:lnum)) + return indent(line(".")) + elseif (align_brackets && getline(v:lnum)[indent(v:lnum)] != ')') || align_funcargs + return ind - 1 + else " must be a ')' and align_brackets==1 and align_funcargs==0 + call JumpToMatch(v:lnum, indent(v:lnum)) + if IsFunctionArgPar(line("."), col(".")) + let ind = -1 + else + return ind - 1 + endif + endif + endif + + break + endwhile + + if ind == -1 + " We are not in a multiline bracketed expression. Thus we look for a + " previous line to use as a reference + let [lnum,ind] = LastBlockIndent(lnum) + let c = len(getline(lnum)) + 1 + if IsInBrackets(lnum, c) + let [first_open_bracket, last_open_bracket, last_closed_bracket, infuncargs] = GetJuliaNestingBrackets(lnum, c) + let lim = first_open_bracket + endif + end + + " Analyse the reference line + let [num_open_blocks, num_closed_blocks] = GetJuliaNestingStruct(lnum, st, lim) + " Increase indentation for each newly opened block in the reference line + let ind += shiftwidth() * num_open_blocks + + " Analyse the current line + let [num_open_blocks, num_closed_blocks] = GetJuliaNestingStruct(v:lnum) + " Decrease indentation for each closed block in the current line + let ind -= shiftwidth() * num_closed_blocks + + " Additional special case: multiline import/using/export statements + + let prevline = getline(lnum) + " Are we in a multiline import/using/export statement, right below the + " opening line? + if IsInContinuationImportLine(v:lnum) && !IsInContinuationImportLine(lnum) + if get(g:, 'julia_indent_align_import', 1) + " if the opening line has a colon followed by non-comments, use it as + " reference point + let cind = JuliaMatch(lnum, prevline, ':', indent(lnum), lim) + if cind >= 0 + let nonwhiteind = JuliaMatch(lnum, prevline, '\S', cind+1, -1, 'basic') + if nonwhiteind >= 0 + " return match(prevline, '\S', cind+1) " a bit overkill... + return cind + 2 + endif + else + " if the opening line is not a naked import/using/export statement, use + " it as reference + let iind = JuliaMatch(lnum, prevline, '\<import\|using\|export\>', indent(lnum), lim) + if iind >= 0 + " assuming whitespace after using... so no `using(XYZ)` please! + let nonwhiteind = JuliaMatch(lnum, prevline, '\S', iind+6, -1, 'basic') + if nonwhiteind >= 0 + return match(prevline, '\S', iind+6) + endif + endif + endif + endif + let ind += shiftwidth() + + " Or did we just close a multiline import/using/export statement? + elseif !IsInContinuationImportLine(v:lnum) && IsInContinuationImportLine(lnum) + " find the starting line of the statement + let ilnum = 0 + for iln in range(lnum-1, 1, -1) + if !IsInContinuationImportLine(iln) + let ilnum = iln + break + endif + endfor + if ilnum == 0 + " something went horribly wrong, give up + let ind = indent(lnum) + endif + let ind = indent(ilnum) + endif + + return ind +endfunction diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 87ecc3eeea..ca8db73d43 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -218,7 +218,7 @@ local function validate_client_config(config) config = { config, 't' }; } validate { - root_dir = { config.root_dir, is_dir, "directory" }; + root_dir = { config.root_dir, optional_validator(is_dir), "directory" }; handlers = { config.handlers, "t", true }; capabilities = { config.capabilities, "t", true }; cmd_cwd = { config.cmd_cwd, optional_validator(is_dir), "directory" }; @@ -289,6 +289,7 @@ end local changetracking = {} do + --@private --- client_id → state --- --- state @@ -547,7 +548,7 @@ end --- --- The following parameters describe fields in the {config} table. --- ---@param root_dir: (required, string) Directory where the LSP server will base +--@param root_dir: (string) Directory where the LSP server will base --- its rootUri on initialization. --- --@param cmd: (required, string or list treated like |jobstart()|) Base command @@ -772,7 +773,7 @@ function lsp.start_client(config) } local version = vim.version() - if not config.workspace_folders then + if config.root_dir and not config.workspace_folders then config.workspace_folders = {{ uri = vim.uri_from_fname(config.root_dir); name = string.format("%s", config.root_dir); @@ -797,7 +798,7 @@ function lsp.start_client(config) rootPath = config.root_dir; -- The rootUri of the workspace. Is null if no folder is open. If both -- `rootPath` and `rootUri` are set `rootUri` wins. - rootUri = vim.uri_from_fname(config.root_dir); + rootUri = config.root_dir and vim.uri_from_fname(config.root_dir); -- User provided initialization options. initializationOptions = config.init_options; -- The capabilities provided by the client (editor or tool) diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 5efd8d74a7..a244e3d6a4 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -362,11 +362,12 @@ end ---@param bufnr number ---@param client_id number|nil If nil, then return all of the diagnostics. --- Else, return just the diagnostics associated with the client_id. -function M.get(bufnr, client_id) +---@param predicate function|nil Optional function for filtering diagnostics +function M.get(bufnr, client_id, predicate) if client_id == nil then local all_diagnostics = {} for iter_client_id, _ in pairs(diagnostic_cache[bufnr]) do - local iter_diagnostics = M.get(bufnr, iter_client_id) + local iter_diagnostics = M.get(bufnr, iter_client_id, predicate) for _, diagnostic in ipairs(iter_diagnostics) do table.insert(all_diagnostics, diagnostic) @@ -376,19 +377,26 @@ function M.get(bufnr, client_id) return all_diagnostics end - return diagnostic_cache[bufnr][client_id] or {} + predicate = predicate or function(_) return true end + local client_diagnostics = {} + for _, diagnostic in ipairs(diagnostic_cache[bufnr][client_id] or {}) do + if predicate(diagnostic) then + table.insert(client_diagnostics, diagnostic) + end + end + return client_diagnostics end --- Get the diagnostics by line --- ----@param bufnr number The buffer number ----@param line_nr number The line number +---@param bufnr number|nil The buffer number +---@param line_nr number|nil The line number ---@param opts table|nil Configuration keys --- - severity: (DiagnosticSeverity, default nil) --- - Only return diagnostics with this severity. Overrides severity_limit --- - severity_limit: (DiagnosticSeverity, default nil) --- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. ----@param client_id number the client id +---@param client_id|nil number the client id ---@return table Table with map of line number to list of diagnostics. -- Structured: { [1] = {...}, [5] = {.... } } function M.get_line_diagnostics(bufnr, line_nr, opts, client_id) @@ -464,63 +472,64 @@ end -- }}} -- Diagnostic Movements {{{ ---- Helper function to iterate through all of the diagnostic lines ----@return table list of diagnostics -local _iter_diagnostic_lines = function(start, finish, step, bufnr, opts, client_id) - if bufnr == nil then - bufnr = vim.api.nvim_get_current_buf() - end - +--- Helper function to find the next diagnostic relative to a position +---@return table the next diagnostic if found +local _next_diagnostic = function(position, search_forward, bufnr, opts, client_id) + position[1] = position[1] - 1 + bufnr = bufnr or vim.api.nvim_get_current_buf() local wrap = if_nil(opts.wrap, true) - - local search = function(search_start, search_finish, search_step) - for line_nr = search_start, search_finish, search_step do - local line_diagnostics = M.get_line_diagnostics(bufnr, line_nr, opts, client_id) - if line_diagnostics and not vim.tbl_isempty(line_diagnostics) then - return line_diagnostics + local line_count = vim.api.nvim_buf_line_count(bufnr) + for i = 0, line_count do + local offset = i * (search_forward and 1 or -1) + local line_nr = position[1] + offset + if line_nr < 0 or line_nr >= line_count then + if not wrap then + return end + line_nr = (line_nr + line_count) % line_count end - end - - local result = search(start, finish, step) - - if wrap then - local wrap_start, wrap_finish - if step == 1 then - wrap_start, wrap_finish = 1, start - else - wrap_start, wrap_finish = vim.api.nvim_buf_line_count(bufnr), start - end - - if not result then - result = search(wrap_start, wrap_finish, step) + local line_diagnostics = M.get_line_diagnostics(bufnr, line_nr, opts, client_id) + if line_diagnostics and not vim.tbl_isempty(line_diagnostics) then + local sort_diagnostics, is_next + if search_forward then + sort_diagnostics = function(a, b) return a.range.start.character < b.range.start.character end + is_next = function(diagnostic) return diagnostic.range.start.character > position[2] end + else + sort_diagnostics = function(a, b) return a.range.start.character > b.range.start.character end + is_next = function(diagnostic) return diagnostic.range.start.character < position[2] end + end + table.sort(line_diagnostics, sort_diagnostics) + if i == 0 then + for _, v in pairs(line_diagnostics) do + if is_next(v) then + return v + end + end + else + return line_diagnostics[1] + end end end - - return result end --@private ---- Helper function to ierate through diagnostic lines and return a position +--- Helper function to return a position from a diagnostic --- ---@return table {row, col} -local function _iter_diagnostic_lines_pos(opts, line_diagnostics) +local function _diagnostic_pos(opts, diagnostic) opts = opts or {} local win_id = opts.win_id or vim.api.nvim_get_current_win() local bufnr = vim.api.nvim_win_get_buf(win_id) - if line_diagnostics == nil or vim.tbl_isempty(line_diagnostics) then - return false - end + if not diagnostic then return false end - local iter_diagnostic = line_diagnostics[1] - return to_position(iter_diagnostic.range.start, bufnr) + return to_position(diagnostic.range.start, bufnr) end --@private -- Move to the diagnostic position -local function _iter_diagnostic_move_pos(name, opts, pos) +local function _diagnostic_move_pos(name, opts, pos) opts = opts or {} local enable_popup = if_nil(opts.enable_popup, true) @@ -536,7 +545,7 @@ local function _iter_diagnostic_move_pos(name, opts, pos) if enable_popup then -- This is a bit weird... I'm surprised that we need to wait til the next tick to do this. vim.schedule(function() - M.show_line_diagnostics(opts.popup_opts, vim.api.nvim_win_get_buf(win_id)) + M.show_position_diagnostics(opts.popup_opts, vim.api.nvim_win_get_buf(win_id)) end) end end @@ -552,14 +561,14 @@ function M.get_prev(opts) local bufnr = vim.api.nvim_win_get_buf(win_id) local cursor_position = opts.cursor_position or vim.api.nvim_win_get_cursor(win_id) - return _iter_diagnostic_lines(cursor_position[1] - 2, 0, -1, bufnr, opts, opts.client_id) + return _next_diagnostic(cursor_position, false, bufnr, opts, opts.client_id) end --- Return the pos, {row, col}, for the prev diagnostic in the current buffer. ---@param opts table See |vim.lsp.diagnostic.goto_next()| ---@return table Previous diagnostic position function M.get_prev_pos(opts) - return _iter_diagnostic_lines_pos( + return _diagnostic_pos( opts, M.get_prev(opts) ) @@ -568,7 +577,7 @@ end --- Move to the previous diagnostic ---@param opts table See |vim.lsp.diagnostic.goto_next()| function M.goto_prev(opts) - return _iter_diagnostic_move_pos( + return _diagnostic_move_pos( "DiagnosticPrevious", opts, M.get_prev_pos(opts) @@ -585,14 +594,14 @@ function M.get_next(opts) local bufnr = vim.api.nvim_win_get_buf(win_id) local cursor_position = opts.cursor_position or vim.api.nvim_win_get_cursor(win_id) - return _iter_diagnostic_lines(cursor_position[1], vim.api.nvim_buf_line_count(bufnr), 1, bufnr, opts, opts.client_id) + return _next_diagnostic(cursor_position, true, bufnr, opts, opts.client_id) end --- Return the pos, {row, col}, for the next diagnostic in the current buffer. ---@param opts table See |vim.lsp.diagnostic.goto_next()| ---@return table Next diagnostic position function M.get_next_pos(opts) - return _iter_diagnostic_lines_pos( + return _diagnostic_pos( opts, M.get_next(opts) ) @@ -617,7 +626,7 @@ end --- - {win_id}: (number, default 0) --- - Window ID function M.goto_next(opts) - return _iter_diagnostic_move_pos( + return _diagnostic_move_pos( "DiagnosticNext", opts, M.get_next_pos(opts) @@ -1208,7 +1217,7 @@ end -- }}} -- Diagnostic User Functions {{{ ---- Open a floating window with the diagnostics from {line_nr} +--- Open a floating window with the provided diagnostics --- --- The floating window can be customized with the following highlight groups: --- <pre> @@ -1218,32 +1227,21 @@ end --- LspDiagnosticsFloatingHint --- </pre> ---@param opts table Configuration table ---- - show_header (boolean, default true): Show "Diagnostics:" header. ---- - Plus all the opts for |vim.lsp.diagnostic.get_line_diagnostics()| ---- and |vim.lsp.util.open_floating_preview()| can be used here. ----@param bufnr number The buffer number ----@param line_nr number The line number ----@param client_id number|nil the client id +--- - show_header (boolean, default true): Show "Diagnostics:" header +--- - all opts for |vim.lsp.util.open_floating_preview()| can be used here +---@param diagnostics table: The diagnostics to display ---@return table {popup_bufnr, win_id} -function M.show_line_diagnostics(opts, bufnr, line_nr, client_id) - opts = opts or {} - - local show_header = if_nil(opts.show_header, true) - - bufnr = bufnr or 0 - line_nr = line_nr or (vim.api.nvim_win_get_cursor(0)[1] - 1) - +local function show_diagnostics(opts, diagnostics) + if vim.tbl_isempty(diagnostics) then return end local lines = {} local highlights = {} + local show_header = if_nil(opts.show_header, true) if show_header then table.insert(lines, "Diagnostics:") table.insert(highlights, {0, "Bold"}) end - local line_diagnostics = M.get_line_diagnostics(bufnr, line_nr, opts, client_id) - if vim.tbl_isempty(line_diagnostics) then return end - - for i, diagnostic in ipairs(line_diagnostics) do + for i, diagnostic in ipairs(diagnostics) do local prefix = string.format("%d. ", i) local hiname = M._get_floating_severity_highlight_name(diagnostic.severity) assert(hiname, 'unknown severity: ' .. tostring(diagnostic.severity)) @@ -1257,7 +1255,6 @@ function M.show_line_diagnostics(opts, bufnr, line_nr, client_id) end end - opts.focus_id = "line_diagnostics" local popup_bufnr, winnr = util.open_floating_preview(lines, 'plaintext', opts) for i, hi in ipairs(highlights) do local prefixlen, hiname = unpack(hi) @@ -1268,6 +1265,57 @@ function M.show_line_diagnostics(opts, bufnr, line_nr, client_id) return popup_bufnr, winnr end +--- Open a floating window with the diagnostics from {position} + +---@param opts table|nil Configuration keys +--- - severity: (DiagnosticSeverity, default nil) +--- - Only return diagnostics with this severity. Overrides severity_limit +--- - severity_limit: (DiagnosticSeverity, default nil) +--- - Limit severity of diagnostics found. E.g. "Warning" means { "Error", "Warning" } will be valid. +--- - all opts for |show_diagnostics()| can be used here +---@param buf_nr number|nil The buffer number +---@param position table|nil The (0,0)-indexed position +---@return table {popup_bufnr, win_id} +function M.show_position_diagnostics(opts, buf_nr, position) + opts = opts or {} + opts.focus_id = "position_diagnostics" + buf_nr = buf_nr or vim.api.nvim_get_current_buf() + if not position then + local curr_position = vim.api.nvim_win_get_cursor(0) + curr_position[1] = curr_position[1] - 1 + position = curr_position + end + local match_position_predicate = function(diag) + return position[1] == diag.range['start'].line and + position[2] >= diag.range['start'].character and + (position[2] <= diag.range['end'].character or position[1] < diag.range['end'].line) + end + local position_diagnostics = M.get(buf_nr, nil, match_position_predicate) + if opts.severity then + position_diagnostics = filter_to_severity_limit(opts.severity, position_diagnostics) + elseif opts.severity_limit then + position_diagnostics = filter_by_severity_limit(opts.severity_limit, position_diagnostics) + end + table.sort(position_diagnostics, function(a, b) return a.severity < b.severity end) + return show_diagnostics(opts, position_diagnostics) +end + +--- Open a floating window with the diagnostics from {line_nr} + +---@param opts table Configuration table +--- - all opts for |vim.lsp.diagnostic.get_line_diagnostics()| and +--- |show_diagnostics()| can be used here +---@param buf_nr number|nil The buffer number +---@param line_nr number|nil The line number +---@param client_id number|nil the client id +---@return table {popup_bufnr, win_id} +function M.show_line_diagnostics(opts, buf_nr, line_nr, client_id) + opts = opts or {} + opts.focus_id = "line_diagnostics" + line_nr = line_nr or (vim.api.nvim_win_get_cursor(0)[1] - 1) + local line_diagnostics = M.get_line_diagnostics(buf_nr, line_nr, opts, client_id) + return show_diagnostics(opts, line_diagnostics) +end --- Clear diagnotics and diagnostic cache --- diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index e003cf577a..bf5bd791c3 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -85,8 +85,10 @@ function TSHighlighterQuery.new(lang, query_string) hl = _link_default_highlight_once(lang .. hl, hl) end - rawset(table, capture, hl) - return hl + local id = a.nvim_get_hl_id_by_name(hl) + + rawset(table, capture, id) + return id end }) diff --git a/runtime/syntax/julia.vim b/runtime/syntax/julia.vim new file mode 100644 index 0000000000..2c2d36a97a --- /dev/null +++ b/runtime/syntax/julia.vim @@ -0,0 +1,550 @@ +" Vim syntax file +" Language: julia +" Maintainer: Carlo Baldassi <carlobaldassi@gmail.com> +" Homepage: https://github.com/JuliaEditorSupport/julia-vim +" Last Change: 2013 feb 11 + +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +if version < 704 + " this is used to disable regex syntax like `\@3<=' + " on older vim versions + function! s:d(x) + return '' + endfunction +else + function! s:d(x) + return string(a:x) + endfunction +endif + +scriptencoding utf-8 + +let s:julia_spellcheck_strings = get(g:, "julia_spellcheck_strings", 0) +let s:julia_spellcheck_docstrings = get(g:, "julia_spellcheck_docstrings", 1) +let s:julia_spellcheck_comments = get(g:, "julia_spellcheck_comments", 1) + +let s:julia_highlight_operators = get(g:, "julia_highlight_operators", 1) + +" List of characters, up to \UFF, which cannot be used in identifiers. +" (It includes operator characters; we don't consider them identifiers.) +" This is used mostly in lookbehinds with `\@<=`, e.g. when we need to check +" that that we're not in the middle of an identifier. +" It doesn't include a few characters (spaces and all closing parentheses) +" because those may or may not be valid in the lookbehind on a case-by-case +" basis. +let s:nonid_chars = '\U00-\U08' . '\U0A-\U1F' + \ . '\U21-\U28' . '\U2A-\U2F' . '\U3A-\U40' . '\U5B-\U5E' . '\U60' . '\U7B\U7C' + \ . '\U7E-\UA1' . '\UA7\UA8' . '\UAB-\UAD' . '\UAF\UB1\UB4' . '\UB6-\UB8' . '\UBB\UBF' . '\UD7\UF7' + +" The complete list +let s:nonidS_chars = '[:space:])\U5D}' . s:nonid_chars + + +" List of all valid operator chars up to \UFF (NOTE: they must all be included +" in s:nonidS_chars, so that if we include that, then this is redundant) +" It does not include '!' since it can be used in an identifier. +" The list contains the following characters: '%&*+-/<=>\\^|~¬±×÷' +let s:op_chars = '\U25\U26\U2A\U2B\U2D\U2F\U3C-\U3E\U5C\U5E\U7C\U7E\UAC\UB1\UD7\UF7' + +" List of all valid operator chars above \UFF +" Written with ranges for performance reasons +" The list contains the following characters: '…⁝⅋←↑→↓↔↚↛↜↝↞↠↢↣↤↦↩↪↫↬↮↶↷↺↻↼↽⇀⇁⇄⇆⇇⇉⇋⇌⇍⇎⇏⇐⇒⇔⇚⇛⇜⇝⇠⇢⇴⇵⇶⇷⇸⇹⇺⇻⇼⇽⇾⇿∈∉∊∋∌∍∓∔∗∘∙√∛∜∝∤∥∦∧∨∩∪∷∸∺∻∽∾≀≁≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊞⊟⊠⊡⊢⊣⊩⊬⊮⊰⊱⊲⊳⊴⊵⊶⊷⊻⊼⊽⋄⋅⋆⋇⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟⋠⋡⋢⋣⋤⋥⋦⋧⋨⋩⋪⋫⋬⋭⋮⋯⋰⋱⋲⋳⋴⋵⋶⋷⋸⋹⋺⋻⋼⋽⋾⋿⌿▷⟂⟈⟉⟑⟒⟕⟖⟗⟰⟱⟵⟶⟷⟹⟺⟻⟼⟽⟾⟿⤀⤁⤂⤃⤄⤅⤆⤇⤈⤉⤊⤋⤌⤍⤎⤏⤐⤑⤒⤓⤔⤕⤖⤗⤘⤝⤞⤟⤠⥄⥅⥆⥇⥈⥉⥊⥋⥌⥍⥎⥏⥐⥑⥒⥓⥔⥕⥖⥗⥘⥙⥚⥛⥜⥝⥞⥟⥠⥡⥢⥣⥤⥥⥦⥧⥨⥩⥪⥫⥬⥭⥮⥯⥰⦷⦸⦼⦾⦿⧀⧁⧡⧣⧤⧥⧴⧶⧷⧺⧻⨇⨈⨝⨟⨢⨣⨤⨥⨦⨧⨨⨩⨪⨫⨬⨭⨮⨰⨱⨲⨳⨴⨵⨶⨷⨸⨹⨺⨻⨼⨽⩀⩁⩂⩃⩄⩅⩊⩋⩌⩍⩎⩏⩐⩑⩒⩓⩔⩕⩖⩗⩘⩚⩛⩜⩝⩞⩟⩠⩡⩢⩣⩦⩧⩪⩫⩬⩭⩮⩯⩰⩱⩲⩳⩴⩵⩶⩷⩸⩹⩺⩻⩼⩽⩾⩿⪀⪁⪂⪃⪄⪅⪆⪇⪈⪉⪊⪋⪌⪍⪎⪏⪐⪑⪒⪓⪔⪕⪖⪗⪘⪙⪚⪛⪜⪝⪞⪟⪠⪡⪢⪣⪤⪥⪦⪧⪨⪩⪪⪫⪬⪭⪮⪯⪰⪱⪲⪳⪴⪵⪶⪷⪸⪹⪺⪻⪼⪽⪾⪿⫀⫁⫂⫃⫄⫅⫆⫇⫈⫉⫊⫋⫌⫍⫎⫏⫐⫑⫒⫓⫔⫕⫖⫗⫘⫙⫛⫷⫸⫹⫺⬰⬱⬲⬳⬴⬵⬶⬷⬸⬹⬺⬻⬼⬽⬾⬿⭀⭁⭂⭃⭄⭇⭈⭉⭊⭋⭌←↑→↓' +let s:op_chars_wc = '\U2026\U205D\U214B\U2190-\U2194\U219A-\U219E\U21A0\U21A2-\U21A4\U21A6\U21A9-\U21AC\U21AE\U21B6\U21B7\U21BA-\U21BD\U21C0\U21C1\U21C4\U21C6\U21C7\U21C9\U21CB-\U21D0\U21D2\U21D4\U21DA-\U21DD\U21E0\U21E2\U21F4-\U21FF\U2208-\U220D\U2213\U2214\U2217-\U221D\U2224-\U222A\U2237\U2238\U223A\U223B\U223D\U223E\U2240-\U228B\U228D-\U229C\U229E-\U22A3\U22A9\U22AC\U22AE\U22B0-\U22B7\U22BB-\U22BD\U22C4-\U22C7\U22C9-\U22D3\U22D5-\U22FF\U233F\U25B7\U27C2\U27C8\U27C9\U27D1\U27D2\U27D5-\U27D7\U27F0\U27F1\U27F5-\U27F7\U27F9-\U27FF\U2900-\U2918\U291D-\U2920\U2944-\U2970\U29B7\U29B8\U29BC\U29BE-\U29C1\U29E1\U29E3-\U29E5\U29F4\U29F6\U29F7\U29FA\U29FB\U2A07\U2A08\U2A1D\U2A1F\U2A22-\U2A2E\U2A30-\U2A3D\U2A40-\U2A45\U2A4A-\U2A58\U2A5A-\U2A63\U2A66\U2A67\U2A6A-\U2AD9\U2ADB\U2AF7-\U2AFA\U2B30-\U2B44\U2B47-\U2B4C\UFFE9-\UFFEC' + +" Full operators regex +let s:operators = '\%(' . '\.\%([-+*/^÷%|&⊻]\|//\|\\\|>>\|>>>\?\)\?=' . + \ '\|' . '[:<>]=\|||\|&&\||>\|<|\|[<>:]:\|<<\|>>>\?\|//\|[-=]>\|\.\.\.\?' . + \ '\|' . '\.\?[!' . s:op_chars . s:op_chars_wc . ']' . + \ '\)' + + +" Characters that can be used to start an identifier. Above \UBF we don't +" bother checking. (If a UTF8 operator is used, it will take precedence anyway.) +let s:id_charsH = '\%([A-Za-z_\UA2-\UA6\UA9\UAA\UAE\UB0\UB5\UBA]\|[^\U00-\UBF]\)' +" Characters that can appear in an identifier, starting in 2nd position. Above +" \UBF we check for operators since we need to stop the identifier if one +" appears. We don't check for invalid characters though. +let s:id_charsW = '\%([0-9A-Za-z_!\UA2-\UA6\UA9\UAA\UAE-\UB0\UB2-\UB5\UB8-\UBA\UBC-\UBE]\|[^\U00-\UBF]\@=[^' . s:op_chars_wc . ']\)' + +" A valid julia identifier, more or less +let s:idregex = '\%(' . s:id_charsH . s:id_charsW . '*\)' + + + +syn case match + +syntax cluster juliaExpressions contains=@juliaParItems,@juliaStringItems,@juliaKeywordItems,@juliaBlocksItems,@juliaTypesItems,@juliaConstItems,@juliaMacroItems,@juliaSymbolItems,@juliaOperatorItems,@juliaNumberItems,@juliaCommentItems,@juliaErrorItems,@juliaSyntaxRegions +syntax cluster juliaExprsPrintf contains=@juliaExpressions,@juliaPrintfItems +syntax cluster juliaExprsNodot contains=@juliaParItems,@juliaStringItems,@juliaMacroItems,@juliaSymbolItems,@juliaOperatorItems,@juliaCommentItems,juliaIdSymbol + +syntax cluster juliaParItems contains=juliaParBlock,juliaSqBraIdxBlock,juliaSqBraBlock,juliaCurBraBlock,juliaQuotedParBlock,juliaQuotedQMarkPar +syntax cluster juliaKeywordItems contains=juliaKeyword,juliaWhereKeyword,juliaImportLine,juliaInfixKeyword,juliaRepKeyword +syntax cluster juliaBlocksItems contains=juliaConditionalBlock,juliaWhileBlock,juliaForBlock,juliaBeginBlock,juliaFunctionBlock,juliaMacroBlock,juliaQuoteBlock,juliaTypeBlock,juliaImmutableBlock,juliaExceptionBlock,juliaLetBlock,juliaDoBlock,juliaModuleBlock,juliaStructBlock,juliaMutableStructBlock,juliaAbstractBlock,juliaPrimitiveBlock +syntax cluster juliaTypesItems contains=juliaBaseTypeBasic,juliaBaseTypeNum,juliaBaseTypeC,juliaBaseTypeError,juliaBaseTypeIter,juliaBaseTypeString,juliaBaseTypeArray,juliaBaseTypeDict,juliaBaseTypeSet,juliaBaseTypeIO,juliaBaseTypeProcess,juliaBaseTypeRange,juliaBaseTypeRegex,juliaBaseTypeFact,juliaBaseTypeFact,juliaBaseTypeSort,juliaBaseTypeRound,juliaBaseTypeSpecial,juliaBaseTypeRandom,juliaBaseTypeDisplay,juliaBaseTypeTime,juliaBaseTypeOther + +syntax cluster juliaConstItems contains=juliaConstNum,juliaConstBool,juliaConstEnv,juliaConstMMap,juliaConstC,juliaConstGeneric,juliaConstIO,juliaPossibleEuler + +syntax cluster juliaMacroItems contains=juliaPossibleMacro,juliaDollarVar,juliaDollarPar,juliaDollarSqBra +syntax cluster juliaSymbolItems contains=juliaPossibleSymbol +syntax cluster juliaNumberItems contains=juliaNumbers +syntax cluster juliaStringItems contains=juliaChar,juliaString,juliabString,juliasString,juliaShellString,juliaDocString,juliaRegEx +syntax cluster juliaPrintfItems contains=juliaPrintfParBlock,juliaPrintfString +syntax cluster juliaOperatorItems contains=juliaOperator,juliaRangeOperator,juliaCTransOperator,juliaTernaryRegion,juliaColon,juliaSemicolon,juliaComma +syntax cluster juliaCommentItems contains=juliaCommentL,juliaCommentM +syntax cluster juliaErrorItems contains=juliaErrorPar,juliaErrorEnd,juliaErrorElse,juliaErrorCatch,juliaErrorFinally + +syntax cluster juliaSyntaxRegions contains=juliaIdSymbol,juliaTypeOperatorR2,juliaTypeOperatorR3,juliaWhereR,juliaDotted + +syntax cluster juliaSpellcheckStrings contains=@spell +syntax cluster juliaSpellcheckDocStrings contains=@spell +syntax cluster juliaSpellcheckComments contains=@spell + +if !s:julia_spellcheck_docstrings + syntax cluster juliaSpellcheckDocStrings remove=@spell +endif +if !s:julia_spellcheck_strings + syntax cluster juliaSpellcheckStrings remove=@spell +endif +if !s:julia_spellcheck_comments + syntax cluster juliaSpellcheckComments remove=@spell +endif + +syntax match juliaSemicolon display ";" +syntax match juliaComma display "," +syntax match juliaColon display ":" + +" A dot can introduce a sort of 'environment' such that words after it are not +" recognized as keywords. This has low precedence so that it can be overridden +" by operators +syntax match juliaDotted transparent "\.\s*[^])}.]" contains=@juliaExprsNodot +syntax match juliaDottedT contained transparent "\.\s*[^])}.]" contains=@juliaExprsNodot,juliaType + +syntax match juliaErrorPar display "[])}]" +syntax match juliaErrorEnd display "\<end\>" +syntax match juliaErrorElse display "\<\%(else\|elseif\)\>" +syntax match juliaErrorCatch display "\<catch\>" +syntax match juliaErrorFinally display "\<finally\>" +syntax match juliaErrorSemicol display contained ";" + +syntax region juliaParBlock matchgroup=juliaParDelim start="(" end=")" contains=@juliaExpressions,juliaComprehensionFor +syntax region juliaParBlockInRange matchgroup=juliaParDelim contained start="(" end=")" contains=@juliaExpressions,juliaParBlockInRange,juliaRangeKeyword,juliaComprehensionFor +syntax region juliaSqBraIdxBlock matchgroup=juliaParDelim start="\[" end="\]" contains=@juliaExpressions,juliaParBlockInRange,juliaRangeKeyword,juliaComprehensionFor,juliaSymbolS,juliaQuotedParBlockS,juliaQuotedQMarkParS +exec 'syntax region juliaSqBraBlock matchgroup=juliaParDelim start="\%(^\|\s\|' . s:operators . '\)\@'.s:d(3).'<=\[" end="\]" contains=@juliaExpressions,juliaComprehensionFor,juliaSymbolS,juliaQuotedParBlockS,juliaQuotedQMarkParS' +syntax region juliaCurBraBlock matchgroup=juliaParDelim start="{" end="}" contains=juliaType,juliaDottedT,@juliaExpressions + +exec 'syntax match juliaType contained "\%(' . s:idregex . '\.\)*\zs' . s:idregex . '"' + +" This is a generic identifier followed by some symbol, either a type +" operator (<: or >:), or an open parenthesis, or an open curly bracket. +" It's used to recognize one of the contained regions looking for identifiers +" only once. Once recognized, those regions no longer need to use the +" expensive s:idregex. +exec 'syntax match juliaIdSymbol transparent "' . s:idregex . '\%(\s*[<>]:\|\.\?(\|{\|\"\)\@=" contains=juliaFunctionCall,juliaParamType,juliaStringPrefixed,juliaTypeOperatorR1' + +syntax match juliaFunctionCall contained "[^{([:space:]<>\"]\+(\@=" nextgroup=juliaParBlock + +exec 'syntax match juliaFunctionDef contained transparent "\%(\<\%(function\|macro\)\)\@'.s:d(8).'<=\s\+\zs' . s:idregex . '\%(\.' . s:idregex . '\)*\ze\s*\%((\|\send\>\|$\)" contains=juliaFunctionName' +exec 'syntax match juliaFunctionName contained "\%(\<\%(function\|macro\)\s\+\)\@'.s:d(20).'<=\%(' . s:idregex . '\.\)*\zs' . s:idregex . '"' + +exec 'syntax match juliaStructR contained transparent "\%(\<\%(\%(mutable\s\+\)\?struct\|\%(abstract\|primitive\)\s\+type\)\s\+\)\@'.s:d(20).'<=\%(' . s:idregex . '\.\)*' . s:idregex . '\>\(\s*(\)\@!" contains=juliaType' + +syntax match juliaKeyword display "\<\%(return\|local\|global\|const\)\>" +syntax match juliaInfixKeyword display "\%(=\s*\)\@<!\<\%(in\|isa\)\>\S\@!\%(\s*=\)\@!" + +" The import/export/using keywords introduce a sort of special parsing +" environment with its own rules +exec 'syntax region juliaImportLine matchgroup=juliaKeyword excludenl start="\<\%(import\|using\|export\)\>" skip="\%(\%(\<\%(import\|using\|export\)\>\)\|^\)\@'.s:d(6).'<=$" end="$" end="\%([])}]\)\@=" contains=@juliaExpressions,juliaAsKeyword,@juliaContinuationItems,juliaMacroName' +syntax match juliaAsKeyword display contained "\<as\>" + +syntax match juliaRepKeyword display "\<\%(break\|continue\)\>" +syntax region juliaConditionalBlock matchgroup=juliaConditional start="\<if\>" end="\<end\>" contains=@juliaExpressions,juliaConditionalEIBlock,juliaConditionalEBlock fold +syntax region juliaConditionalEIBlock matchgroup=juliaConditional transparent contained start="\<elseif\>" end="\<\%(end\|else\|elseif\)\>"me=s-1 contains=@juliaExpressions,juliaConditionalEIBlock,juliaConditionalEBlock +syntax region juliaConditionalEBlock matchgroup=juliaConditional transparent contained start="\<else\>" end="\<end\>"me=s-1 contains=@juliaExpressions +syntax region juliaWhileBlock matchgroup=juliaRepeat start="\<while\>" end="\<end\>" contains=@juliaExpressions fold +syntax region juliaForBlock matchgroup=juliaRepeat start="\<for\>" end="\<end\>" contains=@juliaExpressions,juliaOuter fold +syntax region juliaBeginBlock matchgroup=juliaBlKeyword start="\<begin\>" end="\<end\>" contains=@juliaExpressions fold +syntax region juliaFunctionBlock matchgroup=juliaBlKeyword start="\<function\>" end="\<end\>" contains=@juliaExpressions,juliaFunctionDef fold +syntax region juliaMacroBlock matchgroup=juliaBlKeyword start="\<macro\>" end="\<end\>" contains=@juliaExpressions,juliaFunctionDef fold +syntax region juliaQuoteBlock matchgroup=juliaBlKeyword start="\<quote\>" end="\<end\>" contains=@juliaExpressions fold +syntax region juliaStructBlock matchgroup=juliaBlKeyword start="\<struct\>" end="\<end\>" contains=@juliaExpressions,juliaStructR fold +syntax region juliaMutableStructBlock matchgroup=juliaBlKeyword start="\<mutable\s\+struct\>" end="\<end\>" contains=@juliaExpressions,juliaStructR fold +syntax region juliaLetBlock matchgroup=juliaBlKeyword start="\<let\>" end="\<end\>" contains=@juliaExpressions fold +syntax region juliaDoBlock matchgroup=juliaBlKeyword start="\<do\>" end="\<end\>" contains=@juliaExpressions fold +syntax region juliaModuleBlock matchgroup=juliaBlKeyword start="\<\%(bare\)\?module\>" end="\<end\>" contains=@juliaExpressions fold +syntax region juliaExceptionBlock matchgroup=juliaException start="\<try\>" end="\<end\>" contains=@juliaExpressions,juliaCatchBlock,juliaFinallyBlock fold +syntax region juliaCatchBlock matchgroup=juliaException transparent contained start="\<catch\>" end="\<end\>"me=s-1 contains=@juliaExpressions,juliaFinallyBlock +syntax region juliaFinallyBlock matchgroup=juliaException transparent contained start="\<finally\>" end="\<end\>"me=s-1 contains=@juliaExpressions +syntax region juliaAbstractBlock matchgroup=juliaBlKeyword start="\<abstract\s\+type\>" end="\<end\>" fold contains=@juliaExpressions,juliaStructR +syntax region juliaPrimitiveBlock matchgroup=juliaBlKeyword start="\<primitive\s\+type\>" end="\<end\>" fold contains=@juliaExpressions,juliaStructR + +exec 'syntax region juliaComprehensionFor matchgroup=juliaComprehensionFor transparent contained start="\%([^[:space:],;:({[]\_s*\)\@'.s:d(80).'<=\<for\>" end="\ze[]);]" contains=@juliaExpressions,juliaComprehensionIf,juliaComprehensionFor' +syntax match juliaComprehensionIf contained "\<if\>" + +exec 'syntax match juliaOuter contained "\<outer\ze\s\+' . s:idregex . '\>"' + +syntax match juliaRangeKeyword contained "\<\%(begin\|end\)\>" + +syntax match juliaBaseTypeBasic display "\<\%(\%(N\|Named\)\?Tuple\|Symbol\|Function\|Union\%(All\)\?\|Type\%(Name\|Var\)\?\|Any\|ANY\|Vararg\|Ptr\|Exception\|Module\|Expr\|DataType\|\%(LineNumber\|Quote\)Node\|\%(Weak\|Global\)\?Ref\|Method\|Pair\|Val\|Nothing\|Some\|Missing\)\>" +syntax match juliaBaseTypeNum display "\<\%(U\?Int\%(8\|16\|32\|64\|128\)\?\|Float\%(16\|32\|64\)\|Complex\|Bool\|Char\|Number\|Signed\|Unsigned\|Integer\|AbstractFloat\|Real\|Rational\|\%(Abstract\)\?Irrational\|Enum\|BigInt\|BigFloat\|MathConst\|ComplexF\%(16\|32\|64\)\)\>" +syntax match juliaBaseTypeC display "\<\%(FileOffset\|C\%(u\?\%(char\|short\|int\|long\(long\)\?\|w\?string\)\|float\|double\|\%(ptrdiff\|s\?size\|wchar\|off\|u\?intmax\)_t\|void\)\)\>" +syntax match juliaBaseTypeError display "\<\%(\%(Bounds\|Divide\|Domain\|\%(Stack\)\?Overflow\|EOF\|Undef\%(Ref\|Var\)\|System\|Type\|Parse\|Argument\|Key\|Load\|Method\|Inexact\|OutOfMemory\|Init\|Assertion\|ReadOnlyMemory\|StringIndex\)Error\|\%(Interrupt\|Error\|ProcessExited\|Captured\|Composite\|InvalidState\|Missing\|\%(Process\|Task\)Failed\)Exception\|DimensionMismatch\|SegmentationFault\)\>" +syntax match juliaBaseTypeIter display "\<\%(EachLine\|Enumerate\|Cartesian\%(Index\|Range\)\|LinSpace\|CartesianIndices\)\>" +syntax match juliaBaseTypeString display "\<\%(DirectIndex\|Sub\|Rep\|Rev\|Abstract\|Substitution\)\?String\>" +syntax match juliaBaseTypeArray display "\<\%(\%(Sub\)\?Array\|\%(Abstract\|Dense\|Strided\)\?\%(Array\|Matrix\|Vec\%(tor\|OrMat\)\)\|SparseMatrixCSC\|\%(AbstractSparse\|Bit\|Shared\)\%(Array\|Vector\|Matrix\)\|\%\(D\|Bid\|\%(Sym\)\?Trid\)iagonal\|Hermitian\|Symmetric\|UniformScaling\|\%(Lower\|Upper\)Triangular\|\%(Sparse\|Row\)Vector\|VecElement\|Conj\%(Array\|Matrix\|Vector\)\|Index\%(Cartesian\|Linear\|Style\)\|PermutedDimsArray\|Broadcasted\|Adjoint\|Transpose\|LinearIndices\)\>" +syntax match juliaBaseTypeDict display "\<\%(WeakKey\|Id\|Abstract\)\?Dict\>" +syntax match juliaBaseTypeSet display "\<\%(\%(Abstract\|Bit\)\?Set\)\>" +syntax match juliaBaseTypeIO display "\<\%(IO\%(Stream\|Buffer\|Context\)\?\|RawFD\|StatStruct\|FileMonitor\|PollingFileWatcher\|Timer\|Base64\%(Decode\|Encode\)Pipe\|\%(UDP\|TCP\)Socket\|\%(Abstract\)\?Channel\|BufferStream\|ReentrantLock\|GenericIOBuffer\)\>" +syntax match juliaBaseTypeProcess display "\<\%(Pipe\|Cmd\|PipeBuffer\)\>" +syntax match juliaBaseTypeRange display "\<\%(Dims\|RangeIndex\|\%(Abstract\|Lin\|Ordinal\|Step\|\%(Abstract\)\?Unit\)Range\|Colon\|ExponentialBackOff\|StepRangeLen\)\>" +syntax match juliaBaseTypeRegex display "\<Regex\%(Match\)\?\>" +syntax match juliaBaseTypeFact display "\<\%(Factorization\|BunchKaufman\|\%(Cholesky\|QR\)\%(Pivoted\)\?\|\%(Generalized\)\?\%(Eigen\|SVD\|Schur\)\|Hessenberg\|LDLt\|LQ\|LU\)\>" +syntax match juliaBaseTypeSort display "\<\%(Insertion\|\(Partial\)\?Quick\|Merge\)Sort\>" +syntax match juliaBaseTypeRound display "\<Round\%(ingMode\|FromZero\|Down\|Nearest\%(Ties\%(Away\|Up\)\)\?\|ToZero\|Up\)\>" +syntax match juliaBaseTypeSpecial display "\<\%(LocalProcess\|ClusterManager\)\>" +syntax match juliaBaseTypeRandom display "\<\%(AbstractRNG\|MersenneTwister\|RandomDevice\)\>" +syntax match juliaBaseTypeDisplay display "\<\%(Text\(Display\)\?\|\%(Abstract\)\?Display\|MIME\|HTML\)\>" +syntax match juliaBaseTypeTime display "\<\%(Date\%(Time\)\?\|DateFormat\)\>" +syntax match juliaBaseTypeOther display "\<\%(RemoteRef\|Task\|Condition\|VersionNumber\|IPv[46]\|SerializationState\|WorkerConfig\|Future\|RemoteChannel\|IPAddr\|Stack\%(Trace\|Frame\)\|\(Caching\|Worker\)Pool\|AbstractSerializer\)\>" + +syntax match juliaConstNum display "\%(\<\%(\%(NaN\|Inf\)\%(16\|32\|64\)\?\|pi\|π\)\>\)" +" Note: recognition of ℯ, which Vim does not consider a valid identifier, is +" complicated. We detect possible uses by just looking for the character (for +" performance) and then check that it's actually used by its own. +" (This also tries to detect preceding number constants; it does so in a crude +" way.) +syntax match juliaPossibleEuler "ℯ" contains=juliaEuler +exec 'syntax match juliaEuler contained "\%(\%(^\|[' . s:nonidS_chars . s:op_chars_wc . ']\)\%(.\?[0-9][.0-9eEf_]*\d\)\?\)\@'.s:d(80).'<=ℯ\ze[' . s:nonidS_chars . s:op_chars_wc . ']"' +syntax match juliaConstBool display "\<\%(true\|false\)\>" +syntax match juliaConstEnv display "\<\%(ARGS\|ENV\|ENDIAN_BOM\|LOAD_PATH\|VERSION\|PROGRAM_FILE\|DEPOT_PATH\)\>" +syntax match juliaConstIO display "\<\%(std\%(out\|in\|err\)\|devnull\)\>" +syntax match juliaConstC display "\<\%(C_NULL\)\>" +syntax match juliaConstGeneric display "\<\%(nothing\|Main\|undef\|missing\)\>" + +syntax match juliaParamType contained "[^{([:space:]<>\"]\+\ze{" nextgroup=juliaCurBraBlock + +syntax match juliaPossibleMacro transparent "@" contains=juliaMacroCall,juliaMacroCallP,juliaPrintfMacro,juliaDocMacro,juliaDocMacroPre + +exec 'syntax match juliaMacro contained "@' . s:idregex . '\%(\.' . s:idregex . '\)*"' +syntax match juliaMacro contained "@[!.~$%^*/\\|<>+-]\ze[^0-9]" +exec 'syntax region juliaMacroCall contained transparent start="\(@' . s:idregex . '\%(\.' . s:idregex . '\)*\)\@=\1\%([^(]\|$\)" end="\ze\%([])};#]\|$\|\<for\>\|\<end\>\)" contains=@juliaExpressions,juliaMacro,juliaSymbolS,juliaQuotedParBlockS' +exec 'syntax region juliaMacroCall contained transparent start="\(@.\)\@=\1\%([^(]\|$\)" end="\ze\%([])};#]\|$\|\<for\>\|\<end\>\)" contains=@juliaExpressions,juliaMacro,juliaSymbolS,juliaQuotedParBlockS' +exec 'syntax region juliaMacroCallP contained transparent start="@' . s:idregex . '\%(\.' . s:idregex . '\)*(" end=")\@'.s:d(1).'<=" contains=juliaMacro,juliaParBlock' +exec 'syntax region juliaMacroCallP contained transparent start="@.(" end=")\@'.s:d(1).'<=" contains=juliaMacro,juliaParBlock' + +exec 'syntax match juliaNumbers transparent "\%(^\|[' . s:nonidS_chars . s:op_chars_wc . ']\)\@'.s:d(1).'<=\d\|\.\d\|im\>" contains=juliaNumber,juliaFloat,juliaComplexUnit' + +"integer regexes +let s:dec_regex = '\d\%(_\?\d\)*\%(\>\|im\>\|\ze\D\)' +let s:hex_regex = '0x\x\%(_\?\x\)*\%(\>\|im\>\|\ze\X\)' +let s:bin_regex = '0b[01]\%(_\?[01]\)*\%(\>\|im\>\|\ze[^01]\)' +let s:oct_regex = '0o\o\%(_\?\o\)*\%(\>\|im\>\|\ze\O\)' + +let s:int_regex = '\%(' . s:hex_regex . + \ '\|' . s:bin_regex . + \ '\|' . s:oct_regex . + \ '\|' . s:dec_regex . + \ '\)' + +"floating point regexes +" starting with a dot, optional exponent +let s:float_regex1 = '\.\d\%(_\?\d\)*\%([eEf][-+]\?\d\+\)\?\%(\>\|im\>\|\ze\D\)' +" with dot, optional exponent +let s:float_regex2 = '\d\%(_\?\d\)*\.\%(\d\%(_\?\d\)*\)\?\%([eEf][-+]\?\d\+\)\?\%(\>\|im\>\|\ze\D\)' +" without dot, with exponent +let s:float_regex3 = '\d\%(_\?\d\)*[eEf][-+]\?\d\+\%(\>\|im\>\|\ze\D\)' + +"hex floating point numbers +" starting with a dot +let s:hexfloat_regex1 = '0x\.\%\(\x\%(_\?\x\)*\)\?[pP][-+]\?\d\+\%(\>\|im\>\|\ze\X\)' +" starting with a digit +let s:hexfloat_regex2 = '0x\x\%(_\?\x\)*\%\(\.\%\(\x\%(_\?\x\)*\)\?\)\?[pP][-+]\?\d\+\%(\>\|im\>\|\ze\X\)' + +let s:float_regex = '\%(' . s:float_regex3 . + \ '\|' . s:float_regex2 . + \ '\|' . s:float_regex1 . + \ '\|' . s:hexfloat_regex2 . + \ '\|' . s:hexfloat_regex1 . + \ '\)' + +exec 'syntax match juliaNumber contained "' . s:int_regex . '" contains=juliaComplexUnit' +exec 'syntax match juliaFloat contained "' . s:float_regex . '" contains=juliaComplexUnit' +syntax match juliaComplexUnit display contained "\<im\>" + +syntax match juliaRangeOperator display ":" +exec 'syntax match juliaOperator "' . s:operators . '"' + +exec 'syntax region juliaTernaryRegion matchgroup=juliaTernaryOperator start="\s\zs?\ze\s" skip="\%(:\(:\|[^:[:space:]'."'".'"({[]\+\s*\ze:\)\|\%(?\s*\)\@'.s:d(6).'<=:(\)" end=":" contains=@juliaExpressions,juliaErrorSemicol' + +let s:interp_dollar = '\([' . s:nonidS_chars . s:op_chars_wc . '!]\|^\)\@'.s:d(1).'<=\$' + +exec 'syntax match juliaDollarVar display contained "' . s:interp_dollar . s:idregex . '"' +exec 'syntax region juliaDollarPar matchgroup=juliaDollarVar contained start="' .s:interp_dollar . '(" end=")" contains=@juliaExpressions' +exec 'syntax region juliaDollarSqBra matchgroup=juliaDollarVar contained start="' .s:interp_dollar . '\[" end="\]" contains=@juliaExpressions,juliaComprehensionFor,juliaSymbolS,juliaQuotedParBlockS' + +syntax match juliaChar "'\\\?.'" contains=juliaSpecialChar +syntax match juliaChar display "'\\\o\{3\}'" contains=juliaOctalEscapeChar +syntax match juliaChar display "'\\x\x\{2\}'" contains=juliaHexEscapeChar +syntax match juliaChar display "'\\u\x\{1,4\}'" contains=juliaUniCharSmall +syntax match juliaChar display "'\\U\x\{1,8\}'" contains=juliaUniCharLarge + +exec 'syntax match juliaCTransOperator "[[:space:]}' . s:nonid_chars . s:op_chars_wc . '!]\@'.s:d(1).'<!\.\?' . "'" . 'ᵀ\?"' + +" TODO: some of these might be specialized; the rest could be just left to the +" generic juliaStringPrefixed fallback +syntax region juliaString matchgroup=juliaStringDelim start=+\z("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1+ contains=@juliaStringVars,@juliaSpecialChars,@juliaSpellcheckStrings +syntax region juliaStringPrefixed contained matchgroup=juliaStringDelim start=+[^{([:space:]<>"]\+\z("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1+ contains=@juliaSpecialCharsRaw +syntax region juliabString matchgroup=juliaStringDelim start=+\<b\z("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1+ contains=@juliaSpecialChars +syntax region juliasString matchgroup=juliaStringDelim start=+\<s\z("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1+ contains=@juliaSpecialChars + +syntax region juliaDocString matchgroup=juliaDocStringDelim fold start=+^"""+ skip=+\%(\\\\\)*\\"+ end=+"""+ contains=@juliaStringVars,@juliaSpecialChars,@juliaSpellcheckDocStrings + +exec 'syntax region juliaPrintfMacro contained transparent start="@s\?printf(" end=")\@'.s:d(1).'<=" contains=juliaMacro,juliaPrintfParBlock' +syntax region juliaPrintfMacro contained transparent start="@s\?printf\s\+" end="\ze\%([])};#]\|$\|\<for\>\)" contains=@juliaExprsPrintf,juliaMacro,juliaSymbolS,juliaQuotedParBlockS +syntax region juliaPrintfParBlock contained matchgroup=juliaParDelim start="(" end=")" contains=@juliaExprsPrintf +syntax region juliaPrintfString contained matchgroup=juliaStringDelim start=+"+ skip=+\%(\\\\\)*\\"+ end=+"+ contains=@juliaSpecialChars,@juliaPrintfChars + +exec 'syntax region juliaDocMacroPre contained transparent start=+@doc\s\+\%(' . s:idregex . '\%(\.' . s:idregex . '\)*\)\z("\%(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\(\z1\)\@'.s:d(3).'<=+ contains=juliaMacro,juliaDocStringMRaw' +exec 'syntax region juliaDocMacro contained transparent start=+@doc\s\+\z("\%(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\(\z1\)\@'.s:d(3).'<=+ contains=juliaMacro,juliaDocStringM' +syntax region juliaDocStringMRaw contained fold matchgroup=juliaDocStringDelim fold start=+\z\("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1+ contains=@juliaSpellcheckDocStrings +syntax region juliaDocStringM contained fold matchgroup=juliaDocStringDelim fold start=+\z\("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1+ contains=@juliaStringVars,@juliaSpecialChars,@juliaSpellcheckDocStrings + +syntax region juliaShellString matchgroup=juliaStringDelim start=+`+ skip=+\%(\\\\\)*\\`+ end=+`+ contains=@juliaStringVars,juliaSpecialChar + +syntax cluster juliaStringVars contains=juliaStringVarsPar,juliaStringVarsSqBra,juliaStringVarsCurBra,juliaStringVarsPla +syntax region juliaStringVarsPar contained matchgroup=juliaStringVarDelim start="$(" end=")" contains=@juliaExpressions +syntax region juliaStringVarsSqBra contained matchgroup=juliaStringVarDelim start="$\[" end="\]" contains=@juliaExpressions,juliaComprehensionFor,juliaSymbolS,juliaQuotedParBlockS +syntax region juliaStringVarsCurBra contained matchgroup=juliaStringVarDelim start="${" end="}" contains=@juliaExpressions +exec 'syntax match juliaStringVarsPla contained "\$' . s:idregex . '"' + +" TODO improve RegEx +syntax region juliaRegEx matchgroup=juliaStringDelim start=+\<r\z("\(""\)\?\)+ skip=+\%(\\\\\)*\\"+ end=+\z1[imsx]*+ + +syntax cluster juliaSpecialChars contains=juliaSpecialChar,juliaDoubleBackslash,juliaEscapedQuote,juliaOctalEscapeChar,juliaHexEscapeChar,juliaUniCharSmall,juliaUniCharLarge +syntax match juliaSpecialChar display contained "\\." +syntax match juliaOctalEscapeChar display contained "\\\o\{3\}" +syntax match juliaHexEscapeChar display contained "\\x\x\{2\}" +syntax match juliaUniCharSmall display contained "\\u\x\{1,4\}" +syntax match juliaUniCharLarge display contained "\\U\x\{1,8\}" +syntax cluster juliaSpecialCharsRaw contains=juliaDoubleBackslash,juliaEscapedQuote +syntax match juliaDoubleBackslash contained "\\\\" +syntax match juliaEscapedQuote contained "\\\"" + +syntax cluster juliaPrintfChars contains=juliaErrorPrintfFmt,juliaPrintfFmt +syntax match juliaErrorPrintfFmt display contained "\\\?%." +syntax match juliaPrintfFmt display contained "%\%(\d\+\$\)\=[-+' #0]*\%(\d*\|\*\|\*\d\+\$\)\%(\.\%(\d*\|\*\|\*\d\+\$\)\)\=\%([hlLjqzt]\|ll\|hh\)\=[aAbdiuoxXDOUfFeEgGcCsSpn]" +syntax match juliaPrintfFmt display contained "%%" +syntax match juliaPrintfFmt display contained "\\%\%(\d\+\$\)\=[-+' #0]*\%(\d*\|\*\|\*\d\+\$\)\%(\.\%(\d*\|\*\|\*\d\+\$\)\)\=\%([hlLjqzt]\|ll\|hh\)\=[aAbdiuoxXDOUfFeEgGcCsSpn]"hs=s+1 +syntax match juliaPrintfFmt display contained "\\%%"hs=s+1 + +" this is used to restrict the search for Symbols to when colons appear at all +" (for performance reasons) +syntax match juliaPossibleSymbol transparent ":\ze[^:]" contains=juliaSymbol,juliaQuotedParBlock,juliaQuotedQMarkPar,juliaColon + +let s:quotable = '\%(' . s:idregex . '\|' . s:operators . '\|[?.]\|' . s:float_regex . '\|' . s:int_regex . '\)' +let s:quoting_colon = '\%(\%(^\s*\|\s\{6,\}\|[' . s:nonid_chars . s:op_chars_wc . ']\s*\)\@'.s:d(6).'<=\|\%(\<\%(return\|if\|else\%(if\)\?\|while\|try\|begin\)\s\+\)\@'.s:d(9).'<=\)\zs:' +let s:quoting_colonS = '\s\@'.s:d(1).'<=:' + +" note: juliaSymbolS only works within whitespace-sensitive contexts, +" such as in macro calls without parentheses, or within square brackets. +" It is used to override the recognition of expressions like `a :b` as +" ranges rather than symbols in those contexts. +" (Note that such `a :b` expressions only allows at most 5 spaces between +" the identifier and the colon anyway.) + +exec 'syntax match juliaSymbol contained "' . s:quoting_colon . s:quotable . '"' +exec 'syntax match juliaSymbolS contained "' . s:quoting_colonS . s:quotable . '"' + +" same as above for quoted expressions such as :(expr) +exec 'syntax region juliaQuotedParBlock matchgroup=juliaQParDelim start="' . s:quoting_colon . '(" end=")" contains=@juliaExpressions' +exec 'syntax match juliaQuotedQMarkPar "' . s:quoting_colon . '(\s*?\s*)" contains=juliaQuotedQMark' +exec 'syntax region juliaQuotedParBlockS matchgroup=juliaQParDelim contained start="' . s:quoting_colonS . '(" end=")" contains=@juliaExpressions' + + +syntax match juliaTypeOperatorR1 contained "[^{([:space:]<>\"]\+\%(\s*[<>]:\)\@=" + +" force precedence over Symbols +syntax match juliaTypeOperator contained "[<>:]:" +exec 'syntax match juliaTypeOperatorR2 transparent "[<>:]:\s*\%(' . s:idregex . '\.\)*' . s:idregex . '" contains=juliaTypeOperator,juliaType,juliaDottedT,@juliaExpressions nextgroup=juliaTypeOperator' +syntax match juliaIsaKeyword contained "\<isa\>" +exec 'syntax match juliaTypeOperatorR3 transparent "\<isa\s\+\%(' . s:idregex . '\.\)*' . s:idregex . '" contains=juliaIsaKeyword,juliaType,juliaDottedT,@juliaExpressions nextgroup=juliaIsaKeyword' + +syntax match juliaWhereKeyword "\<where\>" +exec 'syntax match juliaWhereR transparent "\<where\s\+' . s:idregex . '" contains=juliaWhereKeyword,juliaType,juliaDottedT,juliaIdSymbol' + +syntax region juliaCommentL matchgroup=juliaCommentDelim excludenl start="#\ze\%([^=]\|$\)" end="$" contains=juliaTodo,@juliaSpellcheckComments +syntax region juliaCommentM matchgroup=juliaCommentDelim fold start="#=\ze\%([^#]\|$\)" end="=#" contains=juliaTodo,juliaCommentM,@juliaSpellcheckComments +syntax keyword juliaTodo contained TODO FIXME XXX + +" detect an end-of-line with only whitespace or comments before it +let s:eol = '\s*\%(\%(\%(#=\%(=#\@!\|[^=]\|\n\)\{-}=#\)\s*\)\+\)\?\%(#=\@!.*\)\?\n' + +" a trailing comma, or colon, or an empty line in an import/using/export +" multi-line command. Used to recognize the as keyword, and for indentation +" (this needs to take precedence over normal commas and colons, and comments) +syntax cluster juliaContinuationItems contains=juliaContinuationComma,juliaContinuationColon,juliaContinuationNone +exec 'syntax region juliaContinuationComma matchgroup=juliaComma contained start=",\ze'.s:eol.'" end="\n\+\ze." contains=@juliaCommentItems' +exec 'syntax region juliaContinuationColon matchgroup=juliaColon contained start=":\ze'.s:eol.'" end="\n\+\ze." contains=@juliaCommentItems' +exec 'syntax region juliaContinuationNone matchgroup=NONE contained start="\%(\<\%(import\|using\|export\)\>\|^\)\@'.s:d(6).'<=\ze'.s:eol.'" end="\n\+\ze." contains=@juliaCommentItems,juliaAsKeyword' +exec 'syntax match juliaMacroName contained "@' . s:idregex . '\%(\.' . s:idregex . '\)*"' + +" the following are disabled by default, but +" can be enabled by entering e.g. +" :hi link juliaParDelim Delimiter +hi def link juliaParDelim juliaNone +hi def link juliaSemicolon juliaNone +hi def link juliaComma juliaNone +hi def link juliaFunctionCall juliaNone + +hi def link juliaColon juliaOperator + +hi def link juliaFunctionName juliaFunction +hi def link juliaFunctionName1 juliaFunction +hi def link juliaMacroName juliaMacro + + +hi def link juliaKeyword Keyword +hi def link juliaWhereKeyword Keyword +hi def link juliaInfixKeyword Keyword +hi def link juliaIsaKeyword Keyword +hi def link juliaAsKeyword Keyword +hi def link juliaRepKeyword Keyword +hi def link juliaBlKeyword Keyword +hi def link juliaConditional Conditional +hi def link juliaRepeat Repeat +hi def link juliaException Exception +hi def link juliaOuter Keyword +hi def link juliaBaseTypeBasic Type +hi def link juliaBaseTypeNum Type +hi def link juliaBaseTypeC Type +hi def link juliaBaseTypeError Type +hi def link juliaBaseTypeIter Type +hi def link juliaBaseTypeString Type +hi def link juliaBaseTypeArray Type +hi def link juliaBaseTypeDict Type +hi def link juliaBaseTypeSet Type +hi def link juliaBaseTypeIO Type +hi def link juliaBaseTypeProcess Type +hi def link juliaBaseTypeRange Type +hi def link juliaBaseTypeRegex Type +hi def link juliaBaseTypeFact Type +hi def link juliaBaseTypeSort Type +hi def link juliaBaseTypeRound Type +hi def link juliaBaseTypeSpecial Type +hi def link juliaBaseTypeRandom Type +hi def link juliaBaseTypeDisplay Type +hi def link juliaBaseTypeTime Type +hi def link juliaBaseTypeOther Type + +hi def link juliaType Type +hi def link juliaParamType Type +hi def link juliaTypeOperatorR1 Type + +" NOTE: deprecated constants are not highlighted as such. For once, +" one can still legitimately use them by importing Base.MathConstants. +" Plus, one-letter variables like `e` and `γ` can be used with other +" meanings. +hi def link juliaConstNum Constant +hi def link juliaEuler Constant + +hi def link juliaConstEnv Constant +hi def link juliaConstC Constant +hi def link juliaConstLimits Constant +hi def link juliaConstGeneric Constant +hi def link juliaRangeKeyword Constant +hi def link juliaConstBool Boolean +hi def link juliaConstIO Boolean + +hi def link juliaComprehensionFor Keyword +hi def link juliaComprehensionIf Keyword + +hi def link juliaDollarVar Identifier + +hi def link juliaFunction Function +hi def link juliaMacro Macro +hi def link juliaSymbol Identifier +hi def link juliaSymbolS Identifier +hi def link juliaQParDelim Identifier +hi def link juliaQuotedQMarkPar Identifier +hi def link juliaQuotedQMark juliaOperatorHL + +hi def link juliaNumber Number +hi def link juliaFloat Float +hi def link juliaComplexUnit Constant + +hi def link juliaChar Character + +hi def link juliaString String +hi def link juliaStringPrefixed juliaString +hi def link juliabString juliaString +hi def link juliasString juliaString +hi def link juliavString juliaString +hi def link juliarString juliaString +hi def link juliaipString juliaString +hi def link juliabigString juliaString +hi def link juliaMIMEString juliaString +hi def link juliarawString juliaString +hi def link juliatestString juliaString +hi def link juliahtmlString juliaString +hi def link juliaint128String juliaString +hi def link juliaPrintfString juliaString +hi def link juliaShellString juliaString +hi def link juliaDocString juliaString +hi def link juliaDocStringM juliaDocString +hi def link juliaDocStringMRaw juliaDocString +hi def link juliaStringDelim juliaString +hi def link juliaDocStringDelim juliaDocString +hi def link juliaStringVarsPla Identifier +hi def link juliaStringVarDelim Identifier + +hi def link juliaRegEx String + +hi def link juliaSpecialChar SpecialChar +hi def link juliaOctalEscapeChar SpecialChar +hi def link juliaHexEscapeChar SpecialChar +hi def link juliaUniCharSmall SpecialChar +hi def link juliaUniCharLarge SpecialChar +hi def link juliaDoubleBackslash SpecialChar +hi def link juliaEscapedQuote SpecialChar + +hi def link juliaPrintfFmt SpecialChar + +if s:julia_highlight_operators + hi! def link juliaOperatorHL Operator +else + hi! def link juliaOperatorHL juliaNone +endif +hi def link juliaOperator juliaOperatorHL +hi def link juliaRangeOperator juliaOperatorHL +hi def link juliaCTransOperator juliaOperatorHL +hi def link juliaTernaryOperator juliaOperatorHL +hi def link juliaTypeOperator juliaOperatorHL + +hi def link juliaCommentL Comment +hi def link juliaCommentM Comment +hi def link juliaCommentDelim Comment +hi def link juliaTodo Todo + +hi def link juliaErrorPar juliaError +hi def link juliaErrorEnd juliaError +hi def link juliaErrorElse juliaError +hi def link juliaErrorCatch juliaError +hi def link juliaErrorFinally juliaError +hi def link juliaErrorSemicol juliaError +hi def link juliaErrorPrintfFmt juliaError + +hi def link juliaError Error + +syntax sync fromstart + +let b:current_syntax = "julia" + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/scripts/release.sh b/scripts/release.sh index 4d1484b77a..4ec959d697 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -12,6 +12,7 @@ # - CMakeLists.txt: Unset NVIM_VERSION_PRERELEASE # - CMakeLists.txt: Unset NVIM_API_PRERELEASE # - Create test/functional/fixtures/api_level_N.mpack +# - Add date and version to runtime/nvim.appdata.xml # - Tag the commit. # Create the "version bump" commit: # - CMakeLists.txt: Set NVIM_VERSION_PRERELEASE to "-dev" @@ -62,6 +63,10 @@ _do_release_commit() { git add test/functional/fixtures/api_level_$__API_LEVEL.mpack fi + $__sed -i.bk 's,(<releases>),\1\ + <release date="'"${__DATE}"'" version="'"${__VERSION}"'"/>,' runtime/nvim.appdata.xml + git add runtime/nvim.appdata.xml + if ! test "$ARG1" = '--use-current-commit' ; then echo "Building changelog since ${__LAST_TAG}..." @@ -75,14 +80,12 @@ _do_release_commit() { _do_bump_commit() { $__sed -i.bk 's/(NVIM_VERSION_PRERELEASE) ""/\1 "-dev"/' CMakeLists.txt $__sed -i.bk 's/set\((NVIM_VERSION_PATCH) [[:digit:]]/set(\1 ?/' CMakeLists.txt - $__sed -i.bk 's,(<releases>),\1\ - <release date="'"${__DATE}"'" version="xxx"/>,' runtime/nvim.appdata.xml rm CMakeLists.txt.bk rm runtime/nvim.appdata.xml.bk nvim +'/NVIM_VERSION' +1new +'exe "norm! iUpdate version numbers!!!"' \ - -O CMakeLists.txt runtime/nvim.appdata.xml + -O CMakeLists.txt - git add CMakeLists.txt runtime/nvim.appdata.xml + git add CMakeLists.txt git commit -m "$__BUMP_MSG" } @@ -92,11 +95,7 @@ fi _do_bump_commit echo " Next steps: - - Update runtime/nvim.appdata.xml on _master_ - Run tests/CI (version_spec.lua)! - Push the tag: git push --follow-tags - - Update the 'stable' tag: - git push --force upstream HEAD^:refs/tags/stable - git fetch --tags - Update website: index.html" diff --git a/scripts/squash_typos.py b/scripts/squash_typos.py index e7ee2e24a8..26be6010a2 100644 --- a/scripts/squash_typos.py +++ b/scripts/squash_typos.py @@ -7,17 +7,16 @@ This script squashes a PR tagged with the "typo" label into a single, dedicated """ import subprocess +import sys import os -import re def get_authors_and_emails_from_pr(): """ - For a given PR number, returns all contributing authors and their emails - for that PR. This includes co-authors, meaning that if two authors are - credited for a single commit, which is possible with GitHub, then both will - get credited. + Return all contributing authors and their emails for the PR on current branch. + This includes co-authors, meaning that if two authors are credited for a + single commit, which is possible with GitHub, then both will get credited. """ @@ -33,44 +32,85 @@ def get_authors_and_emails_from_pr(): text=True, ).splitlines() - return [(author, mail) for author, mail in zip(authors, emails)] + authors_and_emails_unique = { + (author, mail) for author, mail in zip(authors, emails) + } + return sorted(authors_and_emails_unique) -def rebase_onto_pr(pr, squash_branch): + +def rebase_squash_branch_onto_pr(): """ - Add all commits from PR into current branch. This is done by rebasing - current branch onto the PR. + Rebase current branch onto the PR. """ # Check out the pull request. - subprocess.call(["gh", "pr", "checkout", pr]) + subprocess.call(["gh", "pr", "checkout", os.environ["PR_NUMBER"]]) - pr_branch_name = subprocess.check_output( - ["git", "branch", "--show-current"], text=True - ).strip() + # Rebase onto master + default_branch = f"{os.environ['GITHUB_BASE_REF']}" + subprocess.check_call(["git", "rebase", default_branch]) # Change back to the original branch. - subprocess.call(["git", "switch", squash_branch]) + subprocess.call(["git", "switch", "-"]) + + # Rebase onto the pull request, aka include the commits in the pull request + # in the current branch. Abort with error message if rebase fails. - # Rebase onto the pull request, aka include the commits in the pull - # request in the current branch. - subprocess.call(["git", "rebase", pr_branch_name]) + try: + subprocess.check_call(["git", "rebase", "-"]) + except subprocess.CalledProcessError: + subprocess.call(["git", "rebase", "--abort"]) + 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"Your edit conflicts with an already scheduled fix \ + ({squash_url}). Please check that batch PR whether your fix is \ + already included; if not, then please wait until the batch PR \ + is merged and then rebase your PR on top of master.", + ] + ) + + sys.exit( + f"\n\nERROR: Your edit conflicts with an already scheduled fix \ +{squash_url} \n\n" + ) + + +def rebase_squash_branch_onto_master(): + """ + + Rebase current branch onto the master i.e. make sure current branch is up + to date. Abort on error. + + """ + + default_branch = f"{os.environ['GITHUB_BASE_REF']}" + subprocess.check_call(["git", "rebase", default_branch]) def squash_all_commits(): """ - Squash all commits into a single commit. Credit all authors by name and - email. + Squash all commits on the PR into a single commit. Credit all authors by + name and email. """ - authors_and_emails = get_authors_and_emails_from_pr() - subprocess.call(["git", "reset", "--soft", f"{os.environ['GITHUB_BASE_REF']}"]) + default_branch = f"{os.environ['GITHUB_BASE_REF']}" + subprocess.call(["git", "reset", "--soft", default_branch]) - authors_and_emails = sorted(set(authors_and_emails)) + 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] ) @@ -80,6 +120,12 @@ def squash_all_commits(): def force_push(branch): + """ + + Like the name implies, force push <branch>. + + """ + gh_actor = os.environ["GITHUB_ACTOR"] gh_token = os.environ["GITHUB_TOKEN"] gh_repo = os.environ["GITHUB_REPOSITORY"] @@ -94,55 +140,84 @@ def force_push(branch): ) -def main(): - squash_branch = "marvim/squash-typos" - all_pr_urls = "" +def checkout_branch(branch): + """ + + Create and checkout <branch>. Check if branch exists on remote, if so then + sync local branch to remote. - pr_number = re.sub(r"\D", "", os.environ["GITHUB_REF"]) + Return True if remote branch exists, else False. + + """ + + # FIXME I'm not sure why the local branch isn't tracking the remote branch + # automatically. This works but I'm pretty sure it can be done in a more + # "elegant" fashion show_ref_output = subprocess.check_output(["git", "show-ref"], text=True).strip() - if squash_branch in show_ref_output: - subprocess.call( - ["git", "checkout", "-b", squash_branch, f"origin/{squash_branch}"] - ) - squash_branch_exists = True + if branch in show_ref_output: + subprocess.call(["git", "checkout", "-b", branch, f"origin/{branch}"]) + return True + + subprocess.call(["git", "checkout", "-b", branch]) + return False + + +def get_all_pr_urls(squash_branch_exists): + """ + + Return a list of URLs for the pull requests with the typo fixes. If a + squash branch exists then extract the URLs from the body text. + """ + + all_pr_urls = "" + if squash_branch_exists: all_pr_urls += subprocess.check_output( ["gh", "pr", "view", "--json", "body", "--jq", ".body"], text=True ) - else: - subprocess.call(["git", "checkout", "-b", squash_branch]) - squash_branch_exists = False all_pr_urls += subprocess.check_output( - ["gh", "pr", "view", pr_number, "--json", "url", "--jq", ".url"], text=True + ["gh", "pr", "view", os.environ["PR_NUMBER"], "--json", "url", "--jq", ".url"], + text=True, ).strip() - rebase_onto_pr(pr_number, squash_branch) + return all_pr_urls + + +def main(): + squash_branch = "marvim/squash-typos" + + squash_branch_exists = checkout_branch(squash_branch) + + rebase_squash_branch_onto_master() + force_push(squash_branch) + + rebase_squash_branch_onto_pr() force_push(squash_branch) - subprocess.call(["gh", "pr", "close", pr_number]) + subprocess.call( + [ + "gh", + "pr", + "create", + "--fill", + "--head", + squash_branch, + "--title", + "chore: typo fixes (automated)", + ] + ) squash_all_commits() force_push(squash_branch) - if not squash_branch_exists: - subprocess.call( - [ - "gh", - "pr", - "create", - "--fill", - "--head", - squash_branch, - "--title", - "Dedicated PR for all typo fixes.", - ] - ) - + all_pr_urls = get_all_pr_urls(squash_branch_exists) subprocess.call(["gh", "pr", "edit", "--add-label", "typo", "--body", all_pr_urls]) + subprocess.call(["gh", "pr", "close", os.environ["PR_NUMBER"]]) + if __name__ == "__main__": main() diff --git a/src/clint.py b/src/clint.py index 4a5e435bbd..e7d76366b0 100755 --- a/src/clint.py +++ b/src/clint.py @@ -264,7 +264,7 @@ _error_suppressions_2 = set() # The allowed line length of files. # This is set by --linelength flag. -_line_length = 80 +_line_length = 100 # The allowed extensions for file names # This is set by --extensions flag. diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 58ee53a408..400dbb126c 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -2301,7 +2301,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, } } } - ParserLine plines[] = { + ParserLine parser_lines[] = { { .data = expr.data, .size = expr.size, @@ -2309,7 +2309,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, }, { NULL, 0, false }, }; - ParserLine *plines_p = plines; + ParserLine *plines_p = parser_lines; ParserHighlight colors; kvi_init(colors); ParserHighlight *const colors_p = (highlight ? &colors : NULL); @@ -2335,7 +2335,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight, ret.items[ret.size++] = (KeyValuePair) { .key = STATIC_CSTR_TO_STRING("len"), .value = INTEGER_OBJ((Integer)(pstate.pos.line == 1 - ? plines[0].size + ? parser_lines[0].size : pstate.pos.col)), }; if (east.err.msg != NULL) { diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 145f6f5601..bec9808183 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -1724,7 +1724,7 @@ BYPASS_AU: void block_autocmds(void) { // Remember the value of v:termresponse. - if (is_autocmd_blocked()) { + if (!is_autocmd_blocked()) { old_termresponse = get_vim_var_str(VV_TERMRESPONSE); } autocmd_blocked++; @@ -1737,7 +1737,7 @@ void unblock_autocmds(void) // When v:termresponse was set while autocommands were blocked, trigger // the autocommands now. Esp. useful when executing a shell command // during startup (nvim -d). - if (is_autocmd_blocked() + if (!is_autocmd_blocked() && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse) { apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, false, curbuf); } diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 587ef74b35..29d4fc786a 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4253,7 +4253,7 @@ int build_stl_str_hl( if (*fmt_p == '#') { stl_items[curitem].type = Highlight; stl_items[curitem].start = out_p; - stl_items[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t)); + stl_items[curitem].minwid = -syn_name2id_len(t, (size_t)(fmt_p - t)); curitem++; fmt_p++; } diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 1247e48c5f..b03d69a04c 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1298,7 +1298,7 @@ struct window_S { /* * w_cline_height is the number of physical lines taken by the buffer line - * that the cursor is on. We use this to avoid extra calls to plines(). + * that the cursor is on. We use this to avoid extra calls to plines_win(). */ int w_cline_height; // current size of cursor line bool w_cline_folded; // cursor line is folded diff --git a/src/nvim/change.c b/src/nvim/change.c index 49e403425a..41e1e3911b 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -22,6 +22,7 @@ #include "nvim/misc1.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" @@ -593,9 +594,9 @@ void ins_char_bytes(char_u *buf, size_t charlen) // cells. May result in adding spaces to fill a gap. colnr_T vcol; getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL); - colnr_T new_vcol = vcol + chartabsize(buf, vcol); + colnr_T new_vcol = vcol + win_chartabsize(curwin, buf, vcol); while (oldp[col + oldlen] != NUL && vcol < new_vcol) { - vcol += chartabsize(oldp + col + oldlen, vcol); + vcol += win_chartabsize(curwin, oldp + col + oldlen, vcol); // Don't need to remove a TAB that takes us to the right // position. if (vcol > new_vcol && oldp[col + oldlen] == TAB) { diff --git a/src/nvim/charset.c b/src/nvim/charset.c index e2d844a351..0252ef4e9c 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -25,6 +25,7 @@ #include "nvim/move.h" #include "nvim/option.h" #include "nvim/os_unix.h" +#include "nvim/plines.h" #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/path.h" @@ -733,80 +734,6 @@ int vim_strnsize(char_u *s, int len) return size; } -/// Return the number of characters 'c' will take on the screen, taking -/// into account the size of a tab. -/// Use a define to make it fast, this is used very often!!! -/// Also see getvcol() below. -/// -/// @param p -/// @param col -/// -/// @return Number of characters. -#define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \ - if (*(p) == TAB && (!(wp)->w_p_list || wp->w_p_lcs_chars.tab1)) { \ - return tabstop_padding(col, (buf)->b_p_ts, (buf)->b_p_vts_array); \ - } else { \ - return ptr2cells(p); \ - } - -int chartabsize(char_u *p, colnr_T col) -{ - RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col) -} - -static int win_chartabsize(win_T *wp, char_u *p, colnr_T col) -{ - RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col) -} - -/// Return the number of characters the string 's' will take on the screen, -/// taking into account the size of a tab. -/// -/// @param s -/// -/// @return Number of characters the string will take on the screen. -int linetabsize(char_u *s) -{ - return linetabsize_col(0, s); -} - -/// Like linetabsize(), but starting at column "startcol". -/// -/// @param startcol -/// @param s -/// -/// @return Number of characters the string will take on the screen. -int linetabsize_col(int startcol, char_u *s) -{ - colnr_T col = startcol; - char_u *line = s; /* pointer to start of line, for breakindent */ - - while (*s != NUL) { - col += lbr_chartabsize_adv(line, &s, col); - } - return (int)col; -} - -/// Like linetabsize(), but for a given window instead of the current one. -/// -/// @param wp -/// @param line -/// @param len -/// -/// @return Number of characters the string will take on the screen. -unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len) -{ - colnr_T col = 0; - - for (char_u *s = line; - *s != NUL && (len == MAXCOL || s < line + len); - MB_PTR_ADV(s)) { - col += win_lbr_chartabsize(wp, line, s, col, NULL); - } - - return (unsigned int)col; -} - /// Check that "c" is a normal identifier character: /// Letters and characters from the 'isident' option. /// @@ -936,229 +863,6 @@ bool vim_isprintc_strict(int c) return c > 0 && (g_chartab[c] & CT_PRINT_CHAR); } -/// like chartabsize(), but also check for line breaks on the screen -/// -/// @param line -/// @param s -/// @param col -/// -/// @return The number of characters taken up on the screen. -int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col) -{ - if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) { - if (curwin->w_p_wrap) { - return win_nolbr_chartabsize(curwin, s, col, NULL); - } - RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col) - } - return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL); -} - -/// Call lbr_chartabsize() and advance the pointer. -/// -/// @param line -/// @param s -/// @param col -/// -/// @return The number of characters take up on the screen. -int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col) -{ - int retval; - - retval = lbr_chartabsize(line, *s, col); - MB_PTR_ADV(*s); - return retval; -} - -/// This function is used very often, keep it fast!!!! -/// -/// If "headp" not NULL, set *headp to the size of what we for 'showbreak' -/// string at start of line. Warning: *headp is only set if it's a non-zero -/// value, init to 0 before calling. -/// -/// @param wp -/// @param line -/// @param s -/// @param col -/// @param headp -/// -/// @return The number of characters taken up on the screen. -int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp) -{ - colnr_T col2; - colnr_T col_adj = 0; /* col + screen size of tab */ - colnr_T colmax; - int added; - int mb_added = 0; - int numberextra; - char_u *ps; - int n; - - // No 'linebreak', 'showbreak' and 'breakindent': return quickly. - if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) { - if (wp->w_p_wrap) { - return win_nolbr_chartabsize(wp, s, col, headp); - } - RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col) - } - - // First get normal size, without 'linebreak' - int size = win_chartabsize(wp, s, col); - int c = *s; - if (*s == TAB) { - col_adj = size - 1; - } - - // If 'linebreak' set check at a blank before a non-blank if the line - // needs a break here - if (wp->w_p_lbr - && vim_isbreak(c) - && !vim_isbreak((int)s[1]) - && wp->w_p_wrap - && (wp->w_width_inner != 0)) { - // Count all characters from first non-blank after a blank up to next - // non-blank after a blank. - numberextra = win_col_off(wp); - col2 = col; - colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); - - if (col >= colmax) { - colmax += col_adj; - n = colmax + win_col_off2(wp); - - if (n > 0) { - colmax += (((col - colmax) / n) + 1) * n - col_adj; - } - } - - for (;;) { - ps = s; - MB_PTR_ADV(s); - c = *s; - - if (!(c != NUL - && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) { - break; - } - - col2 += win_chartabsize(wp, s, col2); - - if (col2 >= colmax) { /* doesn't fit */ - size = colmax - col + col_adj; - break; - } - } - } else if ((size == 2) - && (MB_BYTE2LEN(*s) > 1) - && wp->w_p_wrap - && in_win_border(wp, col)) { - // Count the ">" in the last column. - ++size; - mb_added = 1; - } - - // May have to add something for 'breakindent' and/or 'showbreak' - // string at start of line. - // Set *headp to the size of what we add. - added = 0; - - if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) { - colnr_T sbrlen = 0; - int numberwidth = win_col_off(wp); - - numberextra = numberwidth; - col += numberextra + mb_added; - - if (col >= (colnr_T)wp->w_width_inner) { - col -= wp->w_width_inner; - numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp)); - if (col >= numberextra && numberextra > 0) { - col %= numberextra; - } - if (*p_sbr != NUL) { - sbrlen = (colnr_T)MB_CHARLEN(p_sbr); - if (col >= sbrlen) { - col -= sbrlen; - } - } - if (col >= numberextra && numberextra > 0) { - col %= numberextra; - } else if (col > 0 && numberextra > 0) { - col += numberwidth - win_col_off2(wp); - } - - numberwidth -= win_col_off2(wp); - } - - if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) { - if (*p_sbr != NUL) { - if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) { - // Calculate effective window width. - int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth; - int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col)) - : 0; - - if (width <= 0) { - width = 1; - } - added += ((size - prev_width) / width) * vim_strsize(p_sbr); - if ((size - prev_width) % width) { - // Wrapped, add another length of 'sbr'. - added += vim_strsize(p_sbr); - } - } else { - added += vim_strsize(p_sbr); - } - } - - if (wp->w_p_bri) - added += get_breakindent_win(wp, line); - - size += added; - if (col != 0) { - added = 0; - } - } - } - - if (headp != NULL) { - *headp = added + mb_added; - } - return size; -} - -/// Like win_lbr_chartabsize(), except that we know 'linebreak' is off and -/// 'wrap' is on. This means we need to check for a double-byte character that -/// doesn't fit at the end of the screen line. -/// -/// @param wp -/// @param s -/// @param col -/// @param headp -/// -/// @return The number of characters take up on the screen. -static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp) -{ - int n; - - if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { - return tabstop_padding(col, - wp->w_buffer->b_p_ts, - wp->w_buffer->b_p_vts_array); - } - n = ptr2cells(s); - - // Add one cell for a double-width character in the last column of the - // window, displayed with a ">". - if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) { - if (headp != NULL) { - *headp = 1; - } - return 3; - } - return n; -} - /// Check that virtual column "vcol" is in the rightmost column of window "wp". /// /// @param wp window diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 5d2210dc7d..d4a68adeda 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -13,6 +13,7 @@ #include "nvim/memory.h" #include "nvim/misc1.h" #include "nvim/move.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/extmark.h" #include "nvim/state.h" diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 2305faa20c..fec8da2c3c 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -41,6 +41,7 @@ #include "nvim/option.h" #include "nvim/path.h" #include "nvim/popupmnu.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" @@ -7187,7 +7188,7 @@ static void replace_do_bs(int limit_col) // Get the number of screen cells used by the character we are // going to delete. getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL); - orig_vcols = chartabsize(get_cursor_pos_ptr(), start_vcol); + orig_vcols = win_chartabsize(curwin, get_cursor_pos_ptr(), start_vcol); } (void)del_char_after_col(limit_col); if (l_State & VREPLACE_FLAG) { @@ -7201,8 +7202,8 @@ static void replace_do_bs(int limit_col) p = get_cursor_pos_ptr(); ins_len = (int)STRLEN(p) - orig_len; vcol = start_vcol; - for (i = 0; i < ins_len; ++i) { - vcol += chartabsize(p + i, vcol); + for (i = 0; i < ins_len; i++) { + vcol += win_chartabsize(curwin, p + i, vcol); i += (*mb_ptr2len)(p) - 1; } vcol -= start_vcol; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 21c858373c..4e409cca50 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -47,6 +47,7 @@ #include "nvim/os/input.h" #include "nvim/os/shell.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/popupmnu.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" @@ -1055,8 +1056,10 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (virtual_active() && fp == &curwin->w_cursor) { char_u *p = get_cursor_pos_ptr(); - if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, - curwin->w_virtcol - curwin->w_cursor.coladd)) { + if (curwin->w_cursor.coladd + >= (colnr_T)win_chartabsize(curwin, p, + (curwin->w_virtcol + - curwin->w_cursor.coladd))) { int l; if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL) diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 3ad1fb1adc..0c099085a0 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -55,6 +55,7 @@ #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" @@ -828,7 +829,7 @@ void ex_retab(exarg_T *eap) } if (ptr[col] == NUL) break; - vcol += chartabsize(ptr + col, (colnr_T)vcol); + vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol); col += utfc_ptr2len(ptr + col); } if (new_line == NULL) /* out of memory */ @@ -2762,8 +2763,8 @@ int do_ecmd( } } - /* Check if cursors in other windows on the same buffer are still valid */ - check_lnums(FALSE); + // Check if cursors in other windows on the same buffer are still valid + check_lnums(false); /* * Did not read the file, need to show some info about the file. diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index a49b0c15e1..e06a62e0f6 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -1460,7 +1460,7 @@ bool dialog_close_terminal(buf_T *buf) int ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1); - return (ret == VIM_YES) ? true : false; + return ret == VIM_YES; } /// Return true if the buffer "buf" can be abandoned, either by making it diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 2b3d773ca4..7cab3eb650 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2593,7 +2593,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, ColoredCmdline *const ret_ccline_colors) FUNC_ATTR_NONNULL_ALL { - ParserLine plines[] = { + ParserLine parser_lines[] = { { .data = (const char *)colored_ccline->cmdbuff, .size = STRLEN(colored_ccline->cmdbuff), @@ -2601,7 +2601,7 @@ static void color_expr_cmdline(const CmdlineInfo *const colored_ccline, }, { NULL, 0, false }, }; - ParserLine *plines_p = plines; + ParserLine *plines_p = parser_lines; ParserHighlight colors; kvi_init(colors); ParserState pstate; @@ -6259,8 +6259,8 @@ static int open_cmdwin(void) const int histtype = hist_char2type(cmdwin_type); if (histtype == HIST_CMD || histtype == HIST_DEBUG) { if (p_wc == TAB) { - add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT); - add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL); + add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT, false); + add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL, false); } set_option_value("ft", 0L, "vim", OPT_LOCAL); } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index ad8418034a..6989c29d57 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -29,6 +29,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/garray.h" #include "nvim/move.h" #include "nvim/option.h" diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 9f91160034..0454c54faf 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -119,10 +119,10 @@ local get_value = function(v) end local get_defaults = function(d,n) - if (d.vi == nil and d.vim == nil) or (d.vi ~= nil and d.vim ~= nil) then - error("option '"..n.."' should have one and only one default value") + if d == nil then + error("option '"..n.."' should have a default value") end - return get_value(d.vim or d.vi) + return get_value(d) end local defines = {} diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index b0d06b7a30..2b6c5b9f37 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -34,6 +34,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/keymap.h" #include "nvim/garray.h" #include "nvim/move.h" @@ -840,6 +841,14 @@ static void init_typebuf(void) } } +void init_default_mappings(void) +{ + add_map((char_u *)"Y y$", NORMAL, true); + add_map((char_u *)"<C-L> <Cmd>nohlsearch<Bar>diffupdate<CR><C-L>", NORMAL, true); + add_map((char_u *)"<C-U> <C-G>u<C-U>", INSERT, true); + add_map((char_u *)"<C-W> <C-G>u<C-W>", INSERT, true); +} + // Insert a string in position 'offset' in the typeahead buffer (for "@r" // and ":normal" command, vgetorpeek() and check_termcode()) // @@ -1161,7 +1170,7 @@ void may_sync_undo(void) { if ((!(State & (INSERT + CMDLINE)) || arrow_used) && scriptin[curscript] == NULL) - u_sync(FALSE); + u_sync(false); } /* @@ -4356,18 +4365,23 @@ check_map ( } -/* - * Add a mapping "map" for mode "mode". - * Need to put string in allocated memory, because do_map() will modify it. - */ -void add_map(char_u *map, int mode) +/// Add a mapping. Unlike @ref do_map this copies the {map} argument, so +/// static or read-only strings can be used. +/// +/// @param map C-string containing the arguments of the map/abbrev command, +/// i.e. everything except the initial `:[X][nore]map`. +/// @param mode Bitflags representing the mode in which to set the mapping. +/// See @ref get_map_mode. +/// @param nore If true, make a non-recursive mapping. +void add_map(char_u *map, int mode, bool nore) { char_u *s; char_u *cpo_save = p_cpo; p_cpo = (char_u *)""; // Allow <> notation + // Need to put string in allocated memory, because do_map() will modify it. s = vim_strsave(map); - (void)do_map(0, s, mode, FALSE); + (void)do_map(nore ? 2 : 0, s, mode, false); xfree(s); p_cpo = cpo_save; } diff --git a/src/nvim/indent.c b/src/nvim/indent.c index bfb77688b0..a6df0e97e6 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -19,6 +19,7 @@ #include "nvim/misc1.h" #include "nvim/move.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/search.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index 252aa81825..136608afdf 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -166,6 +166,7 @@ void early_init(mparm_T *paramp) init_path(argv0 ? argv0 : "nvim"); init_normal_cmds(); // Init the table of Normal mode commands. highlight_init(); + syntax_init(); #ifdef WIN32 OSVERSIONINFO ovi; @@ -314,6 +315,9 @@ int main(int argc, char **argv) init_highlight(true, false); // Default highlight groups. TIME_MSG("init highlight"); + init_default_mappings(); // Default mappings. + TIME_MSG("init default mappings"); + // Set the break level after the terminal is initialized. debug_break_level = params.use_debug_break_level; diff --git a/src/nvim/map.c b/src/nvim/map.c index 7d97b7f13d..86dc257e40 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -194,6 +194,7 @@ static inline bool ColorKey_eq(ColorKey ae1, ColorKey ae2) MAP_IMPL(int, int, DEFAULT_INITIALIZER) MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER) +MAP_IMPL(cstr_t, int, DEFAULT_INITIALIZER) MAP_IMPL(ptr_t, ptr_t, DEFAULT_INITIALIZER) MAP_IMPL(uint64_t, ptr_t, DEFAULT_INITIALIZER) MAP_IMPL(uint64_t, ssize_t, SSIZE_INITIALIZER) diff --git a/src/nvim/map.h b/src/nvim/map.h index 7bd3d31330..a35a2c1672 100644 --- a/src/nvim/map.h +++ b/src/nvim/map.h @@ -36,6 +36,7 @@ // MAP_DECLS(int, int) MAP_DECLS(cstr_t, ptr_t) +MAP_DECLS(cstr_t, int) MAP_DECLS(ptr_t, ptr_t) MAP_DECLS(uint64_t, ptr_t) MAP_DECLS(uint64_t, ssize_t) diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 771174b854..6d94632687 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -349,178 +349,6 @@ int get_last_leader_offset(char_u *line, char_u **flags) return result; } -/* - * Return the number of window lines occupied by buffer line "lnum". - */ -int plines(const linenr_T lnum) -{ - return plines_win(curwin, lnum, true); -} - -int plines_win( - win_T *const wp, - const linenr_T lnum, - const bool winheight // when true limit to window height -) -{ - /* Check for filler lines above this buffer line. When folded the result - * is one line anyway. */ - return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum); -} - -int plines_nofill(const linenr_T lnum) -{ - return plines_win_nofill(curwin, lnum, true); -} - -int plines_win_nofill( - win_T *const wp, - const linenr_T lnum, - const bool winheight // when true limit to window height -) -{ - if (!wp->w_p_wrap) { - return 1; - } - - if (wp->w_width_inner == 0) { - return 1; - } - - // A folded lines is handled just like an empty line. - if (lineFolded(wp, lnum)) { - return 1; - } - - const int lines = plines_win_nofold(wp, lnum); - if (winheight && lines > wp->w_height_inner) { - return wp->w_height_inner; - } - return lines; -} - -/* - * Return number of window lines physical line "lnum" will occupy in window - * "wp". Does not care about folding, 'wrap' or 'diff'. - */ -int plines_win_nofold(win_T *wp, linenr_T lnum) -{ - char_u *s; - unsigned int col; - int width; - - s = ml_get_buf(wp->w_buffer, lnum, FALSE); - if (*s == NUL) /* empty line */ - return 1; - col = win_linetabsize(wp, s, MAXCOL); - - // If list mode is on, then the '$' at the end of the line may take up one - // extra column. - if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) { - col += 1; - } - - /* - * Add column offset for 'number', 'relativenumber' and 'foldcolumn'. - */ - width = wp->w_width_inner - win_col_off(wp); - if (width <= 0 || col > 32000) { - return 32000; // bigger than the number of screen columns - } - if (col <= (unsigned int)width) { - return 1; - } - col -= (unsigned int)width; - width += win_col_off2(wp); - assert(col <= INT_MAX && (int)col < INT_MAX - (width -1)); - return ((int)col + (width - 1)) / width + 1; -} - -/* - * Like plines_win(), but only reports the number of physical screen lines - * used from the start of the line to the given column number. - */ -int plines_win_col(win_T *wp, linenr_T lnum, long column) -{ - // Check for filler lines above this buffer line. When folded the result - // is one line anyway. - int lines = diff_check_fill(wp, lnum); - - if (!wp->w_p_wrap) - return lines + 1; - - if (wp->w_width_inner == 0) { - return lines + 1; - } - - char_u *line = ml_get_buf(wp->w_buffer, lnum, false); - char_u *s = line; - - colnr_T col = 0; - while (*s != NUL && --column >= 0) { - col += win_lbr_chartabsize(wp, line, s, col, NULL); - MB_PTR_ADV(s); - } - - // If *s is a TAB, and the TAB is not displayed as ^I, and we're not in - // INSERT mode, then col must be adjusted so that it represents the last - // screen position of the TAB. This only fixes an error when the TAB wraps - // from one screen line to the next (when 'columns' is not a multiple of - // 'ts') -- webb. - if (*s == TAB && (State & NORMAL) - && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { - col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1; - } - - // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. - int width = wp->w_width_inner - win_col_off(wp); - if (width <= 0) { - return 9999; - } - - lines += 1; - if (col > width) - lines += (col - width) / (width + win_col_off2(wp)) + 1; - return lines; -} - -/// Get the number of screen lines lnum takes up. This takes care of -/// both folds and topfill, and limits to the current window height. -/// -/// @param[in] wp window line is in -/// @param[in] lnum line number -/// @param[out] nextp if not NULL, the line after a fold -/// @param[out] foldedp if not NULL, whether lnum is on a fold -/// @param[in] cache whether to use the window's cache for folds -/// -/// @return the total number of screen lines -int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, - bool *const foldedp, const bool cache) -{ - bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL); - if (foldedp) { - *foldedp = folded; - } - if (folded) { - return 1; - } else if (lnum == wp->w_topline) { - return plines_win_nofill(wp, lnum, true) + wp->w_topfill; - } - return plines_win(wp, lnum, true); -} - -int plines_m_win(win_T *wp, linenr_T first, linenr_T last) -{ - int count = 0; - - while (first <= last) { - linenr_T next = first; - count += plines_win_full(wp, first, &next, NULL, false); - first = next + 1; - } - return count; -} - int gchar_pos(pos_T *pos) FUNC_ATTR_NONNULL_ARG(1) { diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index f1ad0ed105..6c25525936 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -18,6 +18,7 @@ #include "nvim/diff.h" #include "nvim/move.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/cursor.h" #include "nvim/buffer_defs.h" #include "nvim/memline.h" @@ -236,12 +237,14 @@ retnomove: if (row < 0) { count = 0; for (first = true; curwin->w_topline > 1; ) { - if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) - ++count; - else - count += plines(curwin->w_topline - 1); - if (!first && count > -row) + if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { + count++; + } else { + count += plines_win(curwin, curwin->w_topline - 1, true); + } + if (!first && count > -row) { break; + } first = false; (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)) { @@ -262,7 +265,7 @@ retnomove: if (curwin->w_topfill > 0) { ++count; } else { - count += plines(curwin->w_topline); + count += plines_win(curwin, curwin->w_topline, true); } if (!first && count > row - curwin->w_height_inner + 1) { @@ -522,7 +525,7 @@ static colnr_T scroll_line_len(linenr_T lnum) char_u *line = ml_get(lnum); if (*line != NUL) { for (;;) { - int numchar = chartabsize(line, col); + int numchar = win_chartabsize(curwin, line, col); MB_PTR_ADV(line); if (*line == NUL) { // don't count the last character break; @@ -618,10 +621,10 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // scanned *up to* `col`, nudging it left or right when concealed characters // are encountered. // - // chartabsize() is used to keep track of the virtual column position relative - // to the line's bytes. For example: if col == 9 and the line starts with a - // tab that's 8 columns wide, we would want the cursor to be highlighting the - // second byte, not the ninth. + // win_chartabsize() is used to keep track of the virtual column position + // relative to the line's bytes. For example: if col == 9 and the line + // starts with a tab that's 8 columns wide, we would want the cursor to be + // highlighting the second byte, not the ninth. linenr_T lnum = wp->w_cursor.lnum; char_u *line = ml_get(lnum); @@ -645,7 +648,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) // checked for concealed characters. vcol = 0; while (vcol < offset && *ptr != NUL) { - vcol += chartabsize(ptr, vcol); + vcol += win_chartabsize(curwin, ptr, vcol); ptr += utfc_ptr2len(ptr); } @@ -656,7 +659,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) vcol = offset; ptr_end = ptr_row_offset; while (vcol < col && *ptr_end != NUL) { - vcol += chartabsize(ptr_end, vcol); + vcol += win_chartabsize(curwin, ptr_end, vcol); ptr_end += utfc_ptr2len(ptr_end); } @@ -671,7 +674,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col) #define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end) while (ptr < ptr_end && *ptr != NUL) { - cwidth = chartabsize(ptr, vcol); + cwidth = win_chartabsize(curwin, ptr, vcol); vcol += cwidth; if (cwidth > 1 && *ptr == '\t' && nudge > 0) { // A tab will "absorb" any previous adjustments. diff --git a/src/nvim/move.c b/src/nvim/move.c index 293f51f2d9..09815d1e6a 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -27,6 +27,7 @@ #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/option.h" #include "nvim/popupmnu.h" #include "nvim/screen.h" @@ -1055,8 +1056,9 @@ bool scrolldown(long line_count, int byfold) line_count -= curwin->w_topline - first - 1; curwin->w_botline -= curwin->w_topline - first; curwin->w_topline = first; - } else - done += plines_nofill(curwin->w_topline); + } else { + done += plines_win_nofill(curwin, curwin->w_topline, true); + } } --curwin->w_botline; /* approximate w_botline */ invalidate_botline(); @@ -1090,8 +1092,9 @@ bool scrolldown(long line_count, int byfold) curwin->w_cursor.lnum = 1; else curwin->w_cursor.lnum = first - 1; - } else - wrow -= plines(curwin->w_cursor.lnum--); + } else { + wrow -= plines_win(curwin, curwin->w_cursor.lnum--, true); + } curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL); moved = true; @@ -1194,7 +1197,7 @@ check_topfill ( */ static void max_topfill(void) { - int n = plines_nofill(curwin->w_topline); + int n = plines_win_nofill(curwin, curwin->w_topline, true); if (n >= curwin->w_height_inner) { curwin->w_topfill = 0; } else { @@ -1221,19 +1224,16 @@ void scrolldown_clamp(void) validate_cursor(); /* w_wrow needs to be valid */ - /* - * Compute the row number of the last row of the cursor line - * and make sure it doesn't go off the screen. Make sure the cursor - * doesn't go past 'scrolloff' lines from the screen end. - */ + // Compute the row number of the last row of the cursor line + // and make sure it doesn't go off the screen. Make sure the cursor + // doesn't go past 'scrolloff' lines from the screen end. int end_row = curwin->w_wrow; - if (can_fill) - ++end_row; - else - end_row += plines_nofill(curwin->w_topline - 1); - if (curwin->w_p_wrap - && curwin->w_width_inner != 0 - ) { + if (can_fill) { + end_row++; + } else { + end_row += plines_win_nofill(curwin, curwin->w_topline - 1, true); + } + if (curwin->w_p_wrap && curwin->w_width_inner != 0) { validate_cheight(); validate_virtcol(); end_row += curwin->w_cline_height - 1 - @@ -1266,16 +1266,13 @@ void scrollup_clamp(void) validate_cursor(); /* w_wrow needs to be valid */ - /* - * Compute the row number of the first row of the cursor line - * and make sure it doesn't go off the screen. Make sure the cursor - * doesn't go before 'scrolloff' lines from the screen start. - */ - int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline) - - curwin->w_topfill; - if (curwin->w_p_wrap - && curwin->w_width_inner != 0 - ) { + // Compute the row number of the first row of the cursor line + // and make sure it doesn't go off the screen. Make sure the cursor + // doesn't go before 'scrolloff' lines from the screen start. + int start_row = (curwin->w_wrow + - plines_win_nofill(curwin, curwin->w_topline, true) + - curwin->w_topfill); + if (curwin->w_p_wrap && curwin->w_width_inner != 0) { validate_virtcol(); start_row -= curwin->w_virtcol / curwin->w_width_inner; } @@ -1422,14 +1419,15 @@ void scroll_cursor_top(int min_scroll, int always) while (top > 0) { int i = hasFolding(top, &top, NULL) ? 1 // count one logical line for a sequence of folded lines - : plines_nofill(top); + : plines_win_nofill(curwin, top, true); used += i; if (extra + i <= off && bot < curbuf->b_ml.ml_line_count) { - if (hasFolding(bot, NULL, &bot)) - /* count one logical line for a sequence of folded lines */ - ++used; - else - used += plines(bot); + if (hasFolding(bot, NULL, &bot)) { + // count one logical line for a sequence of folded lines + used++; + } else { + used += plines_win(curwin, bot, true); + } } if (used > curwin->w_height_inner) { break; @@ -1555,12 +1553,12 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) validate_botline(curwin); } - /* The lines of the cursor line itself are always used. */ - used = plines_nofill(cln); + // The lines of the cursor line itself are always used. + used = plines_win_nofill(curwin, cln, true); - /* If the cursor is below botline, we will at least scroll by the height - * of the cursor line. Correct for empty lines, which are really part of - * botline. */ + // If the cursor is below botline, we will at least scroll by the height + // of the cursor line. Correct for empty lines, which are really part of + // botline. if (cln >= curwin->w_botline) { scrolled = used; if (cln == curwin->w_botline) @@ -1704,7 +1702,7 @@ void scroll_cursor_halfway(int atend) loff.lnum = boff.lnum = curwin->w_cursor.lnum; (void)hasFolding(loff.lnum, &loff.lnum, &boff.lnum); - int used = plines_nofill(loff.lnum); + int used = plines_win_nofill(curwin, loff.lnum, true); loff.fill = 0; boff.fill = 0; linenr_T topline = loff.lnum; @@ -1809,17 +1807,19 @@ void cursor_correct(void) int below = curwin->w_filler_rows; /* screen lines below botline */ while ((above < above_wanted || below < below_wanted) && topline < botline) { if (below < below_wanted && (below <= above || above >= above_wanted)) { - if (hasFolding(botline, &botline, NULL)) - ++below; - else - below += plines(botline); - --botline; + if (hasFolding(botline, &botline, NULL)) { + below++; + } else { + below += plines_win(curwin, botline, true); + } + botline--; } if (above < above_wanted && (above < below || below >= below_wanted)) { - if (hasFolding(topline, NULL, &topline)) - ++above; - else - above += plines_nofill(topline); + if (hasFolding(topline, NULL, &topline)) { + above++; + } else { + above += plines_win_nofill(curwin, topline, true); + } /* Count filler lines below this line as context. */ if (topline < botline) @@ -2047,10 +2047,11 @@ static void get_scroll_overlap(lineoff_T *lp, int dir) { int min_height = curwin->w_height_inner - 2; - if (lp->fill > 0) + if (lp->fill > 0) { lp->height = 1; - else - lp->height = plines_nofill(lp->lnum); + } else { + lp->height = plines_win_nofill(curwin, lp->lnum, true); + } int h1 = lp->height; if (h1 > min_height) return; /* no overlap */ @@ -2120,7 +2121,7 @@ void halfpage(bool flag, linenr_T Prenum) n--; curwin->w_topfill--; } else { - i = plines_nofill(curwin->w_topline); + i = plines_win_nofill(curwin, curwin->w_topline, true); n -= i; if (n < 0 && scrolled > 0) break; @@ -2146,12 +2147,12 @@ void halfpage(bool flag, linenr_T Prenum) else { room += i; do { - i = plines(curwin->w_botline); - if (i > room) + i = plines_win(curwin, curwin->w_botline, true); + if (i > room) { break; - (void)hasFolding(curwin->w_botline, NULL, - &curwin->w_botline); - ++curwin->w_botline; + } + (void)hasFolding(curwin->w_botline, NULL, &curwin->w_botline); + curwin->w_botline++; room -= i; } while (curwin->w_botline <= curbuf->b_ml.ml_line_count); } @@ -2180,7 +2181,7 @@ void halfpage(bool flag, linenr_T Prenum) n--; curwin->w_topfill++; } else { - i = plines_nofill(curwin->w_topline - 1); + i = plines_win_nofill(curwin, curwin->w_topline - 1, true); n -= i; if (n < 0 && scrolled > 0) break; diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 54ca216a53..2a530db934 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -45,6 +45,7 @@ #include "nvim/mouse.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/quickfix.h" #include "nvim/screen.h" #include "nvim/search.h" @@ -5122,11 +5123,13 @@ static void nv_scroll(cmdarg_T *cap) --n; break; } - used += plines(curwin->w_topline + n); - if (used >= half) + used += plines_win(curwin, curwin->w_topline + n, true); + if (used >= half) { break; - if (hasFolding(curwin->w_topline + n, NULL, &lnum)) + } + if (hasFolding(curwin->w_topline + n, NULL, &lnum)) { n = lnum - curwin->w_topline; + } } if (n > 0 && used > curwin->w_height_inner) { n--; diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c51dd09d40..a6eda26d75 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -41,6 +41,7 @@ #include "nvim/normal.h" #include "nvim/option.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/state.h" diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 8a45cb69fa..df2a8edc04 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -6,7 +6,7 @@ -- type='number', list=nil, scope={'global'}, -- deny_duplicates=nil, -- enable_if=nil, --- defaults={condition=nil, if_true={vi=224, vim=0}, if_false=nil}, +-- defaults={condition=nil, if_true=224, if_false=nil}, -- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil, -- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil, -- modelineexpr=nil, @@ -21,7 +21,6 @@ -- scopes: global, buffer, window -- redraw options: statuslines, current_window, curent_window_only, -- current_buffer, all_windows, everything, curswant --- default: {vi=…[, vim=…]} -- defaults: {condition=#if condition, if_true=default, if_false=default} -- #if condition: -- string: #ifdef string @@ -57,14 +56,14 @@ return { type='number', scope={'global'}, redraw={'curswant'}, varname='p_aleph', - defaults={if_true={vi=224}} + defaults={if_true=224} }, { full_name='arabic', abbreviation='arab', short_desc=N_("Arabic as a default second language"), type='bool', scope={'window'}, redraw={'curswant'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='arabicshape', abbreviation='arshape', @@ -73,14 +72,14 @@ return { redraw={'all_windows', 'ui_option'}, varname='p_arshape', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='allowrevins', abbreviation='ari', short_desc=N_("allow CTRL-_ in Insert and Command-line mode"), type='bool', scope={'global'}, varname='p_ari', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='ambiwidth', abbreviation='ambw', @@ -88,42 +87,42 @@ return { type='string', scope={'global'}, redraw={'all_windows', 'ui_option'}, varname='p_ambw', - defaults={if_true={vi="single"}} + defaults={if_true="single"} }, { full_name='autochdir', abbreviation='acd', short_desc=N_("change directory to the file in the current window"), type='bool', scope={'global'}, varname='p_acd', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='autoindent', abbreviation='ai', short_desc=N_("take indent for new line from previous line"), type='bool', scope={'buffer'}, varname='p_ai', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='autoread', abbreviation='ar', short_desc=N_("autom. read file when changed outside of Vim"), type='bool', scope={'global', 'buffer'}, varname='p_ar', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='autowrite', abbreviation='aw', short_desc=N_("automatically write file if changed"), type='bool', scope={'global'}, varname='p_aw', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='autowriteall', abbreviation='awa', short_desc=N_("as 'autowrite', but works with more commands"), type='bool', scope={'global'}, varname='p_awa', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='background', abbreviation='bg', @@ -131,7 +130,7 @@ return { type='string', scope={'global'}, redraw={'all_windows'}, varname='p_bg', - defaults={if_true={vim="dark"}} + defaults={if_true="dark"} }, { full_name='backspace', abbreviation='bs', @@ -139,14 +138,14 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_bs', - defaults={if_true={vim="indent,eol,start"}} + defaults={if_true="indent,eol,start"} }, { full_name='backup', abbreviation='bk', short_desc=N_("keep backup file after overwriting a file"), type='bool', scope={'global'}, varname='p_bk', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='backupcopy', abbreviation='bkc', @@ -156,8 +155,8 @@ return { varname='p_bkc', defaults={ condition='UNIX', - if_true={vim="auto"}, - if_false={vim="auto"} + if_true="auto", + if_false="auto" }, }, { @@ -168,7 +167,7 @@ return { secure=true, expand='nodefault', varname='p_bdir', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='backupext', abbreviation='bex', @@ -176,7 +175,7 @@ return { type='string', scope={'global'}, normal_fname_chars=true, varname='p_bex', - defaults={if_true={vi="~"}} + defaults={if_true="~"} }, { full_name='backupskip', abbreviation='bsk', @@ -184,7 +183,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_bsk', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='belloff', abbreviation='bo', @@ -192,7 +191,7 @@ return { type='string', list='comma', scope={'global'}, deny_duplicates=true, varname='p_bo', - defaults={if_true={vi="all"}} + defaults={if_true="all"} }, { full_name='binary', abbreviation='bin', @@ -200,7 +199,7 @@ return { type='bool', scope={'buffer'}, redraw={'statuslines'}, varname='p_bin', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='bomb', @@ -209,7 +208,7 @@ return { no_mkrc=true, redraw={'statuslines'}, varname='p_bomb', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='breakat', abbreviation='brk', @@ -217,14 +216,14 @@ return { type='string', list='flags', scope={'global'}, redraw={'all_windows'}, varname='p_breakat', - defaults={if_true={vi=" \t!@*-+;:,./?"}} + defaults={if_true=" \t!@*-+;:,./?"} }, { full_name='breakindent', abbreviation='bri', short_desc=N_("wrapped line repeats indent"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='breakindentopt', abbreviation='briopt', @@ -233,7 +232,7 @@ return { deny_duplicates=true, alloced=true, redraw={'current_buffer'}, - defaults={if_true={vi=""}}, + defaults={if_true=""}, }, { full_name='browsedir', abbreviation='bsdir', @@ -248,7 +247,7 @@ return { noglob=true, alloced=true, varname='p_bh', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='buflisted', abbreviation='bl', @@ -256,7 +255,7 @@ return { type='bool', scope={'buffer'}, noglob=true, varname='p_bl', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='buftype', abbreviation='bt', @@ -265,7 +264,7 @@ return { noglob=true, alloced=true, varname='p_bt', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='casemap', abbreviation='cmp', @@ -273,7 +272,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_cmp', - defaults={if_true={vi="internal,keepascii"}} + defaults={if_true="internal,keepascii"} }, { full_name='cdpath', abbreviation='cd', @@ -283,14 +282,14 @@ return { expand=true, secure=true, varname='p_cdpath', - defaults={if_true={vi=",,"}} + defaults={if_true=",,"} }, { full_name='cedit', short_desc=N_("used to open the command-line window"), type='string', scope={'global'}, varname='p_cedit', - defaults={if_true={vim=macros('CTRL_F_STR')}} + defaults={if_true=macros('CTRL_F_STR')} }, { full_name='channel', @@ -299,7 +298,7 @@ return { no_mkrc=true, nodefault=true, varname='p_channel', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='charconvert', abbreviation='ccv', @@ -307,14 +306,14 @@ return { type='string', scope={'global'}, secure=true, varname='p_ccv', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='cindent', abbreviation='cin', short_desc=N_("do C program indenting"), type='bool', scope={'buffer'}, varname='p_cin', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='cinkeys', abbreviation='cink', @@ -323,7 +322,7 @@ return { deny_duplicates=true, alloced=true, varname='p_cink', - defaults={if_true={vi=indentkeys_default}} + defaults={if_true=indentkeys_default} }, { full_name='cinoptions', abbreviation='cino', @@ -332,7 +331,7 @@ return { deny_duplicates=true, alloced=true, varname='p_cino', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='cinwords', abbreviation='cinw', @@ -341,7 +340,7 @@ return { deny_duplicates=true, alloced=true, varname='p_cinw', - defaults={if_true={vi="if,else,while,do,for,switch"}} + defaults={if_true="if,else,while,do,for,switch"} }, { full_name='clipboard', abbreviation='cb', @@ -349,7 +348,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_cb', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='cmdheight', abbreviation='ch', @@ -357,14 +356,14 @@ return { type='number', scope={'global'}, redraw={'all_windows'}, varname='p_ch', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='cmdwinheight', abbreviation='cwh', short_desc=N_("height of the command-line window"), type='number', scope={'global'}, varname='p_cwh', - defaults={if_true={vi=7}} + defaults={if_true=7} }, { full_name='colorcolumn', abbreviation='cc', @@ -372,7 +371,7 @@ return { type='string', list='onecomma', scope={'window'}, deny_duplicates=true, redraw={'current_window'}, - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='columns', abbreviation='co', @@ -381,7 +380,7 @@ return { no_mkrc=true, redraw={'everything'}, varname='p_columns', - defaults={if_true={vi=macros('DFLT_COLS')}} + defaults={if_true=macros('DFLT_COLS')} }, { full_name='comments', abbreviation='com', @@ -391,7 +390,7 @@ return { alloced=true, redraw={'curswant'}, varname='p_com', - defaults={if_true={vi="s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-"}} + defaults={if_true="s1:/*,mb:*,ex:*/,://,b:#,:%,:XCOMM,n:>,fb:-"} }, { full_name='commentstring', abbreviation='cms', @@ -400,7 +399,7 @@ return { alloced=true, redraw={'curswant'}, varname='p_cms', - defaults={if_true={vi="/*%s*/"}} + defaults={if_true="/*%s*/"} }, { full_name='compatible', abbreviation='cp', @@ -410,7 +409,7 @@ return { varname='p_force_off', -- pri_mkrc isn't needed here, optval_default() -- always returns TRUE for 'compatible' - defaults={if_true={vim=false}} + defaults={if_true=false} }, { full_name='complete', abbreviation='cpt', @@ -419,7 +418,7 @@ return { deny_duplicates=true, alloced=true, varname='p_cpt', - defaults={if_true={vim=".,w,b,u,t"}} + defaults={if_true=".,w,b,u,t"} }, { full_name='concealcursor', abbreviation='cocu', @@ -427,14 +426,14 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='conceallevel', abbreviation='cole', short_desc=N_("whether concealable text is shown or hidden"), type='number', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='completefunc', abbreviation='cfu', @@ -443,7 +442,7 @@ return { secure=true, alloced=true, varname='p_cfu', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='completeopt', abbreviation='cot', @@ -451,28 +450,28 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_cot', - defaults={if_true={vi="menu,preview"}} + defaults={if_true="menu,preview"} }, { full_name='completeslash', abbreviation='csl', type='string', scope={'buffer'}, varname='p_csl', enable_if='BACKSLASH_IN_FILENAME', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='confirm', abbreviation='cf', short_desc=N_("ask what to do about unsaved/read-only files"), type='bool', scope={'global'}, varname='p_confirm', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='copyindent', abbreviation='ci', short_desc=N_("make 'autoindent' use existing indent structure"), type='bool', scope={'buffer'}, varname='p_ci', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='cpoptions', abbreviation='cpo', @@ -480,14 +479,14 @@ return { type='string', list='flags', scope={'global'}, redraw={'all_windows'}, varname='p_cpo', - defaults={if_true={vim=macros('CPO_VIM')}} + defaults={if_true=macros('CPO_VIM')} }, { full_name='cscopepathcomp', abbreviation='cspc', short_desc=N_("how many components of the path to show"), type='number', scope={'global'}, varname='p_cspc', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='cscopeprg', abbreviation='csprg', @@ -496,7 +495,7 @@ return { secure=true, expand=true, varname='p_csprg', - defaults={if_true={vi="cscope"}} + defaults={if_true="cscope"} }, { full_name='cscopequickfix', abbreviation='csqf', @@ -504,56 +503,56 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_csqf', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='cscoperelative', abbreviation='csre', short_desc=N_("Use cscope.out path basename as prefix"), type='bool', scope={'global'}, varname='p_csre', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='cscopetag', abbreviation='cst', short_desc=N_("use cscope for tag commands"), type='bool', scope={'global'}, varname='p_cst', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='cscopetagorder', abbreviation='csto', short_desc=N_("determines \":cstag\" search order"), type='number', scope={'global'}, varname='p_csto', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='cscopeverbose', abbreviation='csverb', short_desc=N_("give messages when adding a cscope database"), type='bool', scope={'global'}, varname='p_csverbose', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='cursorbind', abbreviation='crb', short_desc=N_("move cursor in window as it moves in other windows"), type='bool', scope={'window'}, pv_name='p_crbind', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='cursorcolumn', abbreviation='cuc', short_desc=N_("highlight the screen column of the cursor"), type='bool', scope={'window'}, redraw={'current_window_only'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='cursorline', abbreviation='cul', short_desc=N_("highlight the screen line of the cursor"), type='bool', scope={'window'}, redraw={'current_window_only'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='cursorlineopt', abbreviation='culopt', @@ -561,14 +560,14 @@ return { type='string', list='onecomma', scope={'window'}, deny_duplicates=true, redraw={'current_window_only'}, - defaults={if_true={vi="both"}} + defaults={if_true="both"} }, { full_name='debug', short_desc=N_("to \"msg\" to see all error messages"), type='string', scope={'global'}, varname='p_debug', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='define', abbreviation='def', @@ -577,14 +576,14 @@ return { alloced=true, redraw={'curswant'}, varname='p_def', - defaults={if_true={vi="^\\s*#\\s*define"}} + defaults={if_true="^\\s*#\\s*define"} }, { full_name='delcombine', abbreviation='deco', short_desc=N_("delete combining characters on their own"), type='bool', scope={'global'}, varname='p_deco', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='dictionary', abbreviation='dict', @@ -594,7 +593,7 @@ return { normal_dname_chars=true, expand=true, varname='p_dict', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='diff', @@ -602,7 +601,7 @@ return { type='bool', scope={'window'}, noglob=true, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='diffexpr', abbreviation='dex', @@ -611,7 +610,7 @@ return { secure=true, redraw={'curswant'}, varname='p_dex', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='diffopt', abbreviation='dip', @@ -621,14 +620,14 @@ return { alloced=true, redraw={'current_window'}, varname='p_dip', - defaults={if_true={vi="internal,filler,closeoff"}} + defaults={if_true="internal,filler,closeoff"} }, { full_name='digraph', abbreviation='dg', short_desc=N_("enable the entering of digraphs in Insert mode"), type='bool', scope={'global'}, varname='p_dg', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='directory', abbreviation='dir', @@ -638,7 +637,7 @@ return { secure=true, expand='nodefault', varname='p_dir', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='display', abbreviation='dy', @@ -647,21 +646,21 @@ return { deny_duplicates=true, redraw={'all_windows'}, varname='p_dy', - defaults={if_true={vim="lastline,msgsep"}} + defaults={if_true="lastline,msgsep"} }, { full_name='eadirection', abbreviation='ead', short_desc=N_("in which direction 'equalalways' works"), type='string', scope={'global'}, varname='p_ead', - defaults={if_true={vi="both"}} + defaults={if_true="both"} }, { full_name='edcompatible', abbreviation='ed', short_desc=N_("No description"), type='bool', scope={'global'}, varname='p_force_off', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='emoji', abbreviation='emo', @@ -669,7 +668,7 @@ return { type='bool', scope={'global'}, redraw={'all_windows', 'ui_option'}, varname='p_emoji', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='encoding', abbreviation='enc', @@ -677,7 +676,7 @@ return { type='string', scope={'global'}, deny_in_modelines=true, varname='p_enc', - defaults={if_true={vi=macros('ENC_DFLT')}} + defaults={if_true=macros('ENC_DFLT')} }, { full_name='endofline', abbreviation='eol', @@ -686,7 +685,7 @@ return { no_mkrc=true, redraw={'statuslines'}, varname='p_eol', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='equalalways', abbreviation='ea', @@ -694,7 +693,7 @@ return { type='bool', scope={'global'}, redraw={'all_windows'}, varname='p_ea', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='equalprg', abbreviation='ep', @@ -703,14 +702,14 @@ return { secure=true, expand=true, varname='p_ep', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='errorbells', abbreviation='eb', short_desc=N_("ring the bell for error messages"), type='bool', scope={'global'}, varname='p_eb', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='errorfile', abbreviation='ef', @@ -719,7 +718,7 @@ return { secure=true, expand=true, varname='p_ef', - defaults={if_true={vi=macros('DFLT_ERRORFILE')}} + defaults={if_true=macros('DFLT_ERRORFILE')} }, { full_name='errorformat', abbreviation='efm', @@ -727,7 +726,7 @@ return { type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, varname='p_efm', - defaults={if_true={vi=macros('DFLT_EFM')}} + defaults={if_true=macros('DFLT_EFM')} }, { full_name='eventignore', abbreviation='ei', @@ -735,14 +734,14 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_ei', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='expandtab', abbreviation='et', short_desc=N_("use spaces when <Tab> is inserted"), type='bool', scope={'buffer'}, varname='p_et', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='exrc', abbreviation='ex', @@ -750,7 +749,7 @@ return { type='bool', scope={'global'}, secure=true, varname='p_exrc', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='fileencoding', abbreviation='fenc', @@ -760,7 +759,7 @@ return { alloced=true, redraw={'statuslines', 'current_buffer'}, varname='p_fenc', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='fileencodings', abbreviation='fencs', @@ -768,7 +767,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_fencs', - defaults={if_true={vi="ucs-bom,utf-8,default,latin1"}} + defaults={if_true="ucs-bom,utf-8,default,latin1"} }, { full_name='fileformat', abbreviation='ff', @@ -778,7 +777,7 @@ return { alloced=true, redraw={'curswant', 'statuslines'}, varname='p_ff', - defaults={if_true={vi=macros('DFLT_FF')}} + defaults={if_true=macros('DFLT_FF')} }, { full_name='fileformats', abbreviation='ffs', @@ -786,7 +785,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_ffs', - defaults={if_true={vim=macros('DFLT_FFS_VIM')}} + defaults={if_true=macros('DFLT_FFS_VIM')} }, { full_name='fileignorecase', abbreviation='fic', @@ -795,8 +794,8 @@ return { varname='p_fic', defaults={ condition='CASE_INSENSITIVE_FILENAME', - if_true={vi=true}, - if_false={vi=false}, + if_true=true, + if_false=false, } }, { @@ -808,7 +807,7 @@ return { alloced=true, expand=true, varname='p_ft', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='fillchars', abbreviation='fcs', @@ -818,7 +817,7 @@ return { alloced=true, redraw={'current_window'}, varname='p_fcs', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='fixendofline', abbreviation='fixeol', @@ -826,7 +825,7 @@ return { type='bool', scope={'buffer'}, redraw={'statuslines'}, varname='p_fixeol', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='foldclose', abbreviation='fcl', @@ -835,7 +834,7 @@ return { deny_duplicates=true, redraw={'current_window'}, varname='p_fcl', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='foldcolumn', abbreviation='fdc', @@ -843,14 +842,14 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="0"}} + defaults={if_true="0"} }, { full_name='foldenable', abbreviation='fen', short_desc=N_("set to display all folds open"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='foldexpr', abbreviation='fde', @@ -859,7 +858,7 @@ return { modelineexpr=true, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="0"}} + defaults={if_true="0"} }, { full_name='foldignore', abbreviation='fdi', @@ -867,14 +866,14 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="#"}} + defaults={if_true="#"} }, { full_name='foldlevel', abbreviation='fdl', short_desc=N_("close folds with a level higher than this"), type='number', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='foldlevelstart', abbreviation='fdls', @@ -882,7 +881,7 @@ return { type='number', scope={'global'}, redraw={'curswant'}, varname='p_fdls', - defaults={if_true={vi=-1}} + defaults={if_true=-1} }, { full_name='foldmarker', abbreviation='fmr', @@ -891,7 +890,7 @@ return { deny_duplicates=true, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="{{{,}}}"}} + defaults={if_true="{{{,}}}"} }, { full_name='foldmethod', abbreviation='fdm', @@ -899,21 +898,21 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="manual"}} + defaults={if_true="manual"} }, { full_name='foldminlines', abbreviation='fml', short_desc=N_("minimum number of lines for a fold to be closed"), type='number', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='foldnestmax', abbreviation='fdn', short_desc=N_("maximum fold depth"), type='number', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=20}} + defaults={if_true=20} }, { full_name='foldopen', abbreviation='fdo', @@ -922,7 +921,7 @@ return { deny_duplicates=true, redraw={'curswant'}, varname='p_fdo', - defaults={if_true={vi="block,hor,mark,percent,quickfix,search,tag,undo"}} + defaults={if_true="block,hor,mark,percent,quickfix,search,tag,undo"} }, { full_name='foldtext', abbreviation='fdt', @@ -931,7 +930,7 @@ return { modelineexpr=true, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="foldtext()"}} + defaults={if_true="foldtext()"} }, { full_name='formatexpr', abbreviation='fex', @@ -940,7 +939,7 @@ return { modelineexpr=true, alloced=true, varname='p_fex', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='formatoptions', abbreviation='fo', @@ -948,7 +947,7 @@ return { type='string', list='flags', scope={'buffer'}, alloced=true, varname='p_fo', - defaults={if_true={vim=macros('DFLT_FO_VIM')}} + defaults={if_true=macros('DFLT_FO_VIM')} }, { full_name='formatlistpat', abbreviation='flp', @@ -956,7 +955,7 @@ return { type='string', scope={'buffer'}, alloced=true, varname='p_flp', - defaults={if_true={vi="^\\s*\\d\\+[\\]:.)}\\t ]\\s*"}} + defaults={if_true="^\\s*\\d\\+[\\]:.)}\\t ]\\s*"} }, { full_name='formatprg', abbreviation='fp', @@ -965,7 +964,7 @@ return { secure=true, expand=true, varname='p_fp', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='fsync', abbreviation='fs', @@ -973,14 +972,14 @@ return { type='bool', scope={'global'}, secure=true, varname='p_fs', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='gdefault', abbreviation='gd', short_desc=N_("the \":substitute\" flag 'g' is default on"), type='bool', scope={'global'}, varname='p_gd', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='grepformat', abbreviation='gfm', @@ -988,7 +987,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_gefm', - defaults={if_true={vi=macros('DFLT_GREPFORMAT')}} + defaults={if_true=macros('DFLT_GREPFORMAT')} }, { full_name='grepprg', abbreviation='gp', @@ -1001,8 +1000,8 @@ return { condition='WIN32', -- Add an extra file name so that grep will always -- insert a file name in the match line. */ - if_true={vi="findstr /n $* nul"}, - if_false={vi="grep -n $* /dev/null"} + if_true="findstr /n $* nul", + if_false="grep -n $* /dev/null" } }, { @@ -1011,7 +1010,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_guicursor', - defaults={if_true={vi="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"}} + defaults={if_true="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"} }, { full_name='guifont', abbreviation='gfn', @@ -1020,7 +1019,7 @@ return { deny_duplicates=true, varname='p_guifont', redraw={'ui_option'}, - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='guifontwide', abbreviation='gfw', @@ -1029,7 +1028,7 @@ return { deny_duplicates=true, redraw={'ui_option'}, varname='p_guifontwide', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='guioptions', abbreviation='go', @@ -1060,14 +1059,14 @@ return { secure=true, expand=true, varname='p_hf', - defaults={if_true={vi=macros('DFLT_HELPFILE')}} + defaults={if_true=macros('DFLT_HELPFILE')} }, { full_name='helpheight', abbreviation='hh', short_desc=N_("minimum height of a new help window"), type='number', scope={'global'}, varname='p_hh', - defaults={if_true={vi=20}} + defaults={if_true=20} }, { full_name='helplang', abbreviation='hlg', @@ -1075,14 +1074,14 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_hlg', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='hidden', abbreviation='hid', short_desc=N_("don't unload buffer when it is |abandon|ed"), type='bool', scope={'global'}, varname='p_hid', - defaults={if_true={vi=false}} + defaults={if_true=true} }, { full_name='highlight', abbreviation='hl', @@ -1090,28 +1089,28 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_hl', - defaults={if_true={vi=macros('HIGHLIGHT_INIT')}} + defaults={if_true=macros('HIGHLIGHT_INIT')} }, { full_name='history', abbreviation='hi', short_desc=N_("number of command-lines that are remembered"), type='number', scope={'global'}, varname='p_hi', - defaults={if_true={vim=10000}} + defaults={if_true=10000} }, { full_name='hkmap', abbreviation='hk', short_desc=N_("Hebrew keyboard mapping"), type='bool', scope={'global'}, varname='p_hkmap', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='hkmapp', abbreviation='hkp', short_desc=N_("phonetic Hebrew keyboard mapping"), type='bool', scope={'global'}, varname='p_hkmapp', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='hlsearch', abbreviation='hls', @@ -1119,14 +1118,14 @@ return { type='bool', scope={'global'}, redraw={'all_windows'}, varname='p_hls', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='icon', short_desc=N_("Vim set the text of the window icon"), type='bool', scope={'global'}, varname='p_icon', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='iconstring', @@ -1134,28 +1133,28 @@ return { type='string', scope={'global'}, modelineexpr=true, varname='p_iconstring', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='ignorecase', abbreviation='ic', short_desc=N_("ignore case in search patterns"), type='bool', scope={'global'}, varname='p_ic', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='imcmdline', abbreviation='imc', short_desc=N_("use IM when starting to edit a command line"), type='bool', scope={'global'}, enable_if=false, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='imdisable', abbreviation='imd', short_desc=N_("do not use the IM in any mode"), type='bool', scope={'global'}, enable_if=false, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='iminsert', abbreviation='imi', @@ -1163,7 +1162,7 @@ return { type='number', scope={'buffer'}, varname='p_iminsert', pv_name='p_imi', defaults={ - if_true={vi=macros('B_IMODE_NONE')}, + if_true=macros('B_IMODE_NONE'), } }, { @@ -1172,7 +1171,7 @@ return { type='number', scope={'buffer'}, varname='p_imsearch', pv_name='p_ims', defaults={ - if_true={vi=macros('B_IMODE_USE_INSERT')}, + if_true=macros('B_IMODE_USE_INSERT'), } }, { @@ -1181,7 +1180,7 @@ return { type='string', scope={'global'}, redraw={'all_windows'}, varname='p_icm', - defaults={if_true={vi=""}} + defaults={if_true="nosplit"} }, { full_name='include', abbreviation='inc', @@ -1189,7 +1188,7 @@ return { type='string', scope={'global', 'buffer'}, alloced=true, varname='p_inc', - defaults={if_true={vi="^\\s*#\\s*include"}} + defaults={if_true="^\\s*#\\s*include"} }, { full_name='includeexpr', abbreviation='inex', @@ -1198,14 +1197,14 @@ return { modelineexpr=true, alloced=true, varname='p_inex', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='incsearch', abbreviation='is', short_desc=N_("highlight match while typing search pattern"), type='bool', scope={'global'}, varname='p_is', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='indentexpr', abbreviation='inde', @@ -1214,7 +1213,7 @@ return { modelineexpr=true, alloced=true, varname='p_inde', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='indentkeys', abbreviation='indk', @@ -1223,21 +1222,21 @@ return { deny_duplicates=true, alloced=true, varname='p_indk', - defaults={if_true={vi=indentkeys_default}} + defaults={if_true=indentkeys_default} }, { full_name='infercase', abbreviation='inf', short_desc=N_("adjust case of match for keyword completion"), type='bool', scope={'buffer'}, varname='p_inf', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='insertmode', abbreviation='im', short_desc=N_("start the edit of a file in Insert mode"), type='bool', scope={'global'}, varname='p_im', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='isfname', abbreviation='isf', @@ -1249,8 +1248,8 @@ return { condition='BACKSLASH_IN_FILENAME', -- Excluded are: & and ^ are special in cmd.exe -- ( and ) are used in text separating fnames */ - if_true={vi="@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,="}, - if_false={vi="@,48-57,/,.,-,_,+,,,#,$,%,~,="} + if_true="@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=", + if_false="@,48-57,/,.,-,_,+,,,#,$,%,~,=" } }, { @@ -1261,8 +1260,8 @@ return { varname='p_isi', defaults={ condition='WIN32', - if_true={vi="@,48-57,_,128-167,224-235"}, - if_false={vi="@,48-57,_,192-255"} + if_true="@,48-57,_,128-167,224-235", + if_false="@,48-57,_,192-255" } }, { @@ -1272,7 +1271,7 @@ return { deny_duplicates=true, alloced=true, varname='p_isk', - defaults={if_true={vim="@,48-57,_,192-255"}} + defaults={if_true="@,48-57,_,192-255"} }, { full_name='isprint', abbreviation='isp', @@ -1281,7 +1280,7 @@ return { deny_duplicates=true, redraw={'all_windows'}, varname='p_isp', - defaults={if_true={vi="@,161-255"} + defaults={if_true="@,161-255" } }, { @@ -1289,7 +1288,7 @@ return { short_desc=N_("two spaces after a period with a join command"), type='bool', scope={'global'}, varname='p_js', - defaults={if_true={vi=true}} + defaults={if_true=false} }, { full_name='jumpoptions', abbreviation='jop', @@ -1297,7 +1296,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_jop', - defaults={if_true={vim=''}} + defaults={if_true=''} }, { full_name='keymap', abbreviation='kmp', @@ -1308,7 +1307,7 @@ return { alloced=true, redraw={'statuslines', 'current_buffer'}, varname='p_keymap', pv_name='p_kmap', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='keymodel', abbreviation='km', @@ -1316,7 +1315,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_km', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='keywordprg', abbreviation='kp', @@ -1326,7 +1325,7 @@ return { expand=true, varname='p_kp', defaults={ - if_true={vi=":Man"}, + if_true=":Man", } }, { @@ -1336,7 +1335,7 @@ return { deny_duplicates=true, secure=true, varname='p_langmap', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='langmenu', abbreviation='lm', @@ -1344,21 +1343,21 @@ return { type='string', scope={'global'}, normal_fname_chars=true, varname='p_lm', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='langnoremap', abbreviation='lnr', short_desc=N_("do not apply 'langmap' to mapped characters"), type='bool', scope={'global'}, varname='p_lnr', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='langremap', abbreviation='lrm', short_desc=N_('No description'), type='bool', scope={'global'}, varname='p_lrm', - defaults={if_true={vim=false}} + defaults={if_true=false} }, { full_name='laststatus', abbreviation='ls', @@ -1366,21 +1365,21 @@ return { type='number', scope={'global'}, redraw={'all_windows'}, varname='p_ls', - defaults={if_true={vim=2}} + defaults={if_true=2} }, { full_name='lazyredraw', abbreviation='lz', short_desc=N_("don't redraw while executing macros"), type='bool', scope={'global'}, varname='p_lz', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='linebreak', abbreviation='lbr', short_desc=N_("wrap long lines at a blank"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='lines', @@ -1389,7 +1388,7 @@ return { no_mkrc=true, redraw={'everything'}, varname='p_lines', - defaults={if_true={vi=macros('DFLT_ROWS')}} + defaults={if_true=macros('DFLT_ROWS')} }, { full_name='linespace', abbreviation='lsp', @@ -1397,14 +1396,14 @@ return { type='number', scope={'global'}, redraw={'ui_option'}, varname='p_linespace', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='lisp', short_desc=N_("indenting for Lisp"), type='bool', scope={'buffer'}, varname='p_lisp', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='lispwords', abbreviation='lw', @@ -1412,14 +1411,14 @@ return { type='string', list='onecomma', scope={'global', 'buffer'}, deny_duplicates=true, varname='p_lispwords', pv_name='p_lw', - defaults={if_true={vi=macros('LISPWORD_VALUE')}} + defaults={if_true=macros('LISPWORD_VALUE')} }, { full_name='list', short_desc=N_("<Tab> and <EOL>"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='listchars', abbreviation='lcs', @@ -1429,21 +1428,21 @@ return { alloced=true, redraw={'current_window'}, varname='p_lcs', - defaults={if_true={vim="tab:> ,trail:-,nbsp:+"}} + defaults={if_true="tab:> ,trail:-,nbsp:+"} }, { full_name='loadplugins', abbreviation='lpl', short_desc=N_("load plugin scripts when starting up"), type='bool', scope={'global'}, varname='p_lpl', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='magic', short_desc=N_("special characters in search patterns"), type='bool', scope={'global'}, varname='p_magic', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='makeef', abbreviation='mef', @@ -1452,14 +1451,14 @@ return { secure=true, expand=true, varname='p_mef', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='makeencoding', abbreviation='menc', short_desc=N_("Converts the output of external commands"), type='string', scope={'global', 'buffer'}, varname='p_menc', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='makeprg', abbreviation='mp', @@ -1468,7 +1467,7 @@ return { secure=true, expand=true, varname='p_mp', - defaults={if_true={vi="make"}} + defaults={if_true="make"} }, { full_name='matchpairs', abbreviation='mps', @@ -1477,49 +1476,49 @@ return { deny_duplicates=true, alloced=true, varname='p_mps', - defaults={if_true={vi="(:),{:},[:]"}} + defaults={if_true="(:),{:},[:]"} }, { full_name='matchtime', abbreviation='mat', short_desc=N_("tenths of a second to show matching paren"), type='number', scope={'global'}, varname='p_mat', - defaults={if_true={vi=5}} + defaults={if_true=5} }, { full_name='maxcombine', abbreviation='mco', short_desc=N_("maximum nr of combining characters displayed"), type='number', scope={'global'}, varname='p_mco', - defaults={if_true={vi=6}} + defaults={if_true=6} }, { full_name='maxfuncdepth', abbreviation='mfd', short_desc=N_("maximum recursive depth for user functions"), type='number', scope={'global'}, varname='p_mfd', - defaults={if_true={vi=100}} + defaults={if_true=100} }, { full_name='maxmapdepth', abbreviation='mmd', short_desc=N_("maximum recursive depth for mapping"), type='number', scope={'global'}, varname='p_mmd', - defaults={if_true={vi=1000}} + defaults={if_true=1000} }, { full_name='maxmempattern', abbreviation='mmp', short_desc=N_("maximum memory (in Kbyte) used for pattern search"), type='number', scope={'global'}, varname='p_mmp', - defaults={if_true={vi=1000}} + defaults={if_true=1000} }, { full_name='menuitems', abbreviation='mis', short_desc=N_("maximum number of items in a menu"), type='number', scope={'global'}, varname='p_mis', - defaults={if_true={vi=25}} + defaults={if_true=25} }, { full_name='mkspellmem', abbreviation='msm', @@ -1528,14 +1527,14 @@ return { secure=true, expand=true, varname='p_msm', - defaults={if_true={vi="460000,2000,500"}} + defaults={if_true="460000,2000,500"} }, { full_name='modeline', abbreviation='ml', short_desc=N_("recognize modelines at start or end of file"), type='bool', scope={'buffer'}, varname='p_ml', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='modelineexpr', abbreviation='mle', @@ -1543,14 +1542,14 @@ return { type='bool', scope={'global'}, secure=true, varname='p_mle', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='modelines', abbreviation='mls', short_desc=N_("number of lines checked for modelines"), type='number', scope={'global'}, varname='p_mls', - defaults={if_true={vi=5}} + defaults={if_true=5} }, { full_name='modifiable', abbreviation='ma', @@ -1558,7 +1557,7 @@ return { type='bool', scope={'buffer'}, noglob=true, varname='p_ma', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='modified', abbreviation='mod', @@ -1567,21 +1566,21 @@ return { no_mkrc=true, redraw={'statuslines'}, varname='p_mod', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='more', short_desc=N_("listings when the whole screen is filled"), type='bool', scope={'global'}, varname='p_more', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='mouse', short_desc=N_("the use of mouse clicks"), type='string', list='flags', scope={'global'}, varname='p_mouse', - defaults={if_true={vim=""}} + defaults={if_true=""} }, { full_name='mousefocus', abbreviation='mousef', @@ -1589,21 +1588,21 @@ return { type='bool', scope={'global'}, redraw={'ui_option'}, varname='p_mousef', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='mousehide', abbreviation='mh', short_desc=N_("hide mouse pointer while typing"), type='bool', scope={'global'}, enable_if=false, - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='mousemodel', abbreviation='mousem', short_desc=N_("changes meaning of mouse buttons"), type='string', scope={'global'}, varname='p_mousem', - defaults={if_true={vi="extend"}} + defaults={if_true="extend"} }, { full_name='mouseshape', abbreviation='mouses', @@ -1617,7 +1616,7 @@ return { short_desc=N_("max time between mouse double-click"), type='number', scope={'global'}, varname='p_mouset', - defaults={if_true={vi=500}} + defaults={if_true=500} }, { full_name='nrformats', abbreviation='nf', @@ -1626,21 +1625,21 @@ return { deny_duplicates=true, alloced=true, varname='p_nf', - defaults={if_true={vim="bin,hex"}} + defaults={if_true="bin,hex"} }, { full_name='number', abbreviation='nu', short_desc=N_("print the line number in front of each line"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='numberwidth', abbreviation='nuw', short_desc=N_("number of columns used for the line number"), type='number', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vim=4}} + defaults={if_true=4} }, { full_name='omnifunc', abbreviation='ofu', @@ -1649,14 +1648,14 @@ return { secure=true, alloced=true, varname='p_ofu', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='opendevice', abbreviation='odev', short_desc=N_("allow reading/writing devices on MS-Windows"), type='bool', scope={'global'}, enable_if=false, - defaults={if_true={vim=false}} + defaults={if_true=false} }, { full_name='operatorfunc', abbreviation='opfunc', @@ -1664,7 +1663,7 @@ return { type='string', scope={'global'}, secure=true, varname='p_opfunc', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='packpath', abbreviation='pp', @@ -1674,14 +1673,14 @@ return { secure=true, expand=true, varname='p_pp', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='paragraphs', abbreviation='para', short_desc=N_("nroff macros that separate paragraphs"), type='string', scope={'global'}, varname='p_para', - defaults={if_true={vi="IPLPPPQPP TPHPLIPpLpItpplpipbp"}} + defaults={if_true="IPLPPPQPP TPHPLIPpLpItpplpipbp"} }, { full_name='paste', @@ -1689,14 +1688,14 @@ return { type='bool', scope={'global'}, pri_mkrc=true, varname='p_paste', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='pastetoggle', abbreviation='pt', short_desc=N_("key code that causes 'paste' to toggle"), type='string', scope={'global'}, varname='p_pt', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='patchexpr', abbreviation='pex', @@ -1704,7 +1703,7 @@ return { type='string', scope={'global'}, secure=true, varname='p_pex', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='patchmode', abbreviation='pm', @@ -1712,7 +1711,7 @@ return { type='string', scope={'global'}, normal_fname_chars=true, varname='p_pm', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='path', abbreviation='pa', @@ -1721,21 +1720,21 @@ return { deny_duplicates=true, expand=true, varname='p_path', - defaults={if_true={vi=".,/usr/include,,"}} + defaults={if_true=".,/usr/include,,"} }, { full_name='preserveindent', abbreviation='pi', short_desc=N_("preserve the indent structure when reindenting"), type='bool', scope={'buffer'}, varname='p_pi', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='previewheight', abbreviation='pvh', short_desc=N_("height of the preview window"), type='number', scope={'global'}, varname='p_pvh', - defaults={if_true={vi=12}} + defaults={if_true=12} }, { full_name='previewwindow', abbreviation='pvw', @@ -1743,7 +1742,7 @@ return { type='bool', scope={'window'}, noglob=true, redraw={'statuslines'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='printdevice', abbreviation='pdev', @@ -1751,14 +1750,14 @@ return { type='string', scope={'global'}, secure=true, varname='p_pdev', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='printencoding', abbreviation='penc', short_desc=N_("encoding to be used for printing"), type='string', scope={'global'}, varname='p_penc', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='printexpr', abbreviation='pexpr', @@ -1766,35 +1765,35 @@ return { type='string', scope={'global'}, secure=true, varname='p_pexpr', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='printfont', abbreviation='pfn', short_desc=N_("name of the font to be used for :hardcopy"), type='string', scope={'global'}, varname='p_pfn', - defaults={if_true={vi="courier"}} + defaults={if_true="courier"} }, { full_name='printheader', abbreviation='pheader', short_desc=N_("format of the header used for :hardcopy"), type='string', scope={'global'}, varname='p_header', - defaults={if_true={vi="%<%f%h%m%=Page %N"}} + defaults={if_true="%<%f%h%m%=Page %N"} }, { full_name='printmbcharset', abbreviation='pmbcs', short_desc=N_("CJK character set to be used for :hardcopy"), type='string', scope={'global'}, varname='p_pmcs', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='printmbfont', abbreviation='pmbfn', short_desc=N_("font names to be used for CJK output of :hardcopy"), type='string', scope={'global'}, varname='p_pmfn', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='printoptions', abbreviation='popt', @@ -1802,14 +1801,14 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_popt', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='prompt', short_desc=N_("enable prompt in Ex mode"), type='bool', scope={'global'}, varname='p_force_on', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='pumblend', abbreviation='pb', @@ -1817,21 +1816,21 @@ return { type='number', scope={'global'}, redraw={'ui_option'}, varname='p_pb', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='pumheight', abbreviation='ph', short_desc=N_("maximum height of the popup menu"), type='number', scope={'global'}, varname='p_ph', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='pumwidth', abbreviation='pw', short_desc=N_("minimum width of the popup menu"), type='number', scope={'global'}, varname='p_pw', - defaults={if_true={vi=15}} + defaults={if_true=15} }, { full_name='pyxversion', abbreviation='pyx', @@ -1839,14 +1838,14 @@ return { type='number', scope={'global'}, secure=true, varname='p_pyx', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='quickfixtextfunc', abbreviation='qftf', short_desc=N_("customize the quickfix window"), type='string', scope={'global'}, varname='p_qftf', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='quoteescape', abbreviation='qe', @@ -1854,7 +1853,7 @@ return { type='string', scope={'buffer'}, alloced=true, varname='p_qe', - defaults={if_true={vi="\\"}} + defaults={if_true="\\"} }, { full_name='readonly', abbreviation='ro', @@ -1863,63 +1862,63 @@ return { noglob=true, redraw={'statuslines'}, varname='p_ro', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='redrawdebug', abbreviation='rdb', short_desc=N_("Changes the way redrawing works (debug)"), type='string', list='onecomma', scope={'global'}, varname='p_rdb', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='redrawtime', abbreviation='rdt', short_desc=N_("timeout for 'hlsearch' and |:match| highlighting"), type='number', scope={'global'}, varname='p_rdt', - defaults={if_true={vi=2000}} + defaults={if_true=2000} }, { full_name='regexpengine', abbreviation='re', short_desc=N_("default regexp engine to use"), type='number', scope={'global'}, varname='p_re', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='relativenumber', abbreviation='rnu', short_desc=N_("show relative line number in front of each line"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='remap', short_desc=N_("mappings to work recursively"), type='bool', scope={'global'}, varname='p_remap', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='report', short_desc=N_("for reporting nr. of lines changed"), type='number', scope={'global'}, varname='p_report', - defaults={if_true={vi=2}} + defaults={if_true=2} }, { full_name='revins', abbreviation='ri', short_desc=N_("inserting characters will work backwards"), type='bool', scope={'global'}, varname='p_ri', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='rightleft', abbreviation='rl', short_desc=N_("window is right-to-left oriented"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='rightleftcmd', abbreviation='rlc', @@ -1927,7 +1926,7 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="search"}} + defaults={if_true="search"} }, { full_name='ruler', abbreviation='ru', @@ -1935,7 +1934,7 @@ return { type='bool', scope={'global'}, redraw={'statuslines'}, varname='p_ru', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='rulerformat', abbreviation='ruf', @@ -1945,7 +1944,7 @@ return { modelineexpr=true, redraw={'statuslines'}, varname='p_ruf', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='runtimepath', abbreviation='rtp', @@ -1955,7 +1954,7 @@ return { secure=true, expand='nodefault', varname='p_rtp', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='scroll', abbreviation='scr', @@ -1963,7 +1962,7 @@ return { type='number', scope={'window'}, no_mkrc=true, pv_name='p_scroll', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='scrollback', abbreviation='scbk', @@ -1971,21 +1970,21 @@ return { type='number', scope={'buffer'}, varname='p_scbk', redraw={'current_buffer'}, - defaults={if_true={vi=-1}} + defaults={if_true=-1} }, { full_name='scrollbind', abbreviation='scb', short_desc=N_("scroll in window as other windows scroll"), type='bool', scope={'window'}, pv_name='p_scbind', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='scrolljump', abbreviation='sj', short_desc=N_("minimum number of lines to scroll"), type='number', scope={'global'}, varname='p_sj', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='scrolloff', abbreviation='so', @@ -1993,7 +1992,7 @@ return { type='number', scope={'global', 'window'}, redraw={'all_windows'}, varname='p_so', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='scrollopt', abbreviation='sbo', @@ -2001,14 +2000,14 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_sbo', - defaults={if_true={vi="ver,jump"}} + defaults={if_true="ver,jump"} }, { full_name='sections', abbreviation='sect', short_desc=N_("nroff macros that separate sections"), type='string', scope={'global'}, varname='p_sections', - defaults={if_true={vi="SHNHH HUnhsh"}} + defaults={if_true="SHNHH HUnhsh"} }, { full_name='secure', @@ -2016,14 +2015,14 @@ return { type='bool', scope={'global'}, secure=true, varname='p_secure', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='selection', abbreviation='sel', short_desc=N_("what type of selection to use"), type='string', scope={'global'}, varname='p_sel', - defaults={if_true={vi="inclusive"}} + defaults={if_true="inclusive"} }, { full_name='selectmode', abbreviation='slm', @@ -2031,7 +2030,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_slm', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='sessionoptions', abbreviation='ssop', @@ -2039,9 +2038,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_ssop', - defaults={if_true={ - vim="blank,buffers,curdir,folds,help,tabpages,winsize" - }} + defaults={if_true="blank,buffers,curdir,folds,help,tabpages,winsize"} }, { full_name='shada', abbreviation='sd', @@ -2050,7 +2047,7 @@ return { deny_duplicates=true, secure=true, varname='p_shada', - defaults={if_true={vim="!,'100,<50,s10,h"}} + defaults={if_true="!,'100,<50,s10,h"} }, { full_name='shadafile', abbreviation='sdf', @@ -2060,7 +2057,7 @@ return { secure=true, expand=true, varname='p_shadafile', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='shell', abbreviation='sh', @@ -2071,8 +2068,8 @@ return { varname='p_sh', defaults={ condition='WIN32', - if_true={vi="cmd.exe"}, - if_false={vi="sh"} + if_true="cmd.exe", + if_false="sh" } }, { @@ -2083,8 +2080,8 @@ return { varname='p_shcf', defaults={ condition='WIN32', - if_true={vi="/s /c"}, - if_false={vi="-c"} + if_true="/s /c", + if_false="-c" } }, { @@ -2095,8 +2092,8 @@ return { varname='p_sp', defaults={ condition='WIN32', - if_true={vi=">%s 2>&1"}, - if_false={vi="| tee"}, + if_true=">%s 2>&1", + if_false="| tee", } }, { @@ -2105,7 +2102,7 @@ return { type='string', scope={'global'}, secure=true, varname='p_shq', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='shellredir', abbreviation='srr', @@ -2115,8 +2112,8 @@ return { varname='p_srr', defaults={ condition='WIN32', - if_true={vi=">%s 2>&1"}, - if_false={vi=">"} + if_true=">%s 2>&1", + if_false=">" } }, { @@ -2125,14 +2122,14 @@ return { type='bool', scope={'global'}, varname='p_ssl', enable_if='BACKSLASH_IN_FILENAME', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='shelltemp', abbreviation='stmp', short_desc=N_("whether to use a temp file for shell commands"), type='bool', scope={'global'}, varname='p_stmp', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='shellxquote', abbreviation='sxq', @@ -2142,8 +2139,8 @@ return { varname='p_sxq', defaults={ condition='WIN32', - if_true={vi="\""}, - if_false={vi=""}, + if_true="\"", + if_false="", } }, { @@ -2152,28 +2149,28 @@ return { type='string', scope={'global'}, secure=true, varname='p_sxe', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='shiftround', abbreviation='sr', short_desc=N_("round indent to multiple of shiftwidth"), type='bool', scope={'global'}, varname='p_sr', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='shiftwidth', abbreviation='sw', short_desc=N_("number of spaces to use for (auto)indent step"), type='number', scope={'buffer'}, varname='p_sw', - defaults={if_true={vi=8}} + defaults={if_true=8} }, { full_name='shortmess', abbreviation='shm', short_desc=N_("list of flags, reduce length of messages"), type='string', list='flags', scope={'global'}, varname='p_shm', - defaults={if_true={vim="filnxtToOF"}} + defaults={if_true="filnxtToOF"} }, { full_name='showbreak', abbreviation='sbr', @@ -2181,35 +2178,35 @@ return { type='string', scope={'global'}, redraw={'all_windows'}, varname='p_sbr', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='showcmd', abbreviation='sc', short_desc=N_("show (partial) command in status line"), type='bool', scope={'global'}, varname='p_sc', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='showfulltag', abbreviation='sft', short_desc=N_("show full tag pattern when completing tag"), type='bool', scope={'global'}, varname='p_sft', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='showmatch', abbreviation='sm', short_desc=N_("briefly jump to matching bracket if insert one"), type='bool', scope={'global'}, varname='p_sm', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='showmode', abbreviation='smd', short_desc=N_("message on status line to show current mode"), type='bool', scope={'global'}, varname='p_smd', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='showtabline', abbreviation='stal', @@ -2217,14 +2214,14 @@ return { type='number', scope={'global'}, redraw={'all_windows', 'ui_option'}, varname='p_stal', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='sidescroll', abbreviation='ss', short_desc=N_("minimum number of columns to scroll horizontal"), type='number', scope={'global'}, varname='p_ss', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='sidescrolloff', abbreviation='siso', @@ -2232,7 +2229,7 @@ return { type='number', scope={'global', 'window'}, redraw={'all_windows'}, varname='p_siso', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='signcolumn', abbreviation='scl', @@ -2240,42 +2237,42 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi="auto"}} + defaults={if_true="auto"} }, { full_name='smartcase', abbreviation='scs', short_desc=N_("no ignore case when pattern has uppercase"), type='bool', scope={'global'}, varname='p_scs', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='smartindent', abbreviation='si', short_desc=N_("smart autoindenting for C programs"), type='bool', scope={'buffer'}, varname='p_si', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='smarttab', abbreviation='sta', short_desc=N_("use 'shiftwidth' when inserting <Tab>"), type='bool', scope={'global'}, varname='p_sta', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='softtabstop', abbreviation='sts', short_desc=N_("number of spaces that <Tab> uses while editing"), type='number', scope={'buffer'}, varname='p_sts', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='spell', short_desc=N_("spell checking"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='spellcapcheck', abbreviation='spc', @@ -2284,7 +2281,7 @@ return { alloced=true, redraw={'current_buffer'}, varname='p_spc', - defaults={if_true={vi="[.?!]\\_[\\])'\" ]\\+"}} + defaults={if_true="[.?!]\\_[\\])'\" ]\\+"} }, { full_name='spellfile', abbreviation='spf', @@ -2295,7 +2292,7 @@ return { alloced=true, expand=true, varname='p_spf', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='spelllang', abbreviation='spl', @@ -2306,7 +2303,7 @@ return { expand=true, redraw={'current_buffer'}, varname='p_spl', - defaults={if_true={vi="en"}} + defaults={if_true="en"} }, { full_name='spellsuggest', abbreviation='sps', @@ -2316,7 +2313,7 @@ return { secure=true, expand=true, varname='p_sps', - defaults={if_true={vi="best"}} + defaults={if_true="best"} }, { full_name='spelloptions', abbreviation='spo', @@ -2325,21 +2322,21 @@ return { secure=true, expand=true, varname='p_spo', - defaults={if_true={vim=""}} + defaults={if_true=""} }, { full_name='splitbelow', abbreviation='sb', short_desc=N_("new window from split is below the current one"), type='bool', scope={'global'}, varname='p_sb', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='splitright', abbreviation='spr', short_desc=N_("new window is put right of the current one"), type='bool', scope={'global'}, varname='p_spr', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='startofline', abbreviation='sol', @@ -2347,7 +2344,7 @@ return { type='bool', scope={'global'}, vim=false, varname='p_sol', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='statusline', abbreviation='stl', @@ -2357,7 +2354,7 @@ return { modelineexpr=true, redraw={'statuslines'}, varname='p_stl', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='suffixes', abbreviation='su', @@ -2365,7 +2362,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_su', - defaults={if_true={vi=".bak,~,.o,.h,.info,.swp,.obj"}} + defaults={if_true=".bak,~,.o,.h,.info,.swp,.obj"} }, { full_name='suffixesadd', abbreviation='sua', @@ -2374,7 +2371,7 @@ return { deny_duplicates=true, alloced=true, varname='p_sua', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='swapfile', abbreviation='swf', @@ -2382,7 +2379,7 @@ return { type='bool', scope={'buffer'}, redraw={'statuslines'}, varname='p_swf', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='switchbuf', abbreviation='swb', @@ -2390,7 +2387,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_swb', - defaults={if_true={vi=""}} + defaults={if_true="uselast"} }, { full_name='synmaxcol', abbreviation='smc', @@ -2398,7 +2395,7 @@ return { type='number', scope={'buffer'}, redraw={'current_buffer'}, varname='p_smc', - defaults={if_true={vi=3000}} + defaults={if_true=3000} }, { full_name='syntax', abbreviation='syn', @@ -2408,14 +2405,14 @@ return { normal_fname_chars=true, alloced=true, varname='p_syn', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='tagfunc', abbreviation='tfu', short_desc=N_("function used to perform tag searches"), type='string', scope={'buffer'}, varname='p_tfu', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='tabline', abbreviation='tal', @@ -2424,14 +2421,14 @@ return { modelineexpr=true, redraw={'all_windows'}, varname='p_tal', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='tabpagemax', abbreviation='tpm', short_desc=N_("maximum number of tab pages for |-p| and \"tab all\""), type='number', scope={'global'}, varname='p_tpm', - defaults={if_true={vim=50}} + defaults={if_true=50} }, { full_name='tabstop', abbreviation='ts', @@ -2439,35 +2436,35 @@ return { type='number', scope={'buffer'}, redraw={'current_buffer'}, varname='p_ts', - defaults={if_true={vi=8}} + defaults={if_true=8} }, { full_name='tagbsearch', abbreviation='tbs', short_desc=N_("use binary searching in tags files"), type='bool', scope={'global'}, varname='p_tbs', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='tagcase', abbreviation='tc', short_desc=N_("how to handle case when searching in tags files"), type='string', scope={'global', 'buffer'}, varname='p_tc', - defaults={if_true={vim="followic"}} + defaults={if_true="followic"} }, { full_name='taglength', abbreviation='tl', short_desc=N_("number of significant characters for a tag"), type='number', scope={'global'}, varname='p_tl', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='tagrelative', abbreviation='tr', short_desc=N_("file names in tag file are relative"), type='bool', scope={'global'}, varname='p_tr', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='tags', abbreviation='tag', @@ -2476,27 +2473,27 @@ return { deny_duplicates=true, expand=true, varname='p_tags', - defaults={if_true={vi="./tags;,tags"}} + defaults={if_true="./tags;,tags"} }, { full_name='tagstack', abbreviation='tgst', short_desc=N_("push tags onto the tag stack"), type='bool', scope={'global'}, varname='p_tgst', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='termbidi', abbreviation='tbidi', short_desc=N_("terminal takes care of bi-directionality"), type='bool', scope={'global'}, varname='p_tbidi', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='termencoding', abbreviation='tenc', short_desc=N_("Terminal encodig"), type='string', scope={'global'}, - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='termguicolors', abbreviation='tgc', @@ -2504,21 +2501,21 @@ return { type='bool', scope={'global'}, redraw={'ui_option'}, varname='p_tgc', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='termpastefilter', abbreviation='tpf', type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_tpf', - defaults={if_true={vim="BS,HT,ESC,DEL"}} + defaults={if_true="BS,HT,ESC,DEL"} }, { full_name='terse', short_desc=N_("hides notification of search wrap"), type='bool', scope={'global'}, varname='p_terse', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='textwidth', abbreviation='tw', @@ -2526,7 +2523,7 @@ return { type='number', scope={'buffer'}, redraw={'current_buffer'}, varname='p_tw', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='thesaurus', abbreviation='tsr', @@ -2536,42 +2533,42 @@ return { normal_dname_chars=true, expand=true, varname='p_tsr', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='tildeop', abbreviation='top', short_desc=N_("tilde command \"~\" behaves like an operator"), type='bool', scope={'global'}, varname='p_to', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='timeout', abbreviation='to', short_desc=N_("time out on mappings and key codes"), type='bool', scope={'global'}, varname='p_timeout', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='timeoutlen', abbreviation='tm', short_desc=N_("time out time in milliseconds"), type='number', scope={'global'}, varname='p_tm', - defaults={if_true={vi=1000}} + defaults={if_true=1000} }, { full_name='title', short_desc=N_("Vim set the title of the window"), type='bool', scope={'global'}, varname='p_title', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='titlelen', short_desc=N_("of 'columns' used for window title"), type='number', scope={'global'}, varname='p_titlelen', - defaults={if_true={vi=85}} + defaults={if_true=85} }, { full_name='titleold', @@ -2580,7 +2577,7 @@ return { secure=true, no_mkrc=true, varname='p_titleold', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='titlestring', @@ -2588,7 +2585,7 @@ return { type='string', scope={'global'}, modelineexpr=true, varname='p_titlestring', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='ttimeout', @@ -2596,7 +2593,7 @@ return { type='bool', scope={'global'}, redraw={'ui_option'}, varname='p_ttimeout', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='ttimeoutlen', abbreviation='ttm', @@ -2604,7 +2601,7 @@ return { type='number', scope={'global'}, redraw={'ui_option'}, varname='p_ttm', - defaults={if_true={vi=50}} + defaults={if_true=50} }, { full_name='ttyfast', abbreviation='tf', @@ -2612,7 +2609,7 @@ return { type='bool', scope={'global'}, no_mkrc=true, varname='p_force_on', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='undodir', abbreviation='udir', @@ -2622,49 +2619,49 @@ return { secure=true, expand='nodefault', varname='p_udir', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='undofile', abbreviation='udf', short_desc=N_("save undo information in a file"), type='bool', scope={'buffer'}, varname='p_udf', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='undolevels', abbreviation='ul', short_desc=N_("maximum number of changes that can be undone"), type='number', scope={'global', 'buffer'}, varname='p_ul', - defaults={if_true={vi=1000}} + defaults={if_true=1000} }, { full_name='undoreload', abbreviation='ur', short_desc=N_("max nr of lines to save for undo on a buffer reload"), type='number', scope={'global'}, varname='p_ur', - defaults={if_true={vi=10000}} + defaults={if_true=10000} }, { full_name='updatecount', abbreviation='uc', short_desc=N_("after this many characters flush swap file"), type='number', scope={'global'}, varname='p_uc', - defaults={if_true={vi=200}} + defaults={if_true=200} }, { full_name='updatetime', abbreviation='ut', short_desc=N_("after this many milliseconds flush swap file"), type='number', scope={'global'}, varname='p_ut', - defaults={if_true={vi=4000}} + defaults={if_true=4000} }, { full_name='varsofttabstop', abbreviation='vsts', short_desc=N_("list of numbers of spaces that <Tab> uses while editing"), type='string', list='comma', scope={'buffer'}, varname='p_vsts', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='vartabstop', abbreviation='vts', @@ -2672,14 +2669,14 @@ return { type='string', list='comma', scope={'buffer'}, varname='p_vts', redraw={'current_buffer'}, - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='verbose', abbreviation='vbs', short_desc=N_("give informative messages"), type='number', scope={'global'}, varname='p_verbose', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='verbosefile', abbreviation='vfile', @@ -2688,7 +2685,7 @@ return { secure=true, expand=true, varname='p_vfile', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='viewdir', abbreviation='vdir', @@ -2697,7 +2694,7 @@ return { secure=true, expand='nodefault', varname='p_vdir', - defaults={if_true={vi=''}} + defaults={if_true=''} }, { full_name='viewoptions', abbreviation='vop', @@ -2705,7 +2702,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_vop', - defaults={if_true={vi="folds,options,cursor,curdir"}} + defaults={if_true="folds,cursor,curdir"} }, { -- Alias for "shada". @@ -2726,42 +2723,42 @@ return { deny_duplicates=true, redraw={'curswant'}, varname='p_ve', - defaults={if_true={vim=""}} + defaults={if_true=""} }, { full_name='visualbell', abbreviation='vb', short_desc=N_("use visual bell instead of beeping"), type='bool', scope={'global'}, varname='p_vb', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='warn', short_desc=N_("for shell command when buffer was changed"), type='bool', scope={'global'}, varname='p_warn', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='whichwrap', abbreviation='ww', short_desc=N_("allow specified keys to cross line boundaries"), type='string', list='flagscomma', scope={'global'}, varname='p_ww', - defaults={if_true={vim="b,s"}} + defaults={if_true="b,s"} }, { full_name='wildchar', abbreviation='wc', short_desc=N_("command-line character for wildcard expansion"), type='number', scope={'global'}, varname='p_wc', - defaults={if_true={vim=imacros('TAB')}} + defaults={if_true=imacros('TAB')} }, { full_name='wildcharm', abbreviation='wcm', short_desc=N_("like 'wildchar' but also works when mapped"), type='number', scope={'global'}, varname='p_wcm', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='wildignore', abbreviation='wig', @@ -2769,21 +2766,21 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_wig', - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='wildignorecase', abbreviation='wic', short_desc=N_("ignore case when completing file names"), type='bool', scope={'global'}, varname='p_wic', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='wildmenu', abbreviation='wmnu', short_desc=N_("use menu for command line completion"), type='bool', scope={'global'}, varname='p_wmnu', - defaults={if_true={vim=true}} + defaults={if_true=true} }, { full_name='wildmode', abbreviation='wim', @@ -2791,7 +2788,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=false, varname='p_wim', - defaults={if_true={vim="full"}} + defaults={if_true="full"} }, { full_name='wildoptions', abbreviation='wop', @@ -2799,21 +2796,21 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, varname='p_wop', - defaults={if_true={vim='pum,tagfile'}} + defaults={if_true='pum,tagfile'} }, { full_name='winaltkeys', abbreviation='wak', short_desc=N_("when the windows system handles ALT keys"), type='string', scope={'global'}, varname='p_wak', - defaults={if_true={vi="menu"}} + defaults={if_true="menu"} }, { full_name='winblend', abbreviation='winbl', short_desc=N_("Controls transparency level for floating windows"), type='number', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='winhighlight', abbreviation='winhl', @@ -2821,105 +2818,105 @@ return { type='string', scope={'window'}, alloced=true, redraw={'current_window'}, - defaults={if_true={vi=""}} + defaults={if_true=""} }, { full_name='window', abbreviation='wi', short_desc=N_("nr of lines to scroll for CTRL-F and CTRL-B"), type='number', scope={'global'}, varname='p_window', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='winheight', abbreviation='wh', short_desc=N_("minimum number of lines for the current window"), type='number', scope={'global'}, varname='p_wh', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='winfixheight', abbreviation='wfh', short_desc=N_("keep window height when opening/closing windows"), type='bool', scope={'window'}, redraw={'statuslines'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='winfixwidth', abbreviation='wfw', short_desc=N_("keep window width when opening/closing windows"), type='bool', scope={'window'}, redraw={'statuslines'}, - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='winminheight', abbreviation='wmh', short_desc=N_("minimum number of lines for any window"), type='number', scope={'global'}, varname='p_wmh', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='winminwidth', abbreviation='wmw', short_desc=N_("minimal number of columns for any window"), type='number', scope={'global'}, varname='p_wmw', - defaults={if_true={vi=1}} + defaults={if_true=1} }, { full_name='winwidth', abbreviation='wiw', short_desc=N_("minimal number of columns for current window"), type='number', scope={'global'}, varname='p_wiw', - defaults={if_true={vi=20}} + defaults={if_true=20} }, { full_name='wrap', short_desc=N_("lines wrap and continue on the next line"), type='bool', scope={'window'}, redraw={'current_window'}, - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='wrapmargin', abbreviation='wm', short_desc=N_("chars from the right where wrapping starts"), type='number', scope={'buffer'}, varname='p_wm', - defaults={if_true={vi=0}} + defaults={if_true=0} }, { full_name='wrapscan', abbreviation='ws', short_desc=N_("searches wrap around the end of the file"), type='bool', scope={'global'}, varname='p_ws', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='write', short_desc=N_("to a file is allowed"), type='bool', scope={'global'}, varname='p_write', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='writeany', abbreviation='wa', short_desc=N_("write to file with no need for \"!\" override"), type='bool', scope={'global'}, varname='p_wa', - defaults={if_true={vi=false}} + defaults={if_true=false} }, { full_name='writebackup', abbreviation='wb', short_desc=N_("make a backup before overwriting a file"), type='bool', scope={'global'}, varname='p_wb', - defaults={if_true={vi=true}} + defaults={if_true=true} }, { full_name='writedelay', abbreviation='wd', short_desc=N_("delay this many msec for each char (for debug)"), type='number', scope={'global'}, varname='p_wd', - defaults={if_true={vi=0}} + defaults={if_true=0} }, } } diff --git a/src/nvim/plines.c b/src/nvim/plines.c new file mode 100644 index 0000000000..6718b7f7a4 --- /dev/null +++ b/src/nvim/plines.c @@ -0,0 +1,481 @@ +// 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 + +// plines.c: calculate the vertical and horizontal size of text in a window + +#include <assert.h> +#include <inttypes.h> +#include <stdbool.h> +#include <string.h> +#include <limits.h> + +#include "nvim/vim.h" +#include "nvim/ascii.h" +#include "nvim/plines.h" +#include "nvim/charset.h" +#include "nvim/cursor.h" +#include "nvim/diff.h" +#include "nvim/func_attr.h" +#include "nvim/fold.h" +#include "nvim/indent.h" +#include "nvim/main.h" +#include "nvim/mbyte.h" +#include "nvim/memline.h" +#include "nvim/memory.h" +#include "nvim/move.h" +#include "nvim/option.h" +#include "nvim/screen.h" +#include "nvim/strings.h" +#include "nvim/window.h" +#include "nvim/buffer.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "plines.c.generated.h" +#endif + +/// Functions calculating vertical size of text when displayed inside a window. +/// Calls horizontal size functions defined below. + +/// @param winheight when true limit to window height +int plines_win(win_T *wp, linenr_T lnum, bool winheight) +{ + // Check for filler lines above this buffer line. When folded the result + // is one line anyway. + return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum); +} + +/// @param winheight when true limit to window height +int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight) +{ + if (!wp->w_p_wrap) { + return 1; + } + + if (wp->w_width_inner == 0) { + return 1; + } + + // A folded lines is handled just like an empty line. + if (lineFolded(wp, lnum)) { + return 1; + } + + const int lines = plines_win_nofold(wp, lnum); + if (winheight && lines > wp->w_height_inner) { + return wp->w_height_inner; + } + return lines; +} + +/// @Return number of window lines physical line "lnum" will occupy in window +/// "wp". Does not care about folding, 'wrap' or 'diff'. +int plines_win_nofold(win_T *wp, linenr_T lnum) +{ + char_u *s; + unsigned int col; + int width; + + s = ml_get_buf(wp->w_buffer, lnum, false); + if (*s == NUL) { // empty line + return 1; + } + col = win_linetabsize(wp, s, MAXCOL); + + // If list mode is on, then the '$' at the end of the line may take up one + // extra column. + if (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL) { + col += 1; + } + + // Add column offset for 'number', 'relativenumber' and 'foldcolumn'. + width = wp->w_width_inner - win_col_off(wp); + if (width <= 0 || col > 32000) { + return 32000; // bigger than the number of screen columns + } + if (col <= (unsigned int)width) { + return 1; + } + col -= (unsigned int)width; + width += win_col_off2(wp); + assert(col <= INT_MAX && (int)col < INT_MAX - (width -1)); + return ((int)col + (width - 1)) / width + 1; +} + +/// Like plines_win(), but only reports the number of physical screen lines +/// used from the start of the line to the given column number. +int plines_win_col(win_T *wp, linenr_T lnum, long column) +{ + // Check for filler lines above this buffer line. When folded the result + // is one line anyway. + int lines = diff_check_fill(wp, lnum); + + if (!wp->w_p_wrap) { + return lines + 1; + } + + if (wp->w_width_inner == 0) { + return lines + 1; + } + + char_u *line = ml_get_buf(wp->w_buffer, lnum, false); + char_u *s = line; + + colnr_T col = 0; + while (*s != NUL && --column >= 0) { + col += win_lbr_chartabsize(wp, line, s, col, NULL); + MB_PTR_ADV(s); + } + + // If *s is a TAB, and the TAB is not displayed as ^I, and we're not in + // INSERT mode, then col must be adjusted so that it represents the last + // screen position of the TAB. This only fixes an error when the TAB wraps + // from one screen line to the next (when 'columns' is not a multiple of + // 'ts') -- webb. + if (*s == TAB && (State & NORMAL) + && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { + col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1; + } + + // Add column offset for 'number', 'relativenumber', 'foldcolumn', etc. + int width = wp->w_width_inner - win_col_off(wp); + if (width <= 0) { + return 9999; + } + + lines += 1; + if (col > width) { + lines += (col - width) / (width + win_col_off2(wp)) + 1; + } + return lines; +} + +/// Get the number of screen lines lnum takes up. This takes care of +/// both folds and topfill, and limits to the current window height. +/// +/// @param[in] wp window line is in +/// @param[in] lnum line number +/// @param[out] nextp if not NULL, the line after a fold +/// @param[out] foldedp if not NULL, whether lnum is on a fold +/// @param[in] cache whether to use the window's cache for folds +/// +/// @return the total number of screen lines +int plines_win_full(win_T *wp, linenr_T lnum, linenr_T *const nextp, + bool *const foldedp, const bool cache) +{ + bool folded = hasFoldingWin(wp, lnum, NULL, nextp, cache, NULL); + if (foldedp) { + *foldedp = folded; + } + if (folded) { + return 1; + } else if (lnum == wp->w_topline) { + return plines_win_nofill(wp, lnum, true) + wp->w_topfill; + } + return plines_win(wp, lnum, true); +} + +int plines_m_win(win_T *wp, linenr_T first, linenr_T last) +{ + int count = 0; + + while (first <= last) { + linenr_T next = first; + count += plines_win_full(wp, first, &next, NULL, false); + first = next + 1; + } + return count; +} + +/// Functions calculating horizontal size of text, when displayed in a window. + +/// Return the number of characters 'c' will take on the screen, taking +/// into account the size of a tab. +/// Also see getvcol() +/// +/// @param p +/// @param col +/// +/// @return Number of characters. +int win_chartabsize(win_T *wp, char_u *p, colnr_T col) +{ + buf_T *buf = wp->w_buffer; + if (*p == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { + return tabstop_padding(col, buf->b_p_ts, buf->b_p_vts_array); + } else { + return ptr2cells(p); + } +} + +/// Return the number of characters the string 's' will take on the screen, +/// taking into account the size of a tab. +/// +/// @param s +/// +/// @return Number of characters the string will take on the screen. +int linetabsize(char_u *s) +{ + return linetabsize_col(0, s); +} + +/// Like linetabsize(), but starting at column "startcol". +/// +/// @param startcol +/// @param s +/// +/// @return Number of characters the string will take on the screen. +int linetabsize_col(int startcol, char_u *s) +{ + colnr_T col = startcol; + char_u *line = s; // pointer to start of line, for breakindent + + while (*s != NUL) { + col += lbr_chartabsize_adv(line, &s, col); + } + return (int)col; +} + +/// Like linetabsize(), but for a given window instead of the current one. +/// +/// @param wp +/// @param line +/// @param len +/// +/// @return Number of characters the string will take on the screen. +unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len) +{ + colnr_T col = 0; + + for (char_u *s = line; + *s != NUL && (len == MAXCOL || s < line + len); + MB_PTR_ADV(s)) { + col += win_lbr_chartabsize(wp, line, s, col, NULL); + } + + return (unsigned int)col; +} + +/// like win_chartabsize(), but also check for line breaks on the screen +/// +/// @param line +/// @param s +/// @param col +/// +/// @return The number of characters taken up on the screen. +int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col) +{ + if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) { + if (curwin->w_p_wrap) { + return win_nolbr_chartabsize(curwin, s, col, NULL); + } + return win_chartabsize(curwin, s, col); + } + return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL); +} + +/// Call lbr_chartabsize() and advance the pointer. +/// +/// @param line +/// @param s +/// @param col +/// +/// @return The number of characters take up on the screen. +int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col) +{ + int retval; + + retval = lbr_chartabsize(line, *s, col); + MB_PTR_ADV(*s); + return retval; +} + +/// This function is used very often, keep it fast!!!! +/// +/// If "headp" not NULL, set *headp to the size of what we for 'showbreak' +/// string at start of line. Warning: *headp is only set if it's a non-zero +/// value, init to 0 before calling. +/// +/// @param wp +/// @param line +/// @param s +/// @param col +/// @param headp +/// +/// @return The number of characters taken up on the screen. +int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, + colnr_T col, int *headp) +{ + colnr_T col2; + colnr_T col_adj = 0; // col + screen size of tab + colnr_T colmax; + int added; + int mb_added = 0; + int numberextra; + char_u *ps; + int n; + + // No 'linebreak', 'showbreak' and 'breakindent': return quickly. + if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) { + if (wp->w_p_wrap) { + return win_nolbr_chartabsize(wp, s, col, headp); + } + return win_chartabsize(wp, s, col); + } + + // First get normal size, without 'linebreak' + int size = win_chartabsize(wp, s, col); + int c = *s; + if (*s == TAB) { + col_adj = size - 1; + } + + // If 'linebreak' set check at a blank before a non-blank if the line + // needs a break here + if (wp->w_p_lbr + && vim_isbreak(c) + && !vim_isbreak((int)s[1]) + && wp->w_p_wrap + && (wp->w_width_inner != 0)) { + // Count all characters from first non-blank after a blank up to next + // non-blank after a blank. + numberextra = win_col_off(wp); + col2 = col; + colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); + + if (col >= colmax) { + colmax += col_adj; + n = colmax + win_col_off2(wp); + + if (n > 0) { + colmax += (((col - colmax) / n) + 1) * n - col_adj; + } + } + + for (;;) { + ps = s; + MB_PTR_ADV(s); + c = *s; + + if (!(c != NUL + && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) { + break; + } + + col2 += win_chartabsize(wp, s, col2); + + if (col2 >= colmax) { // doesn't fit + size = colmax - col + col_adj; + break; + } + } + } else if ((size == 2) + && (MB_BYTE2LEN(*s) > 1) + && wp->w_p_wrap + && in_win_border(wp, col)) { + // Count the ">" in the last column. + size++; + mb_added = 1; + } + + // May have to add something for 'breakindent' and/or 'showbreak' + // string at start of line. + // Set *headp to the size of what we add. + added = 0; + + if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) { + colnr_T sbrlen = 0; + int numberwidth = win_col_off(wp); + + numberextra = numberwidth; + col += numberextra + mb_added; + + if (col >= (colnr_T)wp->w_width_inner) { + col -= wp->w_width_inner; + numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp)); + if (col >= numberextra && numberextra > 0) { + col %= numberextra; + } + if (*p_sbr != NUL) { + sbrlen = (colnr_T)MB_CHARLEN(p_sbr); + if (col >= sbrlen) { + col -= sbrlen; + } + } + if (col >= numberextra && numberextra > 0) { + col %= numberextra; + } else if (col > 0 && numberextra > 0) { + col += numberwidth - win_col_off2(wp); + } + + numberwidth -= win_col_off2(wp); + } + + if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) { + if (*p_sbr != NUL) { + if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) { + // Calculate effective window width. + int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth; + int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col)) + : 0; + + if (width <= 0) { + width = 1; + } + added += ((size - prev_width) / width) * vim_strsize(p_sbr); + if ((size - prev_width) % width) { + // Wrapped, add another length of 'sbr'. + added += vim_strsize(p_sbr); + } + } else { + added += vim_strsize(p_sbr); + } + } + + if (wp->w_p_bri) { + added += get_breakindent_win(wp, line); + } + + size += added; + if (col != 0) { + added = 0; + } + } + } + + if (headp != NULL) { + *headp = added + mb_added; + } + return size; +} + +/// Like win_lbr_chartabsize(), except that we know 'linebreak' is off and +/// 'wrap' is on. This means we need to check for a double-byte character that +/// doesn't fit at the end of the screen line. +/// +/// @param wp +/// @param s +/// @param col +/// @param headp +/// +/// @return The number of characters take up on the screen. +static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp) +{ + int n; + + if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { + return tabstop_padding(col, + wp->w_buffer->b_p_ts, + wp->w_buffer->b_p_vts_array); + } + n = ptr2cells(s); + + // Add one cell for a double-width character in the last column of the + // window, displayed with a ">". + if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) { + if (headp != NULL) { + *headp = 1; + } + return 3; + } + return n; +} + diff --git a/src/nvim/plines.h b/src/nvim/plines.h new file mode 100644 index 0000000000..32778b69f1 --- /dev/null +++ b/src/nvim/plines.h @@ -0,0 +1,9 @@ +#ifndef NVIM_PLINES_H +#define NVIM_PLINES_H + +#include "nvim/vim.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "plines.h.generated.h" +#endif +#endif // NVIM_PLINES_H diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index c2ef217638..6379174938 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -63,6 +63,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/garray.h" #include "nvim/strings.h" diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 2fc5777937..e4030b76a3 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -101,6 +101,7 @@ #include "nvim/option.h" #include "nvim/os_unix.h" #include "nvim/path.h" +#include "nvim/plines.h" #include "nvim/popupmnu.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" @@ -1694,7 +1695,7 @@ static void win_update(win_T *wp, Providers *providers) /* * There is a trick with w_botline. If we invalidate it on each * change that might modify it, this will cause a lot of expensive - * calls to plines() in update_topline() each time. Therefore the + * calls to plines_win() in update_topline() each time. Therefore the * value of w_botline is often approximated, and this value is used to * compute the value of w_topline. If the value of w_botline was * wrong, check that the value of w_topline is correct (cursor is on @@ -2380,13 +2381,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, && wp->w_p_culopt_flags != CULOPT_NBR) { cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); - cul_attr = win_hl_attr(wp, HLF_CUL); - HlAttrs ae = syn_attr2entry(cul_attr); - - // We make a compromise here (#7383): - // * low-priority CursorLine if fg is not set - // * high-priority ("same as Vim" priority) CursorLine if fg is set if (!cul_screenline) { + cul_attr = win_hl_attr(wp, HLF_CUL); + HlAttrs ae = syn_attr2entry(cul_attr); + // We make a compromise here (#7383): + // * low-priority CursorLine if fg is not set + // * high-priority ("same as Vim" priority) CursorLine if fg is set if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { line_attr_lowprio = cul_attr; } else { @@ -2398,7 +2398,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } } } else { - cul_attr = 0; margin_columns_win(wp, &left_curline_col, &right_curline_col); } area_highlighting = true; @@ -2699,6 +2698,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, // Skip this quickly when working on the text. if (draw_state != WL_LINE) { + if (cul_screenline) { + cul_attr = 0; + line_attr = line_attr_save; + line_attr_lowprio = line_attr_lowprio_save; + } + if (draw_state == WL_CMDLINE - 1 && n_extra == 0) { draw_state = WL_CMDLINE; if (cmdwin_type != 0 && wp == curwin) { @@ -2854,9 +2859,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, if (diff_hlf != (hlf_T)0) { char_attr = win_hl_attr(wp, diff_hlf); - if (cul_attr) { - char_attr = hl_combine_attr(char_attr, cul_attr); - } } p_extra = NULL; c_extra = ' '; @@ -2942,21 +2944,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, } } - if (cul_screenline) { - if (draw_state == WL_LINE - && vcol >= left_curline_col - && vcol < right_curline_col) { - cul_attr = win_hl_attr(wp, HLF_CUL); - HlAttrs ae = syn_attr2entry(cul_attr); - if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { - line_attr_lowprio = cul_attr; + if (cul_screenline && draw_state == WL_LINE + && vcol >= left_curline_col + && vcol < right_curline_col) { + cul_attr = win_hl_attr(wp, HLF_CUL); + HlAttrs ae = syn_attr2entry(cul_attr); + if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { + line_attr_lowprio = cul_attr; + } else { + if (!(State & INSERT) && bt_quickfix(wp->w_buffer) + && qf_current_entry(wp) == lnum) { + line_attr = hl_combine_attr(cul_attr, line_attr); } else { line_attr = cul_attr; } - } else { - cul_attr = 0; - line_attr = line_attr_save; - line_attr_lowprio = line_attr_lowprio_save; } } @@ -4119,7 +4120,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, /* * Update w_cline_height and w_cline_folded if the cursor line was - * updated (saves a call to plines() later). + * updated (saves a call to plines_win() later). */ if (wp == curwin && lnum == curwin->w_cursor.lnum) { curwin->w_cline_row = startrow; @@ -5089,7 +5090,7 @@ win_redr_status_matches ( save_p_wmh = p_wmh; p_ls = 2; p_wmh = 0; - last_status(FALSE); + last_status(false); } wild_menu_showing = WM_SHOWN; } diff --git a/src/nvim/search.c b/src/nvim/search.c index e5d545b185..b712e09861 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1620,7 +1620,7 @@ static bool check_prevcol(char_u *linep, int col, int ch, int *prevcol) if (prevcol) { *prevcol = col; } - return (col >= 0 && linep[col] == ch) ? true : false; + return col >= 0 && linep[col] == ch; } /* diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index e9ee63970c..1d45df8ebd 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -53,9 +53,9 @@ static bool did_syntax_onoff = false; /// Structure that stores information about a highlight group. /// The ID of a highlight group is also called group ID. It is the index in /// the highlight_ga array PLUS ONE. -struct hl_group { +typedef struct hl_group { char_u *sg_name; ///< highlight group name - char_u *sg_name_u; ///< uppercase of sg_name + char *sg_name_u; ///< uppercase of sg_name bool sg_cleared; ///< "hi clear" was used int sg_attr; ///< Screen attr @see ATTR_ENTRY int sg_link; ///< link to this highlight group ID @@ -80,7 +80,7 @@ struct hl_group { char *sg_rgb_sp_name; ///< RGB special color name int sg_blend; ///< blend level (0-100 inclusive), -1 if unset -}; +} HlGroup; /// \addtogroup SG_SET /// @{ @@ -91,6 +91,7 @@ struct hl_group { // builtin |highlight-groups| static garray_T highlight_ga = GA_EMPTY_INIT_VALUE; +Map(cstr_t, int) *highlight_unames; static inline struct hl_group * HL_TABLE(void) { @@ -384,6 +385,11 @@ static int current_line_id = 0; // unique number for current line static int syn_time_on = FALSE; # define IF_SYN_TIME(p) (p) +void syntax_init(void) +{ + highlight_unames = map_new(cstr_t, int)(); +} + // Set the timeout used for syntax highlighting. // Use NULL to reset, no timeout. void syn_set_timeout(proftime_T *tm) @@ -3372,7 +3378,7 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) XFREE_CLEAR(SYN_CLSTR(curwin->w_s)[scl_id].scl_list); } } else { - id = syn_namen2id(arg, (int)(arg_end - arg)); + id = syn_name2id_len(arg, (int)(arg_end - arg)); if (id == 0) { EMSG2(_(e_nogroup), arg); break; @@ -3542,7 +3548,7 @@ syn_cmd_list( else syn_list_cluster(id - SYNID_CLUSTER); } else { - int id = syn_namen2id(arg, (int)(arg_end - arg)); + int id = syn_name2id_len(arg, (int)(arg_end - arg)); if (id == 0) { EMSG2(_(e_nogroup), arg); } else { @@ -6635,7 +6641,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) // ":highlight {group-name}": list highlighting for one group. if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) { - id = syn_namen2id((const char_u *)line, (int)(name_end - line)); + id = syn_name2id_len((const char_u *)line, (int)(name_end - line)); if (id == 0) { emsgf(_("E411: highlight group not found: %s"), line); } else { @@ -7113,6 +7119,7 @@ void free_highlight(void) xfree(HL_TABLE()[i].sg_name_u); } ga_clear(&highlight_ga); + map_free(cstr_t, int)(highlight_unames); } #endif @@ -7470,26 +7477,35 @@ static void set_hl_attr(int idx) } } +int syn_name2id(const char_u *name) + FUNC_ATTR_NONNULL_ALL +{ + return syn_name2id_len(name, STRLEN(name)); +} + /// Lookup a highlight group name and return its ID. /// /// @param highlight name e.g. 'Cursor', 'Normal' /// @return the highlight id, else 0 if \p name does not exist -int syn_name2id(const char_u *name) +int syn_name2id_len(const char_u *name, size_t len) FUNC_ATTR_NONNULL_ALL { - int i; - char_u name_u[200]; - - /* Avoid using stricmp() too much, it's slow on some systems */ - /* Avoid alloc()/free(), these are slow too. ID names over 200 chars - * don't deserve to be found! */ - STRLCPY(name_u, name, 200); - vim_strup(name_u); - for (i = highlight_ga.ga_len; --i >= 0; ) - if (HL_TABLE()[i].sg_name_u != NULL - && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0) - break; - return i + 1; + char name_u[201]; + + if (len == 0 || len > 200) { + // ID names over 200 chars don't deserve to be found! + return 0; + } + + // Avoid using stricmp() too much, it's slow on some systems */ + // Avoid alloc()/free(), these are slow too. + memcpy(name_u, name, len); + name_u[len] = '\0'; + vim_strup((char_u *)name_u); + + // map_get(..., int) returns 0 when no key is present, which is + // the expected value for missing highlight group. + return map_get(cstr_t, int)(highlight_unames, name_u); } /// Lookup a highlight group name and return its attributes. @@ -7524,17 +7540,6 @@ char_u *syn_id2name(int id) return HL_TABLE()[id - 1].sg_name; } -/* - * Like syn_name2id(), but take a pointer + length argument. - */ -int syn_namen2id(const char_u *linep, int len) -{ - char_u *name = vim_strnsave(linep, len); - int id = syn_name2id(name); - xfree(name); - - return id; -} /// Find highlight group name in the table and return its ID. /// If it doesn't exist yet, a new entry is created. @@ -7543,14 +7548,11 @@ int syn_namen2id(const char_u *linep, int len) /// @param len length of \p pp /// /// @return 0 for failure else the id of the group -int syn_check_group(const char_u *pp, int len) +int syn_check_group(const char_u *name, int len) { - char_u *name = vim_strnsave(pp, len); - int id = syn_name2id(name); + int id = syn_name2id_len(name, len); if (id == 0) { // doesn't exist yet - id = syn_add_group(name); - } else { - xfree(name); + return syn_add_group(vim_strnsave(name, len)); } return id; } @@ -7593,7 +7595,7 @@ static int syn_add_group(char_u *name) return 0; } - char_u *const name_up = vim_strsave_up(name); + char *const name_up = (char *)vim_strsave_up(name); // Append another syntax_highlight entry. struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); @@ -7605,7 +7607,11 @@ static int syn_add_group(char_u *name) hlgp->sg_blend = -1; hlgp->sg_name_u = name_up; - return highlight_ga.ga_len; /* ID is index plus one */ + int id = highlight_ga.ga_len; // ID is index plus one + + map_put(cstr_t, int)(highlight_unames, name_up, id); + + return id; } /// When, just after calling syn_add_group(), an error is discovered, this @@ -7613,8 +7619,10 @@ static int syn_add_group(char_u *name) static void syn_unadd_group(void) { highlight_ga.ga_len--; - xfree(HL_TABLE()[highlight_ga.ga_len].sg_name); - xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u); + HlGroup *item = &HL_TABLE()[highlight_ga.ga_len]; + map_del(cstr_t, int)(highlight_unames, item->sg_name_u); + xfree(item->sg_name); + xfree(item->sg_name_u); } diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index fcbc28fdc0..b3df8c63e6 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -12,6 +12,7 @@ set directory^=. set fillchars=vert:\|,fold:- set laststatus=1 set listchars=eol:$ +set joinspaces set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd set nrformats+=octal set shortmess-=F @@ -21,6 +22,14 @@ set undodir^=. set wildoptions= set startofline set sessionoptions+=options +set viewoptions+=options +set switchbuf= + +" Unmap Nvim default mappings. +unmap Y +unmap <C-L> +iunmap <C-U> +iunmap <C-W> " Prevent Nvim log from writing to stderr. let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log' diff --git a/src/nvim/testdir/test42.in b/src/nvim/testdir/test42.in Binary files differindex d9057e72fb..456f9ddb07 100644 --- a/src/nvim/testdir/test42.in +++ b/src/nvim/testdir/test42.in diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index ad28118f16..015979e1be 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -998,6 +998,7 @@ func Test_bufunload_all() endfunc au BufUnload * call UnloadAllBufs() au VimLeave * call writefile(['Test Finished'], 'Xout') + set nohidden edit Xxx1 split Xxx2 q @@ -1955,7 +1956,7 @@ func Test_autocmd_sigusr1() let g:sigusr1_passed = 0 au Signal SIGUSR1 let g:sigusr1_passed = 1 - call system('/bin/kill -s usr1 ' . getpid()) + call system('kill -s usr1 ' . getpid()) call WaitForAssert({-> assert_true(g:sigusr1_passed)}) au! Signal diff --git a/src/nvim/testdir/test_command_count.vim b/src/nvim/testdir/test_command_count.vim index 55b230373f..c7dddf4164 100644 --- a/src/nvim/testdir/test_command_count.vim +++ b/src/nvim/testdir/test_command_count.vim @@ -33,7 +33,7 @@ func Test_command_count_0() delcommand RangeBuffers delcommand RangeBuffersAll - set hidden& + set nohidden set swapfile& endfunc diff --git a/src/nvim/testdir/test_cursorline.vim b/src/nvim/testdir/test_cursorline.vim index 4a0f2665fe..39d8b901ed 100644 --- a/src/nvim/testdir/test_cursorline.vim +++ b/src/nvim/testdir/test_cursorline.vim @@ -192,7 +192,29 @@ func Test_cursorline_screenline() call term_sendkeys(buf, "gj") call term_wait(buf) call VerifyScreenDump(buf, 'Test_'. filename. '_18', {}) + call term_sendkeys(buf, ":set breakindent& foldcolumn& signcolumn&\<cr>") endif + " showbreak should not be highlighted with CursorLine when 'number' is off + call term_sendkeys(buf, "gg0") + call term_sendkeys(buf, ":set list cursorlineopt=screenline listchars=space:-\<cr>") + call term_sendkeys(buf, ":set nonumber\<cr>") + call VerifyScreenDump(buf, 'Test_'. filename. '_19', {}) + call term_sendkeys(buf, "fagj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_20', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_21', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_22', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_23', {}) + call term_sendkeys(buf, "gj") + call term_wait(buf) + call VerifyScreenDump(buf, 'Test_'. filename. '_24', {}) + call term_sendkeys(buf, ":set list& cursorlineopt& listchars&\<cr>") call StopVimInTerminal(buf) call delete(filename) diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index 8592f48af7..f39cda7663 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -540,7 +540,7 @@ func Test_diffopt_hiddenoff() bwipe! bwipe! - set hidden& diffopt& + set nohidden diffopt& endfunc func Test_diffoff_hidden() @@ -577,7 +577,7 @@ func Test_diffoff_hidden() bwipe! bwipe! - set hidden& diffopt& + set nohidden diffopt& endfunc func Test_setting_cursor() @@ -990,6 +990,37 @@ func Test_diff_with_cursorline() call delete('Xtest_diff_cursorline') endfunc +func Test_diff_with_cursorline_breakindent() + CheckScreendump + + call writefile([ + \ 'hi CursorLine ctermbg=red ctermfg=white', + \ 'set noequalalways wrap diffopt=followwrap cursorline breakindent', + \ '50vnew', + \ 'call setline(1, [" "," "," "," "])', + \ 'exe "norm 20Afoo\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abar\<Esc>"', + \ 'vnew', + \ 'call setline(1, [" "," "," "," "])', + \ 'exe "norm 20Abee\<Esc>j20Afoo\<Esc>j20Afoo\<Esc>j20Abaz\<Esc>"', + \ 'windo diffthis', + \ '2wincmd w', + \ ], 'Xtest_diff_cursorline_breakindent') + let buf = RunVimInTerminal('-S Xtest_diff_cursorline_breakindent', {}) + + call term_sendkeys(buf, "gg0") + call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_01', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_02', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_03', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_diff_with_cul_bri_04', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_diff_cursorline_breakindent') +endfunc + func Test_diff_with_syntax() CheckScreendump diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 4ab58cd084..c155dbad50 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -263,6 +263,7 @@ let s:filename_checks = { \ 'json': ['file.json', 'file.jsonp', 'file.json-patch', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'], \ 'jsonc': ['file.jsonc'], \ 'jsp': ['file.jsp'], + \ 'julia': ['file.jl'], \ 'kconfig': ['Kconfig', 'Kconfig.debug', 'Kconfig.file'], \ 'kivy': ['file.kv'], \ 'kix': ['file.kix'], @@ -754,6 +755,7 @@ func Test_pp_file() split Xfile.pp call assert_equal('pascal', &filetype) bwipe! + unlet g:filetype_pp " Test dist#ft#FTpp() call writefile(['{ pascal comment'], 'Xfile.pp') diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim index ee548037ba..43efd6248e 100644 --- a/src/nvim/testdir/test_gf.vim +++ b/src/nvim/testdir/test_gf.vim @@ -145,7 +145,7 @@ func Test_gf_visual() bwipe! call delete('Xtest_gf_visual') - set hidden& + set nohidden endfunc func Test_gf_error() diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index 3da3648fec..0fb026f6b0 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -95,7 +95,7 @@ func Test_ins_complete() call delete('Xtest11.one') call delete('Xtest11.two') call delete('Xtestdata') - set cpt& cot& def& tags& tagbsearch& hidden& + set cpt& cot& def& tags& tagbsearch& nohidden cd .. call delete('Xdir', 'rf') endfunc diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim index ac6ef8f29f..ecb969d10a 100644 --- a/src/nvim/testdir/test_join.vim +++ b/src/nvim/testdir/test_join.vim @@ -51,7 +51,7 @@ func Test_join_marks() /^This line/;'}-join call assert_equal([0, 4, 11, 0], getpos("'[")) - call assert_equal([0, 4, 67, 0], getpos("']")) + call assert_equal([0, 4, 66, 0], getpos("']")) enew! endfunc diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index 09448ca71b..0fd76a23ea 100644 --- a/src/nvim/testdir/test_match.vim +++ b/src/nvim/testdir/test_match.vim @@ -157,7 +157,10 @@ func Test_match_error() endfunc func Test_matchadd_error() - call assert_fails("call matchadd('GroupDoesNotExist', 'X')", 'E28:') + call clearmatches() + " Nvim: not an error anymore: + call matchadd('GroupDoesNotExist', 'X') + call assert_equal([{'group': 'GroupDoesNotExist', 'pattern': 'X', 'priority': 10, 'id': 13}], getmatches()) call assert_fails("call matchadd('Search', '\\(')", 'E475:') call assert_fails("call matchadd('Search', 'XXX', 1, 123, 1)", 'E715:') call assert_fails("call matchadd('Error', 'XXX', 1, 3)", 'E798:') diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index fbe764bbf2..c96c6a9678 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -307,7 +307,7 @@ func Test_mksession_buffer_count() call delete('Xbaz') call delete('Xtest_mks.out') %bwipe! - set hidden& + set nohidden endfunc if has('extra_search') diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 8796af7a20..72c151142d 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -539,7 +539,7 @@ func Test_copy_winopt() call assert_equal(4,&numberwidth) bw! - set hidden& + set nohidden endfunc func Test_shortmess_F() diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 5090584e41..283e7bbafe 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -1911,7 +1911,7 @@ func Test_switchbuf() enew | only set switchbuf=useopen cexpr "Xqftestfile1:1:10" - call assert_equal('', &switchbuf) + call assert_equal('uselast', &switchbuf) call delete('Xqftestfile1') call delete('Xqftestfile2') diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 68dcfb6890..b6d9143bc9 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -170,7 +170,7 @@ func Test_tag_symbolic() call assert_equal('Xtest.c', expand('%:t')) call assert_equal(2, col('.')) - set hidden& + set nohidden set tags& enew! call delete('Xtags') diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index a522705238..039de0c623 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -608,7 +608,7 @@ func Test_window_prevwin() " reset q call delete('tmp.txt') - set hidden&vim autoread&vim + set nohidden autoread&vim delfunc Fun_RenewFile endfunc diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 3096fe84c0..c4b48a6ee2 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -1297,8 +1297,8 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf, goto theend; } - /* Undo must be synced. */ - u_sync(TRUE); + // Undo must be synced. + u_sync(true); /* * Write the header. @@ -1783,7 +1783,7 @@ void u_undo(int count) * be compatible. */ if (curbuf->b_u_synced == false) { - u_sync(TRUE); + u_sync(true); count = 1; } @@ -1943,9 +1943,10 @@ void undo_time(long step, bool sec, bool file, bool absolute) bool above = false; bool did_undo = true; - /* First make sure the current undoable change is synced. */ - if (curbuf->b_u_synced == false) - u_sync(TRUE); + // First make sure the current undoable change is synced. + if (curbuf->b_u_synced == false) { + u_sync(true); + } u_newcount = 0; u_oldcount = 0; @@ -2601,13 +2602,10 @@ static void u_undo_end( msgbuf); } -/* - * u_sync: stop adding to the current entry list - */ -void -u_sync( - int force // Also sync when no_u_sync is set. -) +/// u_sync: stop adding to the current entry list +/// +/// @param force if true, also sync when no_u_sync is set. +void u_sync(bool force) { // Skip it when already synced or syncing is disabled. if (curbuf->b_u_synced || (!force && no_u_sync > 0)) { diff --git a/src/nvim/window.c b/src/nvim/window.c index 2f43faef50..fefbab822e 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -31,6 +31,7 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/plines.h" #include "nvim/file_search.h" #include "nvim/garray.h" #include "nvim/move.h" @@ -904,7 +905,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) int new_size = size; int i; int need_status = 0; - int do_equal = FALSE; + bool do_equal = false; int needed; int available; int oldwin_height = 0; @@ -990,9 +991,10 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) new_size = wmw1; } - /* if it doesn't fit in the current window, need win_equal() */ - if (oldwin->w_width - new_size - 1 < p_wmw) - do_equal = TRUE; + // if it doesn't fit in the current window, need win_equal() + if (oldwin->w_width - new_size - 1 < p_wmw) { + do_equal = true; + } // We don't like to take lines for the new window from a // 'winfixwidth' window. Take them from a window to the left or right @@ -1009,9 +1011,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) while (frp != NULL) { if (frp->fr_win != oldwin && frp->fr_win != NULL && (frp->fr_win->w_width > new_size - || frp->fr_win->w_width > oldwin->w_width - - new_size - 1)) { - do_equal = TRUE; + || frp->fr_win->w_width > (oldwin->w_width + - new_size - 1))) { + do_equal = true; break; } frp = frp->fr_next; @@ -1074,9 +1076,10 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) new_size = wmh1; } - /* if it doesn't fit in the current window, need win_equal() */ - if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh) - do_equal = TRUE; + // if it doesn't fit in the current window, need win_equal() + if (oldwin_height - new_size - STATUS_HEIGHT < p_wmh) { + do_equal = true; + } /* We don't like to take lines for the new window from a * 'winfixheight' window. Take them from a window above or below @@ -1105,7 +1108,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) && (frp->fr_win->w_height > new_size || frp->fr_win->w_height > oldwin_height - new_size - STATUS_HEIGHT)) { - do_equal = TRUE; + do_equal = true; break; } frp = frp->fr_next; @@ -1120,19 +1123,19 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) && ((flags & WSP_BOT) || (flags & WSP_BELOW) || (!(flags & WSP_ABOVE) - && ( - (flags & WSP_VERT) ? p_spr : - p_sb)))) { - /* new window below/right of current one */ - if (new_wp == NULL) - wp = win_alloc(oldwin, FALSE); - else + && ((flags & WSP_VERT) ? p_spr : p_sb)))) { + // new window below/right of current one + if (new_wp == NULL) { + wp = win_alloc(oldwin, false); + } else { win_append(oldwin, wp); + } } else { - if (new_wp == NULL) - wp = win_alloc(oldwin->w_prev, FALSE); - else + if (new_wp == NULL) { + wp = win_alloc(oldwin->w_prev, false); + } else { win_append(oldwin->w_prev, wp); + } } if (new_wp == NULL) { @@ -1247,11 +1250,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) frame_add_vsep(curfrp); /* Set width of neighbor frame */ frame_new_width(curfrp, curfrp->fr_width - - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP, - FALSE); - } else + - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP, + false); + } else { win_new_width(oldwin, oldwin->w_width - (new_size + 1)); - if (before) { /* new window left of current one */ + } + if (before) { // new window left of current one wp->w_wincol = oldwin->w_wincol; oldwin->w_wincol += new_size + 1; } else /* new window right of current one */ @@ -1438,7 +1442,7 @@ static void win_init_some(win_T *newp, win_T *oldp) win_copy_options(oldp, newp); } -/// Return TRUE if "win" is floating window in the current tab page. +/// Return true if "win" is floating window in the current tab page. /// /// @param win window to check bool win_valid_floating(const win_T *win) @@ -1516,17 +1520,14 @@ int win_count(void) return count; } -/* - * Make "count" windows on the screen. - * Return actual number of windows on the screen. - * Must be called when there is just one window, filling the whole screen - * (excluding the command line). - */ -int -make_windows ( - int count, - int vertical /* split windows vertically if TRUE */ -) +/// Make "count" windows on the screen. +/// Must be called when there is just one window, filling the whole screen +/// (excluding the command line). +/// +/// @param vertical split windows vertically if true +/// +/// @return actual number of windows on the screen. +int make_windows(int count, bool vertical) { int maxcount; int todo; @@ -1551,8 +1552,9 @@ make_windows ( /* * add status line now, otherwise first window will be too big */ - if (count > 1) - last_status(TRUE); + if (count > 1) { + last_status(true); + } /* * Don't execute autocommands while creating the windows. Must do that @@ -1785,8 +1787,8 @@ static void win_totop(int size, int flags) (void)winframe_remove(curwin, &dir, NULL); } win_remove(curwin, NULL); - last_status(FALSE); /* may need to remove last status line */ - (void)win_comp_pos(); /* recompute window positions */ + last_status(false); // may need to remove last status line + (void)win_comp_pos(); // recompute window positions /* Split a window on the desired side and put the window there. */ (void)win_split_ins(size, flags, curwin, dir); @@ -1897,7 +1899,7 @@ static void win_equal_rec( int room = 0; int new_size; int has_next_curwin = 0; - int hnc; + bool hnc; if (topfr->fr_layout == FR_LEAF) { /* Set the width/height of this frame. @@ -2001,17 +2003,20 @@ static void win_equal_rec( wincount = (n + (fr->fr_next == NULL ? extra_sep : 0)) / (p_wmw + 1); m = frame_minwidth(fr, next_curwin); - if (has_next_curwin) + if (has_next_curwin) { hnc = frame_has_win(fr, next_curwin); - else - hnc = FALSE; - if (hnc) /* don't count next_curwin */ - --wincount; - if (totwincount == 0) + } else { + hnc = false; + } + if (hnc) { // don't count next_curwin + wincount--; + } + if (totwincount == 0) { new_size = room; - else + } else { new_size = (wincount * room + (totwincount / 2)) / totwincount; - if (hnc) { /* add next_curwin size */ + } + if (hnc) { // add next_curwin size next_curwin_size -= p_wiw - (m - n); new_size += next_curwin_size; room -= new_size - next_curwin_size; @@ -2122,17 +2127,20 @@ static void win_equal_rec( wincount = (n + (fr->fr_next == NULL ? extra_sep : 0)) / (p_wmh + 1); m = frame_minheight(fr, next_curwin); - if (has_next_curwin) + if (has_next_curwin) { hnc = frame_has_win(fr, next_curwin); - else - hnc = FALSE; - if (hnc) /* don't count next_curwin */ - --wincount; - if (totwincount == 0) + } else { + hnc = false; + } + if (hnc) { // don't count next_curwin + wincount--; + } + if (totwincount == 0) { new_size = room; - else + } else { new_size = (wincount * room + (totwincount / 2)) / totwincount; - if (hnc) { /* add next_curwin size */ + } + if (hnc) { // add next_curwin size next_curwin_size -= p_wh - (m - n); new_size += next_curwin_size; room -= new_size - next_curwin_size; @@ -2310,8 +2318,8 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, int win_close(win_T *win, bool free_buf) { win_T *wp; - int other_buffer = FALSE; - int close_curwin = FALSE; + bool other_buffer = false; + bool close_curwin = false; int dir; bool help_window = false; tabpage_T *prev_curtab = curtab; @@ -2376,7 +2384,7 @@ int win_close(win_T *win, bool free_buf) * to be the last one left, return now. */ if (wp->w_buffer != curbuf) { - other_buffer = TRUE; + other_buffer = true; win->w_closing = true; apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win)) @@ -2515,7 +2523,7 @@ int win_close(win_T *win, bool free_buf) } } curbuf = curwin->w_buffer; - close_curwin = TRUE; + close_curwin = true; // The cursor position may be invalid if the buffer changed after last // using the window. @@ -2544,7 +2552,7 @@ int win_close(win_T *win, bool free_buf) * If last window has a status line now and we don't want one, * remove the status line. */ - last_status(FALSE); + last_status(false); /* After closing the help window, try restoring the window layout from * before it was opened. */ @@ -2797,7 +2805,7 @@ winframe_remove ( } } frame_new_height(frp2, frp2->fr_height + frp_close->fr_height, - frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE); + frp2 == frp_close->fr_next, false); *dirp = 'v'; } else { /* When 'winfixwidth' is set, try to find another frame in the column @@ -2826,7 +2834,7 @@ winframe_remove ( } } frame_new_width(frp2, frp2->fr_width + frp_close->fr_width, - frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE); + frp2 == frp_close->fr_next, false); *dirp = 'h'; } @@ -2982,18 +2990,14 @@ static bool frame_has_win(const frame_T *frp, const win_T *wp) return false; } -/* - * Set a new height for a frame. Recursively sets the height for contained - * frames and windows. Caller must take care of positions. - */ -static void -frame_new_height ( - frame_T *topfrp, - int height, - int topfirst, /* resize topmost contained frame first */ - int wfh /* obey 'winfixheight' when there is a choice; - may cause the height not to be set */ -) +/// Set a new height for a frame. Recursively sets the height for contained +/// frames and windows. Caller must take care of positions. +/// +/// @param topfirst resize topmost contained frame first. +/// @param wfh obey 'winfixheight' when there is a choice; +/// may cause the height not to be set. +static void frame_new_height(frame_T *topfrp, int height, bool topfirst, + bool wfh) FUNC_ATTR_NONNULL_ALL { frame_T *frp; @@ -3169,18 +3173,14 @@ static void frame_add_statusline(frame_T *frp) } } -/* - * Set width of a frame. Handles recursively going through contained frames. - * May remove separator line for windows at the right side (for win_close()). - */ -static void -frame_new_width ( - frame_T *topfrp, - int width, - int leftfirst, /* resize leftmost contained frame first */ - int wfw /* obey 'winfixwidth' when there is a choice; - may cause the width not to be set */ -) +/// Set width of a frame. Handles recursively going through contained frames. +/// May remove separator line for windows at the right side (for win_close()). +/// +/// @param leftfirst resize leftmost contained frame first. +/// @param wfw obey 'winfixwidth' when there is a choice; +/// may cause the width not to be set. +static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, + bool wfw) { frame_T *frp; int extra_cols; @@ -3537,7 +3537,7 @@ void win_alloc_aucmd_win(void) */ static int win_alloc_firstwin(win_T *oldwin) { - curwin = win_alloc(NULL, FALSE); + curwin = win_alloc(NULL, false); if (oldwin == NULL) { /* Very first window, need to create an empty buffer for it and * initialize from scratch. */ @@ -4341,13 +4341,13 @@ void win_enter(win_T *wp, bool undo_sync) win_enter_ext(wp, undo_sync, false, false, true, true); } -/* - * Make window wp the current window. - * Can be called with "curwin_invalid" TRUE, which means that curwin has just - * been closed and isn't valid. - */ -static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, - int trigger_new_autocmds, bool trigger_enter_autocmds, +/// Make window wp the current window. +/// +/// @param curwin_invalid curwin has just been closed and +/// isn't valid when true. +static void win_enter_ext(win_T *wp, bool undo_sync, bool curwin_invalid, + bool trigger_new_autocmds, + bool trigger_enter_autocmds, bool trigger_leave_autocmds) { int other_buffer = FALSE; @@ -4375,7 +4375,7 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, // sync undo before leaving the current buffer if (undo_sync && curbuf != wp->w_buffer) { - u_sync(FALSE); + u_sync(false); } // Might need to scroll the old window before switching, e.g., when the @@ -4535,11 +4535,9 @@ win_T *buf_jump_open_tab(buf_T *buf) return NULL; } -/* - * Allocate a window structure and link it in the window list when "hidden" is - * FALSE. - */ -static win_T *win_alloc(win_T *after, int hidden) +/// @param hidden allocate a window structure and link it in the window if +// false. +static win_T *win_alloc(win_T *after, bool hidden) { static int last_win_id = LOWEST_WIN_ID - 1; @@ -4829,9 +4827,10 @@ void shell_new_rows(void) /* First try setting the heights of windows with 'winfixheight'. If * that doesn't result in the right height, forget about that option. */ - frame_new_height(topframe, h, FALSE, TRUE); - if (!frame_check_height(topframe, h)) - frame_new_height(topframe, h, FALSE, FALSE); + frame_new_height(topframe, h, false, true); + if (!frame_check_height(topframe, h)) { + frame_new_height(topframe, h, false, false); + } (void)win_comp_pos(); // recompute w_winrow and w_wincol win_reconfig_floats(); // The size of floats might change @@ -5077,8 +5076,9 @@ static void frame_setheight(frame_T *curfrp, int height) /* topframe: can only change the command line */ if (height > ROWS_AVAIL) height = ROWS_AVAIL; - if (height > 0) - frame_new_height(curfrp, height, FALSE, FALSE); + if (height > 0) { + frame_new_height(curfrp, height, false, false); + } } else if (curfrp->fr_parent->fr_layout == FR_ROW) { /* Row of frames: Also need to resize frames left and right of this * one. First check for the minimal height of these. */ @@ -5160,7 +5160,7 @@ static void frame_setheight(frame_T *curfrp, int height) /* * set the current frame to the new height */ - frame_new_height(curfrp, height, FALSE, FALSE); + frame_new_height(curfrp, height, false, false); /* * First take lines from the frames after the current frame. If @@ -5183,16 +5183,15 @@ static void frame_setheight(frame_T *curfrp, int height) if (frp->fr_height - room_reserved > take) room_reserved = frp->fr_height - take; take -= frp->fr_height - room_reserved; - frame_new_height(frp, room_reserved, FALSE, FALSE); + frame_new_height(frp, room_reserved, false, false); room_reserved = 0; } } else { if (frp->fr_height - take < h) { take -= frp->fr_height - h; - frame_new_height(frp, h, FALSE, FALSE); + frame_new_height(frp, h, false, false); } else { - frame_new_height(frp, frp->fr_height - take, - FALSE, FALSE); + frame_new_height(frp, frp->fr_height - take, false, false); take = 0; } } @@ -5323,7 +5322,7 @@ static void frame_setwidth(frame_T *curfrp, int width) /* * set the current frame to the new width */ - frame_new_width(curfrp, width, FALSE, FALSE); + frame_new_width(curfrp, width, false, false); /* * First take lines from the frames right of the current frame. If @@ -5346,16 +5345,15 @@ static void frame_setwidth(frame_T *curfrp, int width) if (frp->fr_width - room_reserved > take) room_reserved = frp->fr_width - take; take -= frp->fr_width - room_reserved; - frame_new_width(frp, room_reserved, FALSE, FALSE); + frame_new_width(frp, room_reserved, false, false); room_reserved = 0; } } else { if (frp->fr_width - take < w) { take -= frp->fr_width - w; - frame_new_width(frp, w, FALSE, FALSE); + frame_new_width(frp, w, false, false); } else { - frame_new_width(frp, frp->fr_width - take, - FALSE, FALSE); + frame_new_width(frp, frp->fr_width - take, false, false); take = 0; } } @@ -5408,16 +5406,14 @@ void win_setminwidth(void) } } -/* - * Status line of dragwin is dragged "offset" lines down (negative is up). - */ +/// Status line of dragwin is dragged "offset" lines down (negative is up). void win_drag_status_line(win_T *dragwin, int offset) { frame_T *curfr; frame_T *fr; int room; int row; - int up; /* if TRUE, drag status line up, otherwise down */ + bool up; // if true, drag status line up, otherwise down int n; fr = dragwin->w_frame; @@ -5443,8 +5439,8 @@ void win_drag_status_line(win_T *dragwin, int offset) fr = fr->fr_parent; } - if (offset < 0) { /* drag up */ - up = TRUE; + if (offset < 0) { // drag up + up = true; offset = -offset; /* sum up the room of the current frame and above it */ if (fr == curfr) { @@ -5458,12 +5454,10 @@ void win_drag_status_line(win_T *dragwin, int offset) break; } } - fr = curfr->fr_next; /* put fr at frame that grows */ - } else { /* drag down */ - up = FALSE; - /* - * Only dragging the last status line can reduce p_ch. - */ + fr = curfr->fr_next; // put fr at frame that grows + } else { // drag down + up = false; + // Only dragging the last status line can reduce p_ch. room = Rows - cmdline_row; if (curfr->fr_next == NULL) room -= 1; @@ -5487,8 +5481,9 @@ void win_drag_status_line(win_T *dragwin, int offset) * Grow frame fr by "offset" lines. * Doesn't happen when dragging the last status line up. */ - if (fr != NULL) - frame_new_height(fr, fr->fr_height + offset, up, FALSE); + if (fr != NULL) { + frame_new_height(fr, fr->fr_height + offset, up, false); + } if (up) fr = curfr; /* current frame gets smaller */ @@ -5502,9 +5497,9 @@ void win_drag_status_line(win_T *dragwin, int offset) n = frame_minheight(fr, NULL); if (fr->fr_height - offset <= n) { offset -= fr->fr_height - n; - frame_new_height(fr, n, !up, FALSE); + frame_new_height(fr, n, !up, false); } else { - frame_new_height(fr, fr->fr_height - offset, !up, FALSE); + frame_new_height(fr, fr->fr_height - offset, !up, false); break; } if (up) @@ -5534,7 +5529,7 @@ void win_drag_vsep_line(win_T *dragwin, int offset) frame_T *curfr; frame_T *fr; int room; - int left; /* if TRUE, drag separator line left, otherwise right */ + bool left; // if true, drag separator line left, otherwise right int n; fr = dragwin->w_frame; @@ -5563,8 +5558,8 @@ void win_drag_vsep_line(win_T *dragwin, int offset) } } - if (offset < 0) { /* drag left */ - left = TRUE; + if (offset < 0) { // drag left + left = true; offset = -offset; /* sum up the room of the current frame and left of it */ room = 0; @@ -5573,10 +5568,10 @@ void win_drag_vsep_line(win_T *dragwin, int offset) if (fr == curfr) break; } - fr = curfr->fr_next; /* put fr at frame that grows */ - } else { /* drag right */ - left = FALSE; - /* sum up the room of frames right of the current one */ + fr = curfr->fr_next; // put fr at frame that grows + } else { // drag right + left = false; + // sum up the room of frames right of the current one room = 0; FOR_ALL_FRAMES(fr, curfr->fr_next) { room += fr->fr_width - frame_minwidth(fr, NULL); @@ -5599,8 +5594,8 @@ void win_drag_vsep_line(win_T *dragwin, int offset) return; // Safety check, should not happen. } - /* grow frame fr by offset lines */ - frame_new_width(fr, fr->fr_width + offset, left, FALSE); + // grow frame fr by offset lines + frame_new_width(fr, fr->fr_width + offset, left, false); /* shrink other frames: current and at the left or at the right */ if (left) @@ -5612,9 +5607,9 @@ void win_drag_vsep_line(win_T *dragwin, int offset) n = frame_minwidth(fr, NULL); if (fr->fr_width - offset <= n) { offset -= fr->fr_width - n; - frame_new_width(fr, n, !left, FALSE); + frame_new_width(fr, n, !left, false); } else { - frame_new_width(fr, fr->fr_width - offset, !left, FALSE); + frame_new_width(fr, fr->fr_width - offset, !left, false); break; } if (left) @@ -5926,7 +5921,7 @@ void command_height(void) */ static void frame_add_height(frame_T *frp, int n) { - frame_new_height(frp, frp->fr_height + n, FALSE, FALSE); + frame_new_height(frp, frp->fr_height + n, false, false); for (;; ) { frp = frp->fr_parent; if (frp == NULL) @@ -6091,21 +6086,18 @@ file_name_in_line ( return find_file_name_in_path(ptr, len, options, count, rel_fname); } -/* - * Add or remove a status line for the bottom window(s), according to the - * value of 'laststatus'. - */ -void -last_status ( - int morewin /* pretend there are two or more windows */ -) +/// Add or remove a status line for the bottom window(s), according to the +/// value of 'laststatus'. +/// +/// @param morewin pretend there are two or more windows if true. +void last_status(bool morewin) { /* Don't make a difference between horizontal or vertical split. */ last_status_rec(topframe, (p_ls == 2 || (p_ls == 1 && (morewin || !one_window())))); } -static void last_status_rec(frame_T *fr, int statusline) +static void last_status_rec(frame_T *fr, bool statusline) { frame_T *fp; win_T *wp; @@ -6134,7 +6126,7 @@ static void last_status_rec(frame_T *fr, int statusline) } wp->w_status_height = 1; if (fp != fr) { - frame_new_height(fp, fp->fr_height - 1, FALSE, FALSE); + frame_new_height(fp, fp->fr_height - 1, false, false); frame_fix_height(wp); (void)win_comp_pos(); } else @@ -6213,12 +6205,11 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT return count <= 1; } -/* - * Correct the cursor line number in other windows. Used after changing the - * current buffer, and before applying autocommands. - * When "do_curwin" is TRUE, also check current window. - */ -void check_lnums(int do_curwin) +/// Correct the cursor line number in other windows. Used after changing the +/// current buffer, and before applying autocommands. +/// +/// @param do_curwin when true, also check current window. +void check_lnums(bool do_curwin) { FOR_ALL_TAB_WINDOWS(tp, wp) { if ((do_curwin || wp != curwin) && wp->w_buffer == curbuf) { @@ -6366,8 +6357,8 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) fr->fr_height = sn->fr_height; fr->fr_width = sn->fr_width; if (fr->fr_layout == FR_LEAF) { - frame_new_height(fr, fr->fr_height, FALSE, FALSE); - frame_new_width(fr, fr->fr_width, FALSE, FALSE); + frame_new_height(fr, fr->fr_height, false, false); + frame_new_width(fr, fr->fr_width, false, false); wp = sn->fr_win; } if (sn->fr_next != NULL) { @@ -6405,15 +6396,16 @@ static win_T *get_snapshot_focus(int idx) return win_valid(sn->fr_win) ? sn->fr_win : NULL; } -/* - * Set "win" to be the curwin and "tp" to be the current tab page. - * restore_win() MUST be called to undo, also when FAIL is returned. - * No autocommands will be executed until restore_win() is called. - * When "no_display" is TRUE the display won't be affected, no redraw is - * triggered, another tabpage access is limited. - * Returns FAIL if switching to "win" failed. - */ -int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display) +/// Set "win" to be the curwin and "tp" to be the current tab page. +/// restore_win() MUST be called to undo, also when FAIL is returned. +/// No autocommands will be executed until restore_win() is called. +/// +/// @param no_display if true the display won't be affected, no redraw is +/// triggered, another tabpage access is limited. +/// +/// @return FAIL if switching to "win" failed. +int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, + tabpage_T *tp, bool no_display) { block_autocmds(); return switch_win_noblock(save_curwin, save_curtab, win, tp, no_display); @@ -6421,7 +6413,7 @@ int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage // As switch_win() but without blocking autocommands. int switch_win_noblock(win_T **save_curwin, tabpage_T **save_curtab, - win_T *win, tabpage_T *tp, int no_display) + win_T *win, tabpage_T *tp, bool no_display) { *save_curwin = curwin; if (tp != NULL) { @@ -6542,8 +6534,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, cur = cur->next; } } - if ((hlg_id = syn_name2id((const char_u *)grp)) == 0) { - EMSG2(_(e_nogroup), grp); + if ((hlg_id = syn_check_group((const char_u *)grp, strlen(grp))) == 0) { return -1; } if (pat != NULL && (regprog = vim_regcomp((char_u *)pat, RE_MAGIC)) == NULL) { @@ -6694,8 +6685,9 @@ fail: /// Delete match with ID 'id' in the match list of window 'wp'. -/// Print error messages if 'perr' is TRUE. -int match_delete(win_T *wp, int id, int perr) +/// +/// @param perr print error messages if true. +int match_delete(win_T *wp, int id, bool perr) { matchitem_T *cur = wp->w_match_head; matchitem_T *prev = cur; diff --git a/test/functional/api/buffer_updates_spec.lua b/test/functional/api/buffer_updates_spec.lua index 05ca0d5f4d..c9c9be5406 100644 --- a/test/functional/api/buffer_updates_spec.lua +++ b/test/functional/api/buffer_updates_spec.lua @@ -159,9 +159,8 @@ describe('API: buffer events:', function() tick = tick + 1 expectn('nvim_buf_lines_event', {b, tick, 29, 29, firstfour, false}) - -- create a new empty buffer and wipe out the old one ... this will - -- turn off buffer events - command('enew!') + -- delete the current buffer to turn off buffer events + command('bdelete!') expectn('nvim_buf_detach_event', {b}) -- add a line at the start of an empty file @@ -269,7 +268,7 @@ describe('API: buffer events:', function() 'original foo'}, false}) -- type text into the first line of a blank file, one character at a time - command('enew!') + command('bdelete!') tick = 2 expectn('nvim_buf_detach_event', {b}) local bnew = nvim('get_current_buf') @@ -666,7 +665,8 @@ describe('API: buffer events:', function() tick = tick + 1 expectn('nvim_buf_changedtick_event', {b, tick}) - -- close our buffer by creating a new one + -- close our buffer and create a new one + command('bdelete') command('enew') expectn('nvim_buf_detach_event', {b}) diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index bb72b63b6c..e4aa1dae8e 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -311,7 +311,8 @@ describe('API/win', function() eq({newwin}, meths.list_wins()) end) - it('handles changed buffer', function() + it("handles changed buffer when 'hidden' is unset", function() + command('set nohidden') local oldwin = meths.get_current_win() insert('text') command('new') diff --git a/test/functional/eval/buf_functions_spec.lua b/test/functional/eval/buf_functions_spec.lua index 06841a4521..e957e5f5af 100644 --- a/test/functional/eval/buf_functions_spec.lua +++ b/test/functional/eval/buf_functions_spec.lua @@ -221,9 +221,9 @@ describe('getbufvar() function', function() eq(0, funcs.getbufvar(1, '&l:autoindent')) eq(0, funcs.getbufvar(1, '&g:autoindent')) -- Also works with global-only options - eq(0, funcs.getbufvar(1, '&hidden')) - eq(0, funcs.getbufvar(1, '&l:hidden')) - eq(0, funcs.getbufvar(1, '&g:hidden')) + eq(1, funcs.getbufvar(1, '&hidden')) + eq(1, funcs.getbufvar(1, '&l:hidden')) + eq(1, funcs.getbufvar(1, '&g:hidden')) -- Also works with window-local options eq(0, funcs.getbufvar(1, '&number')) eq(0, funcs.getbufvar(1, '&l:number')) @@ -279,9 +279,9 @@ describe('setbufvar() function', function() eq(false, winmeths.get_option(windows[3], 'number')) eq(false, winmeths.get_option(meths.get_current_win(), 'number')) - eq(false, meths.get_option('hidden')) - funcs.setbufvar(1, '&hidden', true) eq(true, meths.get_option('hidden')) + funcs.setbufvar(1, '&hidden', 0) + eq(false, meths.get_option('hidden')) eq(false, bufmeths.get_option(buf1, 'autoindent')) funcs.setbufvar(1, '&autoindent', true) diff --git a/test/functional/eval/match_functions_spec.lua b/test/functional/eval/match_functions_spec.lua index f399ef47d3..9f168c913a 100644 --- a/test/functional/eval/match_functions_spec.lua +++ b/test/functional/eval/match_functions_spec.lua @@ -6,7 +6,6 @@ local clear = helpers.clear local funcs = helpers.funcs local command = helpers.command local exc_exec = helpers.exc_exec -local pcall_err = helpers.pcall_err before_each(clear) @@ -40,13 +39,13 @@ describe('setmatches()', function() }}, funcs.getmatches()) end) - it('fails with -1 if highlight group is not defined', function() - eq('Vim:E28: No such highlight group name: 1', - pcall_err(funcs.setmatches, {{group=1, pattern=2, id=3, priority=4}})) - eq({}, funcs.getmatches()) - eq('Vim:E28: No such highlight group name: 1', - pcall_err(funcs.setmatches, {{group=1, pos1={2}, pos2={6}, id=3, priority=4, conceal=5}})) - eq({}, funcs.getmatches()) + it('does not fail if highlight group is not defined', function() + eq(0, funcs.setmatches{{group=1, pattern=2, id=3, priority=4}}) + eq({{group='1', pattern='2', id=3, priority=4}}, + funcs.getmatches()) + eq(0, funcs.setmatches{{group=1, pos1={2}, pos2={6}, id=3, priority=4, conceal=5}}) + eq({{group='1', pos1={2}, pos2={6}, id=3, priority=4, conceal='5'}}, + funcs.getmatches()) end) end) diff --git a/test/functional/ex_cmds/drop_spec.lua b/test/functional/ex_cmds/drop_spec.lua index ef53fe75e3..9d84a2d4f6 100644 --- a/test/functional/ex_cmds/drop_spec.lua +++ b/test/functional/ex_cmds/drop_spec.lua @@ -55,6 +55,7 @@ describe(":drop", function() end) it("splits off a new window when a buffer can't be abandoned", function() + command("set nohidden") feed_command("edit tmp1") feed_command("vsplit") feed_command("edit tmp2") diff --git a/test/functional/ex_cmds/quickfix_commands_spec.lua b/test/functional/ex_cmds/quickfix_commands_spec.lua index 06dafa9ab9..c956a2df2d 100644 --- a/test/functional/ex_cmds/quickfix_commands_spec.lua +++ b/test/functional/ex_cmds/quickfix_commands_spec.lua @@ -47,6 +47,7 @@ for _, c in ipairs({'l', 'c'}) do eq(('%s-2.res'):format(file), funcs.bufname(list[2].bufnr)) -- Run cfile/lfile from a modified buffer + command('set nohidden') command('enew!') curbufmeths.set_lines(1, 1, true, {'Quickfix'}) eq(('Vim(%s):E37: No write since last change (add ! to override)'):format( diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 03ef441ef3..5974e8897f 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -38,10 +38,16 @@ module.nvim_prog = ( module.nvim_set = ( 'set shortmess+=IS background=light noswapfile noautoindent startofline' ..' laststatus=1 undodir=. directory=. viewdir=. backupdir=.' - ..' belloff= wildoptions-=pum noshowcmd noruler nomore redrawdebug=invalid') + ..' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid') module.nvim_argv = { module.nvim_prog, '-u', 'NONE', '-i', 'NONE', - '--cmd', module.nvim_set, '--embed'} + '--cmd', module.nvim_set, + '--cmd', 'unmap Y', + '--cmd', 'unmap <C-L>', + '--cmd', 'iunmap <C-U>', + '--cmd', 'iunmap <C-W>', + '--embed'} + -- Directory containing nvim. module.nvim_dir = module.nvim_prog:gsub("[/\\][^/\\]+$", "") if module.nvim_dir == module.nvim_prog then diff --git a/test/functional/legacy/007_ball_buffer_list_spec.lua b/test/functional/legacy/007_ball_buffer_list_spec.lua index a180e73301..d4e4547c43 100644 --- a/test/functional/legacy/007_ball_buffer_list_spec.lua +++ b/test/functional/legacy/007_ball_buffer_list_spec.lua @@ -8,6 +8,9 @@ describe(':ball', function() setup(clear) it('is working', function() + -- Must disable 'hidden' so that the BufReadPost autocmd is triggered + -- when Xxx2 is reloaded + feed_command('set nohidden') insert([[ start of test file Xxx this is a test @@ -18,7 +21,7 @@ describe(':ball', function() feed('gg') -- Write test file Xxx1 - feed('A1:.,/end of/w! Xxx1<cr>') + feed('A1<esc>:.,/end of/w! Xxx1<cr>') feed_command('sp Xxx1') feed_command('close') diff --git a/test/functional/legacy/008_autocommands_spec.lua b/test/functional/legacy/008_autocommands_spec.lua index 939404cb5e..002f037d09 100644 --- a/test/functional/legacy/008_autocommands_spec.lua +++ b/test/functional/legacy/008_autocommands_spec.lua @@ -71,6 +71,9 @@ describe('autocommands that delete and unload buffers:', function() au BufUnload * call CloseAll() au VimLeave * call WriteToOut() ]]) + -- Must disable 'hidden' so that the BufUnload autocmd is triggered between + -- each :edit + command('set nohidden') command('silent! edit Xxx2') command('silent! edit Xxx1') command('silent! edit Makefile') -- an existing file diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua index 7b6f2f63e9..0fa9290f3c 100644 --- a/test/functional/legacy/011_autocommands_spec.lua +++ b/test/functional/legacy/011_autocommands_spec.lua @@ -129,13 +129,11 @@ describe('file reading, writing and bufnew and filter autocommands', function() -- Will load Xtest.c. feed_command('e! foo.c') feed_command("au FileAppendPre *.out '[,']s/new/NEW/") - feed_command('au FileAppendPost *.out !cat Xtest.c >>test.out') + feed_command('au FileAppendPost *.out !cat Xtest.c >test.out') -- Append it to the output file. feed_command('w>>test.out') -- Discard all prompts and messages. feed('<C-L>') - -- Expect the decompressed file in the buffer. - feed_command('e test.out') expect([[ /* diff --git a/test/functional/legacy/012_directory_spec.lua b/test/functional/legacy/012_directory_spec.lua index 48dd24db9e..f666e51469 100644 --- a/test/functional/legacy/012_directory_spec.lua +++ b/test/functional/legacy/012_directory_spec.lua @@ -80,6 +80,7 @@ describe("'directory' option", function() eq({ "Xtest1.swp", "Xtest3" }, ls_dir_sorted("Xtest2")) meths.set_option('directory', 'Xtest.je') + command('bdelete') command('edit Xtest2/Xtest3') eq(true, curbufmeths.get_option('swapfile')) poke_eventloop() diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua index 67c5750033..6a2e86ccb4 100644 --- a/test/functional/legacy/arglist_spec.lua +++ b/test/functional/legacy/arglist_spec.lua @@ -156,10 +156,12 @@ describe('argument list commands', function() eq({'a', 'b', 'a', 'c'}, eval('argv()')) command('0argedit x') eq({'x', 'a', 'b', 'a', 'c'}, eval('argv()')) + command('set nohidden') command('enew! | set modified') assert_fails('argedit y', 'E37:') command('argedit! y') eq({'x', 'y', 'y', 'a', 'b', 'a', 'c'}, eval('argv()')) + command('set hidden') command('%argd') command('argedit a b') eq({'a', 'b'}, eval('argv()')) diff --git a/test/functional/legacy/cdo_spec.lua b/test/functional/legacy/cdo_spec.lua index 5e46431cc1..8b3216cbfd 100644 --- a/test/functional/legacy/cdo_spec.lua +++ b/test/functional/legacy/cdo_spec.lua @@ -91,7 +91,8 @@ describe('cdo', function() exe "silent! 4,5" . XdoCmd call assert_equal([], l) - " Run commands from an unsaved buffer + " Run commands from an unsaved buffer when 'hidden' is unset + set nohidden let v:errmsg='' let l = [] enew @@ -108,6 +109,7 @@ describe('cdo', function() if subst_count != 1 || getline('.') != 'xLine1' call add(v:errors, 'Abort command on error test failed') endif + set hidden let l = [] exe "2,2" . Xdo . "! call add(l, GetRuler())" diff --git a/test/functional/legacy/fixeol_spec.lua b/test/functional/legacy/fixeol_spec.lua index 50236e8617..d3ff86d349 100644 --- a/test/functional/legacy/fixeol_spec.lua +++ b/test/functional/legacy/fixeol_spec.lua @@ -23,8 +23,6 @@ describe('fixeol', function() it('is working', function() -- First write two test files – with and without trailing EOL. - -- Use Unix fileformat for consistency. - feed_command('set ff=unix') feed_command('enew!') feed('awith eol<esc>:w! XXEol<cr>') feed_command('enew!') @@ -40,7 +38,7 @@ describe('fixeol', function() feed_command('e! XXNoEol') feed('ostays without<esc>:set nofixeol<cr>') feed_command('w! XXTestNoEol') - feed_command('bwipe XXEol XXNoEol XXTestEol XXTestNoEol') + feed_command('bwipe! XXEol XXNoEol XXTestEol XXTestNoEol') feed_command('set fixeol') -- Append "END" to each file so that we can see what the last written char was. diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 863176bfa9..3c4d01ae74 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -266,6 +266,8 @@ describe('LSP', function() if isCI() then pending('hangs the build on CI #14028, re-enable with freeze timeout #14204') return + elseif helpers.skip_fragile(pending) then + return end local expected_handlers = { {NIL, "shutdown", {}, 1, NIL}; diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua index 5663f248bf..a4d78682ad 100644 --- a/test/functional/plugin/shada_spec.lua +++ b/test/functional/plugin/shada_spec.lua @@ -2161,6 +2161,12 @@ describe('plugin/shada.vim', function() reset() wshada('\004\000\009\147\000\196\002ab\196\001a') wshada_tmp('\004\000\009\147\000\196\002ab\196\001b') + + -- Need to set nohidden so that the buffer containing 'fname' is not unloaded + -- after loading 'fname_tmp', otherwise the '++opt not supported' test below + -- won't work since the BufReadCmd autocmd won't be triggered. + nvim_command('set nohidden') + nvim_command('edit ' .. fname) eq({ 'History entry with timestamp ' .. epoch .. ':', diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 51ee922d23..be22d9a403 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -74,7 +74,8 @@ describe('float window', function() funcs.win_execute(win, 'bwipe!') end) - it('win_execute() call commands that not allowed' , function() + it("win_execute() call commands that are not allowed when 'hidden' is not set" , function() + command('set nohidden') local buf = meths.create_buf(false, false) meths.buf_set_lines(buf, 0, -1, true, {'the floatwin'}) local win = meths.open_win(buf, true, {relative='win', width=16, height=1, row=0, col=10}) diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 7471255345..499aeba6ec 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -912,6 +912,97 @@ describe('CursorLine highlight', function() ]]) end) + it("'cursorlineopt' screenline", function() + local screen = Screen.new(20,5) + screen:set_default_attr_ids({ + [1] = {foreground = Screen.colors.Black, background = Screen.colors.White}; + [2] = {foreground = Screen.colors.Yellow}; + [3] = {foreground = Screen.colors.Red, background = Screen.colors.Green}; + [4] = {foreground = Screen.colors.Green, background = Screen.colors.Red}; + }) + screen:attach() + + feed_command('set wrap cursorline cursorlineopt=screenline') + feed_command('set showbreak=>>>') + feed_command('highlight clear NonText') + feed_command('highlight clear CursorLine') + feed_command('highlight NonText guifg=Yellow gui=NONE') + feed_command('highlight LineNr guifg=Red guibg=Green gui=NONE') + feed_command('highlight CursorLine guifg=Black guibg=White gui=NONE') + feed_command('highlight CursorLineNr guifg=Green guibg=Red gui=NONE') + + feed('30iø<esc>o<esc>30ia<esc>') + + -- CursorLine should not apply to 'showbreak' when 'cursorlineopt' contains "screenline" + screen:expect([[ + øøøøøøøøøøøøøøøøøøøø| + {2:>>>}øøøøøøøøøø | + aaaaaaaaaaaaaaaaaaaa| + {2:>>>}{1:aaaaaaaaa^a }| + | + ]]) + feed('gk') + screen:expect([[ + øøøøøøøøøøøøøøøøøøøø| + {2:>>>}øøøøøøøøøø | + {1:aaaaaaaaaaaa^aaaaaaaa}| + {2:>>>}aaaaaaaaaa | + | + ]]) + feed('k') + screen:expect([[ + {1:øøøøøøøøøøøø^øøøøøøøø}| + {2:>>>}øøøøøøøøøø | + aaaaaaaaaaaaaaaaaaaa| + {2:>>>}aaaaaaaaaa | + | + ]]) + + -- CursorLineNr should not apply to line number when 'cursorlineopt' does not contain "number" + feed_command('set relativenumber numberwidth=2') + screen:expect([[ + {3:0 }{1:øøøøøøøøøøøø^øøøøøø}| + {3: }{2:>>>}øøøøøøøøøøøø | + {3:1 }aaaaaaaaaaaaaaaaaa| + {3: }{2:>>>}aaaaaaaaaaaa | + | + ]]) + + -- CursorLineNr should apply to line number when 'cursorlineopt' contains "number" + feed_command('set cursorlineopt+=number') + screen:expect([[ + {4:0 }{1:øøøøøøøøøøøø^øøøøøø}| + {3: }{2:>>>}øøøøøøøøøøøø | + {3:1 }aaaaaaaaaaaaaaaaaa| + {3: }{2:>>>}aaaaaaaaaaaa | + | + ]]) + feed('gj') + screen:expect([[ + {4:0 }øøøøøøøøøøøøøøøøøø| + {3: }{2:>>>}{1:øøøøøøøøø^øøø }| + {3:1 }aaaaaaaaaaaaaaaaaa| + {3: }{2:>>>}aaaaaaaaaaaa | + | + ]]) + feed('gj') + screen:expect([[ + {3:1 }øøøøøøøøøøøøøøøøøø| + {3: }{2:>>>}øøøøøøøøøøøø | + {4:0 }{1:aaaaaaaaaaaa^aaaaaa}| + {3: }{2:>>>}aaaaaaaaaaaa | + | + ]]) + feed('gj') + screen:expect([[ + {3:1 }øøøøøøøøøøøøøøøøøø| + {3: }{2:>>>}øøøøøøøøøøøø | + {4:0 }aaaaaaaaaaaaaaaaaa| + {3: }{2:>>>}{1:aaaaaaaaa^aaa }| + | + ]]) + end) + it('always updated. vim-patch:8.1.0849', function() local screen = Screen.new(50,5) screen:set_default_attr_ids({ diff --git a/test/functional/ui/tabline_spec.lua b/test/functional/ui/tabline_spec.lua index ab8d63cda1..809486d4db 100644 --- a/test/functional/ui/tabline_spec.lua +++ b/test/functional/ui/tabline_spec.lua @@ -69,6 +69,7 @@ describe('ui/ext_tabline', function() command("bnext") local expected_buffers = { + {buffer = { id = 1 }, name = '[No Name]'}, {buffer = { id = 2 }, name = 'another-buffer'}, } screen:expect{grid=[[ diff --git a/test/unit/preprocess.lua b/test/unit/preprocess.lua index 3786bc2122..1073855a7d 100644 --- a/test/unit/preprocess.lua +++ b/test/unit/preprocess.lua @@ -89,10 +89,6 @@ local Gcc = { get_defines_extra_flags = {'-std=c99', '-dM', '-E'}, get_declarations_extra_flags = {'-std=c99', '-P', '-E'}, } -if ffi.abi("32bit") then - table.insert(Gcc.get_defines_extra_flags, '-m32') - table.insert(Gcc.get_declarations_extra_flags, '-m32') -end function Gcc:define(name, args, val) local define = '-D' .. name |