aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig3
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--.github/workflows/release.yml2
-rw-r--r--cmake.deps/CMakeLists.txt4
-rw-r--r--contrib/flake.lock12
-rw-r--r--contrib/flake.nix9
-rw-r--r--runtime/autoload/provider/clipboard.vim6
-rw-r--r--runtime/doc/autocmd.txt58
-rw-r--r--runtime/doc/builtin.txt59
-rw-r--r--runtime/doc/deprecated.txt4
-rw-r--r--runtime/doc/diagnostic.txt50
-rw-r--r--runtime/doc/digraph.txt2
-rw-r--r--runtime/doc/eval.txt8
-rw-r--r--runtime/doc/insert.txt44
-rw-r--r--runtime/doc/lsp.txt4
-rw-r--r--runtime/doc/lua.txt42
-rw-r--r--runtime/doc/map.txt2
-rw-r--r--runtime/doc/news.txt10
-rw-r--r--runtime/doc/nvim_terminal_emulator.txt40
-rw-r--r--runtime/doc/options.txt35
-rw-r--r--runtime/doc/provider.txt1
-rw-r--r--runtime/doc/support.txt4
-rw-r--r--runtime/doc/syntax.txt10
-rw-r--r--runtime/doc/tips.txt2
-rw-r--r--runtime/doc/usr_41.txt13
-rw-r--r--runtime/doc/vim_diff.txt5
-rw-r--r--runtime/doc/windows.txt45
-rw-r--r--runtime/ftplugin/lua.vim4
-rw-r--r--runtime/ftplugin/mermaid.vim49
-rw-r--r--runtime/ftplugin/obse.vim70
-rw-r--r--runtime/indent/obse.vim55
-rw-r--r--runtime/lua/vim/_editor.lua1
-rw-r--r--runtime/lua/vim/diagnostic.lua208
-rw-r--r--runtime/lua/vim/filetype.lua4
-rw-r--r--runtime/lua/vim/fs.lua26
-rw-r--r--runtime/lua/vim/lsp/handlers.lua56
-rw-r--r--runtime/lua/vim/lsp/protocol.lua9
-rw-r--r--runtime/lua/vim/lsp/rpc.lua72
-rw-r--r--runtime/lua/vim/lsp/util.lua9
-rw-r--r--runtime/lua/vim/secure.lua106
-rw-r--r--runtime/optwin.vim2
-rw-r--r--runtime/pack/dist/opt/termdebug/plugin/termdebug.vim30
-rw-r--r--runtime/queries/vim/highlights.scm37
-rw-r--r--runtime/queries/vim/injections.scm14
-rw-r--r--runtime/syntax/go.vim115
-rw-r--r--runtime/syntax/help.vim4
-rw-r--r--runtime/syntax/html.vim12
-rw-r--r--runtime/syntax/mermaid.vim155
-rw-r--r--runtime/syntax/nsis.vim32
-rw-r--r--runtime/syntax/obse.vim3360
-rw-r--r--runtime/syntax/ptcap.vim2
-rw-r--r--runtime/syntax/sshconfig.vim6
-rw-r--r--runtime/syntax/sshdconfig.vim4
-rw-r--r--runtime/syntax/swayconfig.vim28
-rwxr-xr-xscripts/gen_vimdoc.py3
-rw-r--r--src/nvim/api/private/helpers.c2
-rw-r--r--src/nvim/api/win_config.c3
-rw-r--r--src/nvim/api/window.c9
-rw-r--r--src/nvim/auevents.lua3
-rw-r--r--src/nvim/autocmd.c23
-rw-r--r--src/nvim/charset.c6
-rw-r--r--src/nvim/cmdexpand.c80
-rw-r--r--src/nvim/cursor.c27
-rw-r--r--src/nvim/debugger.c12
-rw-r--r--src/nvim/diff.c12
-rw-r--r--src/nvim/drawline.c13
-rw-r--r--src/nvim/edit.c3
-rw-r--r--src/nvim/eval.c67
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c45
-rw-r--r--src/nvim/eval/typval.c36
-rw-r--r--src/nvim/eval/userfunc.c8
-rw-r--r--src/nvim/eval/vars.c16
-rw-r--r--src/nvim/ex_cmds.c13
-rw-r--r--src/nvim/ex_docmd.c9
-rw-r--r--src/nvim/ex_eval.c4
-rw-r--r--src/nvim/ex_getln.c10
-rw-r--r--src/nvim/file_search.c112
-rw-r--r--src/nvim/fileio.c22
-rw-r--r--src/nvim/globals.h5
-rw-r--r--src/nvim/help.c6
-rw-r--r--src/nvim/indent_c.c2
-rw-r--r--src/nvim/insexpand.c13
-rw-r--r--src/nvim/linematch.c3
-rw-r--r--src/nvim/lua/executor.c24
-rw-r--r--src/nvim/main.c33
-rw-r--r--src/nvim/mapping.c44
-rw-r--r--src/nvim/match.c7
-rw-r--r--src/nvim/mbyte.c10
-rw-r--r--src/nvim/memline.c82
-rw-r--r--src/nvim/move.c9
-rw-r--r--src/nvim/msgpack_rpc/unpacker.c1
-rw-r--r--src/nvim/normal.c28
-rw-r--r--src/nvim/ops.c42
-rw-r--r--src/nvim/option.c187
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/options.lua2
-rw-r--r--src/nvim/optionstr.c4
-rw-r--r--src/nvim/os/env.c58
-rw-r--r--src/nvim/os/fs.c2
-rw-r--r--src/nvim/os/process.c13
-rw-r--r--src/nvim/os/shell.c44
-rw-r--r--src/nvim/path.c88
-rw-r--r--src/nvim/po/zh_CN.UTF-8.po11943
-rw-r--r--src/nvim/profile.c2
-rw-r--r--src/nvim/quickfix.c41
-rw-r--r--src/nvim/regexp.c19
-rw-r--r--src/nvim/regexp_bt.c12
-rw-r--r--src/nvim/regexp_nfa.c12
-rw-r--r--src/nvim/runtime.c4
-rw-r--r--src/nvim/search.c294
-rw-r--r--src/nvim/search.h2
-rw-r--r--src/nvim/shada.c4
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/spellfile.c10
-rw-r--r--src/nvim/spellsuggest.c4
-rw-r--r--src/nvim/tag.c1754
-rw-r--r--src/nvim/testdir/check.vim8
-rw-r--r--src/nvim/testdir/runtest.vim5
-rw-r--r--src/nvim/testdir/test_autocmd.vim210
-rw-r--r--src/nvim/testdir/test_buffer.vim9
-rw-r--r--src/nvim/testdir/test_bufline.vim14
-rw-r--r--src/nvim/testdir/test_cmdline.vim5
-rw-r--r--src/nvim/testdir/test_cpoptions.vim76
-rw-r--r--src/nvim/testdir/test_diffmode.vim117
-rw-r--r--src/nvim/testdir/test_edit.vim19
-rw-r--r--src/nvim/testdir/test_excmd.vim8
-rw-r--r--src/nvim/testdir/test_filetype.vim2
-rw-r--r--src/nvim/testdir/test_getvar.vim9
-rw-r--r--src/nvim/testdir/test_lambda.vim2
-rw-r--r--src/nvim/testdir/test_match.vim76
-rw-r--r--src/nvim/testdir/test_method.vim18
-rw-r--r--src/nvim/testdir/test_normal.vim18
-rw-r--r--src/nvim/testdir/test_prompt_buffer.vim2
-rw-r--r--src/nvim/testdir/test_recover.vim414
-rw-r--r--src/nvim/testdir/test_startup.vim1
-rw-r--r--src/nvim/testdir/test_swap.vim159
-rw-r--r--src/nvim/testdir/test_tagjump.vim150
-rw-r--r--src/nvim/testdir/test_taglist.vim37
-rw-r--r--src/nvim/window.c301
-rw-r--r--test/functional/api/proc_spec.lua4
-rw-r--r--test/functional/api/server_notifications_spec.lua4
-rw-r--r--test/functional/api/server_requests_spec.lua2
-rw-r--r--test/functional/api/vim_spec.lua11
-rw-r--r--test/functional/api/window_spec.lua40
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua28
-rw-r--r--test/functional/autocmd/focus_spec.lua2
-rw-r--r--test/functional/autocmd/signal_spec.lua4
-rw-r--r--test/functional/autocmd/termxx_spec.lua8
-rw-r--r--test/functional/autocmd/win_scrolled_resized_spec.lua285
-rw-r--r--test/functional/autocmd/winscrolled_spec.lua99
-rw-r--r--test/functional/core/channels_spec.lua9
-rw-r--r--test/functional/core/fileio_spec.lua16
-rw-r--r--test/functional/core/job_spec.lua48
-rw-r--r--test/functional/core/main_spec.lua4
-rw-r--r--test/functional/core/path_spec.lua4
-rw-r--r--test/functional/core/startup_spec.lua12
-rw-r--r--test/functional/ex_cmds/cd_spec.lua4
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua8
-rw-r--r--test/functional/ex_cmds/source_spec.lua4
-rw-r--r--test/functional/ex_cmds/swapfile_preserve_recover_spec.lua79
-rw-r--r--test/functional/ex_cmds/write_spec.lua22
-rw-r--r--test/functional/ex_cmds/wviminfo_spec.lua4
-rw-r--r--test/functional/helpers.lua21
-rw-r--r--test/functional/legacy/011_autocommands_spec.lua4
-rw-r--r--test/functional/legacy/025_jump_tag_hidden_spec.lua6
-rw-r--r--test/functional/legacy/097_glob_path_spec.lua6
-rw-r--r--test/functional/legacy/delete_spec.lua2
-rw-r--r--test/functional/legacy/excmd_spec.lua8
-rw-r--r--test/functional/legacy/filechanged_spec.lua4
-rw-r--r--test/functional/legacy/match_spec.lua88
-rw-r--r--test/functional/legacy/memory_usage_spec.lua15
-rw-r--r--test/functional/lua/diagnostic_spec.lua104
-rw-r--r--test/functional/lua/fs_spec.lua6
-rw-r--r--test/functional/lua/overrides_spec.lua4
-rw-r--r--test/functional/lua/secure_spec.lua171
-rw-r--r--test/functional/lua/uri_spec.lua4
-rw-r--r--test/functional/options/autochdir_spec.lua2
-rw-r--r--test/functional/options/defaults_spec.lua24
-rw-r--r--test/functional/plugin/lsp_spec.lua8
-rw-r--r--test/functional/plugin/man_spec.lua4
-rw-r--r--test/functional/plugin/shada_spec.lua2
-rw-r--r--test/functional/preload.lua4
-rw-r--r--test/functional/provider/perl_spec.lua6
-rw-r--r--test/functional/shada/compatibility_spec.lua2
-rw-r--r--test/functional/shada/merging_spec.lua2
-rw-r--r--test/functional/shada/shada_spec.lua4
-rw-r--r--test/functional/terminal/altscreen_spec.lua2
-rw-r--r--test/functional/terminal/api_spec.lua2
-rw-r--r--test/functional/terminal/buffer_spec.lua6
-rw-r--r--test/functional/terminal/cursor_spec.lua12
-rw-r--r--test/functional/terminal/edit_spec.lua2
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua26
-rw-r--r--test/functional/terminal/helpers.lua25
-rw-r--r--test/functional/terminal/highlight_spec.lua10
-rw-r--r--test/functional/terminal/mouse_spec.lua14
-rw-r--r--test/functional/terminal/scrollback_spec.lua28
-rw-r--r--test/functional/terminal/tui_spec.lua41
-rw-r--r--test/functional/terminal/window_spec.lua12
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua4
-rw-r--r--test/functional/treesitter/parser_spec.lua4
-rw-r--r--test/functional/ui/cmdline_spec.lua4
-rw-r--r--test/functional/ui/embed_spec.lua2
-rw-r--r--test/functional/ui/hlstate_spec.lua8
-rw-r--r--test/functional/ui/messages_spec.lua7
-rw-r--r--test/functional/ui/mouse_spec.lua43
-rw-r--r--test/functional/ui/output_spec.lua16
-rw-r--r--test/functional/ui/screen_basic_spec.lua12
-rw-r--r--test/functional/ui/spell_spec.lua4
-rw-r--r--test/functional/ui/wildmode_spec.lua6
-rw-r--r--test/functional/vimscript/eval_spec.lua4
-rw-r--r--test/functional/vimscript/executable_spec.lua22
-rw-r--r--test/functional/vimscript/execute_spec.lua4
-rw-r--r--test/functional/vimscript/exepath_spec.lua13
-rw-r--r--test/functional/vimscript/fnamemodify_spec.lua6
-rw-r--r--test/functional/vimscript/functions_spec.lua4
-rw-r--r--test/functional/vimscript/has_spec.lua4
-rw-r--r--test/functional/vimscript/hostname_spec.lua6
-rw-r--r--test/functional/vimscript/msgpack_functions_spec.lua4
-rw-r--r--test/functional/vimscript/server_spec.lua10
-rw-r--r--test/functional/vimscript/system_spec.lua30
-rw-r--r--test/helpers.lua40
222 files changed, 16883 insertions, 6713 deletions
diff --git a/.editorconfig b/.editorconfig
index 2aa956b1fc..07993e25b9 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,6 +10,9 @@ insert_final_newline = true
[*.{c,h,in,lua}]
max_line_length = 100
+[*.py]
+indent_size = 4
+
[{Makefile,**/Makefile,runtime/doc/*.txt}]
indent_style = tab
indent_size = 8
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 53d52ec55a..9c9de055cf 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -340,6 +340,8 @@ jobs:
- name: Install test deps
run: |
+ $PSNativeCommandArgumentPassing = 'Legacy'
+
& build\bin\nvim.exe "--version"
# Ensure that the "win32" feature is set.
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 2655281ef7..113b04ab2b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -266,7 +266,7 @@ jobs:
Invoke-WebRequest https://github.com/neovim/neovim/releases/download/nightly/nvim-win64.msi -OutFile setup.msi
Install-Module -Name 'Carbon.Windows.Installer' -Force
$VERSION = (Get-CMsi (Resolve-Path .\setup.msi).Path).ProductVersion
- echo "version=$VERSION" >> $GITHUB_OUTPUT
+ "version=$VERSION" >> $env:GITHUB_OUTPUT
- if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly')
name: Publish nightly
uses: vedantmgoyal2009/winget-releaser@v1
diff --git a/cmake.deps/CMakeLists.txt b/cmake.deps/CMakeLists.txt
index 62c38e2a2f..9c92d1a71c 100644
--- a/cmake.deps/CMakeLists.txt
+++ b/cmake.deps/CMakeLists.txt
@@ -200,8 +200,8 @@ set(TREESITTER_C_SHA256 af66fde03feb0df4faf03750102a0d265b007e5d957057b6b293c131
set(TREESITTER_LUA_URL https://github.com/MunifTanjim/tree-sitter-lua/archive/v0.0.14.tar.gz)
set(TREESITTER_LUA_SHA256 930d0370dc15b66389869355c8e14305b9ba7aafd36edbfdb468c8023395016d)
-set(TREESITTER_VIM_URL https://github.com/vigoux/tree-sitter-viml/archive/v0.2.0.tar.gz)
-set(TREESITTER_VIM_SHA256 608dcc31a7948cb66ae7f45494620e2e9face1af75598205541f80d782ec4501)
+set(TREESITTER_VIM_URL https://github.com/vigoux/tree-sitter-viml/archive/55ff1b080c09edeced9b748cf4c16d0b49d17fb9.tar.gz)
+set(TREESITTER_VIM_SHA256 1b1cd39e33c8fb02fa7fe3977e844883c2a8508a7edd621f2d21e39a9aeefa92)
set(TREESITTER_HELP_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v1.2.5.tar.gz)
set(TREESITTER_HELP_SHA256 379d764937a0e3a38e3f9ce9a62c93ba24211a236c74181dd04ee3b4631472a8)
diff --git a/contrib/flake.lock b/contrib/flake.lock
index 48f5f0115a..69182ad1e5 100644
--- a/contrib/flake.lock
+++ b/contrib/flake.lock
@@ -2,11 +2,11 @@
"nodes": {
"flake-utils": {
"locked": {
- "lastModified": 1659877975,
- "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
+ "lastModified": 1667395993,
+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
@@ -17,11 +17,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1662019588,
- "narHash": "sha256-oPEjHKGGVbBXqwwL+UjsveJzghWiWV0n9ogo1X6l4cw=",
+ "lastModified": 1669052418,
+ "narHash": "sha256-M1I4BKXBQm2gey1tScemEh5TpHHE3gKptL7BpWUvL8s=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "2da64a81275b68fdad38af669afeda43d401e94b",
+ "rev": "20fc948445a6c22d4e8d5178e9a6bc6e1f5417c8",
"type": "github"
},
"original": {
diff --git a/contrib/flake.nix b/contrib/flake.nix
index cd6242a8d6..8df1768827 100644
--- a/contrib/flake.nix
+++ b/contrib/flake.nix
@@ -9,15 +9,6 @@
outputs = { self, nixpkgs, flake-utils }:
{
overlay = final: prev: rec {
- neovim-unwrapped = prev.neovim-unwrapped.override ({
- libvterm-neovim = prev.libvterm-neovim.overrideAttrs (old: {
- version = "0.3";
- src = builtins.fetchTarball {
- url = "https://www.leonerd.org.uk/code/libvterm/libvterm-0.3.tar.gz";
- sha256 = "0zg6sn5brwrnqaab883pdj0l2swk5askbbwbdam0zq55ikbrzgar";
- };
- });
- });
neovim = final.neovim-unwrapped.overrideAttrs (oa: {
version = "master";
diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim
index de8f2cbdf2..98c80f1843 100644
--- a/runtime/autoload/provider/clipboard.vim
+++ b/runtime/autoload/provider/clipboard.vim
@@ -97,6 +97,12 @@ function! provider#clipboard#Executable() abort
let s:copy['*'] = ['wl-copy', '--foreground', '--primary', '--type', 'text/plain']
let s:paste['*'] = ['wl-paste', '--no-newline', '--primary']
return 'wl-copy'
+ elseif !empty($WAYLAND_DISPLAY) && executable('waycopy') && executable('waypaste')
+ let s:copy['+'] = ['waycopy', '-t', 'text/plain']
+ let s:paste['+'] = ['waypaste', '-t', 'text/plain']
+ let s:copy['*'] = s:copy['+']
+ let s:paste['*'] = s:paste['+']
+ return 'wayclip'
elseif !empty($DISPLAY) && executable('xsel') && s:cmd_ok('xsel -o -b')
let s:copy['+'] = ['xsel', '--nodetach', '-i', '-b']
let s:paste['+'] = ['xsel', '-o', '-b']
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index c30c190301..a39407aeca 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -823,8 +823,8 @@ QuickFixCmdPre Before a quickfix command is run (|:make|,
QuickFixCmdPost Like QuickFixCmdPre, but after a quickfix
command is run, before jumping to the first
location. For |:cfile| and |:lfile| commands
- it is run after error file is read and before
- moving to the first error.
+ it is run after the error file is read and
+ before moving to the first error.
See |QuickFixCmdPost-example|.
*QuitPre*
QuitPre When using `:quit`, `:wq` or `:qall`, before
@@ -1065,8 +1065,9 @@ VimResume After Nvim resumes from |suspend| state.
*VimSuspend*
VimSuspend Before Nvim enters |suspend| state.
*WinClosed*
-WinClosed After closing a window. The pattern is
- matched against the |window-ID|. Both
+WinClosed When closing a window, just before it is
+ removed from the window layout. The pattern
+ is matched against the |window-ID|. Both
<amatch> and <afile> are set to the |window-ID|.
After WinLeave.
Non-recursive (event cannot trigger itself).
@@ -1095,23 +1096,48 @@ WinNew When a new window was created. Not done for
Before WinEnter.
*WinScrolled*
-WinScrolled After scrolling the content of a window or
- resizing a window.
- The pattern is matched against the
- |window-ID|. Both <amatch> and <afile> are
- set to the |window-ID|.
- Non-recursive (the event cannot trigger
- itself). However, if the command causes the
- window to scroll or change size another
+WinScrolled After any window in the current tab page
+ scrolled the text (horizontally or vertically)
+ or changed width or height. See
+ |win-scrolled-resized|.
+
+ The pattern is matched against the |window-ID|
+ of the first window that scrolled or resized.
+ Both <amatch> and <afile> are set to the
+ |window-ID|.
+
+ |v:event| is set with information about size
+ and scroll changes. |WinScrolled-event|
+
+ Only starts triggering after startup finished
+ and the first screen redraw was done.
+ Does not trigger when defining the first
+ WinScrolled or WinResized event, but may
+ trigger when adding more.
+
+ Non-recursive: the event will not trigger
+ while executing commands for the WinScrolled
+ event. However, if the command causes a
+ window to scroll or change size, then another
WinScrolled event will be triggered later.
- Does not trigger when the command is added,
- only after the first scroll or resize.
+
+
+ *WinResized*
+WinResized After a window in the current tab page changed
+ width or height.
+ See |win-scrolled-resized|.
+
+ |v:event| is set with information about size
+ changes. |WinResized-event|
+
+ Same behavior as |WinScrolled| for the
+ pattern, triggering and recursiveness.
==============================================================================
6. Patterns *autocmd-pattern* *{aupat}*
-The {aupat} argument of `:autocmd` can be a comma-separated list. This works
-as if the command was given with each pattern separately. Thus this command: >
+The {aupat} argument of `:autocmd` can be a comma-separated list. This works as
+if the command was given with each pattern separately. Thus this command: >
:autocmd BufRead *.txt,*.info set et
Is equivalent to: >
:autocmd BufRead *.txt set et
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index fa9fb286ae..08c8e2e9d6 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -170,6 +170,7 @@ get({func}, {what}) any get property of funcref/partial {func}
getbufinfo([{buf}]) List information about buffers
getbufline({buf}, {lnum} [, {end}])
List lines {lnum} to {end} of buffer {buf}
+getbufoneline({buf}, {lnum}) String line {lnum} of buffer {buf}
getbufvar({buf}, {varname} [, {def}])
any variable {varname} in buffer {buf}
getchangelist([{buf}]) List list of change list items
@@ -638,6 +639,7 @@ append({lnum}, {text}) *append()*
text line below line {lnum} in the current buffer.
Otherwise append {text} as one text line below line {lnum} in
the current buffer.
+ Any type of item is accepted and converted to a String.
{lnum} can be zero to insert a line before the first one.
{lnum} is used like with |getline()|.
Returns 1 for failure ({lnum} out of range or out of memory),
@@ -2684,11 +2686,13 @@ getbufinfo([{dict}])
Can also be used as a |method|: >
GetBufnr()->getbufinfo()
<
+
*getbufline()*
getbufline({buf}, {lnum} [, {end}])
Return a |List| with the lines starting from {lnum} to {end}
(inclusive) in the buffer {buf}. If {end} is omitted, a
- |List| with only the line {lnum} is returned.
+ |List| with only the line {lnum} is returned. See
+ `getbufoneline()` for only getting the line.
For the use of {buf}, see |bufname()| above.
@@ -2711,6 +2715,11 @@ getbufline({buf}, {lnum} [, {end}])
< Can also be used as a |method|: >
GetBufnr()->getbufline(lnum)
+<
+ *getbufoneline()*
+getbufoneline({buf}, {lnum})
+ Just like `getbufline()` but only get one line and return it
+ as a string.
getbufvar({buf}, {varname} [, {def}]) *getbufvar()*
The result is the value of option or local buffer variable
@@ -3198,7 +3207,8 @@ getline({lnum} [, {end}])
< Can also be used as a |method|: >
ComputeLnum()->getline()
-< To get lines from another buffer see |getbufline()|
+< To get lines from another buffer see |getbufline()| and
+ |getbufoneline()|
getloclist({nr} [, {what}]) *getloclist()*
Returns a |List| with all the entries in the location list for
@@ -6911,29 +6921,38 @@ setbufvar({buf}, {varname}, {val}) *setbufvar()*
setcellwidths({list}) *setcellwidths()*
Specify overrides for cell widths of character ranges. This
- tells Vim how wide characters are, counted in screen cells.
- This overrides 'ambiwidth'. Example: >
- setcellwidths([[0xad, 0xad, 1],
- \ [0x2194, 0x2199, 2]])
-
-< *E1109* *E1110* *E1111* *E1112* *E1113* *E1114*
- The {list} argument is a list of lists with each three
- numbers. These three numbers are [low, high, width]. "low"
- and "high" can be the same, in which case this refers to one
- character. Otherwise it is the range of characters from "low"
- to "high" (inclusive). "width" is either 1 or 2, indicating
- the character width in screen cells.
- An error is given if the argument is invalid, also when a
- range overlaps with another.
+ tells Vim how wide characters are when displayed in the
+ terminal, counted in screen cells. The values override
+ 'ambiwidth'. Example: >
+ call setcellwidths([
+ \ [0x111, 0x111, 1],
+ \ [0x2194, 0x2199, 2],
+ \ ])
+
+< The {list} argument is a List of Lists with each three
+ numbers: [{low}, {high}, {width}]. *E1109* *E1110*
+ {low} and {high} can be the same, in which case this refers to
+ one character. Otherwise it is the range of characters from
+ {low} to {high} (inclusive). *E1111* *E1114*
Only characters with value 0x100 and higher can be used.
+ {width} must be either 1 or 2, indicating the character width
+ in screen cells. *E1112*
+ An error is given if the argument is invalid, also when a
+ range overlaps with another. *E1113*
+
If the new value causes 'fillchars' or 'listchars' to become
invalid it is rejected and an error is given.
- To clear the overrides pass an empty list: >
- setcellwidths([]);
+ To clear the overrides pass an empty {list}: >
+ call setcellwidths([])
+
< You can use the script $VIMRUNTIME/tools/emoji_list.vim to see
- the effect for known emoji characters.
+ the effect for known emoji characters. Move the cursor
+ through the text to check if the cell widths of your terminal
+ match with what Vim knows about each emoji. If it doesn't
+ look right you need to adjust the {list} argument.
+
setcharpos({expr}, {list}) *setcharpos()*
Same as |setpos()| but uses the specified column number as the
@@ -7054,6 +7073,8 @@ setline({lnum}, {text}) *setline()*
{lnum} is used like with |getline()|.
When {lnum} is just below the last line the {text} will be
added below the last line.
+ {text} can be any type or a List of any type, each item is
+ converted to a String.
If this succeeds, FALSE is returned. If this fails (most likely
because {lnum} is invalid) TRUE is returned.
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt
index 5e6bc957a1..401ac87d90 100644
--- a/runtime/doc/deprecated.txt
+++ b/runtime/doc/deprecated.txt
@@ -128,10 +128,6 @@ NORMAL COMMANDS
OPTIONS
- *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
`<>` notation is always enabled.
-- *'exrc'* *'ex'* Security risk: downloaded files could include
- a malicious .nvimrc or .exrc file. See 'secure'.
- Recommended alternative: define an autocommand in your
- |vimrc| to set options for a matching directory.
- 'gdefault' Enables the |:substitute| flag 'g' by default.
- *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
- *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
diff --git a/runtime/doc/diagnostic.txt b/runtime/doc/diagnostic.txt
index d30d6c28a0..07a7d5190f 100644
--- a/runtime/doc/diagnostic.txt
+++ b/runtime/doc/diagnostic.txt
@@ -365,6 +365,11 @@ config({opts}, {namespace}) *vim.diagnostic.config()*
the beginning of the virtual text.
• prefix: (string) Prepend diagnostic message with
prefix.
+ • suffix: (string or function) Append diagnostic
+ message with suffix. If a function, it must have the
+ signature (diagnostic) -> string, where {diagnostic}
+ is of type |diagnostic-structure|. This can be used
+ to render an LSP diagnostic error code.
• format: (function) A function that takes a diagnostic
as input and returns a string. The return value is
the text used to display the diagnostic. Example: >
@@ -426,7 +431,7 @@ fromqflist({list}) *vim.diagnostic.fromqflist()*
|getloclist()|.
Return: ~
- array of diagnostics |diagnostic-structure|
+ Diagnostic [] array of |diagnostic-structure|
get({bufnr}, {opts}) *vim.diagnostic.get()*
Get current diagnostics.
@@ -441,7 +446,7 @@ get({bufnr}, {opts}) *vim.diagnostic.get()*
• severity: See |diagnostic-severity|.
Return: ~
- (table) A list of diagnostic items |diagnostic-structure|.
+ Diagnostic [] table A list of diagnostic items |diagnostic-structure|.
get_namespace({namespace}) *vim.diagnostic.get_namespace()*
Get namespace metadata.
@@ -462,37 +467,39 @@ get_next({opts}) *vim.diagnostic.get_next()*
Get the next diagnostic closest to the cursor position.
Parameters: ~
- • {opts} (table) See |vim.diagnostic.goto_next()|
+ • {opts} (table|nil) See |vim.diagnostic.goto_next()|
Return: ~
- (table) Next diagnostic
+ Diagnostic|nil Next diagnostic
get_next_pos({opts}) *vim.diagnostic.get_next_pos()*
Return the position of the next diagnostic in the current buffer.
Parameters: ~
- • {opts} (table) See |vim.diagnostic.goto_next()|
+ • {opts} (table|nil) See |vim.diagnostic.goto_next()|
Return: ~
- (table) Next diagnostic position as a (row, col) tuple.
+ table|false Next diagnostic position as a (row, col) tuple or false if
+ no next diagnostic.
get_prev({opts}) *vim.diagnostic.get_prev()*
Get the previous diagnostic closest to the cursor position.
Parameters: ~
- • {opts} (table) See |vim.diagnostic.goto_next()|
+ • {opts} nil|table See |vim.diagnostic.goto_next()|
Return: ~
- (table) Previous diagnostic
+ Diagnostic|nil Previous diagnostic
get_prev_pos({opts}) *vim.diagnostic.get_prev_pos()*
Return the position of the previous diagnostic in the current buffer.
Parameters: ~
- • {opts} (table) See |vim.diagnostic.goto_next()|
+ • {opts} (table|nil) See |vim.diagnostic.goto_next()|
Return: ~
- (table) Previous diagnostic position as a (row, col) tuple.
+ table|false Previous diagnostic position as a (row, col) tuple or
+ false if there is no prior diagnostic
goto_next({opts}) *vim.diagnostic.goto_next()*
Move to the next diagnostic.
@@ -532,8 +539,8 @@ hide({namespace}, {bufnr}) *vim.diagnostic.hide()*
|vim.diagnostic.disable()|.
Parameters: ~
- • {namespace} (number|nil) Diagnostic namespace. When omitted, hide
- diagnostics from all namespaces.
+ • {namespace} (number|nil) Diagnostic namespace. When omitted, hide diagnostics from all
+ namespaces.
• {bufnr} (number|nil) Buffer number, or 0 for current buffer. When
omitted, hide diagnostics in all buffers.
@@ -566,8 +573,8 @@ match({str}, {pat}, {groups}, {severity_map}, {defaults})
default to 0 and "severity" defaults to ERROR.
Return: ~
- diagnostic |diagnostic-structure| or `nil` if {pat} fails to match
- {str}.
+ Diagnostic|nil: |diagnostic-structure| or `nil` if {pat} fails to
+ match {str}.
open_float({opts}, {...}) *vim.diagnostic.open_float()*
Show diagnostics in a floating window.
@@ -618,9 +625,12 @@ open_float({opts}, {...}) *vim.diagnostic.open_float()*
{prefix} is a string, it is prepended to each diagnostic in
the window with no highlight. Overrides the setting from
|vim.diagnostic.config()|.
+ • suffix: Same as {prefix}, but appends the text to the
+ diagnostic instead of prepending it. Overrides the setting
+ from |vim.diagnostic.config()|.
Return: ~
- tuple ({float_bufnr}, {win_id})
+ number|nil, number|nil: ({float_bufnr}, {win_id})
reset({namespace}, {bufnr}) *vim.diagnostic.reset()*
Remove all diagnostics from the given namespace.
@@ -631,8 +641,8 @@ reset({namespace}, {bufnr}) *vim.diagnostic.reset()*
re-displayed, use |vim.diagnostic.hide()|.
Parameters: ~
- • {namespace} (number|nil) Diagnostic namespace. When omitted, remove
- diagnostics from all namespaces.
+ • {namespace} (number|nil) Diagnostic namespace. When omitted, remove diagnostics from all
+ namespaces.
• {bufnr} (number|nil) Remove diagnostics for the given buffer.
When omitted, diagnostics are removed for all buffers.
@@ -680,8 +690,8 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
Display diagnostics for the given namespace and buffer.
Parameters: ~
- • {namespace} (number|nil) Diagnostic namespace. When omitted, show
- diagnostics from all namespaces.
+ • {namespace} (number|nil) Diagnostic namespace. When omitted, show diagnostics from all
+ namespaces.
• {bufnr} (number|nil) Buffer number, or 0 for current buffer.
When omitted, show diagnostics in all buffers.
• {diagnostics} (table|nil) The diagnostics to display. When omitted,
@@ -701,6 +711,6 @@ toqflist({diagnostics}) *vim.diagnostic.toqflist()*
• {diagnostics} (table) List of diagnostics |diagnostic-structure|.
Return: ~
- array of quickfix list items |setqflist-what|
+ table[] of quickfix list items |setqflist-what|
vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl:
diff --git a/runtime/doc/digraph.txt b/runtime/doc/digraph.txt
index eb3de0111f..ce0a929bc1 100644
--- a/runtime/doc/digraph.txt
+++ b/runtime/doc/digraph.txt
@@ -156,7 +156,7 @@ These are the RFC1345 digraphs for the one-byte characters. See the output of
":digraphs" for the others.
EURO
-
+ *euro* *euro-digraph*
Exception: RFC1345 doesn't specify the euro sign. In Vim the digraph =e was
added for this. Note the difference between latin1, where the digraph Cu is
used for the currency sign, and latin9 (iso-8859-15), where the digraph =e is
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 4446598a2e..eb42e10338 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -229,13 +229,13 @@ is not available it returns zero or the default value you specify: >
List concatenation ~
-
+ *list-concatenation*
Two lists can be concatenated with the "+" operator: >
:let longlist = mylist + [5, 6]
:let mylist += [7, 8]
-To prepend or append an item turn the item into a list by putting [] around
-it. To change a list in-place see |list-modification| below.
+To prepend or append an item, turn the item into a list by putting [] around
+it. To change a list in-place, refer to |list-modification| below.
Sublist ~
@@ -2698,6 +2698,8 @@ text...
Unlock the internal variable {name}. Does the
opposite of |:lockvar|.
+ No error is given if {name} does not exist.
+
:if {expr1} *:if* *:end* *:endif* *:en* *E171* *E579* *E580*
:en[dif] Execute the commands until the next matching `:else`
or `:endif` if {expr1} evaluates to non-zero.
diff --git a/runtime/doc/insert.txt b/runtime/doc/insert.txt
index 0133824e76..e25f5901ef 100644
--- a/runtime/doc/insert.txt
+++ b/runtime/doc/insert.txt
@@ -857,29 +857,27 @@ invoked and what it should return.
Here is an example that uses the "aiksaurus" command (provided by Magnus
Groß): >
- func Thesaur(findstart, base)
- if a:findstart
- let line = getline('.')
- let start = col('.') - 1
- while start > 0 && line[start - 1] =~ '\a'
- let start -= 1
- endwhile
- return start
- else
- let res = []
- let h = ''
- for l in split(system('aiksaurus ' .. shellescape(a:base)), '\n')
- if l[:3] == '=== '
- let h = substitute(l[4:], ' =*$', '', '')
- elseif l[0] =~ '\a'
- call extend(res, map(split(l, ', '), {_, val -> {'word': val, 'menu': '('.h.')'}}))
- endif
- endfor
- return res
- endif
- endfunc
-
- set thesaurusfunc=Thesaur
+ func Thesaur(findstart, base)
+ if a:findstart
+ return searchpos('\<', 'bnW', line('.'))[1] - 1
+ endif
+ let res = []
+ let h = ''
+ for l in systemlist('aiksaurus ' .. shellescape(a:base))
+ if l[:3] == '=== '
+ let h = '(' .. substitute(l[4:], ' =*$', ')', '')
+ elseif l ==# 'Alphabetically similar known words are: '
+ let h = "\U0001f52e"
+ elseif l[0] =~ '\a' || (h ==# "\U0001f52e" && l[0] ==# "\t")
+ call extend(res, map(split(substitute(l, '^\t', '', ''), ', '), {_, val -> {'word': val, 'menu': h}}))
+ endif
+ endfor
+ return res
+ endfunc
+
+ if exists('+thesaurusfunc')
+ set thesaurusfunc=Thesaur
+ endif
Completing keywords in the current and included files *compl-keyword*
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 036b0bbc6f..0255d78c4c 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -1330,7 +1330,9 @@ hover({_}, {result}, {ctx}, {config}) *vim.lsp.handlers.hover()*
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(
vim.lsp.handlers.hover, {
-- Use a sharp border with `FloatBorder` highlights
- border = "single"
+ border = "single",
+ -- add the title in hover float window
+ title = "hover"
}
)
<
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index cab2f49d94..4055d93f6a 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -2286,11 +2286,12 @@ find({names}, {opts}) *vim.fs.find()*
Parameters: ~
• {names} (string|table|fun(name: string): boolean) Names of the files
and directories to find. Must be base names, paths and globs
- are not supported. If a function it is called per file and
- dir within the traversed directories to test if they match.
+ are not supported. The function is called per file and
+ directory within the traversed directories to test if they
+ match {names}.
• {opts} (table) Optional keyword arguments:
• path (string): Path to begin searching from. If omitted,
- the current working directory is used.
+ the |current-directory| is used.
• upward (boolean, default false): If true, search upward
through parent directories. Otherwise, search through child
directories (recursively).
@@ -2298,13 +2299,14 @@ find({names}, {opts}) *vim.fs.find()*
reached. The directory itself is not searched.
• type (string): Find only files ("file") or directories
("directory"). If omitted, both files and directories that
- match {name} are included.
+ match {names} are included.
• limit (number, default 1): Stop the search after finding
this many matches. Use `math.huge` to place no limit on the
number of matches.
Return: ~
- (table) The paths of all matching files or directories
+ (table) The normalized paths |vim.fs.normalize()| of all matching
+ files or directories
normalize({path}) *vim.fs.normalize()*
Normalize a path to a standard format. A tilde (~) character at the
@@ -2312,16 +2314,16 @@ normalize({path}) *vim.fs.normalize()*
backslash (\) characters are converted to forward slashes (/). Environment
variables are also expanded.
- Example: >
+ Examples: >
- vim.fs.normalize('C:\Users\jdoe')
- => 'C:/Users/jdoe'
+ vim.fs.normalize('C:\Users\jdoe')
+ => 'C:/Users/jdoe'
- vim.fs.normalize('~/src/neovim')
- => '/home/jdoe/src/neovim'
+ vim.fs.normalize('~/src/neovim')
+ => '/home/jdoe/src/neovim'
- vim.fs.normalize('$XDG_CONFIG_HOME/nvim/init.vim')
- => '/Users/jdoe/.config/nvim/init.vim'
+ vim.fs.normalize('$XDG_CONFIG_HOME/nvim/init.vim')
+ => '/Users/jdoe/.config/nvim/init.vim'
<
Parameters: ~
@@ -2354,4 +2356,20 @@ parents({start}) *vim.fs.parents()*
Return: ~
(function) Iterator
+
+==============================================================================
+Lua module: secure *lua-secure*
+
+read({path}) *vim.secure.read()*
+ Attempt to read the file at {path} prompting the user if the file should
+ be trusted. The user's choice is persisted in a trust database at
+ $XDG_STATE_HOME/nvim/trust.
+
+ Parameters: ~
+ • {path} (string) Path to a file to read.
+
+ Return: ~
+ (string|nil) The contents of the given file if it exists and is
+ trusted, or nil otherwise.
+
vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl:
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index c4bacfd632..fe07c2e1c1 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1713,7 +1713,7 @@ When executed as: >
This will invoke: >
:call Myfunc("arg1","arg2")
-< *q-args-example*
+< *q-args-example*
A more substantial example: >
:function Allargs(command)
: let i = 0
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index d339df8479..70643cf00c 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -39,6 +39,14 @@ NEW FEATURES *news-features*
The following new APIs or features were added.
+• |vim.diagnostic.open_float()| (and therefore |vim.diagnostic.config()|) now
+ accepts a `suffix` option which, by default, renders LSP error codes.
+ Similarly, the `virtual_text` configuration in |vim.diagnostic.config()| now
+ has a `suffix` option which does nothing by default.
+
+• |vim.secure.read()| reads a file and prompts the user if it should be
+ trusted and, if so, returns the file's contents.
+
• When using Nvim inside tmux 3.2 or later, the default clipboard provider
will now copy to the system clipboard. |provider-clipboard|
@@ -57,6 +65,8 @@ CHANGED FEATURES *news-changes*
The following changes to existing APIs or features add new behavior.
+• 'exrc' is no longer marked deprecated.
+
==============================================================================
REMOVED FEATURES *news-removed*
diff --git a/runtime/doc/nvim_terminal_emulator.txt b/runtime/doc/nvim_terminal_emulator.txt
index 546f92e92f..3fe86b00bc 100644
--- a/runtime/doc/nvim_terminal_emulator.txt
+++ b/runtime/doc/nvim_terminal_emulator.txt
@@ -355,6 +355,20 @@ TermdebugStopPost After debugging has ended, gdb-related windows
the state before the debugging was restored.
+Customizing ~
+ *termdebug-customizing* *g:termdebug_config*
+In the past several global variables were used for configuration. These are
+deprecated and using the g:termdebug_config dictionary is preferred. When
+g:termdebug_config exists the other global variables will NOT be used.
+The recommended way is to start with an empty dictionary: >
+ let g:termdebug_config = {}
+
+Then you can add entries to the dictionary as mentioned below. The
+deprecated global variable names are mentioned for completeness. If you are
+switching over to using g:termdebug_config you can find the old variable name
+and take over the value, then delete the deprecated variable.
+
+
Prompt mode ~
*termdebug-prompt*
When on MS-Windows, gdb will run in a buffer with 'buftype' set to "prompt".
@@ -368,13 +382,13 @@ This works slightly differently:
*termdebug_use_prompt*
Prompt mode can be used with: >
let g:termdebug_config['use_prompt'] = 1
-Or if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebug_use_prompt = 1
<
*termdebug_map_K*
The K key is normally mapped to :Evaluate. If you do not want this use: >
let g:termdebug_config['map_K'] = 0
-Or if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebug_map_K = 0
<
*termdebug_disasm_window*
@@ -382,7 +396,7 @@ If you want the Asm window shown by default, set the flag to 1.
the "disasm_window_height" entry can be used to set the window height: >
let g:termdebug_config['disasm_window'] = 1
let g:termdebug_config['disasm_window_height'] = 15
-or, if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebug_disasm_window = 15
Any value greater than 1 will set the Asm window height to that value.
@@ -400,25 +414,18 @@ interrupt the running program. But after using the MI command
communication channel.
-Customizing ~
- *termdebug-customizing* *g:termdebug_config*
-In the past several global variables were used for configuration. These are
-deprecated, using the g:termdebug_config dictionary is preferred. When
-g:termdebug_config exists the other global variables will not be used.
-
-
GDB command ~
*g:termdebugger*
To change the name of the gdb command, set "debugger" entry in
g:termdebug_config or the "g:termdebugger" variable before invoking
`:Termdebug`: >
let g:termdebug_config['command'] = "mygdb"
-Or if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebugger = "mygdb"
If the command needs an argument use a List: >
let g:termdebug_config['command'] = ['rr', 'replay', '--']
-Or if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebugger = ['rr', 'replay', '--']
To not use neovim floating windows for previewing variable evaluation, set the
@@ -451,7 +458,7 @@ Then your gdb is too old.
Colors ~
- *hl-debugPC* *hl-debugBreakpoint*
+ *hl-debugPC* *hl-debugBreakpoint*
The color of the signs can be adjusted with these highlight groups:
- debugPC the current position
- debugBreakpoint a breakpoint
@@ -467,7 +474,6 @@ When 'background' is "dark":
Shortcuts ~
*termdebug_shortcuts*
-
You can define your own shortcuts (mappings) to control gdb, that can work in
any window, using the TermDebugSendCommand() function. Example: >
map ,w :call TermDebugSendCommand('where')<CR>
@@ -476,7 +482,6 @@ The argument is the gdb command.
Popup menu ~
*termdebug_popup*
-
By default the Termdebug plugin sets 'mousemodel' to "popup_setpos" and adds
these entries to the popup menu:
Set breakpoint `:Break`
@@ -484,17 +489,16 @@ these entries to the popup menu:
Evaluate `:Evaluate`
If you don't want this then disable it with: >
let g:termdebug_config['popup'] = 0
-or if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebug_popup = 0
Vim window width ~
*termdebug_wide*
-
To change the width of the Vim window when debugging starts and use a vertical
split: >
let g:termdebug_config['wide'] = 163
-Or if there is no g:termdebug_config: >
+If there is no g:termdebug_config you can use: >
let g:termdebug_wide = 163
This will set 'columns' to 163 when `:Termdebug` is used. The value is
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index fd76f11046..36eabfdcbf 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -2264,6 +2264,20 @@ A jump table for the options with a short description can be found at |Q_op|.
This option is reset when the 'paste' option is set and restored when
the 'paste' option is reset.
+ *'exrc'* *'ex'* *'noexrc'* *'noex'*
+'exrc' 'ex' boolean (default off)
+ global
+ Enables the reading of .nvimrc and .exrc files in the current
+ directory.
+
+ The file is only sourced if the user indicates the file is trusted. If
+ it is, the SHA256 hash of the file contents and the full path of the
+ file are persisted to a trust database. The user is only prompted
+ again if the file contents change. See |vim.secure.read()|.
+
+ This option cannot be set from a |modeline| or in the |sandbox|, for
+ security reasons.
+
*'fileencoding'* *'fenc'* *E213*
'fileencoding' 'fenc' string (default: "")
local to buffer
@@ -3335,9 +3349,13 @@ A jump table for the options with a short description can be found at |Q_op|.
local to buffer
Expression to be used to transform the string found with the 'include'
option to a file name. Mostly useful to change "." to "/" for Java: >
- :set includeexpr=substitute(v:fname,'\\.','/','g')
+ :setlocal includeexpr=substitute(v:fname,'\\.','/','g')
< The "v:fname" variable will be set to the file name that was detected.
-
+ Note the double backslash: the `:set` command first halves them, then
+ one remains in the value, where "\." matches a dot literally. For
+ simple character replacements `tr()` avoids the need for escaping: >
+ :setlocal includeexpr=tr(v:fname,'.','/')
+<
Also used for the |gf| command if an unmodified file name can't be
found. Allows doing "gf" on the name after an 'include' statement.
Also used for |<cfile>|.
@@ -5115,19 +5133,6 @@ A jump table for the options with a short description can be found at |Q_op|.
two letters (See |object-motions|). The default makes a section start
at the nroff macros ".SH", ".NH", ".H", ".HU", ".nh" and ".sh".
- *'secure'* *'nosecure'* *E523*
-'secure' boolean (default off)
- global
- When on, ":autocmd", shell and write commands are not allowed in
- ".nvimrc" and ".exrc" in the current directory and map commands are
- displayed. Switch it off only if you know that you will not run into
- problems, or when the 'exrc' option is off. On Unix this option is
- only used if the ".nvimrc" or ".exrc" is not owned by you. This can be
- dangerous if the systems allows users to do a "chown". You better set
- 'secure' at the end of your |init.vim| then.
- This option cannot be set from a |modeline| or in the |sandbox|, for
- security reasons.
-
*'selection'* *'sel'*
'selection' 'sel' string (default "inclusive")
global
diff --git a/runtime/doc/provider.txt b/runtime/doc/provider.txt
index a7b5b1d492..3ccff3dc3c 100644
--- a/runtime/doc/provider.txt
+++ b/runtime/doc/provider.txt
@@ -188,6 +188,7 @@ registers. Nvim looks for these clipboard tools, in order of priority:
- |g:clipboard|
- pbcopy, pbpaste (macOS)
- wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
+ - waycopy, waypaste (if $WAYLAND_DISPLAY is set)
- xclip (if $DISPLAY is set)
- xsel (if $DISPLAY is set)
- lemonade (for SSH) https://github.com/pocke/lemonade
diff --git a/runtime/doc/support.txt b/runtime/doc/support.txt
index a0fc6e9f2c..481959d8f1 100644
--- a/runtime/doc/support.txt
+++ b/runtime/doc/support.txt
@@ -12,8 +12,8 @@ Support *support*
Supported platforms *supported-platforms*
`System` `Tier` `Versions` `Tested versions`
-Linux 1 >= 2.6.32, glibc >= 2.12 Ubuntu 20.04
-macOS (Intel) 1 >= 10.15 macOS 11
+Linux 1 >= 2.6.32, glibc >= 2.12 Ubuntu 22.04
+macOS (Intel) 1 >= 10.15 macOS 12
Windows 64-bit 1 >= 8 Windows Server 2019
FreeBSD 1 >= 10 FreeBSD 13
macOS (M1) 2 >= 10.15
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 033a01ac98..f74a046ee6 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -1854,6 +1854,16 @@ following two lines to the syntax coloring file for that language
Now you just need to make sure that you add all regions that contain
the preprocessor language to the cluster htmlPreproc.
+ *html-folding*
+The HTML syntax file provides syntax |folding| (see |:syn-fold|) between start
+and end tags. This can be turned on by >
+
+ :let g:html_syntax_folding = 1
+ :set foldmethod=syntax
+
+Note: Syntax folding might slow down syntax highlighting significantly,
+especially for large files.
+
HTML/OS (by Aestiva) *htmlos.vim* *ft-htmlos-syntax*
diff --git a/runtime/doc/tips.txt b/runtime/doc/tips.txt
index 5416ba5d89..559f31eb2d 100644
--- a/runtime/doc/tips.txt
+++ b/runtime/doc/tips.txt
@@ -454,7 +454,7 @@ the current window, try this custom `:HelpCurwin` command:
>
command -bar -nargs=? -complete=help HelpCurwin execute s:HelpCurwin(<q-args>)
let s:did_open_help = v:false
-
+
function s:HelpCurwin(subject) abort
let mods = 'silent noautocmd keepalt'
if !s:did_open_help
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 067ad6648c..226bd029a3 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -785,6 +785,13 @@ Working with text in the current buffer: *text-functions*
getcharsearch() return character search information
setcharsearch() set character search information
+Working with text in another buffer:
+ getbufline() get a list of lines from the specified buffer
+ getbufoneline() get a one line from the specified buffer
+ setbufline() replace a line in the specified buffer
+ appendbufline() append a list of lines in the specified buffer
+ deletebufline() delete lines from a specified buffer
+
*system-functions* *file-functions*
System functions and manipulation of files:
glob() expand wildcards
@@ -838,8 +845,10 @@ Buffers, windows and the argument list:
argidx() current position in the argument list
arglistid() get id of the argument list
argv() get one entry from the argument list
+ bufadd() add a file to the list of buffers
bufexists() check if a buffer exists
buflisted() check if a buffer exists and is listed
+ bufload() ensure a buffer is loaded
bufloaded() check if a buffer exists and is loaded
bufname() get the name of a specific buffer
bufnr() get the buffer number of a specific buffer
@@ -850,10 +859,6 @@ Buffers, windows and the argument list:
bufwinid() get the window ID of a specific buffer
bufwinnr() get the window number of a specific buffer
winbufnr() get the buffer number of a specific window
- getbufline() get a list of lines from the specified buffer
- setbufline() replace a line in the specified buffer
- appendbufline() append a list of lines in the specified buffer
- deletebufline() delete lines from a specified buffer
win_findbuf() find windows containing a buffer
win_getid() get window ID of a window
win_gettype() get type of window
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index fe6c28c809..b5222c9ddd 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -417,6 +417,8 @@ Options:
'jumpoptions' "view" tries to restore the |mark-view| when moving through
the |jumplist|, |changelist|, |alternate-file| or using |mark-motions|.
'shortmess' the "F" flag does not affect output from autocommands
+ 'exrc' searches for ".nvimrc" or ".exrc" files. The user is prompted whether
+ to trust the file.
Shell:
Shell output (|:!|, |:make|, …) is always routed through the UI, so it
@@ -639,6 +641,9 @@ Options:
*'prompt'* *'noprompt'*
*'remap'* *'noremap'*
*'restorescreen'* *'rs'* *'norestorescreen'* *'nors'*
+ *'secure'*
+ Everything is allowed in 'exrc' files since they must be explicitly marked
+ trusted.
*'shelltype'*
*'shortname'* *'sn'* *'noshortname'* *'nosn'*
*'swapsync'* *'sws'*
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index dfc2fb5abf..1776c47d33 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -607,6 +607,51 @@ it).
The minimal height and width of a window is set with 'winminheight' and
'winminwidth'. These are hard values, a window will never become smaller.
+
+WinScrolled and WinResized autocommands ~
+ *win-scrolled-resized*
+If you want to get notified of changes in window sizes, the |WinResized|
+autocommand event can be used.
+If you want to get notified of text in windows scrolling vertically or
+horizontally, the |WinScrolled| autocommand event can be used. This will also
+trigger in window size changes.
+ *WinResized-event*
+The |WinResized| event is triggered after updating the display, several
+windows may have changed size then. A list of the IDs of windows that changed
+since last time is provided in the v:event.windows variable, for example:
+ [1003, 1006]
+ *WinScrolled-event*
+The |WinScrolled| event is triggered after |WinResized|, and also if a window
+was scrolled. That can be vertically (the text at the top of the window
+changed) or horizontally (when 'wrap' is off or when the first displayed part
+of the first line changes). Note that |WinScrolled| will trigger many more
+times than |WinResized|, it may slow down editing a bit.
+
+The information provided by |WinScrolled| is a dictionary for each window that
+has changes, using the window ID as the key, and a total count of the changes
+with the key "all". Example value for |v:event|:
+ {
+ all: {width: 0, height: 2, leftcol: 0, topline: 1, skipcol: 0},
+ 1003: {width: 0, height: -1, leftcol: 0, topline: 0, skipcol: 0},
+ 1006: {width: 0, height: 1, leftcol: 0, topline: 1, skipcol: 0},
+ }
+
+Note that the "all" entry has the absolute values of the individual windows
+accumulated.
+
+If you need more information about what changed, or you want to "debounce" the
+events (not handle every event to avoid doing too much work), you may want to
+use the `winlayout()` and `getwininfo()` functions.
+
+|WinScrolled| and |WinResized| do not trigger when the first autocommand is
+added, only after the first scroll or resize. They may trigger when switching
+to another tab page.
+
+The commands executed are expected to not cause window size or scroll changes.
+If this happens anyway, the event will trigger again very soon. In other
+words: Just before triggering the event, the current sizes and scroll
+positions are stored and used to decide whether there was a change.
+
==============================================================================
7. Argument and buffer list commands *buffer-list*
diff --git a/runtime/ftplugin/lua.vim b/runtime/ftplugin/lua.vim
index c28b8aecf8..88b1fc9d44 100644
--- a/runtime/ftplugin/lua.vim
+++ b/runtime/ftplugin/lua.vim
@@ -4,7 +4,7 @@
" Previous Maintainer: Max Ischenko <mfi@ukr.net>
" Contributor: Dorai Sitaram <ds26@gte.com>
" C.D. MacEachern <craig.daniel.maceachern@gmail.com>
-" Last Change: 2022 Oct 15
+" Last Change: 2022 Nov 19
if exists("b:did_ftplugin")
finish
@@ -21,7 +21,7 @@ setlocal formatoptions-=t formatoptions+=croql
let &l:define = '\<function\|\<local\%(\s\+function\)\='
" TODO: handle init.lua
-setlocal includeexpr=substitute(v:fname,'\\.','/','g')
+setlocal includeexpr=tr(v:fname,'.','/')
setlocal suffixesadd=.lua
let b:undo_ftplugin = "setlocal cms< com< def< fo< inex< sua<"
diff --git a/runtime/ftplugin/mermaid.vim b/runtime/ftplugin/mermaid.vim
new file mode 100644
index 0000000000..fe84ab37cf
--- /dev/null
+++ b/runtime/ftplugin/mermaid.vim
@@ -0,0 +1,49 @@
+" Vim filetype plugin
+" Language: Mermaid
+" Maintainer: Craig MacEachern <https://github.com/craigmac/vim-mermaid>
+" Last Change: 2022 Oct 13
+
+if exists("b:did_ftplugin")
+ finish
+endif
+
+let s:keepcpo= &cpo
+set cpo&vim
+
+" Use mermaid live editor's style
+setlocal expandtab
+setlocal shiftwidth=2
+setlocal softtabstop=-1
+setlocal tabstop=4
+
+" TODO: comments, formatlist stuff, based on what?
+setlocal comments=b:#,fb:-
+setlocal commentstring=#\ %s
+setlocal formatoptions+=tcqln formatoptions-=r formatoptions-=o
+setlocal formatlistpat=^\\s*\\d\\+\\.\\s\\+\\\|^\\s*[-*+]\\s\\+\\\|^\\[^\\ze[^\\]]\\+\\]:\\&^.\\{4\\}
+
+if exists('b:undo_ftplugin')
+ let b:undo_ftplugin .= "|setl cms< com< fo< flp< et< ts< sts< sw<"
+else
+ let b:undo_ftplugin = "setl cms< com< fo< flp< et< ts< sts< sw<"
+endif
+
+if !exists("g:no_plugin_maps") && !exists("g:no_markdown_maps")
+ nnoremap <silent><buffer> [[ :<C-U>call search('\%(^#\{1,5\}\s\+\S\\|^\S.*\n^[=-]\+$\)', "bsW")<CR>
+ nnoremap <silent><buffer> ]] :<C-U>call search('\%(^#\{1,5\}\s\+\S\\|^\S.*\n^[=-]\+$\)', "sW")<CR>
+ xnoremap <silent><buffer> [[ :<C-U>exe "normal! gv"<Bar>call search('\%(^#\{1,5\}\s\+\S\\|^\S.*\n^[=-]\+$\)', "bsW")<CR>
+ xnoremap <silent><buffer> ]] :<C-U>exe "normal! gv"<Bar>call search('\%(^#\{1,5\}\s\+\S\\|^\S.*\n^[=-]\+$\)', "sW")<CR>
+ let b:undo_ftplugin .= '|sil! nunmap <buffer> [[|sil! nunmap <buffer> ]]|sil! xunmap <buffer> [[|sil! xunmap <buffer> ]]'
+endif
+
+" if has("folding") && get(g:, "markdown_folding", 0)
+" setlocal foldexpr=MarkdownFold()
+" setlocal foldmethod=expr
+" setlocal foldtext=MarkdownFoldText()
+" let b:undo_ftplugin .= "|setl foldexpr< foldmethod< foldtext<"
+" endif
+
+let &cpo = s:keepcpo
+unlet s:keepcpo
+
+" vim:set sw=2:
diff --git a/runtime/ftplugin/obse.vim b/runtime/ftplugin/obse.vim
new file mode 100644
index 0000000000..6d865f05ee
--- /dev/null
+++ b/runtime/ftplugin/obse.vim
@@ -0,0 +1,70 @@
+" Vim filetype plugin file
+" Language: Oblivion Language (obl)
+" Original Creator: Kat <katisntgood@gmail.com>
+" Maintainer: Kat <katisntgood@gmail.com>
+" Created: August 08, 2021
+" Last Change: 13 November 2022
+
+if exists("b:did_ftplugin")
+ finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+let b:undo_ftplugin = "setl com< cms<"
+
+noremap <script> <buffer> <silent> [[ <nop>
+noremap <script> <buffer> <silent> ]] <nop>
+
+noremap <script> <buffer> <silent> [] <nop>
+noremap <script> <buffer> <silent> ][ <nop>
+
+setlocal commentstring=;%s
+setlocal comments=:;
+
+function s:NextSection(type, backwards, visual)
+ if a:visual
+ normal! gv
+ endif
+
+ if a:type == 1
+ let pattern = '\v(\n\n^\S|%^)'
+ let flags = 'e'
+ elseif a:type == 2
+ let pattern = '\v^\S.*'
+ let flags = ''
+ endif
+
+ if a:backwards
+ let dir = '?'
+ else
+ let dir = '/'
+ endif
+
+ execute 'silent normal! ' . dir . pattern . dir . flags . "\r"
+endfunction
+
+noremap <script> <buffer> <silent> ]]
+ \ :call <SID>NextSection(1, 0, 0)<cr>
+
+noremap <script> <buffer> <silent> [[
+ \ :call <SID>NextSection(1, 1, 0)<cr>
+
+noremap <script> <buffer> <silent> ][
+ \ :call <SID>NextSection(2, 0, 0)<cr>
+
+noremap <script> <buffer> <silent> []
+ \ :call <SID>NextSection(2, 1, 0)<cr>
+
+vnoremap <script> <buffer> <silent> ]]
+ \ :<c-u>call <SID>NextSection(1, 0, 1)<cr>
+vnoremap <script> <buffer> <silent> [[
+ \ :<c-u>call <SID>NextSection(1, 1, 1)<cr>
+vnoremap <script> <buffer> <silent> ][
+ \ :<c-u>call <SID>NextSection(2, 0, 1)<cr>
+vnoremap <script> <buffer> <silent> []
+ \ :<c-u>call <SID>NextSection(2, 1, 1)<cr>
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/runtime/indent/obse.vim b/runtime/indent/obse.vim
new file mode 100644
index 0000000000..6603723dba
--- /dev/null
+++ b/runtime/indent/obse.vim
@@ -0,0 +1,55 @@
+" Vim indent file
+" Language: Oblivion Language (obl)
+" Original Creator: Kat <katisntgood@gmail.com>
+" Maintainer: Kat <katisntgood@gmail.com>
+" Created: 01 November 2021
+" Last Change: 13 November 2022
+
+if exists("b:did_indent")
+ finish
+endif
+let b:did_indent = 1
+let b:undo_indent = 'setlocal indentkeys< indentexpr<'
+
+setlocal indentexpr=GetOblIndent()
+setlocal indentkeys+==~endif,=~else,=~loop,=~end
+
+if exists("*GetOblIndent")
+ finish
+endif
+let s:keepcpo = &cpo
+set cpo&vim
+
+let s:SKIP_LINES = '^\s*\(;.*\)'
+function! GetOblIndent()
+
+ let lnum = prevnonblank(v:lnum - 1)
+ let cur_text = getline(v:lnum)
+ if lnum == 0
+ return 0
+ endif
+ let prev_text = getline(lnum)
+ let found_cont = 0
+ let ind = indent(lnum)
+
+ " indent next line on start terms
+ let i = match(prev_text, '\c^\s*\(\s\+\)\?\(\(if\|while\|foreach\|begin\|else\%[if]\)\>\)')
+ if i >= 0
+ let ind += shiftwidth()
+ if strpart(prev_text, i, 1) == '|' && has('syntax_items')
+ \ && synIDattr(synID(lnum, i, 1), "name") =~ '\(Comment\|String\)$'
+ let ind -= shiftwidth()
+ endif
+ endif
+ " indent current line on end/else terms
+ if cur_text =~ '\c^\s*\(\s\+\)\?\(\(loop\|endif\|else\%[if]\)\>\)'
+ let ind = ind - shiftwidth()
+ " if we are at a begin block just go to column 0
+ elseif cur_text =~ '\c^\s*\(\s\+\)\?\(\(begin\|end\)\>\)'
+ let ind = 0
+ endif
+ return ind
+endfunction
+
+let &cpo = s:keepcpo
+unlet s:keepcpo
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index 0013f38d89..ad4dc20efb 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -36,6 +36,7 @@ for k, v in pairs({
ui = true,
health = true,
fs = true,
+ secure = true,
}) do
vim._submodules[k] = v
end
diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua
index af2d41bf7e..18df1f1586 100644
--- a/runtime/lua/vim/diagnostic.lua
+++ b/runtime/lua/vim/diagnostic.lua
@@ -1,7 +1,8 @@
-local if_nil = vim.F.if_nil
+local api, if_nil = vim.api, vim.F.if_nil
local M = {}
+---@enum DiagnosticSeverity
M.severity = {
ERROR = 1,
WARN = 2,
@@ -47,11 +48,11 @@ local bufnr_and_namespace_cacher_mt = {
local diagnostic_cache
do
- local group = vim.api.nvim_create_augroup('DiagnosticBufWipeout', {})
+ local group = api.nvim_create_augroup('DiagnosticBufWipeout', {})
diagnostic_cache = setmetatable({}, {
__index = function(t, bufnr)
assert(bufnr > 0, 'Invalid buffer number')
- vim.api.nvim_create_autocmd('BufWipeout', {
+ api.nvim_create_autocmd('BufWipeout', {
group = group,
buffer = bufnr,
callback = function()
@@ -245,7 +246,7 @@ end)()
---@private
local function get_bufnr(bufnr)
if not bufnr or bufnr == 0 then
- return vim.api.nvim_get_current_buf()
+ return api.nvim_get_current_buf()
end
return bufnr
end
@@ -299,7 +300,7 @@ end
---@private
local function restore_extmarks(bufnr, last)
for ns, extmarks in pairs(diagnostic_cache_extmarks[bufnr]) do
- local extmarks_current = vim.api.nvim_buf_get_extmarks(bufnr, ns, 0, -1, { details = true })
+ local extmarks_current = api.nvim_buf_get_extmarks(bufnr, ns, 0, -1, { details = true })
local found = {}
for _, extmark in ipairs(extmarks_current) do
-- nvim_buf_set_lines will move any extmark to the line after the last
@@ -312,7 +313,7 @@ local function restore_extmarks(bufnr, last)
if not found[extmark[1]] then
local opts = extmark[4]
opts.id = extmark[1]
- pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, extmark[2], extmark[3], opts)
+ pcall(api.nvim_buf_set_extmark, bufnr, ns, extmark[2], extmark[3], opts)
end
end
end
@@ -322,7 +323,7 @@ end
local function save_extmarks(namespace, bufnr)
bufnr = get_bufnr(bufnr)
if not diagnostic_attached_buffers[bufnr] then
- vim.api.nvim_buf_attach(bufnr, false, {
+ api.nvim_buf_attach(bufnr, false, {
on_lines = function(_, _, _, _, _, last)
restore_extmarks(bufnr, last - 1)
end,
@@ -333,7 +334,7 @@ local function save_extmarks(namespace, bufnr)
diagnostic_attached_buffers[bufnr] = true
end
diagnostic_cache_extmarks[bufnr][namespace] =
- vim.api.nvim_buf_get_extmarks(bufnr, namespace, 0, -1, { details = true })
+ api.nvim_buf_get_extmarks(bufnr, namespace, 0, -1, { details = true })
end
local registered_autocmds = {}
@@ -366,8 +367,8 @@ local function schedule_display(namespace, bufnr, args)
local key = make_augroup_key(namespace, bufnr)
if not registered_autocmds[key] then
- local group = vim.api.nvim_create_augroup(key, { clear = true })
- vim.api.nvim_create_autocmd(insert_leave_auto_cmds, {
+ local group = api.nvim_create_augroup(key, { clear = true })
+ api.nvim_create_autocmd(insert_leave_auto_cmds, {
group = group,
buffer = bufnr,
callback = function()
@@ -384,7 +385,7 @@ local function clear_scheduled_display(namespace, bufnr)
local key = make_augroup_key(namespace, bufnr)
if registered_autocmds[key] then
- vim.api.nvim_del_augroup_by_name(key)
+ api.nvim_del_augroup_by_name(key)
registered_autocmds[key] = nil
end
end
@@ -399,7 +400,7 @@ local function get_diagnostics(bufnr, opts, clamp)
-- Memoized results of buf_line_count per bufnr
local buf_line_count = setmetatable({}, {
__index = function(t, k)
- t[k] = vim.api.nvim_buf_line_count(k)
+ t[k] = api.nvim_buf_line_count(k)
return rawget(t, k)
end,
})
@@ -407,7 +408,7 @@ local function get_diagnostics(bufnr, opts, clamp)
---@private
local function add(b, d)
if not opts.lnum or d.lnum == opts.lnum then
- if clamp and vim.api.nvim_buf_is_loaded(b) then
+ if clamp and api.nvim_buf_is_loaded(b) then
local line_count = buf_line_count[b] - 1
if
d.lnum > line_count
@@ -471,7 +472,7 @@ local function set_list(loclist, opts)
local winnr = opts.winnr or 0
local bufnr
if loclist then
- bufnr = vim.api.nvim_win_get_buf(winnr)
+ bufnr = api.nvim_win_get_buf(winnr)
end
-- Don't clamp line numbers since the quickfix list can already handle line
-- numbers beyond the end of the buffer
@@ -483,7 +484,7 @@ local function set_list(loclist, opts)
vim.fn.setqflist({}, ' ', { title = title, items = items })
end
if open then
- vim.api.nvim_command(loclist and 'lopen' or 'botright copen')
+ api.nvim_command(loclist and 'lopen' or 'botright copen')
end
end
@@ -492,7 +493,7 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
position[1] = position[1] - 1
bufnr = get_bufnr(bufnr)
local wrap = vim.F.if_nil(opts.wrap, true)
- local line_count = vim.api.nvim_buf_line_count(bufnr)
+ local line_count = api.nvim_buf_line_count(bufnr)
local diagnostics =
get_diagnostics(bufnr, vim.tbl_extend('keep', opts, { namespace = namespace }), true)
local line_diagnostics = diagnostic_lines(diagnostics)
@@ -506,7 +507,7 @@ local function next_diagnostic(position, search_forward, bufnr, opts, namespace)
lnum = (lnum + line_count) % line_count
end
if line_diagnostics[lnum] and not vim.tbl_isempty(line_diagnostics[lnum]) then
- local line_length = #vim.api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1]
+ local line_length = #api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1]
local sort_diagnostics, is_next
if search_forward then
sort_diagnostics = function(a, b)
@@ -542,17 +543,17 @@ local function diagnostic_move_pos(opts, pos)
opts = opts or {}
local float = vim.F.if_nil(opts.float, true)
- local win_id = opts.win_id or vim.api.nvim_get_current_win()
+ local win_id = opts.win_id or api.nvim_get_current_win()
if not pos then
- vim.api.nvim_echo({ { 'No more valid diagnostics to move to', 'WarningMsg' } }, true, {})
+ api.nvim_echo({ { 'No more valid diagnostics to move to', 'WarningMsg' } }, true, {})
return
end
- vim.api.nvim_win_call(win_id, function()
+ api.nvim_win_call(win_id, function()
-- Save position in the window's jumplist
vim.cmd("normal! m'")
- vim.api.nvim_win_set_cursor(win_id, { pos[1] + 1, pos[2] })
+ api.nvim_win_set_cursor(win_id, { pos[1] + 1, pos[2] })
-- Open folds under the cursor
vim.cmd('normal! zv')
end)
@@ -561,7 +562,7 @@ local function diagnostic_move_pos(opts, pos)
local float_opts = type(float) == 'table' and float or {}
vim.schedule(function()
M.open_float(vim.tbl_extend('keep', float_opts, {
- bufnr = vim.api.nvim_win_get_buf(win_id),
+ bufnr = api.nvim_win_get_buf(win_id),
scope = 'cursor',
focus = false,
}))
@@ -613,6 +614,10 @@ end
--- * spacing: (number) Amount of empty spaces inserted at the beginning
--- of the virtual text.
--- * prefix: (string) Prepend diagnostic message with prefix.
+--- * suffix: (string or function) Append diagnostic message with suffix.
+--- If a function, it must have the signature (diagnostic) ->
+--- string, where {diagnostic} is of type |diagnostic-structure|.
+--- This can be used to render an LSP diagnostic error code.
--- * format: (function) A function that takes a diagnostic as input and
--- returns a string. The return value is the text used to display
--- the diagnostic. Example:
@@ -666,13 +671,13 @@ function M.config(opts, namespace)
if namespace then
for bufnr, v in pairs(diagnostic_cache) do
- if vim.api.nvim_buf_is_loaded(bufnr) and v[namespace] then
+ if api.nvim_buf_is_loaded(bufnr) and v[namespace] then
M.show(namespace, bufnr)
end
end
else
for bufnr, v in pairs(diagnostic_cache) do
- if vim.api.nvim_buf_is_loaded(bufnr) then
+ if api.nvim_buf_is_loaded(bufnr) then
for ns in pairs(v) do
M.show(ns, bufnr)
end
@@ -707,11 +712,11 @@ function M.set(namespace, bufnr, diagnostics, opts)
set_diagnostic_cache(namespace, bufnr, diagnostics)
end
- if vim.api.nvim_buf_is_loaded(bufnr) then
+ if api.nvim_buf_is_loaded(bufnr) then
M.show(namespace, bufnr, nil, opts)
end
- vim.api.nvim_exec_autocmds('DiagnosticChanged', {
+ api.nvim_exec_autocmds('DiagnosticChanged', {
modeline = false,
buffer = bufnr,
data = { diagnostics = diagnostics },
@@ -726,7 +731,7 @@ function M.get_namespace(namespace)
vim.validate({ namespace = { namespace, 'n' } })
if not all_namespaces[namespace] then
local name
- for k, v in pairs(vim.api.nvim_get_namespaces()) do
+ for k, v in pairs(api.nvim_get_namespaces()) do
if namespace == v then
name = k
break
@@ -751,6 +756,18 @@ function M.get_namespaces()
return vim.deepcopy(all_namespaces)
end
+---@class Diagnostic
+---@field buffer number
+---@field lnum number 0-indexed
+---@field end_lnum nil|number 0-indexed
+---@field col number 0-indexed
+---@field end_col nil|number 0-indexed
+---@field severity DiagnosticSeverity
+---@field message string
+---@field source nil|string
+---@field code nil|string
+---@field user_data nil|any arbitrary data plugins can add
+
--- Get current diagnostics.
---
---@param bufnr number|nil Buffer number to get diagnostics from. Use 0 for
@@ -759,7 +776,7 @@ end
--- - namespace: (number) Limit diagnostics to the given namespace.
--- - lnum: (number) Limit diagnostics to the given line number.
--- - severity: See |diagnostic-severity|.
----@return table A list of diagnostic items |diagnostic-structure|.
+---@return Diagnostic[] table A list of diagnostic items |diagnostic-structure|.
function M.get(bufnr, opts)
vim.validate({
bufnr = { bufnr, 'n', true },
@@ -771,22 +788,23 @@ end
--- Get the previous diagnostic closest to the cursor position.
---
----@param opts table See |vim.diagnostic.goto_next()|
----@return table Previous diagnostic
+---@param opts nil|table See |vim.diagnostic.goto_next()|
+---@return Diagnostic|nil Previous diagnostic
function M.get_prev(opts)
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)
- local cursor_position = opts.cursor_position or vim.api.nvim_win_get_cursor(win_id)
+ local win_id = opts.win_id or api.nvim_get_current_win()
+ local bufnr = api.nvim_win_get_buf(win_id)
+ local cursor_position = opts.cursor_position or api.nvim_win_get_cursor(win_id)
return next_diagnostic(cursor_position, false, bufnr, opts, opts.namespace)
end
--- Return the position of the previous diagnostic in the current buffer.
---
----@param opts table See |vim.diagnostic.goto_next()|
----@return table Previous diagnostic position as a (row, col) tuple.
+---@param opts table|nil See |vim.diagnostic.goto_next()|
+---@return table|false Previous diagnostic position as a (row, col) tuple or false if there is no
+--- prior diagnostic
function M.get_prev_pos(opts)
local prev = M.get_prev(opts)
if not prev then
@@ -804,22 +822,23 @@ end
--- Get the next diagnostic closest to the cursor position.
---
----@param opts table See |vim.diagnostic.goto_next()|
----@return table Next diagnostic
+---@param opts table|nil See |vim.diagnostic.goto_next()|
+---@return Diagnostic|nil Next diagnostic
function M.get_next(opts)
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)
- local cursor_position = opts.cursor_position or vim.api.nvim_win_get_cursor(win_id)
+ local win_id = opts.win_id or api.nvim_get_current_win()
+ local bufnr = api.nvim_win_get_buf(win_id)
+ local cursor_position = opts.cursor_position or api.nvim_win_get_cursor(win_id)
return next_diagnostic(cursor_position, true, bufnr, opts, opts.namespace)
end
--- Return the position of the next diagnostic in the current buffer.
---
----@param opts table See |vim.diagnostic.goto_next()|
----@return table Next diagnostic position as a (row, col) tuple.
+---@param opts table|nil See |vim.diagnostic.goto_next()|
+---@return table|false Next diagnostic position as a (row, col) tuple or false if no next
+--- diagnostic.
function M.get_next_pos(opts)
local next = M.get_next(opts)
if not next then
@@ -931,7 +950,7 @@ M.handlers.underline = {
local ns = M.get_namespace(namespace)
if not ns.user_data.underline_ns then
- ns.user_data.underline_ns = vim.api.nvim_create_namespace('')
+ ns.user_data.underline_ns = api.nvim_create_namespace('')
end
local underline_ns = ns.user_data.underline_ns
@@ -958,7 +977,7 @@ M.handlers.underline = {
local ns = M.get_namespace(namespace)
if ns.user_data.underline_ns then
diagnostic_cache_extmarks[bufnr][ns.user_data.underline_ns] = {}
- vim.api.nvim_buf_clear_namespace(bufnr, ns.user_data.underline_ns, 0, -1)
+ api.nvim_buf_clear_namespace(bufnr, ns.user_data.underline_ns, 0, -1)
end
end,
}
@@ -997,7 +1016,7 @@ M.handlers.virtual_text = {
local ns = M.get_namespace(namespace)
if not ns.user_data.virt_text_ns then
- ns.user_data.virt_text_ns = vim.api.nvim_create_namespace('')
+ ns.user_data.virt_text_ns = api.nvim_create_namespace('')
end
local virt_text_ns = ns.user_data.virt_text_ns
@@ -1009,7 +1028,7 @@ M.handlers.virtual_text = {
local virt_texts = M._get_virt_text_chunks(line_diagnostics, opts.virtual_text)
if virt_texts then
- vim.api.nvim_buf_set_extmark(bufnr, virt_text_ns, line, 0, {
+ api.nvim_buf_set_extmark(bufnr, virt_text_ns, line, 0, {
hl_mode = 'combine',
virt_text = virt_texts,
})
@@ -1021,7 +1040,7 @@ M.handlers.virtual_text = {
local ns = M.get_namespace(namespace)
if ns.user_data.virt_text_ns then
diagnostic_cache_extmarks[bufnr][ns.user_data.virt_text_ns] = {}
- vim.api.nvim_buf_clear_namespace(bufnr, ns.user_data.virt_text_ns, 0, -1)
+ api.nvim_buf_clear_namespace(bufnr, ns.user_data.virt_text_ns, 0, -1)
end
end,
}
@@ -1039,6 +1058,7 @@ function M._get_virt_text_chunks(line_diags, opts)
opts = opts or {}
local prefix = opts.prefix or '■'
+ local suffix = opts.suffix or ''
local spacing = opts.spacing or 4
-- Create a little more space between virtual text and contents
@@ -1052,8 +1072,11 @@ function M._get_virt_text_chunks(line_diags, opts)
-- TODO(tjdevries): Allow different servers to be shown first somehow?
-- TODO(tjdevries): Display server name associated with these?
if last.message then
+ if type(suffix) == 'function' then
+ suffix = suffix(last) or ''
+ end
table.insert(virt_texts, {
- string.format('%s %s', prefix, last.message:gsub('\r', ''):gsub('\n', ' ')),
+ string.format('%s %s%s', prefix, last.message:gsub('\r', ''):gsub('\n', ' '), suffix),
virtual_text_highlight_map[last.severity],
})
@@ -1153,7 +1176,7 @@ function M.show(namespace, bufnr, diagnostics, opts)
if opts.update_in_insert then
clear_scheduled_display(namespace, bufnr)
else
- local mode = vim.api.nvim_get_mode()
+ local mode = api.nvim_get_mode()
if string.sub(mode.mode, 1, 1) == 'i' then
schedule_display(namespace, bufnr, opts)
return
@@ -1220,7 +1243,9 @@ end
--- string, it is prepended to each diagnostic in the window with no
--- highlight.
--- Overrides the setting from |vim.diagnostic.config()|.
----@return tuple ({float_bufnr}, {win_id})
+--- - suffix: Same as {prefix}, but appends the text to the diagnostic instead of
+--- prepending it. Overrides the setting from |vim.diagnostic.config()|.
+---@return number|nil, number|nil: ({float_bufnr}, {win_id})
function M.open_float(opts, ...)
-- Support old (bufnr, opts) signature
local bufnr
@@ -1251,7 +1276,7 @@ function M.open_float(opts, ...)
local lnum, col
if scope == 'line' or scope == 'cursor' then
if not opts.pos then
- local pos = vim.api.nvim_win_get_cursor(0)
+ local pos = api.nvim_win_get_cursor(0)
lnum = pos[1] - 1
col = pos[2]
elseif type(opts.pos) == 'number' then
@@ -1273,7 +1298,7 @@ function M.open_float(opts, ...)
end, diagnostics)
elseif scope == 'cursor' then
-- LSP servers can send diagnostics with `end_col` past the length of the line
- local line_length = #vim.api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1]
+ local line_length = #api.nvim_buf_get_lines(bufnr, lnum, lnum + 1, true)[1]
diagnostics = vim.tbl_filter(function(d)
return d.lnum == lnum
and math.min(d.col, line_length - 1) <= col
@@ -1305,9 +1330,7 @@ function M.open_float(opts, ...)
vim.validate({
header = {
header,
- function(v)
- return type(v) == 'string' or type(v) == 'table'
- end,
+ { 'string', 'table' },
"'string' or 'table'",
},
})
@@ -1315,11 +1338,11 @@ function M.open_float(opts, ...)
-- Don't insert any lines for an empty string
if string.len(if_nil(header[1], '')) > 0 then
table.insert(lines, header[1])
- table.insert(highlights, { 0, header[2] or 'Bold' })
+ table.insert(highlights, { hlname = header[2] or 'Bold' })
end
elseif #header > 0 then
table.insert(lines, header)
- table.insert(highlights, { 0, 'Bold' })
+ table.insert(highlights, { hlname = 'Bold' })
end
end
@@ -1341,9 +1364,7 @@ function M.open_float(opts, ...)
vim.validate({
prefix = {
prefix_opt,
- function(v)
- return type(v) == 'string' or type(v) == 'table' or type(v) == 'function'
- end,
+ { 'string', 'table', 'function' },
"'string' or 'table' or 'function'",
},
})
@@ -1354,18 +1375,52 @@ function M.open_float(opts, ...)
end
end
+ local suffix_opt = if_nil(opts.suffix, function(diagnostic)
+ return diagnostic.code and string.format(' [%s]', diagnostic.code) or ''
+ end)
+
+ local suffix, suffix_hl_group
+ if suffix_opt then
+ vim.validate({
+ suffix = {
+ suffix_opt,
+ { 'string', 'table', 'function' },
+ "'string' or 'table' or 'function'",
+ },
+ })
+ if type(suffix_opt) == 'string' then
+ suffix, suffix_hl_group = suffix_opt, 'NormalFloat'
+ elseif type(suffix_opt) == 'table' then
+ suffix, suffix_hl_group = suffix_opt[1] or '', suffix_opt[2] or 'NormalFloat'
+ end
+ end
+
for i, diagnostic in ipairs(diagnostics) do
if prefix_opt and type(prefix_opt) == 'function' then
prefix, prefix_hl_group = prefix_opt(diagnostic, i, #diagnostics)
prefix, prefix_hl_group = prefix or '', prefix_hl_group or 'NormalFloat'
end
+ if suffix_opt and type(suffix_opt) == 'function' then
+ suffix, suffix_hl_group = suffix_opt(diagnostic, i, #diagnostics)
+ suffix, suffix_hl_group = suffix or '', suffix_hl_group or 'NormalFloat'
+ end
local hiname = floating_highlight_map[diagnostic.severity]
local message_lines = vim.split(diagnostic.message, '\n')
- table.insert(lines, prefix .. message_lines[1])
- table.insert(highlights, { #prefix, hiname, prefix_hl_group })
- for j = 2, #message_lines do
- table.insert(lines, string.rep(' ', #prefix) .. message_lines[j])
- table.insert(highlights, { 0, hiname })
+ for j = 1, #message_lines do
+ local pre = j == 1 and prefix or string.rep(' ', #prefix)
+ local suf = j == #message_lines and suffix or ''
+ table.insert(lines, pre .. message_lines[j] .. suf)
+ table.insert(highlights, {
+ hlname = hiname,
+ prefix = {
+ length = j == 1 and #prefix or 0,
+ hlname = prefix_hl_group,
+ },
+ suffix = {
+ length = j == #message_lines and #suffix or 0,
+ hlname = suffix_hl_group,
+ },
+ })
end
end
@@ -1374,12 +1429,17 @@ function M.open_float(opts, ...)
opts.focus_id = scope
end
local float_bufnr, winnr = require('vim.lsp.util').open_floating_preview(lines, 'plaintext', opts)
- for i, hi in ipairs(highlights) do
- local prefixlen, hiname, prefix_hiname = unpack(hi)
- if prefix_hiname then
- vim.api.nvim_buf_add_highlight(float_bufnr, -1, prefix_hiname, i - 1, 0, prefixlen)
+ for i, hl in ipairs(highlights) do
+ local line = lines[i]
+ local prefix_len = hl.prefix and hl.prefix.length or 0
+ local suffix_len = hl.suffix and hl.suffix.length or 0
+ if prefix_len > 0 then
+ api.nvim_buf_add_highlight(float_bufnr, -1, hl.prefix.hlname, i - 1, 0, prefix_len)
+ end
+ api.nvim_buf_add_highlight(float_bufnr, -1, hl.hlname, i - 1, prefix_len, #line - suffix_len)
+ if suffix_len > 0 then
+ api.nvim_buf_add_highlight(float_bufnr, -1, hl.suffix.hlname, i - 1, #line - suffix_len, -1)
end
- vim.api.nvim_buf_add_highlight(float_bufnr, -1, hiname, i - 1, prefixlen, -1)
end
return float_bufnr, winnr
@@ -1410,7 +1470,7 @@ function M.reset(namespace, bufnr)
M.hide(iter_namespace, iter_bufnr)
end
- vim.api.nvim_exec_autocmds('DiagnosticChanged', {
+ api.nvim_exec_autocmds('DiagnosticChanged', {
modeline = false,
buffer = iter_bufnr,
data = { diagnostics = {} },
@@ -1533,7 +1593,7 @@ end
---@param defaults table|nil Table of default values for any fields not listed in {groups}.
--- When omitted, numeric values default to 0 and "severity" defaults to
--- ERROR.
----@return diagnostic |diagnostic-structure| or `nil` if {pat} fails to match {str}.
+---@return Diagnostic|nil: |diagnostic-structure| or `nil` if {pat} fails to match {str}.
function M.match(str, pat, groups, severity_map, defaults)
vim.validate({
str = { str, 's' },
@@ -1580,7 +1640,7 @@ local errlist_type_map = {
--- passed to |setqflist()| or |setloclist()|.
---
---@param diagnostics table List of diagnostics |diagnostic-structure|.
----@return array of quickfix list items |setqflist-what|
+---@return table[] of quickfix list items |setqflist-what|
function M.toqflist(diagnostics)
vim.validate({
diagnostics = {
@@ -1617,7 +1677,7 @@ end
---
---@param list table A list of quickfix items from |getqflist()| or
--- |getloclist()|.
----@return array of diagnostics |diagnostic-structure|
+---@return Diagnostic[] array of |diagnostic-structure|
function M.fromqflist(list)
vim.validate({
list = {
diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua
index 5aa968e211..1cc9beecc6 100644
--- a/runtime/lua/vim/filetype.lua
+++ b/runtime/lua/vim/filetype.lua
@@ -257,6 +257,7 @@ local extension = {
cc = function(path, bufnr)
return vim.g.cynlib_syntax_for_cc and 'cynlib' or 'cpp'
end,
+ cql = 'cqlang',
crm = 'crm',
csx = 'cs',
cs = 'cs',
@@ -658,6 +659,9 @@ local extension = {
dmt = 'maxima',
wxm = 'maxima',
mel = 'mel',
+ mmd = 'mermaid',
+ mmdc = 'mermaid',
+ mermaid = 'mermaid',
mf = 'mf',
mgl = 'mgl',
mgp = 'mgp',
diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua
index 7bd635d8b6..c7c053852d 100644
--- a/runtime/lua/vim/fs.lua
+++ b/runtime/lua/vim/fs.lua
@@ -79,11 +79,12 @@ end
---@param names (string|table|fun(name: string): boolean) Names of the files
--- and directories to find.
--- Must be base names, paths and globs are not supported.
---- If a function it is called per file and dir within the
---- traversed directories to test if they match.
+--- The function is called per file and directory within the
+--- traversed directories to test if they match {names}.
+---
---@param opts (table) Optional keyword arguments:
--- - path (string): Path to begin searching from. If
---- omitted, the current working directory is used.
+--- omitted, the |current-directory| is used.
--- - upward (boolean, default false): If true, search
--- upward through parent directories. Otherwise,
--- search through child directories
@@ -92,12 +93,13 @@ end
--- reached. The directory itself is not searched.
--- - type (string): Find only files ("file") or
--- directories ("directory"). If omitted, both
---- files and directories that match {name} are
+--- files and directories that match {names} are
--- included.
--- - limit (number, default 1): Stop the search after
--- finding this many matches. Use `math.huge` to
--- place no limit on the number of matches.
----@return (table) The paths of all matching files or directories
+---
+---@return (table) The normalized paths |vim.fs.normalize()| of all matching files or directories
function M.find(names, opts)
opts = opts or {}
vim.validate({
@@ -211,16 +213,16 @@ end
--- backslash (\\) characters are converted to forward slashes (/). Environment
--- variables are also expanded.
---
---- Example:
+--- Examples:
--- <pre>
---- vim.fs.normalize('C:\\Users\\jdoe')
---- => 'C:/Users/jdoe'
+--- vim.fs.normalize('C:\\Users\\jdoe')
+--- => 'C:/Users/jdoe'
---
---- vim.fs.normalize('~/src/neovim')
---- => '/home/jdoe/src/neovim'
+--- vim.fs.normalize('~/src/neovim')
+--- => '/home/jdoe/src/neovim'
---
---- vim.fs.normalize('$XDG_CONFIG_HOME/nvim/init.vim')
---- => '/Users/jdoe/.config/nvim/init.vim'
+--- vim.fs.normalize('$XDG_CONFIG_HOME/nvim/init.vim')
+--- => '/Users/jdoe/.config/nvim/init.vim'
--- </pre>
---
---@param path (string) Path to normalize
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index c648a53555..39e2577294 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -81,22 +81,38 @@ M['window/workDoneProgress/create'] = function(_, result, ctx)
end
--see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_showMessageRequest
+---@param result lsp.ShowMessageRequestParams
M['window/showMessageRequest'] = function(_, result)
- local actions = result.actions
- print(result.message)
- local option_strings = { result.message, '\nRequest Actions:' }
- for i, action in ipairs(actions) do
- local title = action.title:gsub('\r\n', '\\r\\n')
- title = title:gsub('\n', '\\n')
- table.insert(option_strings, string.format('%d. %s', i, title))
- end
-
- -- window/showMessageRequest can return either MessageActionItem[] or null.
- local choice = vim.fn.inputlist(option_strings)
- if choice < 1 or choice > #actions then
- return vim.NIL
+ local actions = result.actions or {}
+ local co, is_main = coroutine.running()
+ if co and not is_main then
+ local opts = {
+ prompt = result.message .. ': ',
+ format_item = function(action)
+ return (action.title:gsub('\r\n', '\\r\\n')):gsub('\n', '\\n')
+ end,
+ }
+ vim.ui.select(actions, opts, function(choice)
+ -- schedule to ensure resume doesn't happen _before_ yield with
+ -- default synchronous vim.ui.select
+ vim.schedule(function()
+ coroutine.resume(co, choice or vim.NIL)
+ end)
+ end)
+ return coroutine.yield()
else
- return actions[choice]
+ local option_strings = { result.message, '\nRequest Actions:' }
+ for i, action in ipairs(actions) do
+ local title = action.title:gsub('\r\n', '\\r\\n')
+ title = title:gsub('\n', '\\n')
+ table.insert(option_strings, string.format('%d. %s', i, title))
+ end
+ local choice = vim.fn.inputlist(option_strings)
+ if choice < 1 or choice > #actions then
+ return vim.NIL
+ else
+ return actions[choice]
+ end
end
end
@@ -301,7 +317,9 @@ end
--- vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(
--- vim.lsp.handlers.hover, {
--- -- Use a sharp border with `FloatBorder` highlights
---- border = "single"
+--- border = "single",
+--- -- add the title in hover float window
+--- title = "hover"
--- }
--- )
--- </pre>
@@ -312,6 +330,10 @@ end
function M.hover(_, result, ctx, config)
config = config or {}
config.focus_id = ctx.method
+ if api.nvim_get_current_buf() ~= ctx.bufnr then
+ -- Ignore result since buffer changed. This happens for slow language servers.
+ return
+ end
if not (result and result.contents) then
vim.notify('No information available')
return
@@ -392,6 +414,10 @@ M['textDocument/implementation'] = location_handler
function M.signature_help(_, result, ctx, config)
config = config or {}
config.focus_id = ctx.method
+ if api.nvim_get_current_buf() ~= ctx.bufnr then
+ -- Ignore result since buffer changed. This happens for slow language servers.
+ return
+ end
-- When use `autocmd CompleteDone <silent><buffer> lua vim.lsp.buf.signature_help()` to call signatureHelp handler
-- If the completion item doesn't have signatures It will make noise. Change to use `print` that can use `<silent>` to ignore
if not (result and result.signatures and result.signatures[1]) then
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index 7442c8f005..8dc93b3b67 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -20,6 +20,14 @@ function transform_schema_to_table()
end
--]=]
+---@class lsp.ShowMessageRequestParams
+---@field type lsp.MessageType
+---@field message string
+---@field actions nil|lsp.MessageActionItem[]
+
+---@class lsp.MessageActionItem
+---@field title string
+
local constants = {
DiagnosticSeverity = {
-- Reports an error.
@@ -39,6 +47,7 @@ local constants = {
Deprecated = 2,
},
+ ---@enum lsp.MessageType
MessageType = {
-- An error message.
Error = 1,
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua
index ff62623544..b93b227150 100644
--- a/runtime/lua/vim/lsp/rpc.lua
+++ b/runtime/lua/vim/lsp/rpc.lua
@@ -391,44 +391,46 @@ function Client:handle_body(body)
-- Schedule here so that the users functions don't trigger an error and
-- we can still use the result.
schedule(function()
- local status, result
- status, result, err = self:try_call(
- client_errors.SERVER_REQUEST_HANDLER_ERROR,
- self.dispatchers.server_request,
- decoded.method,
- decoded.params
- )
- local _ = log.debug()
- and log.debug(
- 'server_request: callback result',
- { status = status, result = result, err = err }
+ coroutine.wrap(function()
+ local status, result
+ status, result, err = self:try_call(
+ client_errors.SERVER_REQUEST_HANDLER_ERROR,
+ self.dispatchers.server_request,
+ decoded.method,
+ decoded.params
)
- if status then
- if result == nil and err == nil then
- error(
- string.format(
- 'method %q: either a result or an error must be sent to the server in response',
- decoded.method
- )
- )
- end
- if err then
- assert(
- type(err) == 'table',
- 'err must be a table. Use rpc_response_error to help format errors.'
- )
- local code_name = assert(
- protocol.ErrorCodes[err.code],
- 'Errors must use protocol.ErrorCodes. Use rpc_response_error to help format errors.'
+ local _ = log.debug()
+ and log.debug(
+ 'server_request: callback result',
+ { status = status, result = result, err = err }
)
- err.message = err.message or code_name
+ if status then
+ if result == nil and err == nil then
+ error(
+ string.format(
+ 'method %q: either a result or an error must be sent to the server in response',
+ decoded.method
+ )
+ )
+ end
+ if err then
+ assert(
+ type(err) == 'table',
+ 'err must be a table. Use rpc_response_error to help format errors.'
+ )
+ local code_name = assert(
+ protocol.ErrorCodes[err.code],
+ 'Errors must use protocol.ErrorCodes. Use rpc_response_error to help format errors.'
+ )
+ err.message = err.message or code_name
+ end
+ else
+ -- On an exception, result will contain the error message.
+ err = rpc_response_error(protocol.ErrorCodes.InternalError, result)
+ result = nil
end
- else
- -- On an exception, result will contain the error message.
- err = rpc_response_error(protocol.ErrorCodes.InternalError, result)
- result = nil
- end
- self:send_response(decoded.id, err, result)
+ self:send_response(decoded.id, err, result)
+ end)()
end)
-- This works because we are expecting vim.NIL here
elseif decoded.id and (decoded.result ~= vim.NIL or decoded.error ~= vim.NIL) then
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index b0f9c1660e..d89757ef0c 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -1050,6 +1050,13 @@ function M.make_floating_popup_options(width, height, opts)
col = 1
end
+ local title = (opts.border and opts.title) and opts.title or nil
+ local title_pos
+
+ if title then
+ title_pos = opts.title_pos or 'center'
+ end
+
return {
anchor = anchor,
col = col + (opts.offset_x or 0),
@@ -1061,6 +1068,8 @@ function M.make_floating_popup_options(width, height, opts)
width = width,
border = opts.border or default_border,
zindex = opts.zindex or 50,
+ title = title,
+ title_pos = title_pos,
}
end
diff --git a/runtime/lua/vim/secure.lua b/runtime/lua/vim/secure.lua
new file mode 100644
index 0000000000..341ff8df05
--- /dev/null
+++ b/runtime/lua/vim/secure.lua
@@ -0,0 +1,106 @@
+local M = {}
+
+--- Attempt to read the file at {path} prompting the user if the file should be
+--- trusted. The user's choice is persisted in a trust database at
+--- $XDG_STATE_HOME/nvim/trust.
+---
+---@param path (string) Path to a file to read.
+---
+---@return (string|nil) The contents of the given file if it exists and is
+--- trusted, or nil otherwise.
+function M.read(path)
+ vim.validate({ path = { path, 's' } })
+ local fullpath = vim.loop.fs_realpath(vim.fs.normalize(path))
+ if not fullpath then
+ return nil
+ end
+
+ local trust = {}
+ do
+ local f = io.open(vim.fn.stdpath('state') .. '/trust', 'r')
+ if f then
+ local contents = f:read('*a')
+ if contents then
+ for line in vim.gsplit(contents, '\n') do
+ local hash, file = string.match(line, '^(%S+) (.+)$')
+ if hash and file then
+ trust[file] = hash
+ end
+ end
+ end
+ f:close()
+ end
+ end
+
+ if trust[fullpath] == '!' then
+ -- File is denied
+ return nil
+ end
+
+ local contents
+ do
+ local f = io.open(fullpath, 'r')
+ if not f then
+ return nil
+ end
+ contents = f:read('*a')
+ f:close()
+ end
+
+ local hash = vim.fn.sha256(contents)
+ if trust[fullpath] == hash then
+ -- File already exists in trust database
+ return contents
+ end
+
+ -- File either does not exist in trust database or the hash does not match
+ local choice = vim.fn.confirm(
+ string.format('%s is not trusted.', fullpath),
+ '&ignore\n&view\n&deny\n&allow',
+ 1
+ )
+
+ if choice == 0 or choice == 1 then
+ -- Cancelled or ignored
+ return nil
+ elseif choice == 2 then
+ -- View
+ vim.cmd('new')
+ local buf = vim.api.nvim_get_current_buf()
+ local lines = vim.split(string.gsub(contents, '\n$', ''), '\n')
+ vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
+ vim.bo[buf].bufhidden = 'hide'
+ vim.bo[buf].buftype = 'nofile'
+ vim.bo[buf].swapfile = false
+ vim.bo[buf].modeline = false
+ vim.bo[buf].buflisted = false
+ vim.bo[buf].readonly = true
+ vim.bo[buf].modifiable = false
+ return nil
+ elseif choice == 3 then
+ -- Deny
+ trust[fullpath] = '!'
+ contents = nil
+ elseif choice == 4 then
+ -- Allow
+ trust[fullpath] = hash
+ end
+
+ do
+ local f, err = io.open(vim.fn.stdpath('state') .. '/trust', 'w')
+ if not f then
+ error(err)
+ end
+
+ local t = {}
+ for p, h in pairs(trust) do
+ t[#t + 1] = string.format('%s %s\n', h, p)
+ end
+ f:write(table.concat(t))
+ f:close()
+ end
+
+ return contents
+end
+
+return M
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index db21066819..23562c6830 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -1,7 +1,7 @@
" These commands create the option window.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2022 Oct 28
+" Last Change: 2022 Nov 23
" If there already is an option window, jump to that one.
let buf = bufnr('option-window')
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index bfece6aa72..99fd7dba42 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -2,7 +2,7 @@
"
" Author: Bram Moolenaar
" Copyright: Vim license applies, see ":help license"
-" Last Change: 2022 Jun 24
+" Last Change: 2022 Nov 10
"
" WORK IN PROGRESS - The basics works stable, more to come
" Note: In general you need at least GDB 7.12 because this provides the
@@ -154,10 +154,16 @@ func s:StartDebug_internal(dict)
let s:save_columns = 0
let s:allleft = 0
- if exists('g:termdebug_wide')
- if &columns < g:termdebug_wide
+ let wide = 0
+ if exists('g:termdebug_config')
+ let wide = get(g:termdebug_config, 'wide', 0)
+ elseif exists('g:termdebug_wide')
+ let wide = g:termdebug_wide
+ endif
+ if wide > 0
+ if &columns < wide
let s:save_columns = &columns
- let &columns = g:termdebug_wide
+ let &columns = wide
" If we make the Vim window wider, use the whole left half for the debug
" windows.
let s:allleft = 1
@@ -168,7 +174,12 @@ func s:StartDebug_internal(dict)
endif
" Override using a terminal window by setting g:termdebug_use_prompt to 1.
- let use_prompt = exists('g:termdebug_use_prompt') && g:termdebug_use_prompt
+ let use_prompt = 0
+ if exists('g:termdebug_config')
+ let use_prompt = get(g:termdebug_config, 'use_prompt', 0)
+ elseif exists('g:termdebug_use_prompt')
+ let use_prompt = g:termdebug_use_prompt
+ endif
if !has('win32') && !use_prompt
let s:way = 'terminal'
else
@@ -903,7 +914,14 @@ func s:InstallCommands()
endif
if has('menu') && &mouse != ''
- call s:InstallWinbar()
+ " install the window toolbar by default, can be disabled in the config
+ let winbar = 1
+ if exists('g:termdebug_config')
+ let winbar = get(g:termdebug_config, 'winbar', 1)
+ endif
+ if winbar
+ call s:InstallWinbar()
+ endif
let popup = 1
if exists('g:termdebug_config')
diff --git a/runtime/queries/vim/highlights.scm b/runtime/queries/vim/highlights.scm
index 3d1729b2cd..239b0a0b37 100644
--- a/runtime/queries/vim/highlights.scm
+++ b/runtime/queries/vim/highlights.scm
@@ -36,7 +36,8 @@
;; Function related
(function_declaration name: (_) @function)
-(call_expression function: (identifier) @function)
+(call_expression function: (identifier) @function.call)
+(call_expression function: (scoped_identifier (identifier) @function.call))
(parameters (identifier) @parameter)
(default_parameter (identifier) @parameter)
@@ -59,14 +60,20 @@
"execute"
"normal"
"set"
+ "setfiletype"
"setlocal"
"silent"
"echo"
+ "echon"
+ "echohl"
"echomsg"
+ "echoerr"
"autocmd"
"augroup"
"return"
"syntax"
+ "filetype"
+ "source"
"lua"
"ruby"
"perl"
@@ -98,10 +105,21 @@
"ex"
"visual"
"view"
+ "eval"
] @keyword
(map_statement cmd: _ @keyword)
(command_name) @function.macro
+;; Filetype command
+
+(filetype_statement [
+ "detect"
+ "plugin"
+ "indent"
+ "on"
+ "off"
+] @keyword)
+
;; Syntax command
(syntax_statement (keyword) @string)
@@ -118,6 +136,8 @@
"match"
"cluster"
"region"
+ "clear"
+ "include"
] @keyword)
(syntax_argument name: _ @keyword)
@@ -175,15 +195,18 @@
;; Literals
-(string_literal) @string @spell
+(string_literal) @string
(integer_literal) @number
(float_literal) @float
(comment) @comment @spell
+(line_continuation_comment) @comment @spell
(pattern) @string.special
(pattern_multi) @string.regex
(filename) @string
(heredoc (body) @string)
-((heredoc (parameter) @keyword))
+(heredoc (parameter) @keyword)
+[ (marker_definition) (endmarker) ] @label
+(literal_dictionary (literal_key) @label)
((scoped_identifier
(scope) @_scope . (identifier) @boolean)
(#eq? @_scope "v:")
@@ -219,12 +242,16 @@
"%="
".="
"..="
+ "<<"
+ "=<<"
+ (match_case)
] @operator
; Some characters have different meanings based on the context
(unary_operation "!" @operator)
(binary_operation "." @operator)
+
;; Punctuation
[
@@ -234,6 +261,7 @@
"}"
"["
"]"
+ "#{"
] @punctuation.bracket
(field_expression "." @punctuation.delimiter)
@@ -249,6 +277,9 @@
((set_value) @number
(#match? @number "^[0-9]+(\.[0-9]+)?$"))
+(inv_option "!" @operator)
+(set_item "?" @operator)
+
((set_item
option: (option_name) @_option
value: (set_value) @function)
diff --git a/runtime/queries/vim/injections.scm b/runtime/queries/vim/injections.scm
index e2dea8fe75..fdd025bfd9 100644
--- a/runtime/queries/vim/injections.scm
+++ b/runtime/queries/vim/injections.scm
@@ -1,13 +1,14 @@
(lua_statement (script (body) @lua))
(lua_statement (chunk) @lua)
-; (ruby_statement (script (body) @ruby))
-; (ruby_statement (chunk) @ruby)
-; (python_statement (script (body) @python))
-; (python_statement (chunk) @python)
+(ruby_statement (script (body) @ruby))
+(ruby_statement (chunk) @ruby)
+(python_statement (script (body) @python))
+(python_statement (chunk) @python)
+;; If we support perl at some point...
;; (perl_statement (script (body) @perl))
;; (perl_statement (chunk) @perl)
-; (autocmd_statement (pattern) @regex)
+(autocmd_statement (pattern) @regex)
((set_item
option: (option_name) @_option
@@ -23,4 +24,5 @@
"patchexpr" "pex"
"charconvert" "ccv"))
-; (comment) @comment
+(comment) @comment
+(line_continuation_comment) @comment
diff --git a/runtime/syntax/go.vim b/runtime/syntax/go.vim
index 0c326254b8..904c8ad7f2 100644
--- a/runtime/syntax/go.vim
+++ b/runtime/syntax/go.vim
@@ -5,7 +5,7 @@
" go.vim: Vim syntax file for Go.
" Language: Go
" Maintainer: Billie Cleek <bhcleek@gmail.com>
-" Latest Revision: 2021-09-18
+" Latest Revision: 2022-11-17
" License: BSD-style. See LICENSE file in source repository.
" Repository: https://github.com/fatih/vim-go
@@ -117,7 +117,7 @@ hi def link goLabel Label
hi def link goRepeat Repeat
" Predefined types
-syn keyword goType chan map bool string error
+syn keyword goType chan map bool string error any comparable
syn keyword goSignedInts int int8 int16 int32 int64 rune
syn keyword goUnsignedInts byte uint uint8 uint16 uint32 uint64 uintptr
syn keyword goFloats float32 float64
@@ -187,6 +187,8 @@ else
syn region goRawString start=+`+ end=+`+
endif
+syn match goImportString /^\%(\s\+\|import \)\(\h\w* \)\?\zs"[^"]\+"$/ contained containedin=goImport
+
if s:HighlightFormatStrings()
" [n] notation is valid for specifying explicit argument indexes
" 1. Match a literal % not preceded by a %.
@@ -204,6 +206,7 @@ if s:HighlightFormatStrings()
hi def link goFormatSpecifier goSpecialString
endif
+hi def link goImportString String
hi def link goString String
hi def link goRawString String
@@ -223,9 +226,9 @@ endif
" import
if s:FoldEnable('import')
- syn region goImport start='import (' end=')' transparent fold contains=goImport,goString,goComment
+ syn region goImport start='import (' end=')' transparent fold contains=goImport,goImportString,goComment
else
- syn region goImport start='import (' end=')' transparent contains=goImport,goString,goComment
+ syn region goImport start='import (' end=')' transparent contains=goImport,goImportString,goComment
endif
" var, const
@@ -245,14 +248,10 @@ endif
syn match goSingleDecl /\%(import\|var\|const\) [^(]\@=/ contains=goImport,goVar,goConst
" Integers
-syn match goDecimalInt "\<-\=\(0\|[1-9]_\?\(\d\|\d\+_\?\d\+\)*\)\%([Ee][-+]\=\d\+\)\=\>"
-syn match goDecimalError "\<-\=\(_\(\d\+_*\)\+\|\([1-9]\d*_*\)\+__\(\d\+_*\)\+\|\([1-9]\d*_*\)\+_\+\)\%([Ee][-+]\=\d\+\)\=\>"
-syn match goHexadecimalInt "\<-\=0[xX]_\?\(\x\+_\?\)\+\>"
-syn match goHexadecimalError "\<-\=0[xX]_\?\(\x\+_\?\)*\(\([^ \t0-9A-Fa-f_)]\|__\)\S*\|_\)\>"
-syn match goOctalInt "\<-\=0[oO]\?_\?\(\o\+_\?\)\+\>"
-syn match goOctalError "\<-\=0[0-7oO_]*\(\([^ \t0-7oOxX_/)\]\}\:;]\|[oO]\{2,\}\|__\)\S*\|_\|[oOxX]\)\>"
-syn match goBinaryInt "\<-\=0[bB]_\?\([01]\+_\?\)\+\>"
-syn match goBinaryError "\<-\=0[bB]_\?[01_]*\([^ \t01_)]\S*\|__\S*\|_\)\>"
+syn match goDecimalInt "\<-\=\%(0\|\%(\d\|\d_\d\)\+\)\>"
+syn match goHexadecimalInt "\<-\=0[xX]_\?\%(\x\|\x_\x\)\+\>"
+syn match goOctalInt "\<-\=0[oO]\?_\?\%(\o\|\o_\o\)\+\>"
+syn match goBinaryInt "\<-\=0[bB]_\?\%([01]\|[01]_[01]\)\+\>"
hi def link goDecimalInt Integer
hi def link goDecimalError Error
@@ -265,19 +264,55 @@ hi def link goBinaryError Error
hi def link Integer Number
" Floating point
-syn match goFloat "\<-\=\d\+\.\d*\%([Ee][-+]\=\d\+\)\=\>"
-syn match goFloat "\<-\=\.\d\+\%([Ee][-+]\=\d\+\)\=\>"
+"float_lit = decimal_float_lit | hex_float_lit .
+"
+"decimal_float_lit = decimal_digits "." [ decimal_digits ] [ decimal_exponent ] |
+" decimal_digits decimal_exponent |
+" "." decimal_digits [ decimal_exponent ] .
+"decimal_exponent = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
+"
+"hex_float_lit = "0" ( "x" | "X" ) hex_mantissa hex_exponent .
+"hex_mantissa = [ "_" ] hex_digits "." [ hex_digits ] |
+" [ "_" ] hex_digits |
+" "." hex_digits .
+"hex_exponent = ( "p" | "P" ) [ "+" | "-" ] decimal_digits .
+" decimal floats with a decimal point
+syn match goFloat "\<-\=\%(0\|\%(\d\|\d_\d\)\+\)\.\%(\%(\%(\d\|\d_\d\)\+\)\=\%([Ee][-+]\=\%(\d\|\d_\d\)\+\)\=\>\)\="
+syn match goFloat "\s\zs-\=\.\%(\d\|\d_\d\)\+\%(\%([Ee][-+]\=\%(\d\|\d_\d\)\+\)\>\)\="
+" decimal floats without a decimal point
+syn match goFloat "\<-\=\%(0\|\%(\d\|\d_\d\)\+\)[Ee][-+]\=\%(\d\|\d_\d\)\+\>"
+" hexadecimal floats with a decimal point
+syn match goHexadecimalFloat "\<-\=0[xX]\%(_\x\|\x\)\+\.\%(\%(\x\|\x_\x\)\+\)\=\%([Pp][-+]\=\%(\d\|\d_\d\)\+\)\=\>"
+syn match goHexadecimalFloat "\<-\=0[xX]\.\%(\x\|\x_\x\)\+\%([Pp][-+]\=\%(\d\|\d_\d\)\+\)\=\>"
+" hexadecimal floats without a decimal point
+syn match goHexadecimalFloat "\<-\=0[xX]\%(_\x\|\x\)\+[Pp][-+]\=\%(\d\|\d_\d\)\+\>"
hi def link goFloat Float
+hi def link goHexadecimalFloat Float
" Imaginary literals
-syn match goImaginary "\<-\=\d\+i\>"
-syn match goImaginary "\<-\=\d\+[Ee][-+]\=\d\+i\>"
-syn match goImaginaryFloat "\<-\=\d\+\.\d*\%([Ee][-+]\=\d\+\)\=i\>"
-syn match goImaginaryFloat "\<-\=\.\d\+\%([Ee][-+]\=\d\+\)\=i\>"
-
-hi def link goImaginary Number
-hi def link goImaginaryFloat Float
+syn match goImaginaryDecimal "\<-\=\%(0\|\%(\d\|\d_\d\)\+\)i\>"
+syn match goImaginaryHexadecimal "\<-\=0[xX]_\?\%(\x\|\x_\x\)\+i\>"
+syn match goImaginaryOctal "\<-\=0[oO]\?_\?\%(\o\|\o_\o\)\+i\>"
+syn match goImaginaryBinary "\<-\=0[bB]_\?\%([01]\|[01]_[01]\)\+i\>"
+
+" imaginary decimal floats with a decimal point
+syn match goImaginaryFloat "\<-\=\%(0\|\%(\d\|\d_\d\)\+\)\.\%(\%(\%(\d\|\d_\d\)\+\)\=\%([Ee][-+]\=\%(\d\|\d_\d\)\+\)\=\)\=i\>"
+syn match goImaginaryFloat "\s\zs-\=\.\%(\d\|\d_\d\)\+\%([Ee][-+]\=\%(\d\|\d_\d\)\+\)\=i\>"
+" imaginary decimal floats without a decimal point
+syn match goImaginaryFloat "\<-\=\%(0\|\%(\d\|\d_\d\)\+\)[Ee][-+]\=\%(\d\|\d_\d\)\+i\>"
+" imaginary hexadecimal floats with a decimal point
+syn match goImaginaryHexadecimalFloat "\<-\=0[xX]\%(_\x\|\x\)\+\.\%(\%(\x\|\x_\x\)\+\)\=\%([Pp][-+]\=\%(\d\|\d_\d\)\+\)\=i\>"
+syn match goImaginaryHexadecimalFloat "\<-\=0[xX]\.\%(\x\|\x_\x\)\+\%([Pp][-+]\=\%(\d\|\d_\d\)\+\)\=i\>"
+" imaginary hexadecimal floats without a decimal point
+syn match goImaginaryHexadecimalFloat "\<-\=0[xX]\%(_\x\|\x\)\+[Pp][-+]\=\%(\d\|\d_\d\)\+i\>"
+
+hi def link goImaginaryDecimal Number
+hi def link goImaginaryHexadecimal Number
+hi def link goImaginaryOctal Number
+hi def link goImaginaryBinary Number
+hi def link goImaginaryFloat Float
+hi def link goImaginaryHexadecimalFloat Float
" Spaces after "[]"
if s:HighlightArrayWhitespaceError()
@@ -346,6 +381,8 @@ if s:HighlightOperators()
syn match goOperator /\%(<<\|>>\|&^\)=\?/
" match remaining two-char operators: := && || <- ++ --
syn match goOperator /:=\|||\|<-\|++\|--/
+ " match ~
+ syn match goOperator /\~/
" match ...
hi def link goPointerOperator goOperator
@@ -353,13 +390,37 @@ if s:HighlightOperators()
endif
hi def link goOperator Operator
+" -> type constraint opening bracket
+" |-> start non-counting group
+" || -> any word character
+" || | -> at least one, as many as possible
+" || | | -> start non-counting group
+" || | | | -> match ~
+" || | | | | -> at most once
+" || | | | | | -> allow a slice type
+" || | | | | | | -> any word character
+" || | | | | | | | -> start a non-counting group
+" || | | | | | | | | -> that matches word characters and |
+" || | | | | | | | | | -> close the non-counting group
+" || | | | | | | | | | | -> close the non-counting group
+" || | | | | | | | | | | |-> any number of matches
+" || | | | | | | | | | | || -> start a non-counting group
+" || | | | | | | | | | | || | -> a comma and whitespace
+" || | | | | | | | | | | || | | -> at most once
+" || | | | | | | | | | | || | | | -> close the non-counting group
+" || | | | | | | | | | | || | | | | -> at least one of those non-counting groups, as many as possible
+" || | | | | | -------- | | | | || | | | | | -> type constraint closing bracket
+" || | | | | || | | | | | || | | | | | |
+syn match goTypeParams /\[\%(\w\+\s\+\%(\~\?\%(\[]\)\?\w\%(\w\||\)\)*\%(,\s*\)\?\)\+\]/ nextgroup=goSimpleParams,goDeclType contained
+
" Functions;
if s:HighlightFunctions() || s:HighlightFunctionParameters()
syn match goDeclaration /\<func\>/ nextgroup=goReceiver,goFunction,goSimpleParams skipwhite skipnl
+ syn match goReceiverDecl /(\s*\zs\%(\%(\w\+\s\+\)\?\*\?\w\+\%(\[\%(\%(\[\]\)\?\w\+\%(,\s*\)\?\)\+\]\)\?\)\ze\s*)/ contained contains=goReceiverVar,goReceiverType,goPointerOperator
syn match goReceiverVar /\w\+\ze\s\+\%(\w\|\*\)/ nextgroup=goPointerOperator,goReceiverType skipwhite skipnl contained
syn match goPointerOperator /\*/ nextgroup=goReceiverType contained skipwhite skipnl
- syn match goFunction /\w\+/ nextgroup=goSimpleParams contained skipwhite skipnl
- syn match goReceiverType /\w\+/ contained
+ syn match goFunction /\w\+/ nextgroup=goSimpleParams,goTypeParams contained skipwhite skipnl
+ syn match goReceiverType /\w\+\%(\[\%(\%(\[\]\)\?\w\+\%(,\s*\)\?\)\+\]\)\?\ze\s*)/ contained
if s:HighlightFunctionParameters()
syn match goSimpleParams /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType nextgroup=goFunctionReturn skipwhite skipnl
syn match goFunctionReturn /(\%(\w\|\_s\|[*\.\[\],\{\}<>-]\)*)/ contained contains=goParamName,goType skipwhite skipnl
@@ -369,7 +430,7 @@ if s:HighlightFunctions() || s:HighlightFunctionParameters()
hi def link goReceiverVar goParamName
hi def link goParamName Identifier
endif
- syn match goReceiver /(\s*\w\+\%(\s\+\*\?\s*\w\+\)\?\s*)\ze\s*\w/ contained nextgroup=goFunction contains=goReceiverVar skipwhite skipnl
+ syn match goReceiver /(\s*\%(\w\+\s\+\)\?\*\?\s*\w\+\%(\[\%(\%(\[\]\)\?\w\+\%(,\s*\)\?\)\+\]\)\?\s*)\ze\s*\w/ contained nextgroup=goFunction contains=goReceiverDecl skipwhite skipnl
else
syn keyword goDeclaration func
endif
@@ -377,7 +438,7 @@ hi def link goFunction Function
" Function calls;
if s:HighlightFunctionCalls()
- syn match goFunctionCall /\w\+\ze(/ contains=goBuiltins,goDeclaration
+ syn match goFunctionCall /\w\+\ze\%(\[\%(\%(\[]\)\?\w\+\(,\s*\)\?\)\+\]\)\?(/ contains=goBuiltins,goDeclaration
endif
hi def link goFunctionCall Type
@@ -404,7 +465,7 @@ hi def link goField Identifier
if s:HighlightTypes()
syn match goTypeConstructor /\<\w\+{\@=/
syn match goTypeDecl /\<type\>/ nextgroup=goTypeName skipwhite skipnl
- syn match goTypeName /\w\+/ contained nextgroup=goDeclType skipwhite skipnl
+ syn match goTypeName /\w\+/ contained nextgroup=goDeclType,goTypeParams skipwhite skipnl
syn match goDeclType /\<\%(interface\|struct\)\>/ skipwhite skipnl
hi def link goReceiverType Type
else
@@ -444,7 +505,7 @@ if s:HighlightBuildConstraints()
" The rs=s+2 option lets the \s*+build portion be part of the inner region
" instead of the matchgroup so it will be highlighted as a goBuildKeyword.
syn region goBuildComment matchgroup=goBuildCommentStart
- \ start="//\s*+build\s"rs=s+2 end="$"
+ \ start="//\(\s*+build\s\|go:build\)"rs=s+2 end="$"
\ contains=goBuildKeyword,goBuildDirectives
hi def link goBuildCommentStart Comment
hi def link goBuildDirectives Type
diff --git a/runtime/syntax/help.vim b/runtime/syntax/help.vim
index 82add63482..181fed8708 100644
--- a/runtime/syntax/help.vim
+++ b/runtime/syntax/help.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: Vim help file
" Maintainer: Bram Moolenaar (Bram@vim.org)
-" Last Change: 2022 Nov 09
+" Last Change: 2022 Nov 13
" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
@@ -11,7 +11,7 @@ endif
let s:cpo_save = &cpo
set cpo&vim
-syn match helpHeadline "^[A-Z.][-A-Z0-9 .,()_]*?\=\ze\(\s\+\*\|$\)"
+syn match helpHeadline "^[A-Z.][-A-Z0-9 .,()_']*?\=\ze\(\s\+\*\|$\)"
syn match helpSectionDelim "^===.*===$"
syn match helpSectionDelim "^---.*--$"
if has("conceal")
diff --git a/runtime/syntax/html.vim b/runtime/syntax/html.vim
index 9061bdee90..605db3ae1c 100644
--- a/runtime/syntax/html.vim
+++ b/runtime/syntax/html.vim
@@ -3,7 +3,7 @@
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Previous Maintainers: Jorge Maldonado Ventura <jorgesumle@freakspot.net>
" Claudio Fleiner <claudio@fleiner.com>
-" Last Change: 2022 Jul 20
+" Last Change: 2022 Nov 18
" Please check :help html.vim for some comments and a description of the options
@@ -272,6 +272,16 @@ if main_syntax == "html"
syn sync minlines=10
endif
+" Folding
+" Originally by Ingo Karkat and Marcus Zanona
+if get(g:, "html_syntax_folding", 0)
+ syn region htmlFold start="<\z(\<\%(area\|base\|br\|col\|command\|embed\|hr\|img\|input\|keygen\|link\|meta\|param\|source\|track\|wbr\>\)\@![a-z-]\+\>\)\%(\_s*\_[^/]\?>\|\_s\_[^>]*\_[^>/]>\)" end="</\z1\_s*>" fold transparent keepend extend containedin=htmlHead,htmlH\d
+ " fold comments (the real ones and the old Netscape ones)
+ if exists("html_wrong_comments")
+ syn region htmlComment start=+<!--+ end=+--\s*>\%(\n\s*<!--\)\@!+ contains=@Spell fold
+ endif
+endif
+
" The default highlighting.
hi def link htmlTag Function
hi def link htmlEndTag Identifier
diff --git a/runtime/syntax/mermaid.vim b/runtime/syntax/mermaid.vim
new file mode 100644
index 0000000000..afdbcc3d62
--- /dev/null
+++ b/runtime/syntax/mermaid.vim
@@ -0,0 +1,155 @@
+" Vim syntax file
+" Language: Mermaid
+" Maintainer: Craig MacEahern <https://github.com/craigmac/vim-mermaid>
+" Filenames: *.mmd
+" Last Change: 2022 Nov 22
+
+if exists("b:current_syntax")
+ finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+syntax iskeyword @,48-57,192-255,$,_,-,:
+syntax keyword mermaidKeyword
+ \ _blank
+ \ _self
+ \ _parent
+ \ _top
+ \ ::icon
+ \ accDescr
+ \ accTitle
+ \ actor
+ \ activate
+ \ alt
+ \ and
+ \ as
+ \ autonumber
+ \ branch
+ \ break
+ \ callback
+ \ checkout
+ \ class
+ \ classDef
+ \ classDiagram
+ \ click
+ \ commit
+ \ commitgitGraph
+ \ critical
+ \ dataFormat
+ \ dateFormat
+ \ deactivate
+ \ direction
+ \ element
+ \ else
+ \ end
+ \ erDiagram
+ \ flowchart
+ \ gantt
+ \ gitGraph
+ \ graph
+ \ journey
+ \ link
+ \ LR
+ \ TD
+ \ TB
+ \ RL
+ \ loop
+ \ merge
+ \ mindmap root
+ \ Note
+ \ Note right of
+ \ Note left of
+ \ Note over
+ \ note
+ \ note right of
+ \ note left of
+ \ note over
+ \ opt
+ \ option
+ \ par
+ \ participant
+ \ pie
+ \ rect
+ \ requirement
+ \ rgb
+ \ section
+ \ sequenceDiagram
+ \ state
+ \ stateDiagram
+ \ stateDiagram-v2
+ \ style
+ \ subgraph
+ \ title
+highlight link mermaidKeyword Keyword
+
+syntax match mermaidStatement "|"
+syntax match mermaidStatement "--\?[>x)]>\?+\?-\?"
+syntax match mermaidStatement "\~\~\~"
+syntax match mermaidStatement "--"
+syntax match mermaidStatement "---"
+syntax match mermaidStatement "-->"
+syntax match mermaidStatement "-\."
+syntax match mermaidStatement "\.->"
+syntax match mermaidStatement "-\.-"
+syntax match mermaidStatement "-\.\.-"
+syntax match mermaidStatement "-\.\.\.-"
+syntax match mermaidStatement "=="
+syntax match mermaidStatement "==>"
+syntax match mermaidStatement "===>"
+syntax match mermaidStatement "====>"
+syntax match mermaidStatement "&"
+syntax match mermaidStatement "--o"
+syntax match mermaidStatement "--x"
+syntax match mermaidStatement "x--x"
+syntax match mermaidStatement "-----"
+syntax match mermaidStatement "---->"
+syntax match mermaidStatement "==="
+syntax match mermaidStatement "===="
+syntax match mermaidStatement "====="
+syntax match mermaidStatement ":::"
+syntax match mermaidStatement "<|--"
+syntax match mermaidStatement "\*--"
+syntax match mermaidStatement "o--"
+syntax match mermaidStatement "o--o"
+syntax match mermaidStatement "<--"
+syntax match mermaidStatement "<-->"
+syntax match mermaidStatement "\.\."
+syntax match mermaidStatement "<\.\."
+syntax match mermaidStatement "<|\.\."
+syntax match mermaidStatement "--|>"
+syntax match mermaidStatement "--\*"
+syntax match mermaidStatement "--o"
+syntax match mermaidStatement "\.\.>"
+syntax match mermaidStatement "\.\.|>"
+syntax match mermaidStatement "<|--|>"
+syntax match mermaidStatement "||--o{"
+highlight link mermaidStatement Statement
+
+syntax match mermaidIdentifier "[\+-]\?\w\+(.*)[\$\*]\?"
+highlight link mermaidIdentifier Identifier
+
+syntax match mermaidType "[\+-\#\~]\?\cint\>"
+syntax match mermaidType "[\+-\#\~]\?\cString\>"
+syntax match mermaidType "[\+-\#\~]\?\cbool\>"
+syntax match mermaidType "[\+-\#\~]\?\cBigDecimal\>"
+syntax match mermaidType "[\+-\#\~]\?\cList\~.\+\~"
+syntax match mermaidType "<<\w\+>>"
+highlight link mermaidType Type
+
+syntax match mermaidComment "%%.*$"
+highlight link mermaidComment Comment
+
+syntax region mermaidDirective start="%%{" end="\}%%"
+highlight link mermaidDirective PreProc
+
+syntax region mermaidString start=/"/ skip=/\\"/ end=/"/
+highlight link mermaidString String
+
+let b:current_syntax = "mermaid"
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
+" vim:set sw=2:
diff --git a/runtime/syntax/nsis.vim b/runtime/syntax/nsis.vim
index 3a73fe0989..49fa17abf1 100644
--- a/runtime/syntax/nsis.vim
+++ b/runtime/syntax/nsis.vim
@@ -3,7 +3,7 @@
" Maintainer: Ken Takata
" URL: https://github.com/k-takata/vim-nsis
" Previous Maintainer: Alex Jakushev <Alex.Jakushev@kemek.lt>
-" Last Change: 2020-10-18
+" Last Change: 2022-11-05
" quit when a syntax file was already loaded
if exists("b:current_syntax")
@@ -394,9 +394,13 @@ syn keyword nsisInstruction contained CreateShortcut nextgroup=nsisCreateShortcu
syn region nsisCreateShortcutOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisCreateShortcutKwd
syn match nsisCreateShortcutKwd contained "/NoWorkingDir\>"
+syn keyword nsisInstruction contained GetWinVer nextgroup=nsisGetWinVerOpt skipwhite
+syn region nsisGetWinVerOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisGetWinVerKwd
+syn keyword nsisGetWinVerKwd contained Major Minor Build ServicePack
+
syn keyword nsisInstruction contained GetDLLVersion GetDLLVersionLocal nextgroup=nsisGetDLLVersionOpt skipwhite
-syn region nsisGetDLLVersionOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisGetDLLVersionKwd
-syn match nsisGetDLLVersionKwd contained "/ProductVersion\>"
+syn region nsisGetDLLVersionOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisGetDLLVersionKwd
+syn match nsisGetDLLVersionKwd contained "/ProductVersion\>"
syn keyword nsisInstruction contained GetFullPathName nextgroup=nsisGetFullPathNameOpt skipwhite
syn region nsisGetFullPathNameOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisGetFullPathNameKwd
@@ -562,10 +566,19 @@ syn match nsisSystem contained "!execute\>"
syn match nsisSystem contained "!makensis\>"
syn match nsisSystem contained "!packhdr\>"
syn match nsisSystem contained "!finalize\>"
+syn match nsisSystem contained "!uninstfinalize\>"
syn match nsisSystem contained "!system\>"
syn match nsisSystem contained "!tempfile\>"
-syn match nsisSystem contained "!getdllversion\>"
-syn match nsisSystem contained "!gettlbversion\>"
+
+" Add 'P' to avoid conflicts with nsisGetDLLVersionOpt. ('P' for preprocessor.)
+syn match nsisSystem contained "!getdllversion\>" nextgroup=nsisPGetdllversionOpt skipwhite
+syn region nsisPGetdllversionOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisPGetdllversionKwd
+syn match nsisPGetdllversionKwd contained "/\%(noerrors\|packed\|productversion\)\>"
+
+syn match nsisSystem contained "!gettlbversion\>" nextgroup=nsisPGettlbversionOpt skipwhite
+syn region nsisPGettlbversionOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisPGettlbversionKwd
+syn match nsisPGettlbversionKwd contained "/\%(noerrors\|packed\)\>"
+
syn match nsisSystem contained "!warning\>"
syn match nsisSystem contained "!pragma\>" nextgroup=nsisPragmaOpt skipwhite
@@ -581,7 +594,10 @@ syn match nsisDefine contained "!define\>" nextgroup=nsisDefineOpt skipwhite
syn region nsisDefineOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisDefineKwd
syn match nsisDefineKwd contained "/\%(ifndef\|redef\|date\|utcdate\|file\|intfmt\|math\)\>"
-syn match nsisDefine contained "!undef\>"
+syn match nsisDefine contained "!undef\>" nextgroup=nsisUndefineOpt skipwhite
+syn region nsisUndefineOpt contained start="" end="$" transparent keepend contains=@nsisAnyOpt,nsisUndefineKwd
+syn match nsisUndefineKwd contained "/noerrors\>"
+
syn match nsisPreCondit contained "!ifdef\>"
syn match nsisPreCondit contained "!ifndef\>"
@@ -659,6 +675,7 @@ hi def link nsisWriteRegMultiStrKwd Constant
hi def link nsisSetRegViewKwd Constant
hi def link nsisCopyFilesKwd Constant
hi def link nsisCreateShortcutKwd Constant
+hi def link nsisGetWinVerKwd Constant
hi def link nsisGetDLLVersionKwd Constant
hi def link nsisGetFullPathNameKwd Constant
hi def link nsisFileAttrib Constant
@@ -696,9 +713,12 @@ hi def link nsisIncludeKwd Constant
hi def link nsisAddplugindirKwd Constant
hi def link nsisAppendfileKwd Constant
hi def link nsisDelfileKwd Constant
+hi def link nsisPGetdllversionKwd Constant
+hi def link nsisPGettlbversionKwd Constant
hi def link nsisPragmaKwd Constant
hi def link nsisVerboseKwd Constant
hi def link nsisDefineKwd Constant
+hi def link nsisUndefineKwd Constant
hi def link nsisIfKwd Constant
hi def link nsisSearchparseKwd Constant
hi def link nsisSearchreplaceKwd Constant
diff --git a/runtime/syntax/obse.vim b/runtime/syntax/obse.vim
new file mode 100644
index 0000000000..4ff04281f3
--- /dev/null
+++ b/runtime/syntax/obse.vim
@@ -0,0 +1,3360 @@
+" Vim syntax file
+" Language: Oblivion Language (obl)
+" Original Creator: Ulthar Seramis
+" Maintainer: Kat <katisntgood@gmail.com>
+" Latest Revision: 13 November 2022
+
+if exists("b:current_syntax")
+ finish
+endif
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+" obse is case insensitive
+syntax case ignore
+
+" Statements {{{
+syn keyword obseStatement set let to skipwhite
+" the second part needs to be separate as to not mess up the next group
+syn match obseStatementTwo ":="
+" }}}
+
+" Regex matched objects {{{
+" these are matched with regex and thus must be set first
+syn match obseNames '\w\+'
+syn match obseScriptNameRegion '\i\+' contained
+syn match obseVariable '\w*\S' contained
+syn match obseReference '\zs\w\+\>\ze\.'
+" }}}
+
+" Operators {{{
+syn match obseOperator "\v\*"
+syn match obseOperator "\v\-"
+syn match obseOperator "\v\+"
+syn match obseOperator "\v\/"
+syn match obseOperator "\v\^"
+syn match obseOperator "\v\="
+syn match obseOperator "\v\>"
+syn match obseOperator "\v\<"
+syn match obseOperator "\v\!"
+syn match obseOperator "\v\&"
+syn match obseOperator "\v\|"
+" }}}
+
+" Numbers {{{
+syn match obseInt '\d\+'
+syn match obseInt '[-+]\d\+'
+syn match obseFloat '\d\+\.\d*'
+syn match obseFloat '[-+]\d\+\.\d*'
+" }}}
+
+" Comments and strings {{{
+syn region obseComment start=";" end="$" keepend fold contains=obseToDo
+syn region obseString start=/"/ end=/"/ keepend fold contains=obseStringFormatting
+syn match obseStringFormatting "%%" contained
+syn match obseStringFormatting "%a" contained
+syn match obseStringFormatting "%B" contained
+syn match obseStringFormatting "%b" contained
+syn match obseStringFormatting "%c" contained
+syn match obseStringFormatting "%e" contained
+syn match obseStringFormatting "%g" contained
+syn match obseStringFormatting "%i" contained
+syn match obseStringFormatting "%k" contained
+syn match obseStringFormatting "%n" contained
+syn match obseStringFormatting "%p" contained
+syn match obseStringFormatting "%ps" contained
+syn match obseStringFormatting "%pp" contained
+syn match obseStringFormatting "%po" contained
+syn match obseStringFormatting "%q" contained
+syn match obseStringFormatting "%r" contained
+syn match obseStringFormatting "%v" contained
+syn match obseStringFormatting "%x" contained
+syn match obseStringFormatting "%z" contained
+syn match obseStringFormatting "%{" contained
+syn match obseStringFormatting "%}" contained
+syn match obseStringFormatting "%\d*.\d*f" contained
+syn match obseStringFormatting "% \d*.\d*f" contained
+syn match obseStringFormatting "%-\d*.\d*f" contained
+syn match obseStringFormatting "%+\d*.\d*f" contained
+syn match obseStringFormatting "%\d*.\d*e" contained
+syn match obseStringFormatting "%-\d*.\d*e" contained
+syn match obseStringFormatting "% \d*.\d*e" contained
+syn match obseStringFormatting "%+\d*.\d*e" contained
+syn keyword obseToDo contained TODO todo Todo ToDo FIXME fixme NOTE note
+" }}}
+
+
+" Conditionals {{{
+syn match obseCondition "If"
+syn match obseCondition "Eval"
+syn match obseCondition "Return"
+syn match obseCondition "EndIf"
+syn match obseCondition "ElseIf"
+syn match obseCondition "Else"
+" }}}
+
+" Repeat loops {{{
+syn match obseRepeat "Label"
+syn match obseRepeat "GoTo"
+syn match obseRepeat "While"
+syn match obseRepeat "Loop"
+syn match obseRepeat "ForEach"
+syn match obseRepeat "Break"
+syn match obseRepeat "Continue"
+" }}}
+
+" Basic Types {{{
+syn keyword obseTypes array_var float int long ref reference short string_var nextgroup=obseNames skipwhite
+syn keyword obseOtherKey Player player playerRef playerREF PlayerRef PlayerREF
+syn keyword obseScriptName ScriptName scriptname Scriptname scn nextgroup=obseScriptNameRegion skipwhite
+syn keyword obseBlock Begin End
+" }}}
+
+" Fold {{{
+setlocal foldmethod=syntax
+syn cluster obseNoFold contains=obseComment,obseString
+syn region obseFoldIfContainer
+ \ start="^\s*\<if\>"
+ \ end="^\s*\<endif\>"
+ \ keepend extend
+ \ containedin=ALLBUT,@obseNoFold
+ \ contains=ALLBUT,obseScriptName,obseScriptNameRegion
+syn region obseFoldIf
+ \ start="^\s*\<if\>"
+ \ end="^\s*\<endif\>"
+ \ fold
+ \ keepend
+ \ contained containedin=obseFoldIfContainer
+ \ nextgroup=obseFoldElseIf,obseFoldElse
+ \ contains=TOP,NONE
+syn region obseFoldElseIf
+ \ start="^\s*\<elseif\>"
+ \ end="^\s*\<endif\>"
+ \ fold
+ \ keepend
+ \ contained containedin=obseFoldIfContainer
+ \ nextgroup=obseFoldElseIf,obseFoldElse
+ \ contains=TOP
+syn region obseFoldElse
+ \ start="^\s*\<else\>"
+ \ end="^\s*\<endif\>"
+ \ fold
+ \ keepend
+ \ contained containedin=obseFoldIfContainer
+ \ contains=TOP
+syn region obseFoldWhile
+ \ start="^\s*\<while\>"
+ \ end="^\s*\<loop\>"
+ \ fold
+ \ keepend extend
+ \ contains=TOP
+ \ containedin=ALLBUT,@obseNoFold
+" fold for loops
+syn region obseFoldFor
+ \ start="^\s*\<foreach\>"
+ \ end="^\s*\<loop\>"
+ \ fold
+ \ keepend extend
+ \ contains=TOP
+ \ containedin=ALLBUT,@obseNoFold
+ \ nextgroup=obseVariable
+" }}}
+
+" Skills and Attributes {{{
+syn keyword skillAttribute
+ \ Strength
+ \ Willpower
+ \ Speed
+ \ Personality
+ \ Intelligence
+ \ Agility
+ \ Endurance
+ \ Luck
+ \ Armorer
+ \ Athletics
+ \ Blade
+ \ Block
+ \ Blunt
+ \ HandToHand
+ \ HeavyArmor
+ \ Alchemy
+ \ Alteration
+ \ Conjuration
+ \ Destruction
+ \ Illusion
+ \ Mysticism
+ \ Restoration
+ \ Acrobatics
+ \ LightArmor
+ \ Marksman
+ \ Mercantile
+ \ Security
+ \ Sneak
+ \ Speechcraft
+" }}}
+
+" Block Types {{{
+syn keyword obseBlockType
+ \ ExitGame
+ \ ExitToMainMenu
+ \ Function
+ \ GameMode
+ \ LoadGame
+ \ MenuMode
+ \ OnActivate
+ \ OnActorDrop
+ \ OnActorEquip
+ \ OnActorUnequip
+ \ OnAdd
+ \ OnAlarm
+ \ OnAlarmTrespass
+ \ OnAlarmVictim
+ \ OnAttack
+ \ OnBlock
+ \ OnBowAttack
+ \ OnClick
+ \ OnClose
+ \ OnCreatePotion
+ \ OnCreateSpell
+ \ OnDeath
+ \ OnDodge
+ \ OnDrinkPotion
+ \ OnDrop
+ \ OnEatIngredient
+ \ OnEnchant
+ \ OnEquip
+ \ OnFallImpact
+ \ OnHealthDamage
+ \ OnHit
+ \ OnHitWith
+ \ OnKnockout
+ \ OnLoad
+ \ OnMagicApply
+ \ OnMagicCast
+ \ OnMagicEffectHit
+ \ OnMagicEffectHit2
+ \ OnMapMarkerAdd
+ \ OnMouseover
+ \ OnMurder
+ \ OnNewGame
+ \ OnOpen
+ \ OnPackageChange
+ \ OnPackageDone
+ \ OnPackageStart
+ \ OnQuestComplete
+ \ OnRecoil
+ \ OnRelease
+ \ OnReset
+ \ OnSaveIni
+ \ OnScriptedSkillUp
+ \ OnScrollCast
+ \ OnSell
+ \ OnSkillUp
+ \ OnSoulTrap
+ \ OnSpellCast
+ \ OnStagger
+ \ OnStartCombat
+ \ OnTrigger
+ \ OnTriggerActor
+ \ OnTriggerMob
+ \ OnUnequip
+ \ OnVampireFeed
+ \ OnWaterDive
+ \ OnWaterSurface
+ \ PostLoadGame
+ \ QQQ
+ \ SaveGame
+ \ ScriptEffectFinish
+ \ ScriptEffectStart
+ \ ScriptEffectUpdate
+" }}}
+
+" Functions {{{
+" CS functions {{{
+syn keyword csFunction
+ \ Activate
+ \ AddAchievement
+ \ AddFlames
+ \ AddItem
+ \ AddScriptPackage
+ \ AddSpell
+ \ AddTopic
+ \ AdvSkill
+ \ AdvancePCLevel
+ \ AdvancePCSkill
+ \ Autosave
+ \ CanHaveFlames
+ \ CanPayCrimeGold
+ \ Cast
+ \ ClearOwnership
+ \ CloseCurrentOblivionGate
+ \ CloseOblivionGate
+ \ CompleteQuest
+ \ CreateFullActorCopy
+ \ DeleteFullActorCopy
+ \ Disable
+ \ DisableLinkedPathPoints
+ \ DisablePlayerControls
+ \ Dispel
+ \ DispelAllSpells
+ \ Drop
+ \ DropMe
+ \ DuplicateAllItems
+ \ DuplicateNPCStats
+ \ Enable
+ \ EnableFastTravel
+ \ EnableLinkedPathPoints
+ \ EnablePlayerControls
+ \ EquipItem
+ \ EssentialDeathReload
+ \ EvaluatePackage
+ \ ForceAV
+ \ ForceActorValue
+ \ ForceCloseOblivionGate
+ \ ForceFlee
+ \ ForceTakeCover
+ \ ForceWeather
+ \ GetAV
+ \ GetActionRef
+ \ GetActorValue
+ \ GetAlarmed
+ \ GetAmountSoldStolen
+ \ GetAngle
+ \ GetArmorRating
+ \ GetArmorRatingUpperBody
+ \ GetAttacked
+ \ GetBarterGold
+ \ GetBaseAV
+ \ GetBaseActorValue
+ \ GetButtonPressed
+ \ GetClassDefaultMatch
+ \ GetClothingValue
+ \ GetContainer
+ \ GetCrime
+ \ GetCrimeGold
+ \ GetCrimeKnown
+ \ GetCurrentAIPackage
+ \ GetCurrentAIProcedure
+ \ GetCurrentTime
+ \ GetCurrentWeatherPercent
+ \ GetDayOfWeek
+ \ GetDead
+ \ GetDeadCount
+ \ GetDestroyed
+ \ GetDetected
+ \ GetDetectionLevel
+ \ GetDisabled
+ \ GetDisposition
+ \ GetDistance
+ \ GetDoorDefaultOpen
+ \ GetEquipped
+ \ GetFactionRank
+ \ GetFactionRankDifference
+ \ GetFactionReaction
+ \ GetFatiguePercentage
+ \ GetForceRun
+ \ GetForceSneak
+ \ GetFriendHit
+ \ GetFurnitureMarkerID
+ \ GetGS
+ \ GetGameSetting
+ \ GetGlobalValue
+ \ GetGold
+ \ GetHeadingAngle
+ \ GetIdleDoneOnce
+ \ GetIgnoreFriendlyHits
+ \ GetInCell
+ \ GetInCellParam
+ \ GetInFaction
+ \ GetInSameCell
+ \ GetInWorldspace
+ \ GetInvestmentGold
+ \ GetIsAlerted
+ \ GetIsClass
+ \ GetIsClassDefault
+ \ GetIsCreature
+ \ GetIsCurrentPackage
+ \ GetIsCurrentWeather
+ \ GetIsGhost
+ \ GetIsID
+ \ GetIsPlayableRace
+ \ GetIsPlayerBirthsign
+ \ GetIsRace
+ \ GetIsReference
+ \ GetIsSex
+ \ GetIsUsedItem
+ \ GetIsUsedItemType
+ \ GetItemCount
+ \ GetKnockedState
+ \ GetLOS
+ \ GetLevel
+ \ GetLockLevel
+ \ GetLocked
+ \ GetMenuHasTrait
+ \ GetName
+ \ GetNoRumors
+ \ GetOffersServicesNow
+ \ GetOpenState
+ \ GetPCExpelled
+ \ GetPCFactionAttack
+ \ GetPCFactionMurder
+ \ GetPCFactionSteal
+ \ GetPCFactionSubmitAuthority
+ \ GetPCFame
+ \ GetPCInFaction
+ \ GetPCInfamy
+ \ GetPCIsClass
+ \ GetPCIsRace
+ \ GetPCIsSex
+ \ GetPCMiscStat
+ \ GetPCSleepHours
+ \ GetPackageTarget
+ \ GetParentRef
+ \ GetPersuasionNumber
+ \ GetPlayerControlsDisabled
+ \ GetPlayerHasLastRiddenHorse
+ \ GetPlayerInSEWorld
+ \ GetPos
+ \ GetQuestRunning
+ \ GetQuestVariable
+ \ GetRandomPercent
+ \ GetRestrained
+ \ GetScale
+ \ GetScriptVariable
+ \ GetSecondsPassed
+ \ GetSelf
+ \ GetShouldAttack
+ \ GetSitting
+ \ GetSleeping
+ \ GetStage
+ \ GetStageDone
+ \ GetStartingAngle
+ \ GetStartingPos
+ \ GetTalkedToPC
+ \ GetTalkedToPCParam
+ \ GetTimeDead
+ \ GetTotalPersuasionNumber
+ \ GetTrespassWarningLevel
+ \ GetUnconscious
+ \ GetUsedItemActivate
+ \ GetUsedItemLevel
+ \ GetVampire
+ \ GetWalkSpeed
+ \ GetWeaponAnimType
+ \ GetWeaponSkillType
+ \ GetWindSpeed
+ \ GoToJail
+ \ HasFlames
+ \ HasMagicEffect
+ \ HasVampireFed
+ \ IsActionRef
+ \ IsActor
+ \ IsActorAVictim
+ \ IsActorDetected
+ \ IsActorEvil
+ \ IsActorUsingATorch
+ \ IsActorsAIOff
+ \ IsAnimPlayer
+ \ IsCellOwner
+ \ IsCloudy
+ \ IsContinuingPackagePCNear
+ \ IsCurrentFurnitureObj
+ \ IsCurrentFurnitureRef
+ \ IsEssential
+ \ IsFacingUp
+ \ IsGuard
+ \ IsHorseStolen
+ \ IsIdlePlaying
+ \ IsInCombat
+ \ IsInDangerousWater
+ \ IsInInterior
+ \ IsInMyOwnedCell
+ \ IsLeftUp
+ \ IsOwner
+ \ IsPCAMurderer
+ \ IsPCSleeping
+ \ IsPlayerInJail
+ \ IsPlayerMovingIntoNewSpace
+ \ IsPlayersLastRiddenHorse
+ \ IsPleasant
+ \ IsRaining
+ \ IsRidingHorse
+ \ IsRunning
+ \ IsShieldOut
+ \ IsSneaking
+ \ IsSnowing
+ \ IsSpellTarget
+ \ IsSwimming
+ \ IsTalking
+ \ IsTimePassing
+ \ IsTorchOut
+ \ IsTrespassing
+ \ IsTurnArrest
+ \ IsWaiting
+ \ IsWeaponOut
+ \ IsXBox
+ \ IsYielding
+ \ Kill
+ \ KillActor
+ \ KillAllActors
+ \ Lock
+ \ Look
+ \ LoopGroup
+ \ Message
+ \ MessageBox
+ \ ModAV
+ \ ModActorValue
+ \ ModAmountSoldStolen
+ \ ModBarterGold
+ \ ModCrimeGold
+ \ ModDisposition
+ \ ModFactionRank
+ \ ModFactionReaction
+ \ ModPCAttribute
+ \ ModPCA
+ \ ModPCFame
+ \ ModPCInfamy
+ \ ModPCMiscStat
+ \ ModPCSkill
+ \ ModPCS
+ \ ModScale
+ \ MoveTo
+ \ MoveToMarker
+ \ PCB
+ \ PayFine
+ \ PayFineThief
+ \ PickIdle
+ \ PlaceAtMe
+ \ PlayBink
+ \ PlayGroup
+ \ PlayMagicEffectVisuals
+ \ PlayMagicShaderVisuals
+ \ PlaySound
+ \ PlaySound3D
+ \ PositionCell
+ \ PositionWorld
+ \ PreloadMagicEffect
+ \ PurgeCellBuffers
+ \ PushActorAway
+ \ RefreshTopicList
+ \ ReleaseWeatherOverride
+ \ RemoveAllItems
+ \ RemoveFlames
+ \ RemoveItem
+ \ RemoveMe
+ \ RemoveScriptPackage
+ \ RemoveSpell
+ \ Reset3DState
+ \ ResetFallDamageTimer
+ \ ResetHealth
+ \ ResetInterior
+ \ Resurrect
+ \ Rotate
+ \ SCAOnActor
+ \ SameFaction
+ \ SameFactionAsPC
+ \ SameRace
+ \ SameRaceAsPC
+ \ SameSex
+ \ SameSexAsPC
+ \ Say
+ \ SayTo
+ \ ScriptEffectElapsedSeconds
+ \ SelectPlayerSpell
+ \ SendTrespassAlarm
+ \ SetAV
+ \ SetActorAlpha
+ \ SetActorFullName
+ \ SetActorRefraction
+ \ SetActorValue
+ \ SetActorsAI
+ \ SetAlert
+ \ SetAllReachable
+ \ SetAllVisible
+ \ SetAngle
+ \ SetAtStart
+ \ SetBarterGold
+ \ SetCellFullName
+ \ SetCellOwnership
+ \ SetCellPublicFlag
+ \ SetClass
+ \ SetCrimeGold
+ \ SetDestroyed
+ \ SetDoorDefaultOpen
+ \ SetEssential
+ \ SetFactionRank
+ \ SetFactionReaction
+ \ SetForceRun
+ \ SetForceSneak
+ \ SetGhost
+ \ SetIgnoreFriendlyHits
+ \ SetInCharGen
+ \ SetInvestmentGold
+ \ SetItemValue
+ \ SetLevel
+ \ SetNoAvoidance
+ \ SetNoRumors
+ \ SetOpenState
+ \ SetOwnership
+ \ SetPCExpelled
+ \ SetPCFactionAttack
+ \ SetPCFactionMurder
+ \ SetPCFactionSteal
+ \ SetPCFactionSubmitAuthority
+ \ SetPCFame
+ \ SetPCInfamy
+ \ SetPCSleepHours
+ \ SetPackDuration
+ \ SetPlayerBirthsign
+ \ SetPlayerInSEWorld
+ \ SetPos
+ \ SetQuestObject
+ \ SetRestrained
+ \ SetRigidBodyMass
+ \ SetScale
+ \ SetSceneIsComplex
+ \ SetShowQuestItems
+ \ SetSize
+ \ SetStage
+ \ SetUnconscious
+ \ SetWeather
+ \ ShowBirthsignMenu
+ \ ShowClassMenu
+ \ ShowDialogSubtitles
+ \ ShowEnchantment
+ \ ShowMap
+ \ ShowRaceMenu
+ \ ShowSpellMaking
+ \ SkipAnim
+ \ StartCombat
+ \ StartConversation
+ \ StartQuest
+ \ StopCombat
+ \ StopCombatAlarmOnActor
+ \ StopLook
+ \ StopMagicEffectVisuals
+ \ StopMagicShaderVisuals
+ \ StopQuest
+ \ StopWaiting
+ \ StreamMusic
+ \ This
+ \ ToggleActorsAI
+ \ TrapUpdate
+ \ TriggerHitShader
+ \ UnequipItem
+ \ Unlock
+ \ VampireFeed
+ \ Wait
+ \ WakeUpPC
+ \ WhichServiceMenu
+ \ Yield
+ \ evp
+ \ pms
+ \ saa
+ \ sms
+" }}}
+
+" OBSE Functions {{{
+syn keyword obseFunction
+ \ abs
+ \ acos
+ \ activate2
+ \ actorvaluetocode
+ \ actorvaluetostring
+ \ actorvaluetostringc
+ \ addeffectitem
+ \ addeffectitemc
+ \ addfulleffectitem
+ \ addfulleffectitemc
+ \ additemns
+ \ addmagiceffectcounter
+ \ addmagiceffectcounterc
+ \ addmecounter
+ \ addmecounterc
+ \ addspellns
+ \ addtoleveledlist
+ \ ahammerkey
+ \ animpathincludes
+ \ appendtoname
+ \ asciitochar
+ \ asin
+ \ atan
+ \ atan2
+ \ avstring
+ \ calcleveleditem
+ \ calclevitemnr
+ \ calclevitems
+ \ cancastpower
+ \ cancorpsecheck
+ \ canfasttravelfromworld
+ \ cantraveltomapmarker
+ \ ceil
+ \ chartoascii
+ \ clearactivequest
+ \ clearhotkey
+ \ clearleveledlist
+ \ clearownershipt
+ \ clearplayerslastriddenhorse
+ \ clickmenubutton
+ \ cloneform
+ \ closeallmenus
+ \ closetextinput
+ \ colvec
+ \ comparefemalebipedpath
+ \ comparefemalegroundpath
+ \ comparefemaleiconpath
+ \ compareiconpath
+ \ comparemalebipedpath
+ \ comparemalegroundpath
+ \ comparemaleiconpath
+ \ comparemodelpath
+ \ comparename
+ \ comparenames
+ \ comparescripts
+ \ con_cal
+ \ con_getinisetting
+ \ con_hairtint
+ \ con_loadgame
+ \ con_modwatershader
+ \ con_playerspellbook
+ \ con_quitgame
+ \ con_refreshini
+ \ con_runmemorypass
+ \ con_save
+ \ con_saveini
+ \ con_setcamerafov
+ \ con_setclipdist
+ \ con_setfog
+ \ con_setgamesetting
+ \ con_setgamma
+ \ con_sethdrparam
+ \ con_setimagespaceglow
+ \ con_setinisetting
+ \ con_setskyparam
+ \ con_settargetrefraction
+ \ con_settargetrefractionfire
+ \ con_sexchange
+ \ con_tcl
+ \ con_tfc
+ \ con_tgm
+ \ con_toggleai
+ \ con_togglecombatai
+ \ con_toggledetection
+ \ con_togglemapmarkers
+ \ con_togglemenus
+ \ con_waterdeepcolor
+ \ con_waterreflectioncolor
+ \ con_watershallowcolor
+ \ copyalleffectitems
+ \ copyeyes
+ \ copyfemalebipedpath
+ \ copyfemalegroundpath
+ \ copyfemaleiconpath
+ \ copyhair
+ \ copyiconpath
+ \ copyir
+ \ copymalebipedpath
+ \ copymalegroundpath
+ \ copymaleiconpath
+ \ copymodelpath
+ \ copyname
+ \ copyntheffectitem
+ \ copyrace
+ \ cos
+ \ cosh
+ \ createtempref
+ \ creaturehasnohead
+ \ creaturehasnoleftarm
+ \ creaturehasnomovement
+ \ creaturehasnorightarm
+ \ creaturenocombatinwater
+ \ creatureusesweaponandshield
+ \ dacos
+ \ dasin
+ \ datan
+ \ datan2
+ \ dcos
+ \ dcosh
+ \ debugprint
+ \ deletefrominputtext
+ \ deletereference
+ \ disablecontrol
+ \ disablekey
+ \ disablemouse
+ \ dispatchevent
+ \ dispelnthactiveeffect
+ \ dispelnthae
+ \ dsin
+ \ dsinh
+ \ dtan
+ \ dtanh
+ \ enablecontrol
+ \ enablekey
+ \ enablemouse
+ \ equipitem2
+ \ equipitem2ns
+ \ equipitemns
+ \ equipitemsilent
+ \ equipme
+ \ eval
+ \ evaluatepackage
+ \ eventhandlerexist
+ \ exp
+ \ factionhasspecialcombat
+ \ fileexists
+ \ floor
+ \ fmod
+ \ forcecolumnvector
+ \ forcerowvector
+ \ generateidentitymatrix
+ \ generaterotationmatrix
+ \ generatezeromatrix
+ \ getactiveeffectcasters
+ \ getactiveeffectcodes
+ \ getactiveeffectcount
+ \ getactivemenucomponentid
+ \ getactivemenufilter
+ \ getactivemenumode
+ \ getactivemenuobject
+ \ getactivemenuref
+ \ getactivemenuselection
+ \ getactivequest
+ \ getactiveuicomponentfullname
+ \ getactiveuicomponentid
+ \ getactiveuicomponentname
+ \ getactoralpha
+ \ getactorbaselevel
+ \ getactorlightamount
+ \ getactormaxlevel
+ \ getactormaxswimbreath
+ \ getactorminlevel
+ \ getactorpackages
+ \ getactorsoullevel
+ \ getactorvaluec
+ \ getalchmenuapparatus
+ \ getalchmenuingredient
+ \ getalchmenuingredientcount
+ \ getallies
+ \ getallmodlocaldata
+ \ getaltcontrol2
+ \ getapbowench
+ \ getapench
+ \ getapparatustype
+ \ getappoison
+ \ getarmorar
+ \ getarmortype
+ \ getarrayvariable
+ \ getarrowprojectilebowenchantment
+ \ getarrowprojectileenchantment
+ \ getarrowprojectilepoison
+ \ getattackdamage
+ \ getavc
+ \ getavforbaseactor
+ \ getavforbaseactorc
+ \ getavmod
+ \ getavmodc
+ \ getavskillmastery
+ \ getavskillmasteryc
+ \ getbarteritem
+ \ getbarteritemquantity
+ \ getbaseactorvaluec
+ \ getbaseav2
+ \ getbaseav2c
+ \ getbaseav3
+ \ getbaseav3c
+ \ getbaseitems
+ \ getbaseobject
+ \ getbipediconpath
+ \ getbipedmodelpath
+ \ getbipedslotmask
+ \ getbirthsignspells
+ \ getbookcantbetaken
+ \ getbookisscroll
+ \ getbooklength
+ \ getbookskilltaught
+ \ getbooktext
+ \ getboundingbox
+ \ getboundingradius
+ \ getcalcalllevels
+ \ getcalceachincount
+ \ getcallingscript
+ \ getcellbehavesasexterior
+ \ getcellchanged
+ \ getcellclimate
+ \ getcelldetachtime
+ \ getcellfactionrank
+ \ getcelllighting
+ \ getcellmusictype
+ \ getcellnorthrotation
+ \ getcellresethours
+ \ getcellwatertype
+ \ getchancenone
+ \ getclass
+ \ getclassattribute
+ \ getclassmenuhighlightedclass
+ \ getclassmenuselectedclass
+ \ getclassskill
+ \ getclassskills
+ \ getclassspecialization
+ \ getclimatehasmasser
+ \ getclimatehassecunda
+ \ getclimatemoonphaselength
+ \ getclimatesunrisebegin
+ \ getclimatesunriseend
+ \ getclimatesunsetbegin
+ \ getclimatesunsetend
+ \ getclimatevolatility
+ \ getclosesound
+ \ getcloudspeedlower
+ \ getcloudspeedupper
+ \ getcombatspells
+ \ getcombatstyle
+ \ getcombatstyleacrobaticsdodgechance
+ \ getcombatstyleattackchance
+ \ getcombatstyleattackduringblockmult
+ \ getcombatstyleattacknotunderattackmult
+ \ getcombatstyleattackskillmodbase
+ \ getcombatstyleattackskillmodmult
+ \ getcombatstyleattackunderattackmult
+ \ getcombatstyleblockchance
+ \ getcombatstyleblocknotunderattackmult
+ \ getcombatstyleblockskillmodbase
+ \ getcombatstyleblockskillmodmult
+ \ getcombatstyleblockunderattackmult
+ \ getcombatstylebuffstandoffdist
+ \ getcombatstyledodgebacknotunderattackmult
+ \ getcombatstyledodgebacktimermax
+ \ getcombatstyledodgebacktimermin
+ \ getcombatstyledodgebackunderattackmult
+ \ getcombatstyledodgechance
+ \ getcombatstyledodgefatiguemodbase
+ \ getcombatstyledodgefatiguemodmult
+ \ getcombatstyledodgefwattackingmult
+ \ getcombatstyledodgefwnotattackingmult
+ \ getcombatstyledodgefwtimermax
+ \ getcombatstyledodgefwtimermin
+ \ getcombatstyledodgelrchance
+ \ getcombatstyledodgelrtimermax
+ \ getcombatstyledodgelrtimermin
+ \ getcombatstyledodgenotunderattackmult
+ \ getcombatstyledodgeunderattackmult
+ \ getcombatstyleencumberedspeedmodbase
+ \ getcombatstyleencumberedspeedmodmult
+ \ getcombatstylefleeingdisabled
+ \ getcombatstylegroupstandoffdist
+ \ getcombatstyleh2hbonustoattack
+ \ getcombatstyleholdtimermax
+ \ getcombatstyleholdtimermin
+ \ getcombatstyleidletimermax
+ \ getcombatstyleidletimermin
+ \ getcombatstyleignorealliesinarea
+ \ getcombatstylekobonustoattack
+ \ getcombatstylekobonustopowerattack
+ \ getcombatstylemeleealertok
+ \ getcombatstylepowerattackchance
+ \ getcombatstylepowerattackfatiguemodbase
+ \ getcombatstylepowerattackfatiguemodmult
+ \ getcombatstyleprefersranged
+ \ getcombatstylerangedstandoffdist
+ \ getcombatstylerangemaxmult
+ \ getcombatstylerangeoptimalmult
+ \ getcombatstylerejectsyields
+ \ getcombatstylerushattackchance
+ \ getcombatstylerushattackdistmult
+ \ getcombatstylestaggerbonustoattack
+ \ getcombatstylestaggerbonustopowerattack
+ \ getcombatstyleswitchdistmelee
+ \ getcombatstyleswitchdistranged
+ \ getcombatstylewillyield
+ \ getcombattarget
+ \ getcompletedquests
+ \ getcontainermenuview
+ \ getcontainerrespawns
+ \ getcontrol
+ \ getcreaturebasescale
+ \ getcreaturecombatskill
+ \ getcreatureflies
+ \ getcreaturemagicskill
+ \ getcreaturemodelpaths
+ \ getcreaturereach
+ \ getcreaturesoullevel
+ \ getcreaturesound
+ \ getcreaturesoundbase
+ \ getcreaturestealthskill
+ \ getcreatureswims
+ \ getcreaturetype
+ \ getcreaturewalks
+ \ getcrosshairref
+ \ getcurrentcharge
+ \ getcurrentclimateid
+ \ getcurrenteditorpackage
+ \ getcurrenteventname
+ \ getcurrenthealth
+ \ getcurrentpackage
+ \ getcurrentpackageprocedure
+ \ getcurrentquests
+ \ getcurrentregion
+ \ getcurrentregions
+ \ getcurrentscript
+ \ getcurrentsoullevel
+ \ getcurrentweatherid
+ \ getcursorpos
+ \ getdebugselection
+ \ getdescription
+ \ getdoorteleportrot
+ \ getdoorteleportx
+ \ getdoorteleporty
+ \ getdoorteleportz
+ \ geteditorid
+ \ geteditorsize
+ \ getenchantment
+ \ getenchantmentcharge
+ \ getenchantmentcost
+ \ getenchantmenttype
+ \ getenchmenubaseitem
+ \ getenchmenuenchitem
+ \ getenchmenusoulgem
+ \ getequipmentslot
+ \ getequipmentslotmask
+ \ getequippedcurrentcharge
+ \ getequippedcurrenthealth
+ \ getequippeditems
+ \ getequippedobject
+ \ getequippedtorchtimeleft
+ \ getequippedweaponpoison
+ \ geteyes
+ \ getfactions
+ \ getfalltimer
+ \ getfirstref
+ \ getfirstrefincell
+ \ getfogdayfar
+ \ getfogdaynear
+ \ getfognightfar
+ \ getfognightnear
+ \ getfollowers
+ \ getformfrommod
+ \ getformidstring
+ \ getfps
+ \ getfullgoldvalue
+ \ getgamedifficulty
+ \ getgameloaded
+ \ getgamerestarted
+ \ getgodmode
+ \ getgoldvalue
+ \ getgridstoload
+ \ getgroundsurfacematerial
+ \ gethair
+ \ gethaircolor
+ \ gethdrvalue
+ \ gethidesamulet
+ \ gethidesrings
+ \ gethighactors
+ \ gethorse
+ \ gethotkeyitem
+ \ geticonpath
+ \ getignoresresistance
+ \ getingredient
+ \ getingredientchance
+ \ getinputtext
+ \ getinventoryobject
+ \ getinvrefsforitem
+ \ getitems
+ \ getkeyname
+ \ getkeypress
+ \ getlastcreatedpotion
+ \ getlastcreatedspell
+ \ getlastenchanteditem
+ \ getlastsigilstonecreateditem
+ \ getlastsigilstoneenchanteditem
+ \ getlastss
+ \ getlastsscreated
+ \ getlastssitem
+ \ getlasttransactionitem
+ \ getlasttransactionquantity
+ \ getlastuniquecreatedpotion
+ \ getlastusedsigilstone
+ \ getlevcreaturetemplate
+ \ getleveledspells
+ \ getlevitembylevel
+ \ getlevitemindexbyform
+ \ getlevitemindexbylevel
+ \ getlightduration
+ \ getlightningfrequency
+ \ getlightradius
+ \ getlightrgb
+ \ getlinkeddoor
+ \ getloadedtypearray
+ \ getlocalgravity
+ \ getloopsound
+ \ getlowactors
+ \ getluckmodifiedskill
+ \ getmagiceffectareasound
+ \ getmagiceffectareasoundc
+ \ getmagiceffectbarterfactor
+ \ getmagiceffectbarterfactorc
+ \ getmagiceffectbasecost
+ \ getmagiceffectbasecostc
+ \ getmagiceffectboltsound
+ \ getmagiceffectboltsoundc
+ \ getmagiceffectcastingsound
+ \ getmagiceffectcastingsoundc
+ \ getmagiceffectchars
+ \ getmagiceffectcharsc
+ \ getmagiceffectcode
+ \ getmagiceffectcounters
+ \ getmagiceffectcountersc
+ \ getmagiceffectenchantfactor
+ \ getmagiceffectenchantfactorc
+ \ getmagiceffectenchantshader
+ \ getmagiceffectenchantshaderc
+ \ getmagiceffecthitshader
+ \ getmagiceffecthitshaderc
+ \ getmagiceffecthitsound
+ \ getmagiceffecthitsoundc
+ \ getmagiceffecticon
+ \ getmagiceffecticonc
+ \ getmagiceffectlight
+ \ getmagiceffectlightc
+ \ getmagiceffectmodel
+ \ getmagiceffectmodelc
+ \ getmagiceffectname
+ \ getmagiceffectnamec
+ \ getmagiceffectnumcounters
+ \ getmagiceffectnumcountersc
+ \ getmagiceffectotheractorvalue
+ \ getmagiceffectotheractorvaluec
+ \ getmagiceffectprojectilespeed
+ \ getmagiceffectprojectilespeedc
+ \ getmagiceffectresistvalue
+ \ getmagiceffectresistvaluec
+ \ getmagiceffectschool
+ \ getmagiceffectschoolc
+ \ getmagiceffectusedobject
+ \ getmagiceffectusedobjectc
+ \ getmagicitemeffectcount
+ \ getmagicitemtype
+ \ getmagicprojectilespell
+ \ getmapmarkers
+ \ getmapmarkertype
+ \ getmapmenumarkername
+ \ getmapmenumarkerref
+ \ getmaxav
+ \ getmaxavc
+ \ getmaxlevel
+ \ getmeareasound
+ \ getmeareasoundc
+ \ getmebarterc
+ \ getmebasecost
+ \ getmebasecostc
+ \ getmeboltsound
+ \ getmeboltsoundc
+ \ getmecastingsound
+ \ getmecastingsoundc
+ \ getmecounters
+ \ getmecountersc
+ \ getmeebarter
+ \ getmeebarterc
+ \ getmeenchant
+ \ getmeenchantc
+ \ getmeenchantshader
+ \ getmeenchantshaderc
+ \ getmehitshader
+ \ getmehitshaderc
+ \ getmehitsound
+ \ getmehitsoundc
+ \ getmeicon
+ \ getmeiconc
+ \ getmelight
+ \ getmelightc
+ \ getmemodel
+ \ getmemodelc
+ \ getmename
+ \ getmenamec
+ \ getmenufloatvalue
+ \ getmenumcounters
+ \ getmenumcountersc
+ \ getmenustringvalue
+ \ getmeotheractorvalue
+ \ getmeotheractorvaluec
+ \ getmeprojspeed
+ \ getmeprojspeedc
+ \ getmerchantcontainer
+ \ getmeresistvalue
+ \ getmeresistvaluec
+ \ getmeschool
+ \ getmeschoolc
+ \ getmessageboxtype
+ \ getmeusedobject
+ \ getmeusedobjectc
+ \ getmiddlehighactors
+ \ getmieffectcount
+ \ getminlevel
+ \ getmitype
+ \ getmodelpath
+ \ getmodindex
+ \ getmodlocaldata
+ \ getmousebuttonpress
+ \ getmousebuttonsswapped
+ \ getmpspell
+ \ getnextref
+ \ getnthacitveeffectmagnitude
+ \ getnthactiveeffectactorvalue
+ \ getnthactiveeffectbounditem
+ \ getnthactiveeffectcaster
+ \ getnthactiveeffectcode
+ \ getnthactiveeffectdata
+ \ getnthactiveeffectduration
+ \ getnthactiveeffectenchantobject
+ \ getnthactiveeffectmagicenchantobject
+ \ getnthactiveeffectmagicitem
+ \ getnthactiveeffectmagicitemindex
+ \ getnthactiveeffectmagnitude
+ \ getnthactiveeffectsummonref
+ \ getnthactiveeffecttimeelapsed
+ \ getnthaeav
+ \ getnthaebounditem
+ \ getnthaecaster
+ \ getnthaecode
+ \ getnthaedata
+ \ getnthaeduration
+ \ getnthaeindex
+ \ getnthaemagicenchantobject
+ \ getnthaemagicitem
+ \ getnthaemagnitude
+ \ getnthaesummonref
+ \ getnthaetime
+ \ getnthchildref
+ \ getnthdetectedactor
+ \ getntheffectitem
+ \ getntheffectitemactorvalue
+ \ getntheffectitemarea
+ \ getntheffectitemcode
+ \ getntheffectitemduration
+ \ getntheffectitemmagnitude
+ \ getntheffectitemname
+ \ getntheffectitemrange
+ \ getntheffectitemscript
+ \ getntheffectitemscriptname
+ \ getntheffectitemscriptschool
+ \ getntheffectitemscriptvisualeffect
+ \ getntheiarea
+ \ getntheiav
+ \ getntheicode
+ \ getntheiduration
+ \ getntheimagnitude
+ \ getntheiname
+ \ getntheirange
+ \ getntheiscript
+ \ getntheisschool
+ \ getntheisvisualeffect
+ \ getnthexplicitref
+ \ getnthfaction
+ \ getnthfactionrankname
+ \ getnthfollower
+ \ getnthlevitem
+ \ getnthlevitemcount
+ \ getnthlevitemlevel
+ \ getnthmagiceffectcounter
+ \ getnthmagiceffectcounterc
+ \ getnthmecounter
+ \ getnthmecounterc
+ \ getnthmodname
+ \ getnthpackage
+ \ getnthplayerspell
+ \ getnthracebonusskill
+ \ getnthracespell
+ \ getnthspell
+ \ getnumchildrefs
+ \ getnumdetectedactors
+ \ getnumericinisetting
+ \ getnumexplicitrefs
+ \ getnumfactions
+ \ getnumfollowers
+ \ getnumitems
+ \ getnumkeyspressed
+ \ getnumlevitems
+ \ getnumloadedmods
+ \ getnumloadedplugins
+ \ getnummousebuttonspressed
+ \ getnumpackages
+ \ getnumranks
+ \ getnumrefs
+ \ getnumrefsincell
+ \ getobjectcharge
+ \ getobjecthealth
+ \ getobjecttype
+ \ getobliviondirectory
+ \ getoblrevision
+ \ getoblversion
+ \ getopenkey
+ \ getopensound
+ \ getowner
+ \ getowningfactionrank
+ \ getowningfactionrequiredrank
+ \ getpackageallowfalls
+ \ getpackageallowswimming
+ \ getpackagealwaysrun
+ \ getpackagealwayssneak
+ \ getpackagearmorunequipped
+ \ getpackagecontinueifpcnear
+ \ getpackagedata
+ \ getpackagedefensivecombat
+ \ getpackagelocationdata
+ \ getpackagelockdoorsatend
+ \ getpackagelockdoorsatlocation
+ \ getpackagelockdoorsatstart
+ \ getpackagemustcomplete
+ \ getpackagemustreachlocation
+ \ getpackagenoidleanims
+ \ getpackageoffersservices
+ \ getpackageonceperday
+ \ getpackagescheduledata
+ \ getpackageskipfalloutbehavior
+ \ getpackagetargetdata
+ \ getpackageunlockdoorsatend
+ \ getpackageunlockdoorsatlocation
+ \ getpackageunlockdoorsatstart
+ \ getpackageusehorse
+ \ getpackageweaponsunequipped
+ \ getparentcell
+ \ getparentcellowner
+ \ getparentcellowningfactionrank
+ \ getparentcellowningfactionrequiredrank
+ \ getparentcellwaterheight
+ \ getparentworldspace
+ \ getpathnodelinkedref
+ \ getpathnodepos
+ \ getpathnodesinradius
+ \ getpathnodesinrect
+ \ getpcattributebonus
+ \ getpcattributebonusc
+ \ getpclastdroppeditem
+ \ getpclastdroppeditemref
+ \ getpclasthorse
+ \ getpclastloaddoor
+ \ getpcmajorskillups
+ \ getpcmovementspeedmodifier
+ \ getpcspelleffectivenessmodifier
+ \ getpctrainingsessionsused
+ \ getplayerbirthsign
+ \ getplayerskilladvances
+ \ getplayerskilladvancesc
+ \ getplayerskilluse
+ \ getplayerskillusec
+ \ getplayerslastactivatedloaddoor
+ \ getplayerslastriddenhorse
+ \ getplayerspell
+ \ getplayerspellcount
+ \ getpluginversion
+ \ getplyerspellcount
+ \ getprocesslevel
+ \ getprojectile
+ \ getprojectiledistancetraveled
+ \ getprojectilelifetime
+ \ getprojectilesource
+ \ getprojectilespeed
+ \ getprojectiletype
+ \ getqmcurrent
+ \ getqmitem
+ \ getqmmaximum
+ \ getqr
+ \ getquality
+ \ getquantitymenucurrentquantity
+ \ getquantitymenuitem
+ \ getquantitymenumaximumquantity
+ \ getrace
+ \ getraceattribute
+ \ getraceattributec
+ \ getracedefaulthair
+ \ getraceeyes
+ \ getracehairs
+ \ getracereaction
+ \ getracescale
+ \ getraceskillbonus
+ \ getraceskillbonusc
+ \ getracespellcount
+ \ getracevoice
+ \ getraceweight
+ \ getrawformidstring
+ \ getrefcount
+ \ getrefvariable
+ \ getrequiredskillexp
+ \ getrequiredskillexpc
+ \ getrider
+ \ getscript
+ \ getscriptactiveeffectindex
+ \ getselectedspells
+ \ getservicesmask
+ \ getsigilstoneuses
+ \ getskillgoverningattribute
+ \ getskillgoverningattributec
+ \ getskillspecialization
+ \ getskillspecializationc
+ \ getskilluseincrement
+ \ getskilluseincrementc
+ \ getsoulgemcapacity
+ \ getsoullevel
+ \ getsoundattenuation
+ \ getsoundplaying
+ \ getsourcemodindex
+ \ getspecialanims
+ \ getspellareaeffectignoreslos
+ \ getspellcount
+ \ getspelldisallowabsorbreflect
+ \ getspelleffectiveness
+ \ getspellexplodeswithnotarget
+ \ getspellhostile
+ \ getspellimmunetosilence
+ \ getspellmagickacost
+ \ getspellmasterylevel
+ \ getspellpcstart
+ \ getspells
+ \ getspellschool
+ \ getspellscripteffectalwaysapplies
+ \ getspelltype
+ \ getstageentries
+ \ getstageids
+ \ getstringgamesetting
+ \ getstringinisetting
+ \ getsundamage
+ \ getsunglare
+ \ gettailmodelpath
+ \ gettargets
+ \ gettelekinesisref
+ \ getteleportcell
+ \ getteleportcellname
+ \ getterrainheight
+ \ gettextinputcontrolpressed
+ \ gettextinputcursorpos
+ \ gettexturepath
+ \ gettilechildren
+ \ gettiletraits
+ \ gettimeleft
+ \ gettotalactiveeffectmagnitude
+ \ gettotalactiveeffectmagnitudec
+ \ gettotalaeabilitymagnitude
+ \ gettotalaeabilitymagnitudec
+ \ gettotalaealchemymagnitude
+ \ gettotalaealchemymagnitudec
+ \ gettotalaeallspellsmagnitude
+ \ gettotalaeallspellsmagnitudec
+ \ gettotalaediseasemagnitude
+ \ gettotalaediseasemagnitudec
+ \ gettotalaeenchantmentmagnitude
+ \ gettotalaeenchantmentmagnitudec
+ \ gettotalaelesserpowermagnitude
+ \ gettotalaelesserpowermagnitudec
+ \ gettotalaemagnitude
+ \ gettotalaemagnitudec
+ \ gettotalaenonabilitymagnitude
+ \ gettotalaenonabilitymagnitudec
+ \ gettotalaepowermagnitude
+ \ gettotalaepowermagnitudec
+ \ gettotalaespellmagnitude
+ \ gettotalaespellmagnitudec
+ \ gettotalpcattributebonus
+ \ gettrainerlevel
+ \ gettrainerskill
+ \ gettransactioninfo
+ \ gettransdelta
+ \ gettravelhorse
+ \ getusedpowers
+ \ getusertime
+ \ getvariable
+ \ getvelocity
+ \ getverticalvelocity
+ \ getwaterheight
+ \ getwatershader
+ \ getweahtercloudspeedupper
+ \ getweaponreach
+ \ getweaponspeed
+ \ getweapontype
+ \ getweatherclassification
+ \ getweathercloudspeedlower
+ \ getweathercloudspeedupper
+ \ getweathercolor
+ \ getweatherfogdayfar
+ \ getweatherfogdaynear
+ \ getweatherfognightfar
+ \ getweatherfognightnear
+ \ getweatherhdrvalue
+ \ getweatherlightningfrequency
+ \ getweatheroverride
+ \ getweathersundamage
+ \ getweathersunglare
+ \ getweathertransdelta
+ \ getweatherwindspeed
+ \ getweight
+ \ getworldparentworld
+ \ getworldspaceparentworldspace
+ \ globalvariableexists
+ \ hammerkey
+ \ hasbeenpickedup
+ \ haseffectshader
+ \ haslowlevelprocessing
+ \ hasmodel
+ \ hasname
+ \ hasnopersuasion
+ \ hasspell
+ \ hastail
+ \ hasvariable
+ \ haswater
+ \ holdkey
+ \ iconpathincludes
+ \ identitymat
+ \ incrementplayerskilluse
+ \ incrementplayerskillusec
+ \ ininvertfasttravel
+ \ insertininputtext
+ \ isactivatable
+ \ isactivator
+ \ isactorrespawning
+ \ isalchemyitem
+ \ isammo
+ \ isanimgroupplaying
+ \ isanimplaying
+ \ isapparatus
+ \ isarmor
+ \ isattacking
+ \ isautomaticdoor
+ \ isbartermenuactive
+ \ isbipediconpathvalid
+ \ isbipedmodelpathvalid
+ \ isblocking
+ \ isbook
+ \ iscantwait
+ \ iscasting
+ \ iscellpublic
+ \ isclassattribute
+ \ isclassattributec
+ \ isclassskill
+ \ isclassskillc
+ \ isclonedform
+ \ isclothing
+ \ isconsoleopen
+ \ iscontainer
+ \ iscontrol
+ \ iscontroldisabled
+ \ iscontrolpressed
+ \ iscreature
+ \ iscreaturebiped
+ \ isdigit
+ \ isdiseased
+ \ isdodging
+ \ isdoor
+ \ isequipped
+ \ isfactionevil
+ \ isfactionhidden
+ \ isfemale
+ \ isflora
+ \ isflying
+ \ isfood
+ \ isformvalid
+ \ isfurniture
+ \ isgamemessagebox
+ \ isglobalcollisiondisabled
+ \ isharvested
+ \ ishiddendoor
+ \ isiconpathvalid
+ \ isinair
+ \ isingredient
+ \ isinoblivion
+ \ isjumping
+ \ iskey
+ \ iskeydisabled
+ \ iskeypressed
+ \ iskeypressed2
+ \ iskeypressed3
+ \ isletter
+ \ islight
+ \ islightcarriable
+ \ isloaddoor
+ \ ismagiceffectcanrecover
+ \ ismagiceffectcanrecoverc
+ \ ismagiceffectdetrimental
+ \ ismagiceffectdetrimentalc
+ \ ismagiceffectforenchanting
+ \ ismagiceffectforenchantingc
+ \ ismagiceffectforspellmaking
+ \ ismagiceffectforspellmakingc
+ \ ismagiceffecthostile
+ \ ismagiceffecthostilec
+ \ ismagiceffectmagnitudepercent
+ \ ismagiceffectmagnitudepercentc
+ \ ismagiceffectonselfallowed
+ \ ismagiceffectonselfallowedc
+ \ ismagiceffectontargetallowed
+ \ ismagiceffectontargetallowedc
+ \ ismagiceffectontouchallowed
+ \ ismagiceffectontouchallowedc
+ \ ismagicitemautocalc
+ \ ismajor
+ \ ismajorc
+ \ ismajorref
+ \ ismapmarkervisible
+ \ ismecanrecover
+ \ ismecanrecoverc
+ \ ismedetrimental
+ \ ismedetrimentalc
+ \ ismeforenchanting
+ \ ismeforenchantingc
+ \ ismeforspellmaking
+ \ ismeforspellmakingc
+ \ ismehostile
+ \ ismehostilec
+ \ ismemagnitudepercent
+ \ ismemagnitudepercentc
+ \ ismeonselfallowed
+ \ ismeonselfallowedc
+ \ ismeontargetallowed
+ \ ismeontargetallowedc
+ \ ismeontouchallowed
+ \ ismeontouchallowedc
+ \ isminimalusedoor
+ \ ismiscitem
+ \ ismodelpathvalid
+ \ ismodloaded
+ \ ismovingbackward
+ \ ismovingforward
+ \ ismovingleft
+ \ ismovingright
+ \ isnaked
+ \ isnthactiveeffectapplied
+ \ isntheffectitemscripted
+ \ isntheffectitemscripthostile
+ \ isntheishostile
+ \ isobliviongate
+ \ isoblivioninterior
+ \ isoblivionworld
+ \ isofflimits
+ \ isonground
+ \ ispathnodedisabled
+ \ ispcleveloffset
+ \ ispersistent
+ \ isplayable
+ \ isplayable2
+ \ isplugininstalled
+ \ ispoison
+ \ ispotion
+ \ ispowerattacking
+ \ isprintable
+ \ ispunctuation
+ \ isquestcomplete
+ \ isquestitem
+ \ isracebonusskill
+ \ isracebonusskillc
+ \ israceplayable
+ \ isrecoiling
+ \ isrefdeleted
+ \ isreference
+ \ isrefessential
+ \ isscripted
+ \ issigilstone
+ \ issoulgem
+ \ isspellhostile
+ \ isstaggered
+ \ issummonable
+ \ istaken
+ \ istextinputinuse
+ \ isthirdperson
+ \ isturningleft
+ \ isturningright
+ \ isunderwater
+ \ isunsaferespawns
+ \ isuppercase
+ \ isweapon
+ \ leftshift
+ \ linktodoor
+ \ loadgameex
+ \ log
+ \ log10
+ \ logicaland
+ \ logicalnot
+ \ logicalor
+ \ logicalxor
+ \ magiceffectcodefromchars
+ \ magiceffectfromchars
+ \ magiceffectfromcode
+ \ magiceffectfxpersists
+ \ magiceffectfxpersistsc
+ \ magiceffecthasnoarea
+ \ magiceffecthasnoareac
+ \ magiceffecthasnoduration
+ \ magiceffecthasnodurationc
+ \ magiceffecthasnohiteffect
+ \ magiceffecthasnohiteffectc
+ \ magiceffecthasnoingredient
+ \ magiceffecthasnoingredientc
+ \ magiceffecthasnomagnitude
+ \ magiceffecthasnomagnitudec
+ \ magiceffectusesarmor
+ \ magiceffectusesarmorc
+ \ magiceffectusesattribute
+ \ magiceffectusesattributec
+ \ magiceffectusescreature
+ \ magiceffectusescreaturec
+ \ magiceffectusesotheractorvalue
+ \ magiceffectusesotheractorvaluec
+ \ magiceffectusesskill
+ \ magiceffectusesskillc
+ \ magiceffectusesweapon
+ \ magiceffectusesweaponc
+ \ magichaseffect
+ \ magichaseffectc
+ \ magicitemhaseffect
+ \ magicitemhaseffectcode
+ \ magicitemhaseffectcount
+ \ magicitemhaseffectcountc
+ \ magicitemhaseffectcountcode
+ \ magicitemhaseffectitemscript
+ \ matadd
+ \ matchpotion
+ \ matinv
+ \ matmult
+ \ matrixadd
+ \ matrixdeterminant
+ \ matrixinvert
+ \ matrixmultiply
+ \ matrixrref
+ \ matrixscale
+ \ matrixsubtract
+ \ matrixtrace
+ \ matrixtranspose
+ \ matscale
+ \ matsubtract
+ \ mecodefromchars
+ \ mefxpersists
+ \ mefxpersistsc
+ \ mehasnoarea
+ \ mehasnoareac
+ \ mehasnoduration
+ \ mehasnodurationc
+ \ mehasnohiteffect
+ \ mehasnohiteffectc
+ \ mehasnoingredient
+ \ mehasnoingredientc
+ \ mehasnomagnitude
+ \ mehasnomagnitudec
+ \ menuholdkey
+ \ menumode
+ \ menureleasekey
+ \ menutapkey
+ \ messageboxex
+ \ messageex
+ \ meusesarmor
+ \ meusesarmorc
+ \ meusesattribute
+ \ meusesattributec
+ \ meusescreature
+ \ meusescreaturec
+ \ meusesotheractorvalue
+ \ meusesotheractorvaluec
+ \ meusesskill
+ \ meusesskillc
+ \ meusesweapon
+ \ meusesweaponc
+ \ modactorvalue2
+ \ modactorvaluec
+ \ modarmorar
+ \ modattackdamage
+ \ modav2
+ \ modavc
+ \ modavmod
+ \ modavmodc
+ \ modcurrentcharge
+ \ modelpathincludes
+ \ modenchantmentcharge
+ \ modenchantmentcost
+ \ modequippedcurrentcharge
+ \ modequippedcurrenthealth
+ \ modfemalebipedpath
+ \ modfemalegroundpath
+ \ modfemaleiconpath
+ \ modgoldvalue
+ \ modiconpath
+ \ modlocaldataexists
+ \ modmalebipedpath
+ \ modmalegroundpath
+ \ modmaleiconpath
+ \ modmodelpath
+ \ modname
+ \ modnthactiveeffectmagnitude
+ \ modnthaemagnitude
+ \ modntheffectitemarea
+ \ modntheffectitemduration
+ \ modntheffectitemmagnitude
+ \ modntheffectitemscriptname
+ \ modntheiarea
+ \ modntheiduration
+ \ modntheimagnitude
+ \ modntheisname
+ \ modobjectcharge
+ \ modobjecthealth
+ \ modpcmovementspeed
+ \ modpcspelleffectiveness
+ \ modplayerskillexp
+ \ modplayerskillexpc
+ \ modquality
+ \ modsigilstoneuses
+ \ modspellmagickacost
+ \ modweaponreach
+ \ modweaponspeed
+ \ modweight
+ \ movemousex
+ \ movemousey
+ \ movetextinputcursor
+ \ nameincludes
+ \ numtohex
+ \ offersapparatus
+ \ offersarmor
+ \ offersbooks
+ \ offersclothing
+ \ offersingredients
+ \ offerslights
+ \ offersmagicitems
+ \ offersmiscitems
+ \ offerspotions
+ \ offersrecharging
+ \ offersrepair
+ \ offersservicesc
+ \ offersspells
+ \ offerstraining
+ \ offersweapons
+ \ oncontroldown
+ \ onkeydown
+ \ opentextinput
+ \ outputlocalmappicturesoverride
+ \ overrideactorswimbreath
+ \ parentcellhaswater
+ \ pathedgeexists
+ \ playidle
+ \ pow
+ \ print
+ \ printactivetileinfo
+ \ printc
+ \ printd
+ \ printtileinfo
+ \ printtoconsole
+ \ questexists
+ \ racos
+ \ rand
+ \ rasin
+ \ ratan
+ \ ratan2
+ \ rcos
+ \ rcosh
+ \ refreshcurrentclimate
+ \ releasekey
+ \ removealleffectitems
+ \ removebasespell
+ \ removeenchantment
+ \ removeequippedweaponpoison
+ \ removeeventhandler
+ \ removefromleveledlist
+ \ removeitemns
+ \ removelevitembylevel
+ \ removemeir
+ \ removemodlocaldata
+ \ removentheffect
+ \ removentheffectitem
+ \ removenthlevitem
+ \ removenthmagiceffectcounter
+ \ removenthmagiceffectcounterc
+ \ removenthmecounter
+ \ removenthmecounterc
+ \ removescript
+ \ removescr
+ \ removespellns
+ \ resetallvariables
+ \ resetfalrior
+ \ resolvemodindex
+ \ rightshift
+ \ rotmat
+ \ rowvec
+ \ rsin
+ \ rsinh
+ \ rtan
+ \ rtanh
+ \ runbatchscript
+ \ runscriptline
+ \ saespassalarm
+ \ setactivequest
+ \ setactrfullname
+ \ setactormaxswimbreath
+ \ setactorrespawns
+ \ setactorswimbreath
+ \ setactorvaluec
+ \ setalvisible
+ \ setaltcontrol2
+ \ setapparatustype
+ \ setarmorar
+ \ setarmortype
+ \ setarrowprojectilebowenchantment
+ \ setarrowprojectileenchantment
+ \ setarrowprojectilepoison
+ \ setattackdamage
+ \ setavc
+ \ setavmod
+ \ setavmodc
+ \ setbaseform
+ \ setbipediconpathex
+ \ setbipedmodelpathex
+ \ setbipedslotmask
+ \ setbookcantbetaken
+ \ setbookisscroll
+ \ setbookskilltaught
+ \ setbuttonpressed
+ \ setcalcalllevels
+ \ setcamerafov2
+ \ setcancastpower
+ \ setcancorpsecheck
+ \ setcanfasttravelfromworld
+ \ setcantraveltomapmarker
+ \ setcantwait
+ \ setcellbehavesasexterior
+ \ setcellclimate
+ \ setcellhaswater
+ \ setcellispublic
+ \ setcelllighting
+ \ setcellmusictype
+ \ setcellublicflag
+ \ setcellresethours
+ \ setcellwaterheight
+ \ setcellwatertype
+ \ setchancenone
+ \ setclassattribute
+ \ setclassattributec
+ \ setclassskills
+ \ setclassskills2
+ \ setclassspecialization
+ \ setclimatehasmasser
+ \ setclimatehasmassser
+ \ setclimatehassecunda
+ \ setclimatemoonphaselength
+ \ setclimatesunrisebegin
+ \ setclimatesunriseend
+ \ setclimatesunsetbegin
+ \ setclimatesunsetend
+ \ setclimatevolatility
+ \ setclosesound
+ \ setcloudspeedlower
+ \ setcloudspeedupper
+ \ setcombatstyle
+ \ setcombatstyleacrobaticsdodgechance
+ \ setcombatstyleattackchance
+ \ setcombatstyleattackduringblockmult
+ \ setcombatstyleattacknotunderattackmult
+ \ setcombatstyleattackskillmodbase
+ \ setcombatstyleattackskillmodmult
+ \ setcombatstyleattackunderattackmult
+ \ setcombatstyleblockchance
+ \ setcombatstyleblocknotunderattackmult
+ \ setcombatstyleblockskillmodbase
+ \ setcombatstyleblockskillmodmult
+ \ setcombatstyleblockunderattackmult
+ \ setcombatstylebuffstandoffdist
+ \ setcombatstyledodgebacknotunderattackmult
+ \ setcombatstyledodgebacktimermax
+ \ setcombatstyledodgebacktimermin
+ \ setcombatstyledodgebackunderattackmult
+ \ setcombatstyledodgechance
+ \ setcombatstyledodgefatiguemodbase
+ \ setcombatstyledodgefatiguemodmult
+ \ setcombatstyledodgefwattackingmult
+ \ setcombatstyledodgefwnotattackingmult
+ \ setcombatstyledodgefwtimermax
+ \ setcombatstyledodgefwtimermin
+ \ setcombatstyledodgelrchance
+ \ setcombatstyledodgelrtimermax
+ \ setcombatstyledodgelrtimermin
+ \ setcombatstyledodgenotunderattackmult
+ \ setcombatstyledodgeunderattackmult
+ \ setcombatstyleencumberedspeedmodbase
+ \ setcombatstyleencumberedspeedmodmult
+ \ setcombatstylefleeingdisabled
+ \ setcombatstylegroupstandoffdist
+ \ setcombatstyleh2hbonustoattack
+ \ setcombatstyleholdtimermax
+ \ setcombatstyleholdtimermin
+ \ setcombatstyleidletimermax
+ \ setcombatstyleidletimermin
+ \ setcombatstyleignorealliesinarea
+ \ setcombatstylekobonustoattack
+ \ setcombatstylekobonustopowerattack
+ \ setcombatstylemeleealertok
+ \ setcombatstylepowerattackchance
+ \ setcombatstylepowerattackfatiguemodbase
+ \ setcombatstylepowerattackfatiguemodmult
+ \ setcombatstyleprefersranged
+ \ setcombatstylerangedstandoffdist
+ \ setcombatstylerangemaxmult
+ \ setcombatstylerangeoptimalmult
+ \ setcombatstylerejectsyields
+ \ setcombatstylerushattackchance
+ \ setcombatstylerushattackdistmult
+ \ setcombatstylestaggerbonustoattack
+ \ setcombatstylestaggerbonustopowerattack
+ \ setcombatstyleswitchdistmelee
+ \ setcombatstyleswitchdistranged
+ \ setcombatstylewillyield
+ \ setcontainerrespawns
+ \ setcontrol
+ \ setcreatureskill
+ \ setcreaturesoundbase
+ \ setcreaturetype
+ \ setcurrentcharge
+ \ setcurrenthealth
+ \ setcurrentsoullevel
+ \ setdebugmode
+ \ setdescription
+ \ setdetectionstate
+ \ setdisableglobalcollision
+ \ setdoorteleport
+ \ setenchantment
+ \ setenchantmentcharge
+ \ setenchantmentcost
+ \ setenchantmenttype
+ \ setequipmentslot
+ \ setequippedcurrentcharge
+ \ setequippedcurrenthealth
+ \ setequippedweaponpoison
+ \ seteventhandler
+ \ seteyes
+ \ setfactionevil
+ \ setfactionhasspecialcombat
+ \ setfactionhidden
+ \ setfactonreaction
+ \ setfactionspecialcombat
+ \ setfemale
+ \ setfemalebipedpath
+ \ setfemalegroundpath
+ \ setfemaleiconpath
+ \ setflycameraspeedmult
+ \ setfogdayfar
+ \ setfogdaynear
+ \ setfognightfar
+ \ setfognightnear
+ \ setforcsneak
+ \ setfunctionvalue
+ \ setgamedifficulty
+ \ setgoldvalue
+ \ setgoldvalue_t
+ \ setgoldvaluet
+ \ sethair
+ \ setharvested
+ \ sethasbeenpickedup
+ \ sethdrvalue
+ \ sethidesamulet
+ \ sethidesrings
+ \ sethotkeyitem
+ \ seticonpath
+ \ setignoresresistance
+ \ setingredient
+ \ setingredientchance
+ \ setinputtext
+ \ setinvertfasttravel
+ \ setisautomaticdoor
+ \ setiscontrol
+ \ setisfood
+ \ setishiddendoor
+ \ setisminimalusedoor
+ \ setisobliviongate
+ \ setisplayable
+ \ setlevcreaturetemplate
+ \ setlightduration
+ \ setlightningfrequency
+ \ setlightradius
+ \ setlightrgb
+ \ setlocalgravity
+ \ setlocalgravityvector
+ \ setloopsound
+ \ setlowlevelprocessing
+ \ setmaagiceffectuseactorvalue
+ \ setmagiceffectareasound
+ \ setmagiceffectareasoundc
+ \ setmagiceffectbarterfactor
+ \ setmagiceffectbarterfactorc
+ \ setmagiceffectbasecost
+ \ setmagiceffectbasecostc
+ \ setmagiceffectboltsound
+ \ setmagiceffectboltsoundc
+ \ setmagiceffectcanrecover
+ \ setmagiceffectcanrecoverc
+ \ setmagiceffectcastingsound
+ \ setmagiceffectcastingsoundc
+ \ setmagiceffectcounters
+ \ setmagiceffectcountersc
+ \ setmagiceffectenchantfactor
+ \ setmagiceffectenchantfactorc
+ \ setmagiceffectenchantshader
+ \ setmagiceffectenchantshaderc
+ \ setmagiceffectforenchanting
+ \ setmagiceffectforenchantingc
+ \ setmagiceffectforspellmaking
+ \ setmagiceffectforspellmakingc
+ \ setmagiceffectfxpersists
+ \ setmagiceffectfxpersistsc
+ \ setmagiceffecthitshader
+ \ setmagiceffecthitshaderc
+ \ setmagiceffecthitsound
+ \ setmagiceffecthitsoundc
+ \ setmagiceffecticon
+ \ setmagiceffecticonc
+ \ setmagiceffectisdetrimental
+ \ setmagiceffectisdetrimentalc
+ \ setmagiceffectishostile
+ \ setmagiceffectishostilec
+ \ setmagiceffectlight
+ \ setmagiceffectlightc
+ \ setmagiceffectmagnitudepercent
+ \ setmagiceffectmagnitudepercentc
+ \ setmagiceffectmodel
+ \ setmagiceffectmodelc
+ \ setmagiceffectname
+ \ setmagiceffectnamec
+ \ setmagiceffectnoarea
+ \ setmagiceffectnoareac
+ \ setmagiceffectnoduration
+ \ setmagiceffectnodurationc
+ \ setmagiceffectnohiteffect
+ \ setmagiceffectnohiteffectc
+ \ setmagiceffectnoingredient
+ \ setmagiceffectnoingredientc
+ \ setmagiceffectnomagnitude
+ \ setmagiceffectnomagnitudec
+ \ setmagiceffectonselfallowed
+ \ setmagiceffectonselfallowedc
+ \ setmagiceffectontargetallowed
+ \ setmagiceffectontargetallowedc
+ \ setmagiceffectontouchallowed
+ \ setmagiceffectontouchallowedc
+ \ setmagiceffectotheractorvalue
+ \ setmagiceffectotheractorvaluec
+ \ setmagiceffectprojectilespeed
+ \ setmagiceffectprojectilespeedc
+ \ setmagiceffectresistvalue
+ \ setmagiceffectresistvaluec
+ \ setmagiceffectschool
+ \ setmagiceffectschoolc
+ \ setmagiceffectuseactorvaluec
+ \ setmagiceffectusedobject
+ \ setmagiceffectusedobjectc
+ \ setmagiceffectusesactorvalue
+ \ setmagiceffectusesactorvaluec
+ \ setmagiceffectusesarmor
+ \ setmagiceffectusesarmorc
+ \ setmagiceffectusesattribute
+ \ setmagiceffectusesattributec
+ \ setmagiceffectusescreature
+ \ setmagiceffectusescreaturec
+ \ setmagiceffectusesskill
+ \ setmagiceffectusesskillc
+ \ setmagiceffectusesweapon
+ \ setmagiceffectusesweaponc
+ \ setmagicitemautocalc
+ \ setmagicprojectilespell
+ \ setmalebipedpath
+ \ setmalegroundpath
+ \ setmaleiconpath
+ \ setmapmarkertype
+ \ setmapmarkervisible
+ \ setmeareasound
+ \ setmeareasoundc
+ \ setmebarterfactor
+ \ setmebarterfactorc
+ \ setmebasecost
+ \ setmebasecostc
+ \ setmeboltsound
+ \ setmeboltsoundc
+ \ setmecanrecover
+ \ setmecanrecoverc
+ \ setmecastingsound
+ \ setmecastingsoundc
+ \ setmeenchantfactor
+ \ setmeenchantfactorc
+ \ setmeenchantshader
+ \ setmeenchantshaderc
+ \ setmeforenchanting
+ \ setmeforenchantingc
+ \ setmeforspellmaking
+ \ setmeforspellmakingc
+ \ setmefxpersists
+ \ setmefxpersistsc
+ \ setmehitshader
+ \ setmehitshaderc
+ \ setmehitsound
+ \ setmehitsoundc
+ \ setmeicon
+ \ setmeiconc
+ \ setmeisdetrimental
+ \ setmeisdetrimentalc
+ \ setmeishostile
+ \ setmeishostilec
+ \ setmelight
+ \ setmelightc
+ \ setmemagnitudepercent
+ \ setmemagnitudepercentc
+ \ setmemodel
+ \ setmemodelc
+ \ setmename
+ \ setmenamec
+ \ setmenoarea
+ \ setmenoareac
+ \ setmenoduration
+ \ setmenodurationc
+ \ setmenohiteffect
+ \ setmenohiteffectc
+ \ setmenoingredient
+ \ setmenoingredientc
+ \ setmenomagnitude
+ \ setmenomagnitudec
+ \ setmenufloatvalue
+ \ setmenustringvalue
+ \ setmeonselfallowed
+ \ setmeonselfallowedc
+ \ setmeontargetallowed
+ \ setmeontargetallowedc
+ \ setmeontouchallowed
+ \ setmeontouchallowedc
+ \ setmeotheractorvalue
+ \ setmeotheractorvaluec
+ \ setmeprojectilespeed
+ \ setmeprojectilespeedc
+ \ setmerchantcontainer
+ \ setmeresistvalue
+ \ setmeresistvaluec
+ \ setmeschool
+ \ setmeschoolc
+ \ setmessageicon
+ \ setmessagesound
+ \ setmeuseactorvalue
+ \ setmeuseactorvaluec
+ \ setmeusedobject
+ \ setmeusedobjectc
+ \ setmeusesarmor
+ \ setmeusesarmorc
+ \ setmeusesattribute
+ \ setmeusesattributec
+ \ setmeusescreature
+ \ setmeusescreaturec
+ \ setmeusesskill
+ \ setmeusesskillc
+ \ setmeusesweapon
+ \ setmeusesweaponc
+ \ setmodelpath
+ \ setmodlocaldata
+ \ setmousespeedx
+ \ setmousespeedy
+ \ setmpspell
+ \ setname
+ \ setnameex
+ \ setnopersuasion
+ \ setnthactiveeffectmagnitude
+ \ setnthaemagnitude
+ \ setntheffectitemactorvalue
+ \ setntheffectitemactorvaluec
+ \ setntheffectitemarea
+ \ setntheffectitemduration
+ \ setntheffectitemmagnitude
+ \ setntheffectitemrange
+ \ setntheffectitemscript
+ \ setntheffectitemscripthostile
+ \ setntheffectitemscriptname
+ \ setntheffectitemscriptnameex
+ \ setntheffectitemscriptschool
+ \ setntheffectitemscriptvisualeffect
+ \ setntheffectitemscriptvisualeffectc
+ \ setntheiarea
+ \ setntheiav
+ \ setntheiavc
+ \ setntheiduration
+ \ setntheimagnitude
+ \ setntheirange
+ \ setntheiscript
+ \ setntheishostile
+ \ setntheisname
+ \ setntheisschool
+ \ setntheisvisualeffect
+ \ setntheisvisualeffectc
+ \ setnthfactionranknameex
+ \ setnumericgamesetting
+ \ setnumericinisetting
+ \ setobjectcharge
+ \ setobjecthealth
+ \ setoffersapparatus
+ \ setoffersarmor
+ \ setoffersbooks
+ \ setoffersclothing
+ \ setoffersingredients
+ \ setofferslights
+ \ setoffersmagicitems
+ \ setoffersmiscitems
+ \ setofferspotions
+ \ setoffersrecharging
+ \ setoffersrepair
+ \ setoffersservicesc
+ \ setoffersspells
+ \ setofferstraining
+ \ setoffersweapons
+ \ setolmpgrids
+ \ setopenkey
+ \ setopensound
+ \ setopenstip
+ \ setownership_t
+ \ setowningrequiredrank
+ \ setpackageallowfalls
+ \ setpackageallowswimming
+ \ setpackagealwaysrun
+ \ setpackagealwayssneak
+ \ setpackagearmorunequipped
+ \ setpackagecontinueifpcnear
+ \ setpackagedata
+ \ setpackagedefensivecombat
+ \ setpackagelocationdata
+ \ setpackagelockdoorsatend
+ \ setpackagelockdoorsatlocation
+ \ setpackagelockdoorsatstart
+ \ setpackagemustcomplete
+ \ setpackagemustreachlocation
+ \ setpackagenoidleanims
+ \ setpackageoffersservices
+ \ setpackageonceperday
+ \ setpackagescheduledata
+ \ setpackageskipfalloutbehavior
+ \ setpackagetarget
+ \ setpackagetargetdata
+ \ setpackageunlockdoorsatend
+ \ setpackageunlockdoorsatlocation
+ \ setpackageunlockdoorsatstart
+ \ setpackageusehorse
+ \ setpackageweaponsunequipped
+ \ setparentcellowningfactionrequiredrank
+ \ setpathnodedisabled
+ \ setpcamurderer
+ \ setpcattributebonus
+ \ setpcattributebonusc
+ \ setpcexpy
+ \ setpcleveloffset
+ \ setpcmajorskillups
+ \ setpctrainingsessionsused
+ \ setplayerbseworld
+ \ setplayerprojectile
+ \ setplayerskeletonpath
+ \ setplayerskilladvances
+ \ setplayerskilladvancesc
+ \ setplayerslastriddenhorse
+ \ setpos_t
+ \ setpowertimer
+ \ setprojectilesource
+ \ setprojectilespeed
+ \ setquality
+ \ setquestitem
+ \ setracealias
+ \ setraceplayable
+ \ setracescale
+ \ setracevoice
+ \ setraceweight
+ \ setrefcount
+ \ setrefessential
+ \ setreale
+ \ setscaleex
+ \ setscript
+ \ setsigilstoneuses
+ \ setskillgoverningattribute
+ \ setskillgoverningattributec
+ \ setskillspecialization
+ \ setskillspecializationc
+ \ setskilluseincrement
+ \ setskilluseincrementc
+ \ setsoulgemcapacity
+ \ setsoullevel
+ \ setsoundattenuation
+ \ setspellareaeffectignoreslos
+ \ setspelldisallowabsorbreflect
+ \ setspellexplodeswithnotarget
+ \ setspellhostile
+ \ setspellimmunetosilence
+ \ setspellmagickacost
+ \ setspellmasterylevel
+ \ setspellpcstart
+ \ setspellscripteffectalwaysapplies
+ \ setspelltype
+ \ setstagedate
+ \ setstagetext
+ \ setstringgamesettingex
+ \ setstringinisetting
+ \ setsummonable
+ \ setsundamage
+ \ setsunglare
+ \ settaken
+ \ settextinputcontrolhandler
+ \ settextinputdefaultcontrolsdisabled
+ \ settextinputhandler
+ \ settexturepath
+ \ settimeleft
+ \ settrainerlevel
+ \ settrainerskill
+ \ settransdelta
+ \ settravelhorse
+ \ setunsafecontainer
+ \ setvelocity
+ \ setverticalvelocity
+ \ setweaponreach
+ \ setweaponspeed
+ \ setweapontype
+ \ setweathercloudspeedlower
+ \ setweathercloudspeedupper
+ \ setweathercolor
+ \ setweatherfogdayfar
+ \ setweatherfogdaynear
+ \ setweatherfognightfar
+ \ setweatherfognightnear
+ \ setweatherhdrvalue
+ \ setweatherlightningfrequency
+ \ setweathersundamage
+ \ setweathersunglare
+ \ setweathertransdelta
+ \ setweatherwindspeed
+ \ setweight
+ \ setwindspeed
+ \ showellmaking
+ \ sin
+ \ sinh
+ \ skipansqrt
+ \ squareroot
+ \ startcc
+ \ stringtoactorvalue
+ \ tan
+ \ tanh
+ \ tapcontrol
+ \ tapkey
+ \ testexpr
+ \ thiactorsai
+ \ togglecreaturemodel
+ \ togglefirstperson
+ \ toggleskillperk
+ \ togglespecialanim
+ \ tolower
+ \ tonumber
+ \ tostring
+ \ toupper
+ \ trapuphitshader
+ \ triggerplayerskilluse
+ \ triggerplayerskillusec
+ \ typeof
+ \ uncompletequest
+ \ unequipitemns
+ \ unequipitemsilent
+ \ unequipme
+ \ unhammerkey
+ \ unsetstagetext
+ \ update3d
+ \ updatecontainermenu
+ \ updatespellpurchasemenu
+ \ updatetextinput
+ \ vecmag
+ \ vecnorm
+ \ vectorcross
+ \ vectordot
+ \ vectormagnitude
+ \ vectornormalize
+ \ zeromat
+" }}}
+
+" Array Functions {{{
+syn keyword obseArrayFunction
+ \ ar_Append
+ \ ar_BadNumericIndex
+ \ ar_BadStringIndex
+ \ ar_Construct
+ \ ar_Copy
+ \ ar_CustomSort
+ \ ar_DeepCopy
+ \ ar_Dump
+ \ ar_DumpID
+ \ ar_Erase
+ \ ar_Find
+ \ ar_First
+ \ ar_HasKey
+ \ ar_Insert
+ \ ar_InsertRange
+ \ ar_Keys
+ \ ar_Last
+ \ ar_List
+ \ ar_Map
+ \ ar_Next
+ \ ar_Null
+ \ ar_Prev
+ \ ar_Range
+ \ ar_Resize
+ \ ar_Size
+ \ ar_Sort
+ \ ar_SortAlpha
+" }}}
+
+" String Functions {{{
+syn keyword obseStringFunction
+ \ sv_ToLower
+ \ sv_ToUpper
+ \ sv_Compare
+ \ sv_Construct
+ \ sv_Count
+ \ sv_Destruct
+ \ sv_Erase
+ \ sv_Find
+ \ sv_Insert
+ \ sv_Length
+ \ sv_Percentify
+ \ sv_Replace
+ \ sv_Split
+ \ sv_ToNumeric
+" }}}
+
+" Pluggy Functions {{{
+syn keyword pluggyFunction
+ \ ArrayCmp
+ \ ArrayCount
+ \ ArrayEsp
+ \ ArrayProtect
+ \ ArraySize
+ \ AutoSclHudS
+ \ AutoSclHudT
+ \ CopyArray
+ \ CopyString
+ \ CreateArray
+ \ CreateEspBook
+ \ CreateString
+ \ DelAllHudSs
+ \ DelAllHudTs
+ \ DelFile
+ \ DelHudS
+ \ DelHudT
+ \ DelTxtFile
+ \ DestroyAllArrays
+ \ DestroyAllStrings
+ \ DestroyArray
+ \ DestroyString
+ \ DupArray
+ \ EspToString
+ \ FileToString
+ \ FindFirstFile
+ \ FindFloatInArray
+ \ FindInArray
+ \ FindNextFile
+ \ FindRefInArray
+ \ FirstFreeInArray
+ \ FirstInArray
+ \ FixName
+ \ FixNameEx
+ \ FloatToString
+ \ FmtString
+ \ FromOBSEString
+ \ FromTSFC
+ \ GetEsp
+ \ GetFileSize
+ \ GetInArray
+ \ GetRefEsp
+ \ GetTypeInArray
+ \ Halt
+ \ HasFixedName
+ \ HudSEsp
+ \ HudSProtect
+ \ HudS_Align
+ \ HudS_L
+ \ HudS_Opac
+ \ HudS_SclX
+ \ HudS_SclY
+ \ HudS_Show
+ \ HudS_Tex
+ \ HudS_X
+ \ HudS_Y
+ \ HudTEsp
+ \ HudTInfo
+ \ HudTProtect
+ \ HudT_Align
+ \ HudT_Font
+ \ HudT_L
+ \ HudT_Opac
+ \ HudT_SclX
+ \ HudT_SclY
+ \ HudT_Show
+ \ HudT_Text
+ \ HudT_X
+ \ HudT_Y
+ \ HudsInfo
+ \ IniDelKey
+ \ IniGetNthSection
+ \ IniKeyExists
+ \ IniReadFloat
+ \ IniReadInt
+ \ IniReadRef
+ \ IniReadString
+ \ IniSectionsCount
+ \ IniWriteFloat
+ \ IniWriteInt
+ \ IniWriteRef
+ \ IniWriteString
+ \ IntToHex
+ \ IntToString
+ \ IsHUDEnabled
+ \ IsPluggyDataReset
+ \ KillMenu
+ \ LC
+ \ LongToRef
+ \ ModRefEsp
+ \ NewHudS
+ \ NewHudT
+ \ PackArray
+ \ PauseBox
+ \ PlgySpcl
+ \ RefToLong
+ \ RefToString
+ \ RemInArray
+ \ RenFile
+ \ RenTxtFile
+ \ ResetName
+ \ RunBatString
+ \ SanString
+ \ ScreenInfo
+ \ SetFloatInArray
+ \ SetHudT
+ \ SetInArray
+ \ SetRefInArray
+ \ SetString
+ \ StrLC
+ \ StringCat
+ \ StringCmp
+ \ StringEsp
+ \ StringGetName
+ \ StringGetNameEx
+ \ StringIns
+ \ StringLen
+ \ StringMsg
+ \ StringMsgBox
+ \ StringPos
+ \ StringProtect
+ \ StringRep
+ \ StringSetName
+ \ StringSetNameEx
+ \ StringToFloat
+ \ StringToInt
+ \ StringToRef
+ \ StringToTxtFile
+ \ ToOBSE
+ \ ToOBSEString
+ \ ToTSFC
+ \ TxtFileExists
+ \ UserFileExists
+ \ csc
+ \ rcsc
+" }}}
+
+" tfscFunction {{{
+syn keyword tfscFunction
+ \ StrAddNewLine
+ \ StrAppend
+ \ StrAppendCharCode
+ \ StrCat
+ \ StrClear
+ \ StrClearLast
+ \ StrCompare
+ \ StrCopy
+ \ StrDel
+ \ StrDeleteAll
+ \ StrExpr
+ \ StrGetFemaleBipedPath
+ \ StrGetFemaleGroundPath
+ \ StrGetFemaleIconPath
+ \ StrGetMaleBipedPath
+ \ StrGetMaleIconPath
+ \ StrGetModelPath
+ \ StrGetName
+ \ StrGetNthEffectItemScriptName
+ \ StrGetNthFactionRankName
+ \ StrGetRandomName
+ \ StrIDReplace
+ \ StrLength
+ \ StrLoad
+ \ StrMessageBox
+ \ StrNew
+ \ StrPrint
+ \ StrReplace
+ \ StrSave
+ \ StrSet
+ \ StrSetFemaleBipedPath
+ \ StrSetFemaleGroundPath
+ \ StrSetFemaleIconPath
+ \ StrSetMaleBipedPath
+ \ StrSetMaleIconPath
+ \ StrSetModelPath
+ \ StrSetName
+ \ StrSetNthEffectItemScriptName
+" }}}
+
+" Blockhead Functions {{{
+syn keyword blockheadFunction
+ \ GetBodyAssetOverride
+ \ GetFaceGenAge
+ \ GetHeadAssetOverride
+ \ RefreshAnimData
+ \ RegisterEquipmentOverrideHandler
+ \ ResetAgeTextureOverride
+ \ ResetBodyAssetOverride
+ \ ResetHeadAssetOverride
+ \ SetAgeTextureOverride
+ \ SetBodyAssetOverride
+ \ SetFaceGenAge
+ \ SetHeadAssetOverride
+ \ ToggleAnimOverride
+ \ UnregisterEquipmentOverrideHandler
+" }}}
+
+" switchNightEyeShaderFunction {{{
+syn keyword switchNightEyeShaderFunction
+ \ EnumNightEyeShader
+ \ SetNightEyeShader
+" }}}
+
+" Oblivion Reloaded Functions {{{
+syn keyword obseivionReloadedFunction
+ \ cameralookat
+ \ cameralookatposition
+ \ camerareset
+ \ camerarotate
+ \ camerarotatetoposition
+ \ cameratranslate
+ \ cameratranslatetoposition
+ \ getlocationname
+ \ getsetting
+ \ getversion
+ \ getweathername
+ \ isthirdperson
+ \ setcustomconstant
+ \ setextraeffectenabled
+ \ setsetting
+" }}}
+" menuQue Functions {{{
+syn keyword menuQueFunction
+ \ GetAllSkills
+ \ GetAVSkillMasteryLevelC
+ \ GetAVSkillMasteryLevelF
+ \ GetFontLoaded
+ \ GetGenericButtonPressed
+ \ GetLoadedFonts
+ \ GetLocalMapSeen
+ \ GetMenuEventType
+ \ GetMenuFloatValue
+ \ GetMenuStringValue
+ \ GetMouseImage
+ \ GetMousePos
+ \ GetPlayerSkillAdvancesF
+ \ GetPlayerSkillUseF
+ \ GetRequiredSkillExpC
+ \ GetRequiredSkillExpF
+ \ GetSkillCode
+ \ GetSkillForm
+ \ GetSkillGoverningAttributeF
+ \ GetSkillSpecializationC
+ \ GetSkillSpecializationF
+ \ GetSkillUseIncrementF
+ \ GetTextEditBox
+ \ GetTextEditString
+ \ GetTrainingMenuCost
+ \ GetTrainingMenuLevel
+ \ GetTrainingMenuSkill
+ \ GetWorldMapData
+ \ GetWorldMapDoor
+ \ IncrementPlayerSkillUseF
+ \ InsertXML
+ \ InsertXMLTemplate
+ \ IsTextEditInUse
+ \ Kyoma_Test
+ \ ModPlayerSkillExpF
+ \ mqCreateMenuFloatValue
+ \ mqCreateMenuStringValue
+ \ mqGetActiveQuest
+ \ mqGetActiveQuestTargets
+ \ mqGetCompletedQuests
+ \ mqGetCurrentQuests
+ \ mqGetEnchMenuBaseItem
+ \ mqGetHighlightedClass
+ \ mqGetMapMarkers
+ \ mqGetMenuActiveChildIndex
+ \ mqGetMenuActiveFloatValue
+ \ mqGetMenuActiveStringValue
+ \ mqGetMenuChildCount
+ \ mqGetMenuChildFloatValue
+ \ mqGetMenuChildHasTrait
+ \ mqGetMenuChildName
+ \ mqGetMenuChildStringValue
+ \ mqGetMenuGlobalFloatValue
+ \ mqGetMenuGlobalStringValue
+ \ mqGetQuestCompleted
+ \ mqGetSelectedClass
+ \ mqSetActiveQuest
+ \ mqSetMenuActiveFloatValue
+ \ mqSetMenuActiveStringValue
+ \ mqSetMenuChildFloatValue
+ \ mqSetMenuChildStringValue
+ \ mqSetMenuGlobalStringValue
+ \ mqSetMenuGlobalFloatValue
+ \ mqSetMessageBoxSource
+ \ mqUncompleteQuest
+ \ RemoveMenuEventHandler
+ \ SetMenuEventHandler
+ \ SetMouseImage
+ \ SetPlayerSkillAdvancesF
+ \ SetSkillGoverningAttributeF
+ \ SetSkillSpecializationC
+ \ SetSkillSpecializationF
+ \ SetSkillUseIncrementF
+ \ SetTextEditString
+ \ SetTrainerSkillC
+ \ SetWorldMapData
+ \ ShowGenericMenu
+ \ ShowLevelUpMenu
+ \ ShowMagicPopupMenu
+ \ ShowTextEditMenu
+ \ ShowTrainingMenu
+ \ tile_FadeFloat
+ \ tile_GetFloat
+ \ tile_GetInfo
+ \ tile_GetName
+ \ tile_GetString
+ \ tile_GetVar
+ \ tile_HasTrait
+ \ tile_SetFloat
+ \ tile_SetString
+ \ TriggerPlayerSkillUseF
+ \ UpdateLocalMap
+" }}}
+
+" eaxFunction {{{
+syn keyword eaxFunction
+ \ CreateEAXeffect
+ \ DeleteEAXeffect
+ \ DisableEAX
+ \ EAXcopyEffect
+ \ EAXeffectExists
+ \ EAXeffectsAreEqual
+ \ EAXgetActiveEffect
+ \ EAXnumEffects
+ \ EAXpushEffect
+ \ EAXpopEffect
+ \ EAXremoveAllInstances
+ \ EAXremoveFirstInstance
+ \ EAXstackIsEmpty
+ \ EAXstackSize
+ \ EnableEAX
+ \ GetEAXAirAbsorptionHF
+ \ GetEAXDecayHFRatio
+ \ GetEAXDecayTime
+ \ GetEAXEnvironment
+ \ GetEAXEnvironmentSize
+ \ GetEAXEnvironmentDiffusion
+ \ GetEAXReflections
+ \ GetEAXReflectionsDelay
+ \ GetEAXReverb
+ \ GetEAXReverbDelay
+ \ GetEAXRoom
+ \ GetEAXRoomHF
+ \ GetEAXRoomRolloffFactor
+ \ InitializeEAX
+ \ IsEAXEnabled
+ \ IsEAXInitialized
+ \ SetEAXAirAbsorptionHF
+ \ SetEAXallProperties
+ \ SetEAXDecayTime
+ \ SetEAXDecayHFRatio
+ \ SetEAXEnvironment
+ \ SetEAXEnvironmentSize
+ \ SetEAXEnvironmentDiffusion
+ \ SetEAXReflections
+ \ SetEAXReflectionsDelay
+ \ SetEAXReverb
+ \ SetEAXReverbDelay
+ \ SetEAXRoom
+ \ SetEAXRoomHF
+ \ SetEAXRoomRolloffFactor
+" }}}
+
+" networkPipeFunction {{{
+syn keyword networkPipeFunction
+ \ NetworkPipe_CreateClient
+ \ NetworkPipe_GetData
+ \ NetworkPipe_IsNewGame
+ \ NetworkPipe_KillClient
+ \ NetworkPipe_Receive
+ \ NetworkPipe_SetData
+ \ NetworkPipe_Send
+ \ NetworkPipe_StartService
+ \ NetworkPipe_StopService
+" }}}
+
+" nifseFunction {{{
+syn keyword nifseFunction
+ \ BSFurnitureMarkerGetPositionRefs
+ \ BSFurnitureMarkerSetPositionRefs
+ \ GetNifTypeIndex
+ \ NiAVObjectAddProperty
+ \ NiAVObjectClearCollisionObject
+ \ NiAVObjectCopyCollisionObject
+ \ NiAVObjectDeleteProperty
+ \ NiAVObjectGetCollisionMode
+ \ NiAVObjectGetCollisionObject
+ \ NiAVObjectGetLocalRotation
+ \ NiAVObjectGetLocalScale
+ \ NiAVObjectGetLocalTransform
+ \ NiAVObjectGetLocalTranslation
+ \ NiAVObjectGetNumProperties
+ \ NiAVObjectGetProperties
+ \ NiAVObjectGetPropertyByType
+ \ NiAVObjectSetCollisionMode
+ \ NiAVObjectSetLocalRotation
+ \ NiAVObjectSetLocalScale
+ \ NiAVObjectSetLocalTransform
+ \ NiAVObjectSetLocalTranslation
+ \ NiAlphaPropertyGetBlendState
+ \ NiAlphaPropertyGetDestinationBlendFunction
+ \ NiAlphaPropertyGetSourceBlendFunction
+ \ NiAlphaPropertyGetTestFunction
+ \ NiAlphaPropertyGetTestState
+ \ NiAlphaPropertyGetTestThreshold
+ \ NiAlphaPropertyGetTriangleSortMode
+ \ NiAlphaPropertySetBlendState
+ \ NiAlphaPropertySetDestinationBlendFunction
+ \ NiAlphaPropertySetSourceBlendFunction
+ \ NiAlphaPropertySetTestFunction
+ \ NiAlphaPropertySetTestState
+ \ NiAlphaPropertySetTestThreshold
+ \ NiAlphaPropertySetTriangleSortMode
+ \ NiExtraDataGetArray
+ \ NiExtraDataGetName
+ \ NiExtraDataGetNumber
+ \ NiExtraDataGetString
+ \ NiExtraDataSetArray
+ \ NiExtraDataSetName
+ \ NiExtraDataSetNumber
+ \ NiExtraDataSetString
+ \ NiMaterialPropertyGetAmbientColor
+ \ NiMaterialPropertyGetDiffuseColor
+ \ NiMaterialPropertyGetEmissiveColor
+ \ NiMaterialPropertyGetGlossiness
+ \ NiMaterialPropertyGetSpecularColor
+ \ NiMaterialPropertyGetTransparency
+ \ NiMaterialPropertySetAmbientColor
+ \ NiMaterialPropertySetDiffuseColor
+ \ NiMaterialPropertySetEmissiveColor
+ \ NiMaterialPropertySetGlossiness
+ \ NiMaterialPropertySetSpecularColor
+ \ NiMaterialPropertySetTransparency
+ \ NiNodeAddChild
+ \ NiNodeCopyChild
+ \ NiNodeDeleteChild
+ \ NiNodeGetChildByName
+ \ NiNodeGetChildren
+ \ NiNodeGetNumChildren
+ \ NiObjectGetType
+ \ NiObjectGetTypeName
+ \ NiObjectNETAddExtraData
+ \ NiObjectNETDeleteExtraData
+ \ NiObjectNETGetExtraData
+ \ NiObjectNETGetExtraDataByName
+ \ NiObjectNETGetName
+ \ NiObjectNETGetNumExtraData
+ \ NiObjectNETSetName
+ \ NiObjectTypeDerivesFrom
+ \ NiSourceTextureGetFile
+ \ NiSourceTextureIsExternal
+ \ NiSourceTextureSetExternalTexture
+ \ NiStencilPropertyGetFaceDrawMode
+ \ NiStencilPropertyGetFailAction
+ \ NiStencilPropertyGetPassAction
+ \ NiStencilPropertyGetStencilFunction
+ \ NiStencilPropertyGetStencilMask
+ \ NiStencilPropertyGetStencilRef
+ \ NiStencilPropertyGetStencilState
+ \ NiStencilPropertyGetZFailAction
+ \ NiStencilPropertySetFaceDrawMode
+ \ NiStencilPropertySetFailAction
+ \ NiStencilPropertySetPassAction
+ \ NiStencilPropertySetStencilFunction
+ \ NiStencilPropertySetStencilMask
+ \ NiStencilPropertySetStencilRef
+ \ NiStencilPropertySetStencilState
+ \ NiStencilPropertySetZFailAction
+ \ NiTexturingPropertyAddTextureSource
+ \ NiTexturingPropertyDeleteTextureSource
+ \ NiTexturingPropertyGetTextureCenterOffset
+ \ NiTexturingPropertyGetTextureClampMode
+ \ NiTexturingPropertyGetTextureCount
+ \ NiTexturingPropertyGetTextureFilterMode
+ \ NiTexturingPropertyGetTextureFlags
+ \ NiTexturingPropertyGetTextureRotation
+ \ NiTexturingPropertyGetTextureSource
+ \ NiTexturingPropertyGetTextureTiling
+ \ NiTexturingPropertyGetTextureTranslation
+ \ NiTexturingPropertyGetTextureUVSet
+ \ NiTexturingPropertyHasTexture
+ \ NiTexturingPropertySetTextureCenterOffset
+ \ NiTexturingPropertySetTextureClampMode
+ \ NiTexturingPropertySetTextureCount
+ \ NiTexturingPropertySetTextureFilterMode
+ \ NiTexturingPropertySetTextureFlags
+ \ NiTexturingPropertySetTextureHasTransform
+ \ NiTexturingPropertySetTextureRotation
+ \ NiTexturingPropertySetTextureTiling
+ \ NiTexturingPropertySetTextureTranslation
+ \ NiTexturingPropertySetTextureUVSet
+ \ NiTexturingPropertyTextureHasTransform
+ \ NiVertexColorPropertyGetLightingMode
+ \ NiVertexColorPropertyGetVertexMode
+ \ NiVertexColorPropertySetLightingMode
+ \ NiVertexColorPropertySetVertexMode
+ \ NifClose
+ \ NifGetAltGrip
+ \ NifGetBackShield
+ \ NifGetNumBlocks
+ \ NifGetOffHand
+ \ NifGetOriginalPath
+ \ NifGetPath
+ \ NifOpen
+ \ NifWriteToDisk
+" }}}
+
+" reidFunction {{{
+syn keyword reidFunction
+ \ GetRuntimeEditorID
+" }}}
+
+" runtimeDebuggerFunction {{{
+syn keyword runtimeDebuggerFunction
+ \ DebugBreak
+ \ ToggleDebugBreaking
+" }}}
+
+" addActorValuesFunction {{{
+syn keyword addActorValuesFunction
+ \ DumpActorValueC
+ \ DumpActorValueF
+ \ GetActorValueBaseCalcC
+ \ GetActorValueBaseCalcF
+ \ GetActorValueCurrentC
+ \ GetActorValueCurrentF
+ \ GetActorValueMaxC
+ \ GetActorValueMaxF
+ \ GetActorValueModC
+ \ GetActorValueModF
+ \ ModActorValueModC
+ \ ModActorValueModF
+ \ SetActorValueModC
+ \ SetActorValueModF
+ \ DumpAVC
+ \ DumpAVF
+ \ GetAVModC
+ \ GetAVModF
+ \ ModAVModC
+ \ ModAVModF
+ \ SetAVModC
+ \ SetAVModF
+ \ GetAVBaseCalcC
+ \ GetAVBaseCalcF
+ \ GetAVMaxC
+ \ GetAVMaxF
+ \ GetAVCurrentC
+ \ GetAVCurrent
+" }}}
+
+" memoryDumperFunction {{{
+syn keyword memoryDumperFunction
+ \ SetDumpAddr
+ \ SetDumpType
+ \ SetFadeAmount
+ \ SetObjectAddr
+ \ ShowMemoryDump
+" }}}
+
+" algoholFunction {{{
+syn keyword algoholFunction
+ \ QFromAxisAngle
+ \ QFromEuler
+ \ QInterpolate
+ \ QMultQuat
+ \ QMultVector3
+ \ QNormalize
+ \ QToEuler
+ \ V3Crossproduct
+ \ V3Length
+ \ V3Normalize
+" }}}
+
+" soundCommandsFunction {{{
+syn keyword soundCommandsFunction
+ \ FadeMusic
+ \ GetEffectsVolume
+ \ GetFootVolume
+ \ GetMasterVolume
+ \ GetMusicVolume
+ \ GetVoiceVolume
+ \ PlayMusicFile
+ \ SetEffectsVolume
+ \ SetFootVolume
+ \ SetMasterVolume
+ \ SetMusicVolume
+ \ SetVoiceVolume
+" }}}
+
+" emcFunction {{{
+syn keyword emcFunction
+ \ emcAddPathToPlaylist
+ \ emcCreatePlaylist
+ \ emcGetAllPlaylists
+ \ emcGetAfterBattleDelay
+ \ emcGetBattleDelay
+ \ emcGetEffectsVolume
+ \ emcGetFadeTime
+ \ emcGetFootVolume
+ \ emcGetMasterVolume
+ \ emcGetMaxRestoreTime
+ \ emcGetMusicSpeed
+ \ emcGetMusicType
+ \ emcGetMusicVolume
+ \ emcGetPauseTime
+ \ emcGetPlaylist
+ \ emcGetPlaylistTracks
+ \ emcGetTrackName
+ \ emcGetTrackDuration
+ \ emcGetTrackPosition
+ \ emcGetVoiceVolume
+ \ emcIsBattleOverridden
+ \ emcIsMusicOnHold
+ \ emcIsMusicSwitching
+ \ emcIsPlaylistActive
+ \ emcMusicNextTrack
+ \ emcMusicPause
+ \ emcMusicRestart
+ \ emcMusicResume
+ \ emcMusicStop
+ \ emcPlaylistExists
+ \ emcPlayTrack
+ \ emcRestorePlaylist
+ \ emcSetAfterBattleDelay
+ \ emcSetBattleDelay
+ \ emcSetBattleOverride
+ \ emcSetEffectsVolume
+ \ emcSetFadeTime
+ \ emcSetFootVolume
+ \ emcSetMasterVolume
+ \ emcSetMaxRestoreTime
+ \ emcSetMusicHold
+ \ emcSetMusicSpeed
+ \ emcSetMusicVolume
+ \ emcSetPauseTime
+ \ emcSetPlaylist
+ \ emcSetTrackPosition
+ \ emcSetMusicType
+ \ emcSetVoiceVolume
+" }}}
+
+" vipcxjFunction {{{
+syn keyword vipcxjFunction
+ \ vcAddMark
+ \ vcGetFilePath
+ \ vcGetHairColorRGB
+ \ vcGetValueNumeric
+ \ vcGetValueString
+ \ vcIsMarked
+ \ vcPrintIni
+ \ vcSetActorState
+ \ vcSetHairColor
+ \ vcSetHairColorRGB
+ \ vcSetHairColorRGB3P
+" }}}
+
+" cameraCommandsFunction {{{
+syn keyword cameraCommandsFunction
+ \ CameraGetRef
+ \ CameraLookAt
+ \ CameraLookAtPosition
+ \ CameraMove
+ \ CameraMoveToPosition
+ \ CameraReset
+ \ CameraRotate
+ \ CameraRotateToPosition
+ \ CameraSetRef
+ \ CameraStopLook
+" }}}
+
+" obmeFunction {{{
+syn keyword obmeFunction
+ \ ClearNthEIBaseCost
+ \ ClearNthEIEffectName
+ \ ClearNthEIHandlerParam
+ \ ClearNthEIHostility
+ \ ClearNthEIIconPath
+ \ ClearNthEIResistAV
+ \ ClearNthEISchool
+ \ ClearNthEIVFXCode
+ \ CreateMgef
+ \ GetMagicEffectHandlerC
+ \ GetMagicEffectHandlerParamC
+ \ GetMagicEffectHostilityC
+ \ GetNthEIBaseCost
+ \ GetNthEIEffectName
+ \ GetNthEIHandlerParam
+ \ GetNthEIHostility
+ \ GetNthEIIconPath
+ \ GetNthEIResistAV
+ \ GetNthEISchool
+ \ GetNthEIVFXCode
+ \ ResolveMgefCode
+ \ SetMagicEffectHandlerC
+ \ SetMagicEffectHandlerIntParamC
+ \ SetMagicEffectHandlerRefParamC
+ \ SetMagicEffectHostilityC
+ \ SetNthEIBaseCost
+ \ SetNthEIEffectName
+ \ SetNthEIHandlerIntParam
+ \ SetNthEIHandlerRefParam
+ \ SetNthEIHostility
+ \ SetNthEIIconPath
+ \ SetNthEIResistAV
+ \ SetNthEISchool
+ \ SetNthEIVFXCode
+" }}}
+
+" conscribeFunction {{{
+syn keyword conscribeFunction
+ \ DeleteLinesFromLog
+ \ GetLogLineCount
+ \ GetRegisteredLogNames
+ \ ReadFromLog
+ \ RegisterLog
+ \ Scribe
+ \ UnregisterLog
+" }}}
+
+" systemDialogFunction {{{
+syn keyword systemDialogFunction
+ \ Sysdlg_Browser
+ \ Sysdlg_ReadBrowser
+ \ Sysdlg_TextInput
+" }}}
+
+" csiFunction {{{
+syn keyword csiFunction
+ \ ClearSpellIcon
+ \ HasAssignedIcon
+ \ OverwriteSpellIcon
+ \ SetSpellIcon
+" }}}
+
+" haelFunction {{{
+syn keyword haelFunction
+ \ GetHUDActiveEffectLimit
+ \ SetHUDActiveEffectLimit
+" }}}
+
+" lcdFunction {{{
+syn keyword lcdFunction
+ \ lcd_addinttobuffer
+ \ lcd_addtexttobuffer
+ \ lcd_clearrect
+ \ lcd_cleartextbuffer
+ \ lcd_close
+ \ lcd_drawcircle
+ \ lcd_drawgrid
+ \ lcd_drawint
+ \ lcd_drawline
+ \ lcd_drawprogressbarh
+ \ lcd_drawprogressbarv
+ \ lcd_drawprogresscircle
+ \ lcd_drawrect
+ \ lcd_drawtext
+ \ lcd_drawtextbuffer
+ \ lcd_drawtexture
+ \ lcd_flush
+ \ lcd_getbuttonstate
+ \ lcd_getheight
+ \ lcd_getwidth
+ \ lcd_ismulti
+ \ lcd_isopen
+ \ lcd_open
+ \ lcd_refresh
+ \ lcd_savebuttonsnapshot
+ \ lcd_scale
+ \ lcd_setfont
+" }}}
+
+" Deprecated: {{{
+syn keyword obDeprecated
+ \ SetAltControl
+ \ GetAltControl
+ \ RefreshControlMap
+" }}}
+" }}}
+
+if !exists("did_obl_inits")
+
+ let did_obl_inits = 1
+ hi def link obseStatement Statement
+ hi def link obseStatementTwo Statement
+ hi def link obseDescBlock String
+ hi def link obseComment Comment
+ hi def link obseString String
+ hi def link obseStringFormatting Keyword
+ hi def link obseFloat Float
+ hi def link obseInt Number
+ hi def link obseToDo Todo
+ hi def link obseTypes Type
+ hi def link obseCondition Conditional
+ hi def link obseOperator Operator
+ hi def link obseOtherKey Special
+ hi def link obseScriptName Special
+ hi def link obseBlock Conditional
+ hi def link obseBlockType Structure
+ hi def link obseScriptNameRegion Underlined
+ hi def link obseNames Identifier
+ hi def link obseVariable Identifier
+ hi def link obseReference Special
+ hi def link obseRepeat Repeat
+
+ hi def link csFunction Function
+ hi def link obseFunction Function
+ hi def link obseArrayFunction Function
+ hi def link pluggyFunction Function
+ hi def link obseStringFunction Function
+ hi def link obseArrayFunction Function
+ hi def link tsfcFunction Function
+ hi def link blockheadFunction Function
+ hi def link switchNightEyeShaderFunction Function
+ hi def link obseivionReloadedFunction Function
+ hi def link menuQueFunction Function
+ hi def link eaxFunction Function
+ hi def link networkPipeFunction Function
+ hi def link nifseFunction Function
+ hi def link reidFunction Function
+ hi def link runtimeDebuggerFunction Function
+ hi def link addActorValuesFunction Function
+ hi def link memoryDumperFunction Function
+ hi def link algoholFunction Function
+ hi def link soundCommandsFunction Function
+ hi def link emcFunction Function
+ hi def link vipcxjFunction Function
+ hi def link cameraCommands Function
+ hi def link obmeFunction Function
+ hi def link conscribeFunction Function
+ hi def link systemDialogFunction Function
+ hi def link csiFunction Function
+ hi def link haelFunction Function
+ hi def link lcdFunction Function
+ hi def link skillAttribute String
+ hi def link obDeprecated WarningMsg
+
+endif
+
+let b:current_syntax = 'obse'
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
diff --git a/runtime/syntax/ptcap.vim b/runtime/syntax/ptcap.vim
index 1ebeb5227b..5db7bda896 100644
--- a/runtime/syntax/ptcap.vim
+++ b/runtime/syntax/ptcap.vim
@@ -53,7 +53,7 @@ syn match ptcapNumberError "#0x\x*[^[:xdigit:]:\\]"lc=1 contained
" The `=' operator assigns a string to the preceding flag
syn match ptcapOperator "[@#=]" contained
-" Some terminal capabilites have special names like `#5' and `@1', and we
+" Some terminal capabilities have special names like `#5' and `@1', and we
" need special rules to match these properly
syn match ptcapSpecialCap "\W[#@]\d" contains=ptcapDelimiter contained
diff --git a/runtime/syntax/sshconfig.vim b/runtime/syntax/sshconfig.vim
index 88665e5f6d..750289d83e 100644
--- a/runtime/syntax/sshconfig.vim
+++ b/runtime/syntax/sshconfig.vim
@@ -6,7 +6,7 @@
" Contributor: Leonard Ehrenfried <leonard.ehrenfried@web.de>
" Contributor: Karsten Hopp <karsten@redhat.com>
" Contributor: Dean, Adam Kenneth <adam.ken.dean@hpe.com>
-" Last Change: 2022 Nov 09
+" Last Change: 2022 Nov 10
" Added RemoteCommand from pull request #4809
" Included additional keywords from Martin.
" Included PR #5753
@@ -171,6 +171,7 @@ syn keyword sshconfigKeyword EnableSSHKeysign
syn keyword sshconfigKeyword EscapeChar
syn keyword sshconfigKeyword ExitOnForwardFailure
syn keyword sshconfigKeyword FingerprintHash
+syn keyword sshconfigKeyword ForkAfterAuthentication
syn keyword sshconfigKeyword ForwardAgent
syn keyword sshconfigKeyword ForwardX11
syn keyword sshconfigKeyword ForwardX11Timeout
@@ -221,13 +222,16 @@ syn keyword sshconfigKeyword RekeyLimit
syn keyword sshconfigKeyword RemoteCommand
syn keyword sshconfigKeyword RemoteForward
syn keyword sshconfigKeyword RequestTTY
+syn keyword sshconfigKeyword RequiredRSASize
syn keyword sshconfigKeyword RevokedHostKeys
syn keyword sshconfigKeyword SecurityKeyProvider
syn keyword sshconfigKeyword SendEnv
syn keyword sshconfigKeyword ServerAliveCountMax
syn keyword sshconfigKeyword ServerAliveInterval
+syn keyword sshconfigKeyword SessionType
syn keyword sshconfigKeyword SmartcardDevice
syn keyword sshconfigKeyword SetEnv
+syn keyword sshconfigKeyword StdinNull
syn keyword sshconfigKeyword StreamLocalBindMask
syn keyword sshconfigKeyword StreamLocalBindUnlink
syn keyword sshconfigKeyword StrictHostKeyChecking
diff --git a/runtime/syntax/sshdconfig.vim b/runtime/syntax/sshdconfig.vim
index d8e12047e0..c0d9c3f598 100644
--- a/runtime/syntax/sshdconfig.vim
+++ b/runtime/syntax/sshdconfig.vim
@@ -7,7 +7,7 @@
" Contributor: Leonard Ehrenfried <leonard.ehrenfried@web.de>
" Contributor: Karsten Hopp <karsten@redhat.com>
" Originally: 2009-07-09
-" Last Change: 2022 Nov 09
+" Last Change: 2022 Nov 10
" SSH Version: 8.5p1
"
@@ -221,6 +221,7 @@ syn keyword sshdconfigKeyword Match
syn keyword sshdconfigKeyword MaxAuthTries
syn keyword sshdconfigKeyword MaxSessions
syn keyword sshdconfigKeyword MaxStartups
+syn keyword sshdconfigKeyword ModuliFile
syn keyword sshdconfigKeyword PasswordAuthentication
syn keyword sshdconfigKeyword PerSourceMaxStartups
syn keyword sshdconfigKeyword PerSourceNetBlockSize
@@ -244,6 +245,7 @@ syn keyword sshdconfigKeyword PubkeyAuthentication
syn keyword sshdconfigKeyword PubkeyAuthOptions
syn keyword sshdconfigKeyword RSAAuthentication
syn keyword sshdconfigKeyword RekeyLimit
+syn keyword sshdconfigKeyword RequiredRSASize
syn keyword sshdconfigKeyword RevokedKeys
syn keyword sshdconfigKeyword RDomain
syn keyword sshdconfigKeyword RhostsRSAAuthentication
diff --git a/runtime/syntax/swayconfig.vim b/runtime/syntax/swayconfig.vim
index d9f31da47b..996b8f596c 100644
--- a/runtime/syntax/swayconfig.vim
+++ b/runtime/syntax/swayconfig.vim
@@ -2,7 +2,8 @@
" Language: sway window manager config
" Original Author: James Eapen <james.eapen@vai.org>
" Maintainer: James Eapen <james.eapen@vai.org>
-" Version: 0.11.1
+" Version: 0.1.6
+" Reference version (jamespeapen/swayconfig.vim): 0.11.6
" Last Change: 2022 Aug 08
" References:
@@ -23,10 +24,6 @@ scriptencoding utf-8
" Error
"syn match swayConfigError /.*/
-" Group mode/bar
-syn keyword swayConfigBlockKeyword set input contained
-syn region swayConfigBlock start=+.*s\?{$+ end=+^}$+ contains=i3ConfigBlockKeyword,swayConfigBlockKeyword,i3ConfigString,i3ConfigBind,i3ConfigComment,i3ConfigFont,i3ConfigFocusWrappingType,i3ConfigColor,i3ConfigVariable transparent keepend extend
-
" binding
syn keyword swayConfigBindKeyword bindswitch bindgesture contained
syn match swayConfigBind /^\s*\(bindswitch\)\s\+.*$/ contains=i3ConfigVariable,i3ConfigBindKeyword,swayConfigBindKeyword,i3ConfigVariableAndModifier,i3ConfigNumber,i3ConfigUnit,i3ConfigUnitOr,i3ConfigBindArgument,i3ConfigModifier,i3ConfigAction,i3ConfigString,i3ConfigGapStyleKeyword,i3ConfigBorderStyleKeyword
@@ -45,7 +42,7 @@ syn match swayConfigFloating /^\s*floating\s\+\(enable\|disable\|toggle\)\s*$/ c
syn clear i3ConfigFloatingModifier
syn keyword swayConfigFloatingModifier floating_modifier contained
-syn match swayConfigFloatingMouseAction /^\s\?.*floating_modifier\s.*\(normal\|inverted\)$/ contains=swayConfigFloatingModifier,i3ConfigVariable
+syn match swayConfigFloatingMouseAction /^\s\?.*floating_modifier\s\S\+\s\?\(normal\|inverted\|none\)\?$/ contains=swayConfigFloatingModifier,i3ConfigVariable
" Gaps
syn clear i3ConfigSmartBorderKeyword
@@ -57,6 +54,10 @@ syn match swayConfigSmartBorder /^\s*smart_borders\s\+\(on\|no_gaps\|off\)\s\?$/
syn keyword swayConfigClientColorKeyword focused_tab_title contained
syn match swayConfigClientColor /^\s*client.\w\+\s\+.*$/ contains=i3ConfigClientColorKeyword,i3ConfigColor,i3ConfigVariable,i3ConfigClientColorKeyword,swayConfigClientColorKeyword
+" Input config
+syn keyword swayConfigInputKeyword input contained
+syn match swayConfigInput /^\s*input\s\+.*$/ contains=swayConfigInputKeyword
+
" set display outputs
syn match swayConfigOutput /^\s*output\s\+.*$/ contains=i3ConfigOutput
@@ -65,21 +66,34 @@ syn keyword swayConfigFocusKeyword focus contained
syn keyword swayConfigFocusType output contained
syn match swayConfigFocus /^\s*focus\soutput\s.*$/ contains=swayConfigFocusKeyword,swayConfigFocusType
+" focus follows mouse
+syn clear i3ConfigFocusFollowsMouseType
+syn clear i3ConfigFocusFollowsMouse
+
+syn keyword swayConfigFocusFollowsMouseType yes no always contained
+syn match swayConfigFocusFollowsMouse /^\s*focus_follows_mouse\s\+\(yes\|no\|always\)\s\?$/ contains=i3ConfigFocusFollowsMouseKeyword,swayConfigFocusFollowsMouseType
+
+
" xwayland
syn keyword swayConfigXwaylandKeyword xwayland contained
syn match swayConfigXwaylandModifier /^\s*xwayland\s\+\(enable\|disable\|force\)\s\?$/ contains=swayConfigXwaylandKeyword
+" Group mode/bar
+syn clear i3ConfigBlock
+syn region swayConfigBlock start=+.*s\?{$+ end=+^}$+ contains=i3ConfigBlockKeyword,i3ConfigString,i3ConfigBind,i3ConfigInitializeKeyword,i3ConfigComment,i3ConfigFont,i3ConfigFocusWrappingType,i3ConfigColor,i3ConfigVariable,swayConfigInputKeyword,i3ConfigOutput transparent keepend extend
+
"hi def link swayConfigError Error
hi def link i3ConfigFloating Error
hi def link swayConfigFloating Type
hi def link swayConfigFloatingMouseAction Type
hi def link swayConfigFocusKeyword Type
hi def link swayConfigSmartBorderKeyword Type
+hi def link swayConfigInputKeyword Type
+hi def link swayConfigFocusFollowsMouseType Type
hi def link swayConfigBindGestureCommand Identifier
hi def link swayConfigBindGestureDirection Constant
hi def link swayConfigBindGesturePinchDirection Constant
hi def link swayConfigBindKeyword Identifier
-hi def link swayConfigBlockKeyword Identifier
hi def link swayConfigClientColorKeyword Identifier
hi def link swayConfigFloatingKeyword Identifier
hi def link swayConfigFloatingModifier Identifier
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index e77d3ea286..a720f055ed 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -131,6 +131,7 @@ CONFIG = {
'filetype.lua',
'keymap.lua',
'fs.lua',
+ 'secure.lua',
],
'files': [
'runtime/lua/vim/_editor.lua',
@@ -140,6 +141,7 @@ CONFIG = {
'runtime/lua/vim/filetype.lua',
'runtime/lua/vim/keymap.lua',
'runtime/lua/vim/fs.lua',
+ 'runtime/lua/vim/secure.lua',
],
'file_patterns': '*.lua',
'fn_name_prefix': '',
@@ -166,6 +168,7 @@ CONFIG = {
'filetype': 'vim.filetype',
'keymap': 'vim.keymap',
'fs': 'vim.fs',
+ 'secure': 'vim.secure',
},
'append_only': [
'shared.lua',
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index b7cd0c82fb..ca8ad16cbf 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -505,7 +505,7 @@ String buf_get_text(buf_T *buf, int64_t lnum, int64_t start_col, int64_t end_col
return rv;
}
- return cstrn_as_string((char *)&bufstr[start_col], (size_t)(end_col - start_col));
+ return cstrn_as_string(&bufstr[start_col], (size_t)(end_col - start_col));
}
void api_free_string(String value)
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index 532052f9b0..cfe887d762 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -382,7 +382,7 @@ static void parse_border_title(Object title, Object title_pos, FloatConfig *fcon
return;
}
- if (title.type == kObjectTypeArray && title.data.array.size == 0) {
+ if (title.data.array.size == 0) {
api_set_error(err, kErrorTypeValidation, "title cannot be an empty array");
return;
}
@@ -391,7 +391,6 @@ static void parse_border_title(Object title, Object title_pos, FloatConfig *fcon
fconfig->title_chunks = parse_virt_text(title.data.array, err, &fconfig->title_width);
fconfig->title = true;
- return;
}
static bool parse_title_pos(Object title_pos, FloatConfig *fconfig, Error *err)
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index 3f7c734cd1..8d17570077 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -118,8 +118,13 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
// Make sure we stick in this column.
win->w_set_curswant = true;
- // make sure cursor is in visible range even if win != curwin
- update_topline_win(win);
+ // make sure cursor is in visible range and
+ // cursorcolumn and cursorline are updated even if win != curwin
+ switchwin_T switchwin;
+ switch_win(&switchwin, win, NULL, true);
+ update_topline(curwin);
+ validate_cursor();
+ restore_win(&switchwin, true);
redraw_later(win, UPD_VALID);
win->w_redr_status = true;
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 65c22c922a..2c0cb771c3 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -123,7 +123,8 @@ return {
'WinEnter', -- after entering a window
'WinLeave', -- before leaving a window
'WinNew', -- when entering a new window
- 'WinScrolled', -- after scrolling a window
+ 'WinResized', -- after a window was resized
+ 'WinScrolled', -- after a window was scrolled or resized
},
aliases = {
BufCreate = 'BufAdd',
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 4df14411c5..426899c581 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -1141,14 +1141,19 @@ int autocmd_register(int64_t id, event_T event, char *pat, int patlen, int group
curwin->w_last_cursormoved = curwin->w_cursor;
}
- // Initialize the fields checked by the WinScrolled trigger to
- // stop it from firing right after the first autocmd is defined.
- if (event == EVENT_WINSCROLLED && !has_event(EVENT_WINSCROLLED)) {
- curwin->w_last_topline = curwin->w_topline;
- curwin->w_last_leftcol = curwin->w_leftcol;
- curwin->w_last_skipcol = curwin->w_skipcol;
- curwin->w_last_width = curwin->w_width;
- curwin->w_last_height = curwin->w_height;
+ // Initialize the fields checked by the WinScrolled and
+ // WinResized trigger to prevent them from firing right after
+ // the first autocmd is defined.
+ if ((event == EVENT_WINSCROLLED || event == EVENT_WINRESIZED)
+ && !(has_event(EVENT_WINSCROLLED) || has_event(EVENT_WINRESIZED))) {
+ tabpage_T *save_curtab = curtab;
+ FOR_ALL_TABS(tp) {
+ unuse_tabpage(curtab);
+ use_tabpage(tp);
+ snapshot_windows_scroll_size();
+ }
+ unuse_tabpage(curtab);
+ use_tabpage(save_curtab);
}
ap->cmds = NULL;
@@ -1777,7 +1782,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|| event == EVENT_SIGNAL || event == EVENT_SPELLFILEMISSING
|| event == EVENT_SYNTAX || event == EVENT_TABCLOSED
|| event == EVENT_USER || event == EVENT_WINCLOSED
- || event == EVENT_WINSCROLLED) {
+ || event == EVENT_WINRESIZED || event == EVENT_WINSCROLLED) {
fname = xstrdup(fname);
} else {
fname = FullName_save(fname, false);
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 82a4698058..1f9b8f9a65 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -274,7 +274,7 @@ int buf_init_chartab(buf_T *buf, int global)
/// @param bufsize
void trans_characters(char *buf, int bufsize)
{
- char_u *trs; // translated character
+ char *trs; // translated character
int len = (int)strlen(buf); // length of string needing translation
int room = bufsize - len; // room in buffer after string
@@ -284,8 +284,8 @@ void trans_characters(char *buf, int bufsize)
if ((trs_len = utfc_ptr2len(buf)) > 1) {
len -= trs_len;
} else {
- trs = transchar_byte((uint8_t)(*buf));
- trs_len = (int)STRLEN(trs);
+ trs = (char *)transchar_byte((uint8_t)(*buf));
+ trs_len = (int)strlen(trs);
if (trs_len > 1) {
room -= trs_len - 1;
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index 39865d7508..79ffd7552d 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -180,7 +180,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
CmdlineInfo *const ccline = get_cmdline_info();
int i, j;
char_u *p1;
- char_u *p2;
+ char *p2;
int difflen;
if (xp->xp_numfiles == -1) {
@@ -210,7 +210,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
if (type == WILD_NEXT || type == WILD_PREV || type == WILD_PUM_WANT) {
// Get next/previous match for a previous expanded pattern.
- p2 = (char_u *)ExpandOne(xp, NULL, NULL, 0, type);
+ p2 = ExpandOne(xp, NULL, NULL, 0, type);
} else {
// Translate string into pattern and expand it.
p1 = (char_u *)addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
@@ -220,8 +220,8 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
| WILD_SILENT
| (escape ? WILD_ESCAPE : 0)
| (p_wic ? WILD_ICASE : 0));
- p2 = (char_u *)ExpandOne(xp, (char *)p1, xstrnsave(&ccline->cmdbuff[i], xp->xp_pattern_len),
- use_options, type);
+ p2 = ExpandOne(xp, (char *)p1, xstrnsave(&ccline->cmdbuff[i], xp->xp_pattern_len),
+ use_options, type);
xfree(p1);
// xp->xp_pattern might have been modified by ExpandOne (for example,
@@ -237,14 +237,14 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
break;
}
}
- if ((int)STRLEN(p2) < j) {
+ if ((int)strlen(p2) < j) {
XFREE_CLEAR(p2);
}
}
}
if (p2 != NULL && !got_int) {
- difflen = (int)STRLEN(p2) - (int)(xp->xp_pattern_len);
+ difflen = (int)strlen(p2) - (int)(xp->xp_pattern_len);
if (ccline->cmdlen + difflen + 4 > ccline->cmdbufflen) {
realloc_cmdbuff(ccline->cmdlen + difflen + 4);
xp->xp_pattern = ccline->cmdbuff + i;
@@ -253,7 +253,7 @@ int nextwild(expand_T *xp, int type, int options, bool escape)
memmove(&ccline->cmdbuff[ccline->cmdpos + difflen],
&ccline->cmdbuff[ccline->cmdpos],
(size_t)ccline->cmdlen - (size_t)ccline->cmdpos + 1);
- memmove(&ccline->cmdbuff[i], p2, STRLEN(p2));
+ memmove(&ccline->cmdbuff[i], p2, strlen(p2));
ccline->cmdlen += difflen;
ccline->cmdpos += difflen;
}
@@ -588,7 +588,7 @@ static char *ExpandOne_start(int mode, expand_T *xp, char *str, int options)
char *ss = NULL;
// Do the expansion.
- if (ExpandFromContext(xp, (char_u *)str, &xp->xp_numfiles, &xp->xp_files, options) == FAIL) {
+ if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files, options) == FAIL) {
#ifdef FNAME_ILLEGAL
// Illegal file name has been silently skipped. But when there
// are wildcards, the real problem is that there was no match,
@@ -1600,13 +1600,13 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, cons
case CMD_doautoall:
return (const char *)set_context_in_autocmd(xp, (char *)arg, true);
case CMD_set:
- set_context_in_set_cmd(xp, (char_u *)arg, 0);
+ set_context_in_set_cmd(xp, (char *)arg, 0);
break;
case CMD_setglobal:
- set_context_in_set_cmd(xp, (char_u *)arg, OPT_GLOBAL);
+ set_context_in_set_cmd(xp, (char *)arg, OPT_GLOBAL);
break;
case CMD_setlocal:
- set_context_in_set_cmd(xp, (char_u *)arg, OPT_LOCAL);
+ set_context_in_set_cmd(xp, (char *)arg, OPT_LOCAL);
break;
case CMD_tag:
case CMD_stag:
@@ -2163,7 +2163,7 @@ int expand_cmdline(expand_T *xp, const char_u *str, int col, int *matchcount, ch
}
// find all files that match the description
- if (ExpandFromContext(xp, file_str, matchcount, matches, options) == FAIL) {
+ if (ExpandFromContext(xp, (char *)file_str, matchcount, matches, options) == FAIL) {
*matchcount = 0;
*matches = NULL;
}
@@ -2352,7 +2352,7 @@ static int ExpandOther(expand_T *xp, regmatch_T *rmp, int *num_file, char ***fil
/// Do the expansion based on xp->xp_context and "pat".
///
/// @param options WILD_ flags
-static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char ***file, int options)
+static int ExpandFromContext(expand_T *xp, char *pat, int *num_file, char ***file, int options)
{
regmatch_T regmatch;
int ret;
@@ -2381,7 +2381,7 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char ***f
if (xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_FILES_IN_PATH) {
- return expand_files_and_dirs(xp, (char *)pat, file, num_file, flags, options);
+ return expand_files_and_dirs(xp, pat, file, num_file, flags, options);
}
*file = NULL;
@@ -2389,7 +2389,7 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char ***f
if (xp->xp_context == EXPAND_HELP) {
// With an empty argument we would get all the help tags, which is
// very slow. Get matches for "help" instead.
- if (find_help_tags(*pat == NUL ? "help" : (char *)pat,
+ if (find_help_tags(*pat == NUL ? "help" : pat,
num_file, file, false) == OK) {
cleanup_help_tags(*num_file, *file);
return OK;
@@ -2399,7 +2399,7 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char ***f
if (xp->xp_context == EXPAND_SHELLCMD) {
*file = NULL;
- expand_shellcmd((char *)pat, num_file, file, flags);
+ expand_shellcmd(pat, num_file, file, flags);
return OK;
}
if (xp->xp_context == EXPAND_OLD_SETTING) {
@@ -2407,30 +2407,30 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char ***f
return OK;
}
if (xp->xp_context == EXPAND_BUFFERS) {
- return ExpandBufnames((char *)pat, num_file, file, options);
+ return ExpandBufnames(pat, num_file, file, options);
}
if (xp->xp_context == EXPAND_DIFF_BUFFERS) {
- return ExpandBufnames((char *)pat, num_file, file, options | BUF_DIFF_FILTER);
+ return ExpandBufnames(pat, num_file, file, options | BUF_DIFF_FILTER);
}
if (xp->xp_context == EXPAND_TAGS
|| xp->xp_context == EXPAND_TAGS_LISTFILES) {
- return expand_tags(xp->xp_context == EXPAND_TAGS, pat, num_file, file);
+ return expand_tags(xp->xp_context == EXPAND_TAGS, (char_u *)pat, num_file, file);
}
if (xp->xp_context == EXPAND_COLORS) {
char *directories[] = { "colors", NULL };
- return ExpandRTDir((char *)pat, DIP_START + DIP_OPT + DIP_LUA, num_file, file, directories);
+ return ExpandRTDir(pat, DIP_START + DIP_OPT + DIP_LUA, num_file, file, directories);
}
if (xp->xp_context == EXPAND_COMPILER) {
char *directories[] = { "compiler", NULL };
- return ExpandRTDir((char *)pat, DIP_LUA, num_file, file, directories);
+ return ExpandRTDir(pat, DIP_LUA, num_file, file, directories);
}
if (xp->xp_context == EXPAND_OWNSYNTAX) {
char *directories[] = { "syntax", NULL };
- return ExpandRTDir((char *)pat, 0, num_file, file, directories);
+ return ExpandRTDir(pat, 0, num_file, file, directories);
}
if (xp->xp_context == EXPAND_FILETYPE) {
char *directories[] = { "syntax", "indent", "ftplugin", NULL };
- return ExpandRTDir((char *)pat, DIP_LUA, num_file, file, directories);
+ return ExpandRTDir(pat, DIP_LUA, num_file, file, directories);
}
if (xp->xp_context == EXPAND_USER_LIST) {
return ExpandUserList(xp, num_file, file);
@@ -2439,32 +2439,32 @@ static int ExpandFromContext(expand_T *xp, char_u *pat, int *num_file, char ***f
return ExpandUserLua(xp, num_file, file);
}
if (xp->xp_context == EXPAND_PACKADD) {
- return ExpandPackAddDir((char *)pat, num_file, file);
+ return ExpandPackAddDir(pat, num_file, file);
}
// When expanding a function name starting with s:, match the <SNR>nr_
// prefix.
char *tofree = NULL;
if (xp->xp_context == EXPAND_USER_FUNC && STRNCMP(pat, "^s:", 3) == 0) {
- const size_t len = STRLEN(pat) + 20;
+ const size_t len = strlen(pat) + 20;
tofree = xmalloc(len);
snprintf(tofree, len, "^<SNR>\\d\\+_%s", pat + 3);
- pat = (char_u *)tofree;
+ pat = tofree;
}
if (xp->xp_context == EXPAND_LUA) {
ILOG("PAT %s", pat);
- return nlua_expand_pat(xp, (char *)pat, num_file, file);
+ return nlua_expand_pat(xp, pat, num_file, file);
}
- regmatch.regprog = vim_regcomp((char *)pat, p_magic ? RE_MAGIC : 0);
+ regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
if (regmatch.regprog == NULL) {
return FAIL;
}
// set ignore-case according to p_ic, p_scs and pat
- regmatch.rm_ic = ignorecase(pat);
+ regmatch.rm_ic = ignorecase((char_u *)pat);
if (xp->xp_context == EXPAND_SETTINGS
|| xp->xp_context == EXPAND_BOOL_SETTINGS) {
@@ -2651,19 +2651,19 @@ static void expand_shellcmd(char *filepat, int *num_file, char ***file, int flag
ga_grow(&ga, *num_file);
{
for (i = 0; i < *num_file; i++) {
- char_u *name = (char_u *)(*file)[i];
+ char *name = (*file)[i];
- if (STRLEN(name) > l) {
+ if (strlen(name) > l) {
// Check if this name was already found.
- hash_T hash = hash_hash(name + l);
+ hash_T hash = hash_hash((char_u *)name + l);
hashitem_T *hi =
hash_lookup(&found_ht, (const char *)(name + l),
- STRLEN(name + l), hash);
+ strlen(name + l), hash);
if (HASHITEM_EMPTY(hi)) {
// Remove the path that was prepended.
STRMOVE(name, name + l);
- ((char_u **)ga.ga_data)[ga.ga_len++] = name;
- hash_add_item(&found_ht, hi, name, hash);
+ ((char **)ga.ga_data)[ga.ga_len++] = name;
+ hash_add_item(&found_ht, hi, (char_u *)name, hash);
name = NULL;
}
}
@@ -2834,14 +2834,14 @@ void globpath(char *path, char *file, garray_T *ga, int expand_options)
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- char_u *buf = xmalloc(MAXPATHL);
+ char *buf = xmalloc(MAXPATHL);
// Loop over all entries in {path}.
while (*path != NUL) {
// Copy one item of the path to buf[] and concatenate the file name.
- copy_option_part(&path, (char *)buf, MAXPATHL, ",");
- if (STRLEN(buf) + strlen(file) + 2 < MAXPATHL) {
- add_pathsep((char *)buf);
+ copy_option_part(&path, buf, MAXPATHL, ",");
+ if (strlen(buf) + strlen(file) + 2 < MAXPATHL) {
+ add_pathsep(buf);
STRCAT(buf, file); // NOLINT
char **p;
@@ -2849,7 +2849,7 @@ void globpath(char *path, char *file, garray_T *ga, int expand_options)
(void)ExpandFromContext(&xpc, buf, &num_p, &p,
WILD_SILENT | expand_options);
if (num_p > 0) {
- ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT | expand_options);
+ ExpandEscape(&xpc, (char_u *)buf, num_p, p, WILD_SILENT | expand_options);
// Concatenate new results to previous ones.
ga_grow(ga, num_p);
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 811f397cb8..0d56319891 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -108,14 +108,14 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
|| (VIsual_active && *p_sel != 'o')
|| ((get_ve_flags() & VE_ONEMORE) && wcol < MAXCOL);
- char_u *line = (char_u *)ml_get_buf(curbuf, pos->lnum, false);
+ char *line = ml_get_buf(curbuf, pos->lnum, false);
if (wcol >= MAXCOL) {
- idx = (int)STRLEN(line) - 1 + one_more;
+ idx = (int)strlen(line) - 1 + one_more;
col = wcol;
if ((addspaces || finetune) && !VIsual_active) {
- curwin->w_curswant = linetabsize(line) + one_more;
+ curwin->w_curswant = linetabsize((char_u *)line) + one_more;
if (curwin->w_curswant > 0) {
curwin->w_curswant--;
}
@@ -129,7 +129,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
&& curwin->w_width_inner != 0
&& wcol >= (colnr_T)width
&& width > 0) {
- csize = linetabsize(line);
+ csize = linetabsize((char_u *)line);
if (csize > 0) {
csize--;
}
@@ -145,7 +145,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
}
chartabsize_T cts;
- init_chartabsize_arg(&cts, curwin, pos->lnum, 0, (char *)line, (char *)line);
+ init_chartabsize_arg(&cts, curwin, pos->lnum, 0, line, line);
while (cts.cts_vcol <= wcol && *cts.cts_ptr != NUL) {
// Count a tab for what it's worth (if list mode not on)
csize = win_lbr_chartabsize(&cts, &head);
@@ -153,7 +153,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
cts.cts_vcol += csize;
}
col = cts.cts_vcol;
- idx = (int)(cts.cts_ptr - (char *)line);
+ idx = (int)(cts.cts_ptr - line);
clear_chartabsize_arg(&cts);
// Handle all the special cases. The virtual_active() check
@@ -188,7 +188,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
col = wcol;
} else {
// Break a tab
- int linelen = (int)STRLEN(line);
+ int linelen = (int)strlen(line);
int correct = wcol - col - csize + 1; // negative!!
char_u *newline;
@@ -315,8 +315,8 @@ void check_pos(buf_T *buf, pos_T *pos)
}
if (pos->col > 0) {
- char_u *line = (char_u *)ml_get_buf(buf, pos->lnum, false);
- colnr_T len = (colnr_T)STRLEN(line);
+ char *line = ml_get_buf(buf, pos->lnum, false);
+ colnr_T len = (colnr_T)strlen(line);
if (pos->col > len) {
pos->col = len;
}
@@ -456,12 +456,13 @@ bool leftcol_changed(void)
// If the cursor is right or left of the screen, move it to last or first
// character.
- if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso)) {
+ long siso = get_sidescrolloff_value(curwin);
+ if (curwin->w_virtcol > (colnr_T)(lastcol - siso)) {
retval = true;
- coladvance((colnr_T)(lastcol - p_siso));
- } else if (curwin->w_virtcol < curwin->w_leftcol + p_siso) {
+ coladvance((colnr_T)(lastcol - siso));
+ } else if (curwin->w_virtcol < curwin->w_leftcol + siso) {
retval = true;
- coladvance((colnr_T)(curwin->w_leftcol + p_siso));
+ coladvance((colnr_T)(curwin->w_leftcol + siso));
}
// If the start of the character under the cursor is not on the screen,
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 71959cfa29..6f7d6a27ef 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -808,26 +808,26 @@ static linenr_T debuggy_find(bool file, char_u *fname, linenr_T after, garray_T
typval_T *const tv = eval_expr_no_emsg(bp);
if (tv != NULL) {
if (bp->dbg_val == NULL) {
- debug_oldval = typval_tostring(NULL);
+ debug_oldval = typval_tostring(NULL, true);
bp->dbg_val = tv;
- debug_newval = typval_tostring(bp->dbg_val);
+ debug_newval = typval_tostring(bp->dbg_val, true);
line = true;
} else {
if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK
&& tv->vval.v_number == false) {
line = true;
- debug_oldval = typval_tostring(bp->dbg_val);
+ debug_oldval = typval_tostring(bp->dbg_val, true);
// Need to evaluate again, typval_compare() overwrites "tv".
typval_T *const v = eval_expr_no_emsg(bp);
- debug_newval = typval_tostring(v);
+ debug_newval = typval_tostring(v, true);
tv_free(bp->dbg_val);
bp->dbg_val = v;
}
tv_free(tv);
}
} else if (bp->dbg_val != NULL) {
- debug_oldval = typval_tostring(bp->dbg_val);
- debug_newval = typval_tostring(NULL);
+ debug_oldval = typval_tostring(bp->dbg_val, true);
+ debug_newval = typval_tostring(NULL, true);
tv_free(bp->dbg_val);
bp->dbg_val = NULL;
line = true;
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 4b71142c11..121b98d047 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1043,7 +1043,7 @@ static int check_external_diff(diffio_T *diffio)
for (;;) {
// For normal diff there must be a line that contains
// "1c1". For unified diff "@@ -1 +1 @@".
- if (vim_fgets((char_u *)linebuf, LBUFLEN, fd)) {
+ if (vim_fgets(linebuf, LBUFLEN, fd)) {
break;
}
@@ -1218,9 +1218,9 @@ void ex_diffpatch(exarg_T *eap)
esc_name =
(char *)vim_strsave_shellescape((char_u *)(fullname != NULL ? fullname : eap->arg), true, true);
#else
- esc_name = vim_strsave_shellescape(eap->arg, true, true);
+ esc_name = (char *)vim_strsave_shellescape(eap->arg, true, true);
#endif
- size_t buflen = STRLEN(tmp_orig) + STRLEN(esc_name) + STRLEN(tmp_new) + 16;
+ size_t buflen = strlen(tmp_orig) + strlen(esc_name) + strlen(tmp_new) + 16;
buf = xmalloc(buflen);
#ifdef UNIX
@@ -1557,7 +1557,7 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle)
{
for (;;) {
char line[LBUFLEN]; // only need to hold the diff line
- if (vim_fgets((char_u *)line, LBUFLEN, fd)) {
+ if (vim_fgets(line, LBUFLEN, fd)) {
return true; // end of file
}
@@ -1577,9 +1577,9 @@ static bool extract_hunk(FILE *fd, diffhunk_T *hunk, diffstyle_T *diffstyle)
} else if ((STRNCMP(line, "@@ ", 3) == 0)) {
*diffstyle = DIFF_UNIFIED;
} else if ((STRNCMP(line, "--- ", 4) == 0) // -V501
- && (vim_fgets((char_u *)line, LBUFLEN, fd) == 0) // -V501
+ && (vim_fgets(line, LBUFLEN, fd) == 0) // -V501
&& (STRNCMP(line, "+++ ", 4) == 0)
- && (vim_fgets((char_u *)line, LBUFLEN, fd) == 0) // -V501
+ && (vim_fgets(line, LBUFLEN, fd) == 0) // -V501
&& (STRNCMP(line, "@@ ", 3) == 0)) {
*diffstyle = DIFF_UNIFIED;
} else {
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 93f3ea569e..f0637549f7 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -618,6 +618,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
LineDrawState draw_state = WL_START; // what to draw next
+ int match_conc = 0; ///< cchar for match functions
+ bool on_last_col = false;
int syntax_flags = 0;
int syntax_seqnr = 0;
int prev_syntax_id = 0;
@@ -627,7 +629,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
///< force wrapping
int vcol_off = 0; ///< offset for concealed characters
int did_wcol = false;
- int match_conc = 0; ///< cchar for match functions
int old_boguscols = 0;
#define VCOL_HLC (vcol - vcol_off)
#define FIX_FOR_BOGUSCOLS \
@@ -1429,8 +1430,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
// When another match, have to check for start again.
v = (ptr - line);
search_attr = update_search_hl(wp, lnum, (colnr_T)v, &line, &screen_search_hl,
- &has_match_conc,
- &match_conc, lcs_eol_one, &search_attr_from_match);
+ &has_match_conc, &match_conc, lcs_eol_one,
+ &on_last_col, &search_attr_from_match);
ptr = line + v; // "line" may have been changed
// Do not allow a conceal over EOL otherwise EOL will be missed
@@ -1843,6 +1844,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
n_extra = 0;
}
}
+ if (on_last_col && c != TAB) {
+ // Do not continue search/match highlighting over the
+ // line break, but for TABs the highlighting should
+ // include the complete width of the character
+ search_attr = 0;
+ }
if (c == TAB && n_extra + col > grid->cols) {
n_extra = tabstop_padding((colnr_T)vcol, wp->w_buffer->b_p_ts,
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 91a67c7c50..cfcc33c65e 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1339,8 +1339,7 @@ void ins_redraw(bool ready)
}
if (ready) {
- // Trigger Scroll if viewport changed.
- may_trigger_winscrolled();
+ may_trigger_win_scrolled_resized();
}
// Trigger BufModified if b_changed_invalid is set.
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 4b52cae777..a41a559fd9 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -90,6 +90,7 @@
#define DICT_MAXNEST 100 // maximum nesting of lists and dicts
static char *e_missbrac = N_("E111: Missing ']'");
+static char *e_list_end = N_("E697: Missing end of List ']': %s");
static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
static char *e_nowhitespace
= N_("E274: No white space allowed before parenthesis");
@@ -1235,8 +1236,6 @@ int eval_foldexpr(char *arg, int *cp)
return (int)retval;
}
-// TODO(ZyX-I): move to eval/executor
-
/// Get an lvalue
///
/// Lvalue may be
@@ -1621,8 +1620,6 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
return p;
}
-// TODO(ZyX-I): move to eval/executor
-
/// Clear lval "lp" that was filled by get_lval().
void clear_lval(lval_T *lp)
{
@@ -1630,8 +1627,6 @@ void clear_lval(lval_T *lp)
xfree(lp->ll_newkey);
}
-// TODO(ZyX-I): move to eval/executor
-
/// Set a variable that was parsed by get_lval() to "rettv".
///
/// @param endp points to just after the parsed name.
@@ -1839,8 +1834,6 @@ notify:
}
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Evaluate the expression used in a ":for var in expr" command.
/// "arg" points to "var".
///
@@ -1916,8 +1909,6 @@ void *eval_for_line(const char *arg, bool *errp, char **nextcmdp, int skip)
return fi;
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Use the first item in a ":for" list. Advance to the next.
/// Assign the values to the variable (list). "arg" points to the first one.
///
@@ -1964,8 +1955,6 @@ bool next_for_item(void *fi_void, char *arg)
fi->fi_semicolon, fi->fi_varcount, false, NULL) == OK);
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Free the structure used to store info used by ":for".
void free_for_info(void *fi_void)
{
@@ -2211,8 +2200,6 @@ char *get_user_var_name(expand_T *xp, int idx)
return NULL;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Does not use 'cpo' and always uses 'magic'.
///
/// @return true if "pat" matches "text".
@@ -2292,8 +2279,6 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ
return ret;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// The "evaluate" argument: When false, the argument is only parsed but not
/// executed. The function may return OK, but the rettv will be of type
/// VAR_UNKNOWN. The function still returns FAIL for a syntax error.
@@ -2343,8 +2328,6 @@ int eval0(char *arg, typval_T *rettv, char **nextcmd, int evaluate)
return ret;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle top level expression:
/// expr2 ? expr1 : expr1
///
@@ -2409,8 +2392,6 @@ int eval1(char **arg, typval_T *rettv, int evaluate)
return OK;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle first level expression:
/// expr2 || expr2 || expr2 logical OR
///
@@ -2468,8 +2449,6 @@ static int eval2(char **arg, typval_T *rettv, int evaluate)
return OK;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle second level expression:
/// expr3 && expr3 && expr3 logical AND
///
@@ -2527,8 +2506,6 @@ static int eval3(char **arg, typval_T *rettv, int evaluate)
return OK;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle third level expression:
/// var1 == var2
/// var1 =~ var2
@@ -2632,8 +2609,6 @@ static int eval4(char **arg, typval_T *rettv, int evaluate)
return OK;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle fourth level expression:
/// + number addition
/// - number subtraction
@@ -2795,8 +2770,6 @@ static int eval5(char **arg, typval_T *rettv, int evaluate)
return OK;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle fifth level expression:
/// - * number multiplication
/// - / number division
@@ -2912,8 +2885,6 @@ static int eval6(char **arg, typval_T *rettv, int evaluate, int want_string)
return OK;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Handle sixth level expression:
/// number number constant
/// 0zFFFFFFFF Blob constant
@@ -3407,8 +3378,6 @@ static int eval_method(char **const arg, typval_T *const rettv, const bool evalu
return ret;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
/// "*arg" points to the '[' or '.'.
///
@@ -3708,8 +3677,6 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose)
return OK;
}
-// TODO(ZyX-I): move to eval/executor
-
/// Get an option value
///
/// @param[in,out] arg Points to the '&' or '+' before the option name. Is
@@ -3973,8 +3940,6 @@ char *partial_name(partial_T *pt)
return (char *)pt->pt_func->uf_name;
}
-// TODO(ZyX-I): Move to eval/typval.h
-
static void partial_free(partial_T *pt)
{
for (int i = 0; i < pt->pt_argc; i++) {
@@ -3991,8 +3956,6 @@ static void partial_free(partial_T *pt)
xfree(pt);
}
-// TODO(ZyX-I): Move to eval/typval.h
-
/// Unreference a closure: decrement the reference count and free it when it
/// becomes zero.
void partial_unref(partial_T *pt)
@@ -4035,7 +3998,7 @@ static int get_list_tv(char **arg, typval_T *rettv, int evaluate)
}
if (**arg != ']') {
- semsg(_("E697: Missing end of List ']': %s"), *arg);
+ semsg(_(e_list_end), *arg);
failret:
if (evaluate) {
tv_list_free(l);
@@ -5591,9 +5554,9 @@ void screenchar_adjust(ScreenGrid **grid, int *row, int *col)
*col -= (*grid)->comp_col;
}
-/// Set line or list of lines in buffer "buf".
-void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T *lines,
- typval_T *rettv)
+/// Set line or list of lines in buffer "buf" to "lines".
+/// Any type is allowed and converted to a string.
+void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, typval_T *lines, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(4, 5)
{
linenr_T lnum = lnum_arg + (append ? 1 : 0);
@@ -5631,7 +5594,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
list_T *l = NULL;
listitem_T *li = NULL;
- const char *line = NULL;
+ char *line = NULL;
if (lines->v_type == VAR_LIST) {
l = lines->vval.v_list;
if (l == NULL || tv_list_len(l) == 0) {
@@ -5643,7 +5606,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
}
li = tv_list_first(l);
} else {
- line = tv_get_string_chk(lines);
+ line = typval_tostring(lines, false);
}
// Default result is zero == OK.
@@ -5653,7 +5616,8 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
if (li == NULL) {
break;
}
- line = tv_get_string_chk(TV_LIST_ITEM_TV(li));
+ xfree(line);
+ line = typval_tostring(TV_LIST_ITEM_TV(li), false);
li = TV_LIST_ITEM_NEXT(l, li);
}
@@ -5673,7 +5637,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
// Existing line, replace it.
int old_len = (int)strlen(ml_get(lnum));
if (u_savesub(lnum) == OK
- && ml_replace(lnum, (char *)line, true) == OK) {
+ && ml_replace(lnum, line, true) == OK) {
inserted_bytes(lnum, 0, old_len, (int)strlen(line));
if (is_curbuf && lnum == curwin->w_cursor.lnum) {
check_cursor_col();
@@ -5683,7 +5647,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
} else if (added > 0 || u_save(lnum - 1, lnum) == OK) {
// append the line.
added++;
- if (ml_append(lnum - 1, (char *)line, 0, false) == OK) {
+ if (ml_append(lnum - 1, line, 0, false) == OK) {
rettv->vval.v_number = 0; // OK
}
}
@@ -5693,6 +5657,7 @@ void set_buffer_lines(buf_T *buf, linenr_T lnum_arg, bool append, const typval_T
}
lnum++;
}
+ xfree(line);
if (added > 0) {
appended_lines_mark(append_lnum, added);
@@ -8964,10 +8929,16 @@ int typval_compare(typval_T *typ1, typval_T *typ2, exprtype_T type, bool ic)
return OK;
}
-char *typval_tostring(typval_T *arg)
+/// Convert any type to a string, never give an error.
+/// When "quotes" is true add quotes to a string.
+/// Returns an allocated string.
+char *typval_tostring(typval_T *arg, bool quotes)
{
if (arg == NULL) {
return xstrdup("(does not exist)");
}
+ if (!quotes && arg->v_type == VAR_STRING) {
+ return xstrdup(arg->vval.v_string == NULL ? "" : arg->vval.v_string);
+ }
return encode_tv2string(arg, NULL);
}
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index dd30f51eb4..14be6aba73 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -146,6 +146,7 @@ return {
get={args={2, 3}, base=1},
getbufinfo={args={0, 1}, base=1},
getbufline={args={2, 3}, base=1},
+ getbufoneline={args=2, base=1},
getbufvar={args={2, 3}, base=1},
getchangelist={args={0, 1}, base=1},
getchar={args={0, 1}},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 244802a183..8ab1178b17 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -2343,13 +2343,13 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST) {
xfree(fresult);
}
- fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
- first ? strlen(fname) : 0,
- 0, first, path,
- find_what, (char_u *)curbuf->b_ffname,
- (find_what == FINDFILE_DIR
- ? (char_u *)""
- : (char_u *)curbuf->b_p_sua));
+ fresult = (char_u *)find_file_in_path_option(first ? (char *)fname : NULL,
+ first ? strlen(fname) : 0,
+ 0, first, (char *)path,
+ find_what, curbuf->b_ffname,
+ (find_what == FINDFILE_DIR
+ ? ""
+ : curbuf->b_p_sua));
first = false;
if (fresult != NULL && rettv->v_type == VAR_LIST) {
@@ -2528,13 +2528,17 @@ static void f_get(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
const char *const what = tv_get_string(&argvars[1]);
if (strcmp(what, "func") == 0 || strcmp(what, "name") == 0) {
+ const char *name = (const char *)partial_name(pt);
rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING);
- const char *const n = (const char *)partial_name(pt);
- assert(n != NULL);
- rettv->vval.v_string = xstrdup(n);
+ assert(name != NULL);
if (rettv->v_type == VAR_FUNC) {
- func_ref((char_u *)rettv->vval.v_string);
+ func_ref((char_u *)name);
}
+ if (*what == 'n' && pt->pt_name == NULL && pt->pt_func != NULL) {
+ // use <SNR> instead of the byte code
+ name = (const char *)printable_func_name(pt->pt_func);
+ }
+ rettv->vval.v_string = xstrdup(name);
} else if (strcmp(what, "dict") == 0) {
what_is_dict = true;
if (pt->pt_dict != NULL) {
@@ -2667,8 +2671,9 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli
}
}
-/// "getbufline()" function
-static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+/// @param retlist true: "getbufline()" function
+/// false: "getbufoneline()" function
+static void getbufline(typval_T *argvars, typval_T *rettv, bool retlist)
{
const int did_emsg_before = did_emsg;
buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
@@ -2680,7 +2685,19 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
? lnum
: tv_get_lnum_buf(&argvars[2], buf));
- get_buffer_lines(buf, lnum, end, true, rettv);
+ get_buffer_lines(buf, lnum, end, retlist, rettv);
+}
+
+/// "getbufline()" function
+static void f_getbufline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ getbufline(argvars, rettv, true);
+}
+
+/// "getbufoneline()" function
+static void f_getbufoneline(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
+{
+ getbufline(argvars, rettv, false);
}
/// "getchangelist()" function
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index f38e07f09d..25b2a20bac 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -2446,10 +2446,10 @@ void tv_dict_clear(dict_T *const d)
///
/// @param d1 Dictionary to extend.
/// @param[in] d2 Dictionary to extend with.
-/// @param[in] action "error", "force", "keep":
-///
+/// @param[in] action "error", "force", "move", "keep":
/// e*, including "error": duplicate key gives an error.
/// f*, including "force": duplicate d2 keys override d1.
+/// m*, including "move": move items instead of copying.
/// other, including "keep": duplicate d2 keys ignored.
void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action)
FUNC_ATTR_NONNULL_ALL
@@ -2458,19 +2458,33 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action
const char *const arg_errmsg = _("extend() argument");
const size_t arg_errmsg_len = strlen(arg_errmsg);
- TV_DICT_ITER(d2, di2, {
+ if (*action == 'm') {
+ hash_lock(&d2->dv_hashtab); // don't rehash on hash_remove()
+ }
+
+ HASHTAB_ITER(&d2->dv_hashtab, hi2, {
+ dictitem_T *const di2 = TV_DICT_HI2DI(hi2);
dictitem_T *const di1 = tv_dict_find(d1, (const char *)di2->di_key, -1);
// Check the key to be valid when adding to any scope.
if (d1->dv_scope != VAR_NO_SCOPE && !valid_varname((const char *)di2->di_key)) {
break;
}
if (di1 == NULL) {
- dictitem_T *const new_di = tv_dict_item_copy(di2);
- if (tv_dict_add(d1, new_di) == FAIL) {
- tv_dict_item_free(new_di);
- } else if (watched) {
- tv_dict_watcher_notify(d1, (const char *)new_di->di_key, &new_di->di_tv,
- NULL);
+ if (*action == 'm') {
+ // Cheap way to move a dict item from "d2" to "d1".
+ // If dict_add() fails then "d2" won't be empty.
+ dictitem_T *const new_di = di2;
+ if (tv_dict_add(d1, new_di) == OK) {
+ hash_remove(&d2->dv_hashtab, hi2);
+ tv_dict_watcher_notify(d1, (const char *)new_di->di_key, &new_di->di_tv, NULL);
+ }
+ } else {
+ dictitem_T *const new_di = tv_dict_item_copy(di2);
+ if (tv_dict_add(d1, new_di) == FAIL) {
+ tv_dict_item_free(new_di);
+ } else if (watched) {
+ tv_dict_watcher_notify(d1, (const char *)new_di->di_key, &new_di->di_tv, NULL);
+ }
}
} else if (*action == 'e') {
semsg(_("E737: Key already exists: %s"), di2->di_key);
@@ -2501,6 +2515,10 @@ void tv_dict_extend(dict_T *const d1, dict_T *const d2, const char *const action
}
}
});
+
+ if (*action == 'm') {
+ hash_unlock(&d2->dv_hashtab);
+ }
}
/// Compare two dictionaries
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 2210a61d7c..42f78422cb 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -297,6 +297,7 @@ int get_lambda_tv(char **arg, typval_T *rettv, bool evaluate)
e = (char_u *)(*arg);
*arg = skipwhite(*arg);
if (**arg != '}') {
+ semsg(_("E451: Expected }: %s"), *arg);
goto errret;
}
(*arg)++;
@@ -1651,6 +1652,11 @@ theend:
return ret;
}
+char_u *printable_func_name(ufunc_T *fp)
+{
+ return fp->uf_name_exp != NULL ? fp->uf_name_exp : fp->uf_name;
+}
+
/// List the head of the function: "name(arg1, arg2)".
///
/// @param[in] fp Function pointer.
@@ -2954,8 +2960,6 @@ void ex_return(exarg_T *eap)
}
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// ":1,25call func(arg1, arg2)" function call.
void ex_call(exarg_T *eap)
{
diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c
index 54ff0a53d3..733bc3ac2d 100644
--- a/src/nvim/eval/vars.c
+++ b/src/nvim/eval/vars.c
@@ -558,8 +558,6 @@ static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
return arg;
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Set one item of `:let var = expr` or `:let [v1, v2] = list` to its value
///
/// @param[in] arg Start of the variable name.
@@ -769,8 +767,6 @@ void ex_unlet(exarg_T *eap)
ex_unletlock(eap, eap->arg, 0, do_unlet_var);
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// ":lockvar" and ":unlockvar" commands
void ex_lockvar(exarg_T *eap)
{
@@ -787,8 +783,6 @@ void ex_lockvar(exarg_T *eap)
ex_unletlock(eap, arg, deep, do_lock_var);
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Common parsing logic for :unlet, :lockvar and :unlockvar.
///
/// Invokes `callback` afterwards if successful and `eap->skip == false`.
@@ -853,8 +847,6 @@ static void ex_unletlock(exarg_T *eap, char *argstart, int deep, ex_unletlock_ca
eap->nextcmd = check_nextcmd(arg);
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Unlet a variable indicated by `lp`.
///
/// @param[in] lp The lvalue.
@@ -944,8 +936,6 @@ static int do_unlet_var(lval_T *lp, char *name_end, exarg_T *eap, int deep FUNC_
return ret;
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// unlet a variable
///
/// @param[in] name Variable name to unlet.
@@ -1016,8 +1006,6 @@ int do_unlet(const char *const name, const size_t name_len, const bool forceit)
return FAIL;
}
-// TODO(ZyX-I): move to eval/ex_cmds
-
/// Lock or unlock variable indicated by `lp`.
///
/// Locks if `eap->cmdidx == CMD_lockvar`, unlocks otherwise.
@@ -1463,8 +1451,6 @@ bool var_check_fixed(const int flags, const char *name, size_t name_len)
return false;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Check if name is a valid name to assign funcref to
///
/// @param[in] name Possible function/funcref name.
@@ -1493,8 +1479,6 @@ bool var_wrong_func_name(const char *const name, const bool new_var)
return false;
}
-// TODO(ZyX-I): move to eval/expressions
-
/// Check if a variable name is valid
///
/// @param[in] varname Variable name to check.
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index c6dd30e549..c405b4f4c1 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -1018,7 +1018,9 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
ml_delete(line1 + extra, true);
}
if (!global_busy && num_lines > p_report) {
- smsg(NGETTEXT("1 line moved", "%" PRId64 " lines moved", num_lines), (int64_t)num_lines);
+ smsg(NGETTEXT("%" PRId64 " line moved",
+ "%" PRId64 " lines moved", num_lines),
+ (int64_t)num_lines);
}
extmark_move_region(curbuf, line1 - 1, 0, start_byte,
@@ -1134,8 +1136,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out
int scroll_save = msg_scroll;
//
- // Disallow shell commands from .exrc and .vimrc in current directory for
- // security reasons.
+ // Disallow shell commands in secure mode
//
if (check_secure()) {
return;
@@ -1477,8 +1478,7 @@ filterend:
/// @param flags may be SHELL_DOOUT when output is redirected
void do_shell(char *cmd, int flags)
{
- // Disallow shell commands from .exrc and .vimrc in current directory for
- // security reasons.
+ // Disallow shell commands in secure mode
if (check_secure()) {
msg_end();
return;
@@ -3215,8 +3215,7 @@ void ex_z(exarg_T *eap)
ex_no_reprint = true;
}
-/// @return true if the secure flag is set (.exrc or .vimrc in current directory)
-/// and also give an error message.
+/// @return true if the secure flag is set and also give an error message.
/// Otherwise, return false.
bool check_secure(void)
{
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index e0e4fa332f..a2bd6fb43f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -3378,7 +3378,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int
}
searchcmdlen = 0;
flags = silent ? 0 : SEARCH_HIS | SEARCH_MSG;
- if (!do_search(NULL, c, c, (char_u *)cmd, 1L, flags, NULL)) {
+ if (!do_search(NULL, c, c, cmd, 1L, flags, NULL)) {
curwin->w_cursor = pos;
cmd = NULL;
goto error;
@@ -3831,7 +3831,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, char **errormsgp)
// if there are still wildcards present.
if (vim_strchr(eap->arg, '$') != NULL
|| vim_strchr(eap->arg, '~') != NULL) {
- expand_env_esc((char_u *)eap->arg, (char_u *)NameBuff, MAXPATHL, true, true, NULL);
+ expand_env_esc(eap->arg, NameBuff, MAXPATHL, true, true, NULL);
has_wildcards = path_has_wildcard(NameBuff);
p = (char *)NameBuff;
} else {
@@ -4223,8 +4223,7 @@ theend:
static void ex_autocmd(exarg_T *eap)
{
- // Disallow autocommands from .exrc and .vimrc in current
- // directory for security reasons.
+ // Disallow autocommands in secure mode.
if (secure) {
secure = 2;
eap->errmsg = _(e_curdir);
@@ -5542,7 +5541,7 @@ bool changedir_func(char *new_dir, CdScope scope)
bool dir_differs = pdir == NULL || pathcmp(pdir, new_dir, -1) != 0;
if (dir_differs) {
do_autocmd_dirchanged(new_dir, scope, kCdCauseManual, true);
- if (vim_chdir((char_u *)new_dir) != 0) {
+ if (vim_chdir(new_dir) != 0) {
emsg(_(e_failed));
xfree(pdir);
return false;
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index cd80da729b..db0b20036f 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -1,8 +1,6 @@
// 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
-// TODO(ZyX-I): move to eval/executor
-
/// @file ex_eval.c
///
/// Functions for Ex command line for the +eval feature.
@@ -862,7 +860,7 @@ void ex_endif(exarg_T *eap)
/// Handle ":else" and ":elseif".
void ex_else(exarg_T *eap)
{
- int result;
+ bool result = false;
cstack_T *const cstack = eap->cstack;
bool skip = CHECK_SKIP;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 0520c0e4a0..fc9559172f 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -439,7 +439,7 @@ static void may_do_incsearch_highlighting(int firstc, long count, incsearch_stat
.sa_tm = &tm,
};
found = do_search(NULL, firstc == ':' ? '/' : firstc, search_delim,
- (char_u *)ccline.cmdbuff + skiplen, count,
+ ccline.cmdbuff + skiplen, count,
search_flags, &sia);
ccline.cmdbuff[skiplen + patlen] = next_char;
emsg_off--;
@@ -1613,6 +1613,8 @@ static int command_line_handle_key(CommandLineState *s)
return 0; // back to cmd mode
case Ctrl_R: { // insert register
+ const int save_new_cmdpos = new_cmdpos;
+
putcmdline('"', true);
no_mapping++;
allow_keys++;
@@ -1627,8 +1629,6 @@ static int command_line_handle_key(CommandLineState *s)
no_mapping--;
allow_keys--;
// Insert the result of an expression.
- // Need to save the current command line, to be able to enter
- // a new one...
new_cmdpos = -1;
if (s->c == '=') {
if (ccline.cmdfirstc == '=' // can't do this recursively
@@ -1660,8 +1660,12 @@ static int command_line_handle_key(CommandLineState *s)
}
}
}
+ new_cmdpos = save_new_cmdpos;
+
+ // remove the double quote
ccline.special_char = NUL;
redrawcmd();
+
return command_line_changed(s);
}
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 1d891799a5..36d58923b0 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -82,8 +82,8 @@ typedef struct ff_stack {
// the fix part (no wildcards) and the part containing the wildcards
// of the search path
- char_u *ffs_fix_path;
- char_u *ffs_wc_path;
+ char *ffs_fix_path;
+ char *ffs_wc_path;
// files/dirs found in the above directory, matched by the first wildcard
// of wc_part
@@ -511,7 +511,7 @@ char_u *vim_findfile_stopdir(char_u *buf)
while (*r_ptr != NUL && *r_ptr != ';') {
if (r_ptr[0] == '\\' && r_ptr[1] == ';') {
// Overwrite the escape char,
- // use STRLEN(r_ptr) to move the trailing '\0'.
+ // use strlen(r_ptr) to move the trailing '\0'.
STRMOVE(r_ptr, r_ptr + 1);
r_ptr++;
}
@@ -553,12 +553,12 @@ void vim_findfile_cleanup(void *ctx)
/// NULL if nothing found.
char_u *vim_findfile(void *search_ctx_arg)
{
- char_u *file_path;
- char_u *rest_of_wildcards;
+ char *file_path;
+ char *rest_of_wildcards;
char_u *path_end = NULL;
ff_stack_T *stackp = NULL;
size_t len;
- char_u *p;
+ char *p;
char *suf;
ff_search_ctx_T *search_ctx;
@@ -612,7 +612,7 @@ char_u *vim_findfile(void *search_ctx_arg)
// first time (hence stackp->ff_filearray == NULL)
if (stackp->ffs_filearray == NULL
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list->ffvl_visited_list,
- (char *)stackp->ffs_fix_path, (char *)stackp->ffs_wc_path) == FAIL) {
+ stackp->ffs_fix_path, stackp->ffs_wc_path) == FAIL) {
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
@@ -650,37 +650,37 @@ char_u *vim_findfile(void *search_ctx_arg)
char *dirptrs[2];
// we use filepath to build the path expand_wildcards() should expand.
- dirptrs[0] = (char *)file_path;
+ dirptrs[0] = file_path;
dirptrs[1] = NULL;
// if we have a start dir copy it in
- if (!vim_isAbsName(stackp->ffs_fix_path)
+ if (!vim_isAbsName((char_u *)stackp->ffs_fix_path)
&& search_ctx->ffsc_start_dir) {
if (strlen(search_ctx->ffsc_start_dir) + 1 >= MAXPATHL) {
ff_free_stack_element(stackp);
goto fail;
}
STRCPY(file_path, search_ctx->ffsc_start_dir);
- if (!add_pathsep((char *)file_path)) {
+ if (!add_pathsep(file_path)) {
ff_free_stack_element(stackp);
goto fail;
}
}
// append the fix part of the search path
- if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 >= MAXPATHL) {
+ if (strlen(file_path) + strlen(stackp->ffs_fix_path) + 1 >= MAXPATHL) {
ff_free_stack_element(stackp);
goto fail;
}
STRCAT(file_path, stackp->ffs_fix_path);
- if (!add_pathsep((char *)file_path)) {
+ if (!add_pathsep(file_path)) {
ff_free_stack_element(stackp);
goto fail;
}
rest_of_wildcards = stackp->ffs_wc_path;
if (*rest_of_wildcards != NUL) {
- len = STRLEN(file_path);
+ len = strlen(file_path);
if (STRNCMP(rest_of_wildcards, "**", 2) == 0) {
// pointer to the restrict byte
// The restrict byte is not a character!
@@ -705,7 +705,7 @@ char_u *vim_findfile(void *search_ctx_arg)
if (stackp->ffs_star_star_empty == 0) {
// if not done before, expand '**' to empty
stackp->ffs_star_star_empty = 1;
- dirptrs[1] = (char *)stackp->ffs_fix_path;
+ dirptrs[1] = stackp->ffs_fix_path;
}
}
@@ -748,7 +748,7 @@ char_u *vim_findfile(void *search_ctx_arg)
stackp->ffs_filearray_cur = 0;
stackp->ffs_stage = 0;
} else {
- rest_of_wildcards = &stackp->ffs_wc_path[STRLEN(stackp->ffs_wc_path)];
+ rest_of_wildcards = &stackp->ffs_wc_path[strlen(stackp->ffs_wc_path)];
}
if (stackp->ffs_stage == 0) {
@@ -768,7 +768,7 @@ char_u *vim_findfile(void *search_ctx_arg)
goto fail;
}
STRCPY(file_path, stackp->ffs_filearray[i]);
- if (!add_pathsep((char *)file_path)) {
+ if (!add_pathsep(file_path)) {
ff_free_stack_element(stackp);
goto fail;
}
@@ -776,7 +776,7 @@ char_u *vim_findfile(void *search_ctx_arg)
// Try without extra suffix and then with suffixes
// from 'suffixesadd'.
- len = STRLEN(file_path);
+ len = strlen(file_path);
if (search_ctx->ffsc_tagfile) {
suf = "";
} else {
@@ -784,14 +784,14 @@ char_u *vim_findfile(void *search_ctx_arg)
}
for (;;) {
// if file exists and we didn't already find it
- if ((path_with_url((char *)file_path)
- || (os_path_exists((char *)file_path)
+ if ((path_with_url(file_path)
+ || (os_path_exists(file_path)
&& (search_ctx->ffsc_find_what == FINDFILE_BOTH
|| ((search_ctx->ffsc_find_what == FINDFILE_DIR)
- == os_isdir((char *)file_path)))))
+ == os_isdir(file_path)))))
#ifndef FF_VERBOSE
&& (ff_check_visited(&search_ctx->ffsc_visited_list->ffvl_visited_list,
- (char *)file_path, "") == OK)
+ file_path, "") == OK)
#endif
) {
#ifdef FF_VERBOSE
@@ -812,12 +812,11 @@ char_u *vim_findfile(void *search_ctx_arg)
stackp->ffs_filearray_cur = i + 1;
ff_push(search_ctx, stackp);
- if (!path_with_url((char *)file_path)) {
- simplify_filename(file_path);
+ if (!path_with_url(file_path)) {
+ simplify_filename((char_u *)file_path);
}
- if (os_dirname((char_u *)ff_expand_buffer, MAXPATHL)
- == OK) {
- p = (char_u *)path_shorten_fname((char *)file_path, ff_expand_buffer);
+ if (os_dirname((char_u *)ff_expand_buffer, MAXPATHL) == OK) {
+ p = path_shorten_fname(file_path, ff_expand_buffer);
if (p != NULL) {
STRMOVE(file_path, p);
}
@@ -830,7 +829,7 @@ char_u *vim_findfile(void *search_ctx_arg)
verbose_leave_scroll();
}
#endif
- return file_path;
+ return (char_u *)file_path;
}
// Not found or found already, try next suffix.
@@ -838,7 +837,7 @@ char_u *vim_findfile(void *search_ctx_arg)
break;
}
assert(MAXPATHL >= len);
- copy_option_part(&suf, (char *)file_path + len, MAXPATHL - len, ",");
+ copy_option_part(&suf, file_path + len, MAXPATHL - len, ",");
}
}
} else {
@@ -849,7 +848,7 @@ char_u *vim_findfile(void *search_ctx_arg)
}
ff_push(search_ctx,
ff_create_stack_element(stackp->ffs_filearray[i],
- (char *)rest_of_wildcards,
+ rest_of_wildcards,
stackp->ffs_level - 1, 0));
}
}
@@ -863,7 +862,7 @@ char_u *vim_findfile(void *search_ctx_arg)
for (int i = stackp->ffs_filearray_cur;
i < stackp->ffs_filearray_size; i++) {
if (path_fnamecmp(stackp->ffs_filearray[i],
- (char *)stackp->ffs_fix_path) == 0) {
+ stackp->ffs_fix_path) == 0) {
continue; // don't repush same directory
}
if (!os_isdir(stackp->ffs_filearray[i])) {
@@ -871,7 +870,7 @@ char_u *vim_findfile(void *search_ctx_arg)
}
ff_push(search_ctx,
ff_create_stack_element(stackp->ffs_filearray[i],
- (char *)stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
+ stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
}
}
@@ -911,13 +910,13 @@ char_u *vim_findfile(void *search_ctx_arg)
goto fail;
}
STRCPY(file_path, search_ctx->ffsc_start_dir);
- if (!add_pathsep((char *)file_path)) {
+ if (!add_pathsep(file_path)) {
goto fail;
}
STRCAT(file_path, search_ctx->ffsc_fix_path);
// create a new stack entry
- sptr = ff_create_stack_element((char *)file_path,
+ sptr = ff_create_stack_element(file_path,
search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
ff_push(search_ctx, sptr);
} else {
@@ -1136,12 +1135,12 @@ static ff_stack_T *ff_create_stack_element(char *fix_part, char *wc_part, int le
if (fix_part == NULL) {
fix_part = "";
}
- new->ffs_fix_path = (char_u *)xstrdup(fix_part);
+ new->ffs_fix_path = xstrdup(fix_part);
if (wc_part == NULL) {
wc_part = "";
}
- new->ffs_wc_path = (char_u *)xstrdup(wc_part);
+ new->ffs_wc_path = xstrdup(wc_part);
return new;
}
@@ -1242,7 +1241,7 @@ static int ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v)
}
for (i = 0; stopdirs_v[i] != NULL; i++) {
- if ((int)STRLEN(stopdirs_v[i]) > path_len) {
+ if ((int)strlen(stopdirs_v[i]) > path_len) {
// match for parent directory. So '/home' also matches
// '/home/rks'. Check for PATHSEP in stopdirs_v[i], else
// '/home/r' would also match '/home/rks'
@@ -1288,11 +1287,11 @@ static int ff_path_in_stoplist(char *path, int path_len, char **stopdirs_v)
/// @return an allocated string for the file name. NULL for error.
char_u *find_file_in_path(char_u *ptr, size_t len, int options, int first, char_u *rel_fname)
{
- return find_file_in_path_option(ptr, len, options, first,
- (*curbuf->b_p_path == NUL
- ? p_path
- : (char_u *)curbuf->b_p_path),
- FINDFILE_BOTH, rel_fname, (char_u *)curbuf->b_p_sua);
+ return (char_u *)find_file_in_path_option((char *)ptr, len, options, first,
+ (*curbuf->b_p_path == NUL
+ ? (char *)p_path
+ : curbuf->b_p_path),
+ FINDFILE_BOTH, (char *)rel_fname, curbuf->b_p_sua);
}
static char *ff_file_to_find = NULL;
@@ -1323,8 +1322,8 @@ void free_findfile(void)
/// @return an allocated string for the file name. NULL for error.
char_u *find_directory_in_path(char_u *ptr, size_t len, int options, char_u *rel_fname)
{
- return find_file_in_path_option(ptr, len, options, true, p_cdpath,
- FINDFILE_DIR, rel_fname, (char_u *)"");
+ return (char_u *)find_file_in_path_option((char *)ptr, len, options, true, (char *)p_cdpath,
+ FINDFILE_DIR, (char *)rel_fname, "");
}
/// @param ptr file name
@@ -1334,13 +1333,12 @@ char_u *find_directory_in_path(char_u *ptr, size_t len, int options, char_u *rel
/// @param find_what FINDFILE_FILE, _DIR or _BOTH
/// @param rel_fname file name we are looking relative to.
/// @param suffixes list of suffixes, 'suffixesadd' option
-char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first,
- char_u *path_option, int find_what, char_u *rel_fname,
- char_u *suffixes)
+char *find_file_in_path_option(char *ptr, size_t len, int options, int first, char *path_option,
+ int find_what, char *rel_fname, char *suffixes)
{
static char *dir;
static int did_findfile_init = false;
- char_u save_char;
+ char save_char;
char *file_name = NULL;
char *buf = NULL;
int rel_to_curdir;
@@ -1358,16 +1356,16 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
// copy file name into NameBuff, expanding environment variables
save_char = ptr[len];
ptr[len] = NUL;
- expand_env_esc(ptr, (char_u *)NameBuff, MAXPATHL, false, true, NULL);
+ expand_env_esc(ptr, NameBuff, MAXPATHL, false, true, NULL);
ptr[len] = save_char;
xfree(ff_file_to_find);
ff_file_to_find = xstrdup(NameBuff);
if (options & FNAME_UNESC) {
// Change all "\ " to " ".
- for (ptr = (char_u *)ff_file_to_find; *ptr != NUL; ptr++) {
+ for (ptr = ff_file_to_find; *ptr != NUL; ptr++) {
if (ptr[0] == '\\' && ptr[1] == ' ') {
- memmove(ptr, ptr + 1, STRLEN(ptr));
+ memmove(ptr, ptr + 1, strlen(ptr));
}
}
}
@@ -1406,7 +1404,7 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
&& rel_to_curdir
&& (options & FNAME_REL)
&& rel_fname != NULL
- && STRLEN(rel_fname) + l < MAXPATHL) {
+ && strlen(rel_fname) + l < MAXPATHL) {
STRCPY(NameBuff, rel_fname);
STRCPY(path_tail((char *)NameBuff), ff_file_to_find);
l = strlen(NameBuff);
@@ -1416,7 +1414,7 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
}
// When the file doesn't exist, try adding parts of 'suffixesadd'.
- buf = (char *)suffixes;
+ buf = suffixes;
for (;;) {
if ((os_path_exists(NameBuff)
&& (find_what == FINDFILE_BOTH
@@ -1440,7 +1438,7 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
if (first == true) {
// vim_findfile_free_visited can handle a possible NULL pointer
vim_findfile_free_visited(fdip_search_ctx);
- dir = (char *)path_option;
+ dir = path_option;
did_findfile_init = false;
}
@@ -1472,7 +1470,7 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
r_ptr = vim_findfile_stopdir((char_u *)buf);
fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
(char *)r_ptr, 100, false, find_what,
- fdip_search_ctx, false, (char *)rel_fname);
+ fdip_search_ctx, false, rel_fname);
if (fdip_search_ctx != NULL) {
did_findfile_init = true;
}
@@ -1501,7 +1499,7 @@ char_u *find_file_in_path_option(char_u *ptr, size_t len, int options, int first
}
theend:
- return (char_u *)file_name;
+ return file_name;
}
void do_autocmd_dirchanged(char *new_dir, CdScope scope, CdCause cause, bool pre)
@@ -1608,9 +1606,9 @@ int vim_chdirfile(char *fname, CdCause cause)
}
/// Change directory to "new_dir". Search 'cdpath' for relative directory names.
-int vim_chdir(char_u *new_dir)
+int vim_chdir(char *new_dir)
{
- char *dir_name = (char *)find_directory_in_path(new_dir, STRLEN(new_dir),
+ char *dir_name = (char *)find_directory_in_path((char_u *)new_dir, strlen(new_dir),
FNAME_MESS, (char_u *)curbuf->b_ffname);
if (dir_name == NULL) {
return -1;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 6c5469d020..746788413f 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -993,7 +993,7 @@ retry:
tlen = 0;
for (;;) {
p = (char_u *)ml_get(read_buf_lnum) + read_buf_col;
- n = (int)STRLEN(p);
+ n = (int)strlen((char *)p);
if ((int)tlen + n + 1 > size) {
// Filled up to "size", append partial line.
// Change NL to NUL to reverse the effect done
@@ -2211,8 +2211,7 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
return FAIL;
}
- // Disallow writing from .exrc and .vimrc in current directory for
- // security reasons.
+ // Disallow writing in secure mode.
if (check_secure()) {
return FAIL;
}
@@ -3738,22 +3737,22 @@ static bool msg_add_fileformat(int eol_type)
/// Append line and character count to IObuff.
void msg_add_lines(int insert_space, long lnum, off_T nchars)
{
- char_u *p;
+ char *p;
- p = (char_u *)IObuff + STRLEN(IObuff);
+ p = IObuff + strlen(IObuff);
if (insert_space) {
*p++ = ' ';
}
if (shortmess(SHM_LINES)) {
- vim_snprintf((char *)p, (size_t)(IOSIZE - (p - (char_u *)IObuff)), "%" PRId64 "L, %" PRId64 "B",
+ vim_snprintf(p, (size_t)(IOSIZE - (p - IObuff)), "%" PRId64 "L, %" PRId64 "B",
(int64_t)lnum, (int64_t)nchars);
} else {
- vim_snprintf((char *)p, (size_t)(IOSIZE - (p - (char_u *)IObuff)),
+ vim_snprintf(p, (size_t)(IOSIZE - (p - IObuff)),
NGETTEXT("%" PRId64 " line, ", "%" PRId64 " lines, ", lnum),
(int64_t)lnum);
- p += STRLEN(p);
- vim_snprintf((char *)p, (size_t)(IOSIZE - (p - (char_u *)IObuff)),
+ p += strlen(p);
+ vim_snprintf(p, (size_t)(IOSIZE - (p - IObuff)),
NGETTEXT("%" PRId64 " byte", "%" PRId64 " bytes", nchars),
(int64_t)nchars);
}
@@ -4343,7 +4342,8 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
/// @param fp file to read from
///
/// @return true for EOF or error
-bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL
+bool vim_fgets(char *buf, int size, FILE *fp)
+ FUNC_ATTR_NONNULL_ALL
{
char *retval;
@@ -4352,7 +4352,7 @@ bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL
do {
errno = 0;
- retval = fgets((char *)buf, size, fp);
+ retval = fgets(buf, size, fp);
} while (retval == NULL && errno == EINTR && ferror(fp));
if (buf[size - 2] != NUL && buf[size - 2] != '\n') {
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 76f62fe267..130f3f6c48 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -489,8 +489,7 @@ EXTERN int stdin_fd INIT(= -1);
// true when doing full-screen output, otherwise only writing some messages.
EXTERN int full_screen INIT(= false);
-/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
-/// .vimrc in current directory.
+/// Non-zero when only "safe" commands are allowed
EXTERN int secure INIT(= 0);
/// Non-zero when changing text and jumping to another window or editing another buffer is not
@@ -864,7 +863,7 @@ EXTERN char e_api_spawn_failed[] INIT(= N_("E903: Could not spawn API job"));
EXTERN char e_argreq[] INIT(= N_("E471: Argument required"));
EXTERN char e_backslash[] INIT(= N_("E10: \\ should be followed by /, ? or &"));
EXTERN char e_cmdwin[] INIT(= N_("E11: Invalid in command-line window; <CR> executes, CTRL-C quits"));
-EXTERN char e_curdir[] INIT(= N_("E12: Command not allowed from exrc/vimrc in current dir or tag search"));
+EXTERN char e_curdir[] INIT(= N_("E12: Command not allowed in secure mode in current dir or tag search"));
EXTERN char e_command_too_recursive[] INIT(= N_("E169: Command too recursive"));
EXTERN char e_endif[] INIT(= N_("E171: Missing :endif"));
EXTERN char e_endtry[] INIT(= N_("E600: Missing :endtry"));
diff --git a/src/nvim/help.c b/src/nvim/help.c
index 7ea7dfb709..8930f74e7f 100644
--- a/src/nvim/help.c
+++ b/src/nvim/help.c
@@ -570,7 +570,7 @@ int find_help_tags(const char *arg, int *num_matches, char ***matches, bool keep
void cleanup_help_tags(int num_file, char **file)
{
char buf[4];
- char_u *p = (char_u *)buf;
+ char *p = buf;
if (p_hlg[0] != NUL && (p_hlg[0] != 'e' || p_hlg[1] != 'n')) {
*p++ = '@';
@@ -785,7 +785,7 @@ void fix_help_buffer(void)
if (fd == NULL) {
continue;
}
- vim_fgets((char_u *)IObuff, IOSIZE, fd);
+ vim_fgets(IObuff, IOSIZE, fd);
if (IObuff[0] == '*'
&& (s = vim_strchr((char *)IObuff + 1, '*'))
!= NULL) {
@@ -944,7 +944,7 @@ static void helptags_one(char *dir, const char *ext, const char *tagfname, bool
const char *const fname = files[fi] + dirlen + 1;
bool firstline = true;
- while (!vim_fgets((char_u *)IObuff, IOSIZE, fd) && !got_int) {
+ while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
if (firstline) {
// Detect utf-8 file by a non-ASCII char in the first line.
TriState this_utf8 = kNone;
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index 77fe176de1..0f1159fb94 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -1003,7 +1003,7 @@ static int cin_iswhileofdo(const char_u *p, linenr_T lnum) // XXX
curwin->w_cursor.col++;
}
if ((trypos = findmatchlimit(NULL, 0, 0, curbuf->b_ind_maxparen)) != NULL
- && *cin_skipcomment(ml_get_pos(trypos) + 1) == ';') {
+ && *cin_skipcomment((char_u *)ml_get_pos(trypos) + 1) == ';') {
retval = true;
}
curwin->w_cursor = cursor_save;
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index ed851683fd..65380b92fc 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -1463,12 +1463,12 @@ static void ins_compl_files(int count, char **files, int thesaurus, int flags, r
// Read dictionary file line by line.
// Check each line for a match.
- while (!got_int && !compl_interrupted && !vim_fgets(buf, LSIZE, fp)) {
+ while (!got_int && !compl_interrupted && !vim_fgets((char *)buf, LSIZE, fp)) {
ptr = buf;
while (vim_regexec(regmatch, (char *)buf, (colnr_T)(ptr - buf))) {
ptr = (char_u *)regmatch->startp[0];
if (ctrl_x_mode_line_or_eval()) {
- ptr = find_line_end(ptr);
+ ptr = (char_u *)find_line_end((char *)ptr);
} else {
ptr = find_word_end(ptr);
}
@@ -1529,12 +1529,13 @@ char_u *find_word_end(char_u *ptr)
}
/// Find the end of the line, omitting CR and NL at the end.
-/// Returns a pointer to just after the line.
-static char_u *find_line_end(char_u *ptr)
+///
+/// @return a pointer to just after the line.
+static char *find_line_end(char *ptr)
{
- char_u *s;
+ char *s;
- s = ptr + STRLEN(ptr);
+ s = ptr + strlen(ptr);
while (s > ptr && (s[-1] == CAR || s[-1] == NL)) {
s--;
}
diff --git a/src/nvim/linematch.c b/src/nvim/linematch.c
index 9897c92ac5..f8b286fcd8 100644
--- a/src/nvim/linematch.c
+++ b/src/nvim/linematch.c
@@ -1,3 +1,6 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 79cc3ed112..43a3b12a98 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -2193,3 +2193,27 @@ plain:
kv_printf(str, "<Lua %d>", ref);
return str.items;
}
+
+char *nlua_read_secure(const char *path)
+{
+ lua_State *const lstate = global_lstate;
+ lua_getglobal(lstate, "vim");
+ lua_getfield(lstate, -1, "secure");
+ lua_getfield(lstate, -1, "read");
+ lua_pushstring(lstate, path);
+ lua_call(lstate, 1, 1);
+
+ size_t len = 0;
+ const char *contents = lua_tolstring(lstate, -1, &len);
+ char *buf = NULL;
+ if (contents != NULL) {
+ // Add one to include trailing null byte
+ buf = xcalloc(len + 1, sizeof(char));
+ memcpy(buf, contents, len + 1);
+ }
+
+ // Pop return value, "vim", and "secure"
+ lua_pop(lstate, 3);
+
+ return buf;
+}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index d8570f49eb..a369ca0256 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1989,35 +1989,22 @@ static void source_startup_scripts(const mparm_T *const parmp)
do_system_initialization();
if (do_user_initialization()) {
- // Read initialization commands from ".vimrc" or ".exrc" in current
+ // Read initialization commands from ".nvimrc" or ".exrc" in current
// directory. This is only done if the 'exrc' option is set.
- // Because of security reasons we disallow shell and write commands
- // now, except for unix if the file is owned by the user or 'secure'
- // option has been reset in environment of global "exrc" or "vimrc".
// Only do this if VIMRC_FILE is not the same as vimrc file sourced in
// do_user_initialization.
-#if defined(UNIX)
- // If vimrc file is not owned by user, set 'secure' mode.
- if (!os_file_owned(VIMRC_FILE)) // NOLINT(readability/braces)
-#endif
- secure = p_secure;
-
- if (do_source(VIMRC_FILE, true, DOSO_VIMRC) == FAIL) {
-#if defined(UNIX)
- // if ".exrc" is not owned by user set 'secure' mode
- if (!os_file_owned(EXRC_FILE)) {
- secure = p_secure;
- } else {
- secure = 0;
+ char *str = nlua_read_secure(VIMRC_FILE);
+ if (str != NULL) {
+ do_source_str(str, VIMRC_FILE);
+ xfree(str);
+ } else {
+ str = nlua_read_secure(EXRC_FILE);
+ if (str != NULL) {
+ do_source_str(str, EXRC_FILE);
+ xfree(str);
}
-#endif
- (void)do_source(EXRC_FILE, false, DOSO_NONE);
}
}
- if (secure == 2) {
- need_wait_return = true;
- }
- secure = 0;
}
TIME_MSG("sourcing vimrc file(s)");
}
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index 9b10ea901e..cc8ebe10cf 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -419,7 +419,7 @@ static int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *ma
// {lhs_end} is a pointer to the "terminating whitespace" after {lhs}.
// Use that to initialize {rhs_start}.
- const char_u *rhs_start = (char_u *)skipwhite((char *)lhs_end);
+ const char *rhs_start = skipwhite((char *)lhs_end);
// Given {lhs} might be larger than MAXMAPLEN before replace_termcodes
// (e.g. "<Space>" is longer than ' '), so first copy into a buffer.
@@ -430,9 +430,9 @@ static int str_to_mapargs(const char_u *strargs, bool is_unmap, MapArguments *ma
char_u lhs_to_replace[256];
STRLCPY(lhs_to_replace, to_parse, orig_lhs_len + 1);
- size_t orig_rhs_len = STRLEN(rhs_start);
+ size_t orig_rhs_len = strlen(rhs_start);
if (!set_maparg_lhs_rhs((char *)lhs_to_replace, orig_lhs_len,
- (char *)rhs_start, orig_rhs_len, LUA_NOREF,
+ rhs_start, orig_rhs_len, LUA_NOREF,
CPO_TO_CPO_FLAGS, mapargs)) {
return 1;
}
@@ -471,7 +471,7 @@ static void map_add(buf_T *buf, mapblock_T **map_table, mapblock_T **abbr_table,
args->orig_rhs = NULL;
args->rhs_lua = LUA_NOREF;
}
- mp->m_keylen = (int)STRLEN(mp->m_keys);
+ mp->m_keylen = (int)strlen((char *)mp->m_keys);
mp->m_noremap = noremap;
mp->m_nowait = args->nowait;
mp->m_silent = args->silent;
@@ -1392,7 +1392,7 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
int len;
int scol; // starting column of the abbr.
int j;
- char_u *s;
+ char *s;
char_u tb[MB_MAXBYTES + 4];
mapblock_T *mp;
mapblock_T *mp2;
@@ -1462,7 +1462,7 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
// Might have K_SPECIAL escaped mp->m_keys.
q = xstrdup((char *)mp->m_keys);
vim_unescape_ks((char_u *)q);
- qlen = (int)STRLEN(q);
+ qlen = (int)strlen(q);
}
// find entries with right mode and keys
match = (mp->m_mode & State)
@@ -1505,9 +1505,9 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
int newlen = utf_char2bytes(c, (char *)tb + j);
tb[j + newlen] = NUL;
// Need to escape K_SPECIAL.
- char_u *escaped = (char_u *)vim_strsave_escape_ks((char *)tb + j);
+ char *escaped = vim_strsave_escape_ks((char *)tb + j);
if (escaped != NULL) {
- newlen = (int)STRLEN(escaped);
+ newlen = (int)strlen(escaped);
memmove(tb + j, escaped, (size_t)newlen);
j += newlen;
xfree(escaped);
@@ -1518,15 +1518,15 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
(void)ins_typebuf((char *)tb, 1, 0, true, mp->m_silent);
}
if (mp->m_expr) {
- s = (char_u *)eval_map_expr(mp, c);
+ s = eval_map_expr(mp, c);
} else {
- s = (char_u *)mp->m_str;
+ s = mp->m_str;
}
if (s != NULL) {
// insert the to string
- (void)ins_typebuf((char *)s, mp->m_noremap, 0, true, mp->m_silent);
+ (void)ins_typebuf(s, mp->m_noremap, 0, true, mp->m_silent);
// no abbrev. for these chars
- typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1;
+ typebuf.tb_no_abbr_cnt += (int)strlen(s) + j + 1;
if (mp->m_expr) {
xfree(s);
}
@@ -1597,7 +1597,7 @@ char *eval_map_expr(mapblock_T *mp, int c)
char *res = NULL;
if (mp->m_replace_keycodes) {
- replace_termcodes(p, STRLEN(p), &res, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS);
+ replace_termcodes(p, strlen(p), &res, REPTERM_DO_LT, NULL, CPO_TO_CPO_FLAGS);
} else {
// Escape K_SPECIAL in the result to be able to use the string as typeahead.
res = vim_strsave_escape_ks(p);
@@ -1926,14 +1926,14 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
/// @param abbr do abbreviations
/// @param mp_ptr return: pointer to mapblock or NULL
/// @param local_ptr return: buffer-local mapping or NULL
-char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr,
- int *local_ptr, int *rhs_lua)
+char *check_map(char *keys, int mode, int exact, int ign_mod, int abbr, mapblock_T **mp_ptr,
+ int *local_ptr, int *rhs_lua)
{
int len, minlen;
mapblock_T *mp;
*rhs_lua = LUA_NOREF;
- len = (int)STRLEN(keys);
+ len = (int)strlen(keys);
for (int local = 1; local >= 0; local--) {
// loop over all hash lists
for (int hash = 0; hash < 256; hash++) {
@@ -1970,7 +1970,7 @@ char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapb
*local_ptr = local;
}
*rhs_lua = mp->m_luaref;
- return mp->m_luaref == LUA_NOREF ? (char_u *)mp->m_str : NULL;
+ return mp->m_luaref == LUA_NOREF ? mp->m_str : NULL;
}
}
}
@@ -2104,7 +2104,8 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
mapblock_T *mp = NULL;
int buffer_local;
LuaRef rhs_lua;
- char_u *rhs = check_map(keys_simplified, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
+ char *rhs = check_map((char *)keys_simplified, mode, exact, false, abbr, &mp, &buffer_local,
+ &rhs_lua);
if (did_simplify) {
// When the lhs is being simplified the not-simplified keys are
// preferred for printing, like in do_map().
@@ -2112,7 +2113,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
strlen(keys),
&alt_keys_buf, flags | REPTERM_NO_SIMPLIFY, NULL,
CPO_TO_CPO_FLAGS);
- rhs = check_map((char_u *)alt_keys_buf, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
+ rhs = check_map(alt_keys_buf, mode, exact, false, abbr, &mp, &buffer_local, &rhs_lua);
}
if (!get_dict) {
@@ -2121,7 +2122,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
if (*rhs == NUL) {
rettv->vval.v_string = xstrdup("<Nop>");
} else {
- rettv->vval.v_string = str2special_save((char *)rhs, false, false);
+ rettv->vval.v_string = str2special_save(rhs, false, false);
}
} else if (rhs_lua != LUA_NOREF) {
rettv->vval.v_string = nlua_funcref_str(mp->m_luaref);
@@ -2446,8 +2447,7 @@ void ex_abbreviate(exarg_T *eap)
/// ":map" and friends.
void ex_map(exarg_T *eap)
{
- // If we are sourcing .exrc or .vimrc in current directory we
- // print the mappings for security reasons.
+ // If we are in a secure mode we print the mappings for security reasons.
if (secure) {
secure = 2;
msg_outtrans(eap->cmd);
diff --git a/src/nvim/match.c b/src/nvim/match.c
index fc98ad8396..83d1055fd0 100644
--- a/src/nvim/match.c
+++ b/src/nvim/match.c
@@ -425,7 +425,7 @@ static void next_search_hl(win_T *win, match_T *search_hl, match_T *shl, linenr_
const int called_emsg_before = called_emsg;
// for :{range}s/pat only highlight inside the range
- if (lnum < search_first_line || lnum > search_last_line) {
+ if ((lnum < search_first_line || lnum > search_last_line) && cur == NULL) {
shl->lnum = 0;
return;
}
@@ -677,9 +677,11 @@ bool prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **l
/// After end, check for start/end of next match.
/// When another match, have to check for start again.
/// Watch out for matching an empty string!
+/// "on_last_col" is set to true with non-zero search_attr and the next column
+/// is endcol.
/// Return the updated search_attr.
int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match_T *search_hl,
- int *has_match_conc, int *match_conc, int lcs_eol_one,
+ int *has_match_conc, int *match_conc, int lcs_eol_one, bool *on_last_col,
bool *search_attr_from_match)
{
matchitem_T *cur = wp->w_match_head; // points to the match list
@@ -792,6 +794,7 @@ int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match
}
if (shl->attr_cur != 0) {
search_attr = shl->attr_cur;
+ *on_last_col = col + 1 >= shl->endcol;
*search_attr_from_match = shl != search_hl;
}
if (shl != search_hl && cur != NULL) {
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 42b3ec0202..1a30852e72 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -71,10 +71,6 @@
# include <locale.h>
#endif
-#ifdef __STDC_ISO_10646__
-# include <stdc-predef.h>
-#endif
-
typedef struct {
int rangeStart;
int rangeEnd;
@@ -1235,12 +1231,9 @@ int mb_toupper(int a)
return TOUPPER_ASC(a);
}
-#if defined(__STDC_ISO_10646__)
- // If towupper() is available and handles Unicode, use it.
if (!(cmp_flags & CMP_INTERNAL)) {
return (int)towupper((wint_t)a);
}
-#endif
// For characters below 128 use locale sensitive toupper().
if (a < 128) {
@@ -1266,12 +1259,9 @@ int mb_tolower(int a)
return TOLOWER_ASC(a);
}
-#if defined(__STDC_ISO_10646__)
- // If towlower() is available and handles Unicode, use it.
if (!(cmp_flags & CMP_INTERNAL)) {
return (int)towlower((wint_t)a);
}
-#endif
// For characters below 128 use locale sensitive tolower().
if (a < 128) {
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 1f601f0668..6e1316d651 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -72,7 +72,7 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/option.h"
-#include "nvim/os/fs_defs.h"
+#include "nvim/os/fs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/process.h"
@@ -131,7 +131,8 @@ struct data_block {
unsigned db_free; // free space available
unsigned db_txt_start; // byte where text starts
unsigned db_txt_end; // byte just after data block
- linenr_T db_line_count; // number of lines in this block
+ // linenr_T db_line_count;
+ long db_line_count; // number of lines in this block
unsigned db_index[1]; // index for start of line (actually bigger)
// followed by empty space up to db_txt_start
// followed by the text in the lines until
@@ -698,6 +699,23 @@ static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
}
}
+/// Return true if the process with number "b0p->b0_pid" is still running.
+/// "swap_fname" is the name of the swap file, if it's from before a reboot then
+/// the result is false;
+static bool swapfile_process_running(const ZERO_BL *b0p, const char *swap_fname)
+{
+ FileInfo st;
+ double uptime;
+ // If the system rebooted after when the swap file was written then the
+ // process can't be running now.
+ if (os_fileinfo(swap_fname, &st)
+ && uv_uptime(&uptime) == 0
+ && (Timestamp)st.stat.st_mtim.tv_sec < os_time() - (Timestamp)uptime) {
+ return false;
+ }
+ return os_proc_running((int)char_to_long(b0p->b0_pid));
+}
+
/// Try to recover curbuf from the .swp file.
///
/// @param checkext if true, check the extension and detect whether it is a
@@ -1138,7 +1156,14 @@ void ml_recover(bool checkext)
} else {
msg(_("Recovery completed. Buffer contents equals file contents."));
}
- msg_puts(_("\nYou may want to delete the .swp file now.\n\n"));
+ msg_puts(_("\nYou may want to delete the .swp file now."));
+ if (swapfile_process_running(b0p, fname_used)) {
+ // Warn there could be an active Vim on the same file, the user may
+ // want to kill it.
+ msg_puts(_("\nNote: process STILL RUNNING: "));
+ msg_outnum(char_to_long(b0p->b0_pid));
+ }
+ msg_puts("\n\n");
cmdline_row = msg_row;
}
redraw_curbuf_later(UPD_NOT_VALID);
@@ -1237,7 +1262,7 @@ int recover_names(char_u *fname, int list, int nr, char **fname_out)
names[2] = concat_fnames(dir_name, ".sw?", true);
num_names = 3;
} else {
- int len = (int)STRLEN(dir_name);
+ int len = (int)strlen(dir_name);
p = dir_name + len;
if (after_pathsep(dir_name, p)
&& len > 1
@@ -1478,7 +1503,7 @@ static time_t swapfile_info(char_u *fname)
if (char_to_long(b0.b0_pid) != 0L) {
msg_puts(_("\n process ID: "));
msg_outnum(char_to_long(b0.b0_pid));
- if (os_proc_running((int)char_to_long(b0.b0_pid))) {
+ if (swapfile_process_running(&b0, (const char *)fname)) {
msg_puts(_(" (STILL RUNNING)"));
process_still_running = true;
}
@@ -1533,14 +1558,27 @@ static bool swapfile_unchanged(char *fname)
ret = false;
}
+ // Host name must be known and must equal the current host name, otherwise
+ // comparing pid is meaningless.
+ if (*(b0.b0_hname) == NUL) {
+ ret = false;
+ } else {
+ char hostname[B0_HNAME_SIZE];
+ os_get_hostname(hostname, B0_HNAME_SIZE);
+ hostname[B0_HNAME_SIZE - 1] = NUL;
+ b0.b0_hname[B0_HNAME_SIZE - 1] = NUL; // in case of corruption
+ if (STRICMP(b0.b0_hname, hostname) != 0) {
+ ret = false;
+ }
+ }
+
// process must be known and not running.
- long pid = char_to_long(b0.b0_pid);
- if (pid == 0L || os_proc_running((int)pid)) {
+ if (char_to_long(b0.b0_pid) == 0L || swapfile_process_running(&b0, fname)) {
ret = false;
}
- // TODO(bram): Should we check if the swap file was created on the current
- // system? And the current user?
+ // We do not check the user, it should be irrelevant for whether the swap
+ // file is still useful.
close(fd);
return ret;
@@ -1707,10 +1745,10 @@ char *ml_get(linenr_T lnum)
}
/// @return pointer to position "pos".
-char_u *ml_get_pos(const pos_T *pos)
+char *ml_get_pos(const pos_T *pos)
FUNC_ATTR_NONNULL_ALL
{
- return (char_u *)ml_get_buf(curbuf, pos->lnum, false) + pos->col;
+ return ml_get_buf(curbuf, pos->lnum, false) + pos->col;
}
/// @return codepoint at pos. pos must be either valid or have col set to MAXCOL!
@@ -1721,7 +1759,7 @@ int gchar_pos(pos_T *pos)
if (pos->col == MAXCOL) {
return NUL;
}
- return utf_ptr2char((char *)ml_get_pos(pos));
+ return utf_ptr2char(ml_get_pos(pos));
}
/// @param will_change true mark the buffer dirty (chars in the line will be changed)
@@ -1790,7 +1828,7 @@ errorret:
}
if (will_change) {
buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
- ml_add_deleted_len_buf(buf, buf->b_ml.ml_line_ptr, -1);
+ ml_add_deleted_len_buf(buf, (char *)buf->b_ml.ml_line_ptr, -1);
}
return (char *)buf->b_ml.ml_line_ptr;
@@ -2266,10 +2304,10 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char_u *line, colnr_T len, b
void ml_add_deleted_len(char *ptr, ssize_t len)
{
- ml_add_deleted_len_buf(curbuf, (char_u *)ptr, len);
+ ml_add_deleted_len_buf(curbuf, ptr, len);
}
-void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len)
+void ml_add_deleted_len_buf(buf_T *buf, char *ptr, ssize_t len)
{
if (inhibit_delete_count) {
return;
@@ -2281,7 +2319,7 @@ void ml_add_deleted_len_buf(buf_T *buf, char_u *ptr, ssize_t len)
curbuf->deleted_bytes += (size_t)len + 1;
curbuf->deleted_bytes2 += (size_t)len + 1;
if (curbuf->update_need_codepoints) {
- mb_utflen(ptr, (size_t)len, &curbuf->deleted_codepoints,
+ mb_utflen((char_u *)ptr, (size_t)len, &curbuf->deleted_codepoints,
&curbuf->deleted_codeunits);
curbuf->deleted_codepoints++; // NL char
curbuf->deleted_codeunits++;
@@ -2324,14 +2362,14 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy)
if (buf->b_ml.ml_line_lnum != lnum) { // other line buffered
ml_flush_line(buf); // flush it
} else if (buf->b_ml.ml_flags & ML_LINE_DIRTY) { // same line allocated
- ml_add_deleted_len_buf(buf, buf->b_ml.ml_line_ptr, -1);
+ ml_add_deleted_len_buf(buf, (char *)buf->b_ml.ml_line_ptr, -1);
readlen = false; // already added the length
xfree(buf->b_ml.ml_line_ptr); // free it
}
if (readlen && kv_size(buf->update_callbacks)) {
- ml_add_deleted_len_buf(buf, (char_u *)ml_get_buf(buf, lnum, false), -1);
+ ml_add_deleted_len_buf(buf, ml_get_buf(buf, lnum, false), -1);
}
buf->b_ml.ml_line_ptr = (char_u *)line;
@@ -2408,7 +2446,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
// Line should always have an NL char internally (represented as NUL),
// even if 'noeol' is set.
assert(line_size >= 1);
- ml_add_deleted_len_buf(buf, (char_u *)dp + line_start, line_size - 1);
+ ml_add_deleted_len_buf(buf, (char *)dp + line_start, line_size - 1);
// special case: If there is only one line in the data block it becomes empty.
// Then we have to remove the entry, pointing to this data block, from the
@@ -2965,8 +3003,8 @@ int resolve_symlink(const char *fname, char *buf)
if (path_is_absolute((char_u *)buf)) {
STRCPY(tmp, buf);
} else {
- char_u *tail = (char_u *)path_tail(tmp);
- if (STRLEN(tail) + strlen(buf) >= MAXPATHL) {
+ char *tail = path_tail(tmp);
+ if (strlen(tail) + strlen(buf) >= MAXPATHL) {
return FAIL;
}
STRCPY(tail, buf);
@@ -3930,7 +3968,7 @@ int inc(pos_T *lp)
{
// when searching position may be set to end of a line
if (lp->col != MAXCOL) {
- const char_u *const p = ml_get_pos(lp);
+ const char *const p = ml_get_pos(lp);
if (*p != NUL) { // still within line, move to next char (may be NUL)
const int l = utfc_ptr2len((char *)p);
diff --git a/src/nvim/move.c b/src/nvim/move.c
index df79b169b8..25d27d154b 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -341,15 +341,6 @@ void update_topline(win_T *wp)
*so_ptr = save_so;
}
-// Update win->w_topline to move the cursor onto the screen.
-void update_topline_win(win_T *win)
-{
- switchwin_T switchwin;
- switch_win(&switchwin, win, NULL, true);
- update_topline(curwin);
- restore_win(&switchwin, true);
-}
-
// Return the scrolljump value to use for the current window.
// When 'scrolljump' is positive use it as-is.
// When 'scrolljump' is negative use it as a percentage of the window height.
diff --git a/src/nvim/msgpack_rpc/unpacker.c b/src/nvim/msgpack_rpc/unpacker.c
index e5583cf91b..c082bba660 100644
--- a/src/nvim/msgpack_rpc/unpacker.c
+++ b/src/nvim/msgpack_rpc/unpacker.c
@@ -380,6 +380,7 @@ bool unpacker_parse_redraw(Unpacker *p)
size_t size = p->read_size;
GridLineEvent *g = p->grid_line_event;
+// -V:NEXT_TYPE:501
#define NEXT_TYPE(tok, typ) \
result = mpack_rtoken(&data, &size, &tok); \
if (result == MPACK_EOF) { \
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index ed689df91c..f993bf339b 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1230,8 +1230,7 @@ static void normal_check_interrupt(NormalState *s)
static void normal_check_window_scrolled(NormalState *s)
{
if (!finish_op) {
- // Trigger Scroll if the viewport changed.
- may_trigger_winscrolled();
+ may_trigger_win_scrolled_resized();
}
}
@@ -1397,6 +1396,9 @@ static int normal_check(VimState *state)
fclose(time_fd);
time_fd = NULL;
}
+ // After the first screen update may start triggering WinScrolled
+ // autocmd events. Store all the scroll positions and sizes now.
+ may_make_initial_scroll_size_snapshot();
}
// May perform garbage collection when waiting for a character, but
@@ -1832,11 +1834,11 @@ void clear_showcmd(void)
int chars = 0;
if (cursor_bot) {
- s = ml_get_pos(&VIsual);
+ s = (char_u *)ml_get_pos(&VIsual);
e = (char_u *)get_cursor_pos_ptr();
} else {
s = (char_u *)get_cursor_pos_ptr();
- e = ml_get_pos(&VIsual);
+ e = (char_u *)ml_get_pos(&VIsual);
}
while ((*p_sel != 'e') ? s <= e : s < e) {
l = utfc_ptr2len((char *)s);
@@ -2740,7 +2742,7 @@ static int nv_zg_zw(cmdarg_T *cap, int nchar)
len = spell_move_to(curwin, FORWARD, true, true, NULL);
emsg_off--;
if (len != 0 && curwin->w_cursor.col <= pos.col) {
- ptr = (char *)ml_get_pos(&curwin->w_cursor);
+ ptr = ml_get_pos(&curwin->w_cursor);
}
curwin->w_cursor = pos;
}
@@ -2766,7 +2768,7 @@ static void nv_zet(cmdarg_T *cap)
long old_fdl = curwin->w_p_fdl;
int old_fen = curwin->w_p_fen;
- int l_p_siso = (int)get_sidescrolloff_value(curwin);
+ int siso = (int)get_sidescrolloff_value(curwin);
if (ascii_isdigit(nchar) && !nv_z_get_count(cap, &nchar)) {
return;
@@ -2896,8 +2898,8 @@ static void nv_zet(cmdarg_T *cap)
} else {
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
}
- if (col > l_p_siso) {
- col -= l_p_siso;
+ if (col > siso) {
+ col -= siso;
} else {
col = 0;
}
@@ -2917,10 +2919,10 @@ static void nv_zet(cmdarg_T *cap)
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
}
n = curwin->w_width_inner - curwin_col_off();
- if (col + l_p_siso < n) {
+ if (col + siso < n) {
col = 0;
} else {
- col = col + l_p_siso - n + 1;
+ col = col + siso - n + 1;
}
if (curwin->w_leftcol != col) {
curwin->w_leftcol = col;
@@ -3586,10 +3588,10 @@ bool get_visual_text(cmdarg_T *cap, char **pp, size_t *lenp)
*lenp = strlen(*pp);
} else {
if (lt(curwin->w_cursor, VIsual)) {
- *pp = (char *)ml_get_pos(&curwin->w_cursor);
+ *pp = ml_get_pos(&curwin->w_cursor);
*lenp = (size_t)VIsual.col - (size_t)curwin->w_cursor.col + 1;
} else {
- *pp = (char *)ml_get_pos(&VIsual);
+ *pp = ml_get_pos(&VIsual);
*lenp = (size_t)curwin->w_cursor.col - (size_t)VIsual.col + 1;
}
if (**pp == NUL) {
@@ -4006,7 +4008,7 @@ static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrappe
curwin->w_set_curswant = true;
CLEAR_FIELD(sia);
- int i = do_search(cap->oap, dir, dir, (char_u *)pat, cap->count1,
+ int i = do_search(cap->oap, dir, dir, pat, cap->count1,
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
if (wrapped != NULL) {
*wrapped = sia.sa_wrapped;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index f1814291b8..0cae0e854f 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -80,7 +80,7 @@ struct block_def {
int startspaces; // 'extra' cols before first char
int endspaces; // 'extra' cols after last char
int textlen; // chars in block
- char_u *textstart; // pointer to 1st char (partially) in block
+ char *textstart; // pointer to 1st char (partially) in block
colnr_T textcol; // index of chars (partially) in block
colnr_T start_vcol; // start col of 1st char wholly inside block
colnr_T end_vcol; // start col of 1st char wholly after block
@@ -90,7 +90,7 @@ struct block_def {
int pre_whitesp; // screen cols of ws before block
int pre_whitesp_c; // chars of ws before block
colnr_T end_char_vcols; // number of vcols of post-block char
- colnr_T start_char_vcols; // number of vcols of pre-block char
+ colnr_T start_char_vcols; // number of vcols of pre-block char
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -358,7 +358,7 @@ static void shift_block(oparg_T *oap, int amount)
return; // multiplication overflow
}
- char_u *const oldp = (char_u *)get_cursor_line_ptr();
+ char *const oldp = get_cursor_line_ptr();
int startcol, oldlen, newlen;
@@ -369,9 +369,9 @@ static void shift_block(oparg_T *oap, int amount)
// 4. Construct new string
total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
- char_u *old_textstart = bd.textstart;
+ char *old_textstart = bd.textstart;
if (bd.startspaces) {
- if (utfc_ptr2len((char *)bd.textstart) == 1) {
+ if (utfc_ptr2len(bd.textstart) == 1) {
bd.textstart++;
} else {
ws_vcol = 0;
@@ -382,13 +382,13 @@ static void shift_block(oparg_T *oap, int amount)
// TODO(vim): is passing bd.textstart for start of the line OK?
chartabsize_T cts;
init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum,
- bd.start_vcol, (char *)bd.textstart, (char *)bd.textstart);
+ bd.start_vcol, bd.textstart, bd.textstart);
while (ascii_iswhite(*cts.cts_ptr)) {
incr = lbr_chartabsize_adv(&cts);
total += incr;
cts.cts_vcol += incr;
}
- bd.textstart = (char_u *)cts.cts_ptr;
+ bd.textstart = cts.cts_ptr;
bd.start_vcol = cts.cts_vcol;
clear_chartabsize_arg(&cts);
@@ -403,7 +403,7 @@ static void shift_block(oparg_T *oap, int amount)
// if we're splitting a TAB, allow for it
int col_pre = bd.pre_whitesp_c - (bd.startspaces != 0);
bd.textcol -= col_pre;
- const int len = (int)STRLEN(bd.textstart) + 1;
+ const int len = (int)strlen(bd.textstart) + 1;
int col = bd.textcol + i + j + len;
assert(col >= 0);
newp = (char_u *)xmalloc((size_t)col);
@@ -419,14 +419,14 @@ static void shift_block(oparg_T *oap, int amount)
} else { // left
colnr_T destination_col; // column to which text in block will
// be shifted
- char_u *verbatim_copy_end; // end of the part of the line which is
+ char *verbatim_copy_end; // end of the part of the line which is
// copied verbatim
colnr_T verbatim_copy_width; // the (displayed) width of this part
// of line
size_t fill; // nr of spaces that replace a TAB
size_t new_line_len; // the length of the line after the
// block shift
- char *non_white = (char *)bd.textstart;
+ char *non_white = bd.textstart;
// Firstly, let's find the first non-whitespace character that is
// displayed after the block's start column and the character's column
@@ -446,7 +446,7 @@ static void shift_block(oparg_T *oap, int amount)
chartabsize_T cts;
init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum,
- non_white_col, (char *)bd.textstart, non_white);
+ non_white_col, bd.textstart, non_white);
while (ascii_iswhite(*cts.cts_ptr)) {
incr = lbr_chartabsize_adv(&cts);
cts.cts_vcol += incr;
@@ -475,7 +475,7 @@ static void shift_block(oparg_T *oap, int amount)
verbatim_copy_width -= bd.start_char_vcols;
}
init_chartabsize_arg(&cts, curwin, 0, verbatim_copy_width,
- (char *)bd.textstart, (char *)verbatim_copy_end);
+ bd.textstart, verbatim_copy_end);
while (cts.cts_vcol < destination_col) {
incr = lbr_chartabsize(&cts);
if (cts.cts_vcol + incr > destination_col) {
@@ -485,7 +485,7 @@ static void shift_block(oparg_T *oap, int amount)
MB_PTR_ADV(cts.cts_ptr);
}
verbatim_copy_width = cts.cts_vcol;
- verbatim_copy_end = (char_u *)cts.cts_ptr;
+ verbatim_copy_end = cts.cts_ptr;
clear_chartabsize_arg(&cts);
// If "destination_col" is different from the width of the initial
@@ -504,7 +504,7 @@ static void shift_block(oparg_T *oap, int amount)
newp = (char_u *)xmalloc(new_line_len);
startcol = (int)verbatim_diff;
- oldlen = bd.textcol + (int)(non_white - (char *)bd.textstart) - (int)verbatim_diff;
+ oldlen = bd.textcol + (int)(non_white - bd.textstart) - (int)verbatim_diff;
newlen = (int)fill;
memmove(newp, oldp, verbatim_diff);
memset(newp + verbatim_diff, ' ', fill);
@@ -2095,7 +2095,7 @@ void op_tilde(oparg_T *oap)
for (;;) {
did_change |= swapchars(oap->op_type, &pos,
pos.lnum == oap->end.lnum ? oap->end.col + 1 :
- (int)STRLEN(ml_get_pos(&pos)));
+ (int)strlen(ml_get_pos(&pos)));
if (ltoreq(oap->end, pos) || inc(&pos) == -1) {
break;
}
@@ -2138,7 +2138,7 @@ static int swapchars(int op_type, pos_T *pos, int length)
int did_change = 0;
for (int todo = length; todo > 0; todo--) {
- const int len = utfc_ptr2len((char *)ml_get_pos(pos));
+ const int len = utfc_ptr2len(ml_get_pos(pos));
// we're counting bytes, not characters
if (len > 0) {
@@ -2727,7 +2727,7 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
} else {
bd.textlen = endcol - startcol + oap->inclusive;
}
- bd.textstart = (char_u *)p + startcol;
+ bd.textstart = p + startcol;
yank_copy_line(reg, &bd, y_idx, false);
break;
}
@@ -2838,7 +2838,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx,
int s = bd->textlen + bd->endspaces;
while (s > 0 && ascii_iswhite(*(bd->textstart + s - 1))) {
- s = s - utf_head_off((char *)bd->textstart, (char *)bd->textstart + s - 1) - 1;
+ s = s - utf_head_off(bd->textstart, bd->textstart + s - 1) - 1;
pnew--;
}
}
@@ -4346,7 +4346,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool
bdp->textlen = (int)(pend - pstart);
}
bdp->textcol = (colnr_T)(pstart - line);
- bdp->textstart = (char_u *)pstart;
+ bdp->textstart = pstart;
restore_lbr(lbr_saved);
}
@@ -5403,7 +5403,7 @@ void cursor_pos_info(dict_T *dict)
virtual_op = virtual_active();
block_prep(&oparg, &bd, lnum, false);
virtual_op = kNone;
- s = (char *)bd.textstart;
+ s = bd.textstart;
len = (long)bd.textlen;
break;
case 'V':
@@ -6085,7 +6085,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
// Include the trailing byte of a multi-byte char.
if (oap->inclusive) {
- const int l = utfc_ptr2len((char *)ml_get_pos(&oap->end));
+ const int l = utfc_ptr2len(ml_get_pos(&oap->end));
if (l > 1) {
oap->end.col += l - 1;
}
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 827b755ce8..b78fc7c27a 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -702,14 +702,14 @@ void set_helplang_default(const char *lang)
int idx = findoption("hlg");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
if (options[idx].flags & P_ALLOCED) {
- free_string_option((char *)p_hlg);
+ free_string_option(p_hlg);
}
- p_hlg = (char_u *)xmemdupz(lang, lang_len);
+ p_hlg = xmemdupz(lang, lang_len);
// zh_CN becomes "cn", zh_TW becomes "tw".
- if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) {
- p_hlg[0] = (char_u)TOLOWER_ASC(p_hlg[3]);
- p_hlg[1] = (char_u)TOLOWER_ASC(p_hlg[4]);
- } else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C') {
+ if (STRNICMP(p_hlg, "zh_", 3) == 0 && strlen(p_hlg) >= 5) {
+ p_hlg[0] = (char)TOLOWER_ASC(p_hlg[3]);
+ p_hlg[1] = (char)TOLOWER_ASC(p_hlg[4]);
+ } else if (strlen(p_hlg) >= 1 && *p_hlg == 'C') {
// any C like setting, such as C.UTF-8, becomes "en"
p_hlg[0] = 'e';
p_hlg[1] = 'n';
@@ -1686,9 +1686,9 @@ static char *option_expand(int opt_idx, char *val)
// Escape spaces when expanding 'tags', they are used to separate file
// names.
// For 'spellsuggest' expand after "file:".
- expand_env_esc((char_u *)val, (char_u *)NameBuff, MAXPATHL,
+ expand_env_esc(val, NameBuff, MAXPATHL,
(char_u **)options[opt_idx].var == &p_tags, false,
- (char_u **)options[opt_idx].var == (char_u **)&p_sps ? (char_u *)"file:" :
+ (char_u **)options[opt_idx].var == (char_u **)&p_sps ? "file:" :
NULL);
if (strcmp(NameBuff, val) == 0) { // they are the same
return NULL;
@@ -1899,6 +1899,46 @@ void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
}
}
+/// Apply the OptionSet autocommand.
+static void apply_optionset_autocmd(int opt_idx, long opt_flags, long oldval, long oldval_g,
+ long newval, const char *errmsg)
+{
+ // Don't do this while starting up, failure or recursively.
+ if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
+ return;
+ }
+
+ char buf_old[12], buf_old_global[12], buf_new[12], buf_type[12];
+
+ vim_snprintf(buf_old, sizeof(buf_old), "%ld", oldval);
+ vim_snprintf(buf_old_global, sizeof(buf_old_global), "%ld", oldval_g);
+ vim_snprintf(buf_new, sizeof(buf_new), "%ld", newval);
+ vim_snprintf(buf_type, sizeof(buf_type), "%s",
+ (opt_flags & OPT_LOCAL) ? "local" : "global");
+ set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
+ set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
+ set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
+ if (opt_flags & OPT_LOCAL) {
+ set_vim_var_string(VV_OPTION_COMMAND, "setlocal", -1);
+ set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
+ }
+ if (opt_flags & OPT_GLOBAL) {
+ set_vim_var_string(VV_OPTION_COMMAND, "setglobal", -1);
+ set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
+ }
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
+ set_vim_var_string(VV_OPTION_COMMAND, "set", -1);
+ set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
+ set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
+ }
+ if (opt_flags & OPT_MODELINE) {
+ set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
+ set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
+ }
+ apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL);
+ reset_v_option_vars();
+}
+
/// Set the value of a boolean option, taking care of side effects
///
/// @param[in] opt_idx Option index in options[] table.
@@ -2153,40 +2193,10 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
options[opt_idx].flags |= P_WAS_SET;
- // Don't do this while starting up or recursively.
- if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL) {
- char buf_old[2];
- char buf_old_global[2];
- char buf_new[2];
- char buf_type[7];
- vim_snprintf(buf_old, ARRAY_SIZE(buf_old), "%d", old_value ? true : false);
- vim_snprintf(buf_old_global, ARRAY_SIZE(buf_old_global), "%d", old_global_value ? true : false);
- vim_snprintf(buf_new, ARRAY_SIZE(buf_new), "%d", value ? true : false);
- vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s",
- (opt_flags & OPT_LOCAL) ? "local" : "global");
- set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
- set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
- set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
- if (opt_flags & OPT_LOCAL) {
- set_vim_var_string(VV_OPTION_COMMAND, "setlocal", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
- }
- if (opt_flags & OPT_GLOBAL) {
- set_vim_var_string(VV_OPTION_COMMAND, "setglobal", -1);
- set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
- }
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
- set_vim_var_string(VV_OPTION_COMMAND, "set", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
- set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
- }
- if (opt_flags & OPT_MODELINE) {
- set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
- }
- apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL);
- reset_v_option_vars();
- }
+ apply_optionset_autocmd(opt_idx, opt_flags,
+ (long)(old_value ? true : false),
+ (long)(old_global_value ? true : false),
+ (long)(value ? true : false), NULL);
if (options[opt_idx].flags & P_UI_OPTION) {
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
@@ -2596,41 +2606,8 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf,
options[opt_idx].flags |= P_WAS_SET;
- // Don't do this while starting up, failure or recursively.
- if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL) {
- char buf_old[NUMBUFLEN];
- char buf_old_global[NUMBUFLEN];
- char buf_new[NUMBUFLEN];
- char buf_type[7];
-
- vim_snprintf(buf_old, ARRAY_SIZE(buf_old), "%ld", old_value);
- vim_snprintf(buf_old_global, ARRAY_SIZE(buf_old_global), "%ld", old_global_value);
- vim_snprintf(buf_new, ARRAY_SIZE(buf_new), "%ld", value);
- vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s",
- (opt_flags & OPT_LOCAL) ? "local" : "global");
- set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
- set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
- set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
- if (opt_flags & OPT_LOCAL) {
- set_vim_var_string(VV_OPTION_COMMAND, "setlocal", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
- }
- if (opt_flags & OPT_GLOBAL) {
- set_vim_var_string(VV_OPTION_COMMAND, "setglobal", -1);
- set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1);
- }
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
- set_vim_var_string(VV_OPTION_COMMAND, "set", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
- set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1);
- }
- if (opt_flags & OPT_MODELINE) {
- set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1);
- }
- apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL);
- reset_v_option_vars();
- }
+ apply_optionset_autocmd(opt_idx, opt_flags, old_value, old_global_value,
+ value, errmsg);
if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) {
ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
@@ -4588,13 +4565,13 @@ static char_u expand_option_name[5] = { 't', '_', NUL, NUL, NUL };
static int expand_option_flags = 0;
/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
-void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
+void set_context_in_set_cmd(expand_T *xp, char *arg, int opt_flags)
{
- char_u nextchar;
+ char nextchar;
uint32_t flags = 0; // init for GCC
int opt_idx = 0; // init for GCC
- char_u *p;
- char_u *s;
+ char *p;
+ char *s;
int is_term_option = false;
int key;
@@ -4602,12 +4579,12 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
xp->xp_context = EXPAND_SETTINGS;
if (*arg == NUL) {
- xp->xp_pattern = (char *)arg;
+ xp->xp_pattern = arg;
return;
}
- p = arg + STRLEN(arg) - 1;
+ p = arg + strlen(arg) - 1;
if (*p == ' ' && *(p - 1) != '\\') {
- xp->xp_pattern = (char *)p + 1;
+ xp->xp_pattern = p + 1;
return;
}
while (p > arg) {
@@ -4633,7 +4610,7 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
xp->xp_context = EXPAND_BOOL_SETTINGS;
p += 3;
}
- xp->xp_pattern = (char *)p;
+ xp->xp_pattern = p;
arg = p;
if (*arg == '<') {
while (*p != '>') {
@@ -4641,7 +4618,7 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
return;
}
}
- key = get_special_key_code(arg + 1);
+ key = get_special_key_code((char_u *)arg + 1);
if (key == 0) { // unknown name
xp->xp_context = EXPAND_NOTHING;
return;
@@ -4661,8 +4638,8 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
}
nextchar = *++p;
is_term_option = true;
- expand_option_name[2] = p[-2];
- expand_option_name[3] = p[-1];
+ expand_option_name[2] = (char_u)p[-2];
+ expand_option_name[3] = (char_u)p[-1];
} else {
// Allow * wildcard.
while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*') {
@@ -4701,7 +4678,7 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
} else {
expand_option_idx = opt_idx;
}
- xp->xp_pattern = (char *)p + 1;
+ xp->xp_pattern = p + 1;
return;
}
xp->xp_context = EXPAND_NOTHING;
@@ -4709,29 +4686,29 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
return;
}
- xp->xp_pattern = (char *)p + 1;
+ xp->xp_pattern = p + 1;
if (flags & P_EXPAND) {
- p = options[opt_idx].var;
- if (p == (char_u *)&p_bdir
- || p == (char_u *)&p_dir
- || p == (char_u *)&p_path
- || p == (char_u *)&p_pp
- || p == (char_u *)&p_rtp
- || p == (char_u *)&p_cdpath
- || p == (char_u *)&p_vdir) {
+ p = (char *)options[opt_idx].var;
+ if (p == (char *)&p_bdir
+ || p == (char *)&p_dir
+ || p == (char *)&p_path
+ || p == (char *)&p_pp
+ || p == (char *)&p_rtp
+ || p == (char *)&p_cdpath
+ || p == (char *)&p_vdir) {
xp->xp_context = EXPAND_DIRECTORIES;
- if (p == (char_u *)&p_path || p == (char_u *)&p_cdpath) {
+ if (p == (char *)&p_path || p == (char *)&p_cdpath) {
xp->xp_backslash = XP_BS_THREE;
} else {
xp->xp_backslash = XP_BS_ONE;
}
- } else if (p == (char_u *)&p_ft) {
+ } else if (p == (char *)&p_ft) {
xp->xp_context = EXPAND_FILETYPE;
} else {
xp->xp_context = EXPAND_FILES;
// for 'tags' need three backslashes for a space
- if (p == (char_u *)&p_tags) {
+ if (p == (char *)&p_tags) {
xp->xp_backslash = XP_BS_THREE;
} else {
xp->xp_backslash = XP_BS_ONE;
@@ -4741,16 +4718,16 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
// For an option that is a list of file names, find the start of the
// last file name.
- for (p = arg + STRLEN(arg) - 1; p > (char_u *)xp->xp_pattern; p--) {
+ for (p = arg + strlen(arg) - 1; p > xp->xp_pattern; p--) {
// count number of backslashes before ' ' or ','
if (*p == ' ' || *p == ',') {
s = p;
- while (s > (char_u *)xp->xp_pattern && *(s - 1) == '\\') {
+ while (s > xp->xp_pattern && *(s - 1) == '\\') {
s--;
}
if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3))
|| (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0)) {
- xp->xp_pattern = (char *)p + 1;
+ xp->xp_pattern = p + 1;
break;
}
}
@@ -4758,7 +4735,7 @@ void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags)
// for 'spellsuggest' start at "file:"
if (options[opt_idx].var == (char_u *)&p_sps
&& STRNCMP(p, "file:", 5) == 0) {
- xp->xp_pattern = (char *)p + 5;
+ xp->xp_pattern = p + 5;
break;
}
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index c60925d485..40ce022bea 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -545,7 +545,7 @@ EXTERN char_u *p_guifont; // 'guifont'
EXTERN char_u *p_guifontwide; // 'guifontwide'
EXTERN char *p_hf; // 'helpfile'
EXTERN long p_hh; // 'helpheight'
-EXTERN char_u *p_hlg; // 'helplang'
+EXTERN char *p_hlg; // 'helplang'
EXTERN int p_hid; // 'hidden'
EXTERN char *p_hl; // 'highlight'
EXTERN int p_hls; // 'hlsearch'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index dc0561d560..1cf8ab3253 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -2007,7 +2007,7 @@ return {
},
{
full_name='secure',
- short_desc=N_("mode for reading .vimrc in current dir"),
+ short_desc=N_("No description"),
type='bool', scope={'global'},
secure=true,
varname='p_secure',
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 5022334582..7522745bcb 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -741,9 +741,9 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
errmsg = check_colorcolumn(curwin);
- } else if (varp == (char **)&p_hlg) { // 'helplang'
+ } else if (varp == &p_hlg) { // 'helplang'
// Check for "", "ab", "ab,cd", etc.
- for (s = (char *)p_hlg; *s != NUL; s += 3) {
+ for (s = p_hlg; *s != NUL; s += 3) {
if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL)) {
errmsg = e_invarg;
break;
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 8f58f5217e..dac3cae199 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -554,7 +554,7 @@ char *expand_env_save(char *src)
char_u *expand_env_save_opt(char_u *src, bool one)
{
char_u *p = xmalloc(MAXPATHL);
- expand_env_esc(src, p, MAXPATHL, false, one, NULL);
+ expand_env_esc((char *)src, (char *)p, MAXPATHL, false, one, NULL);
return p;
}
@@ -568,7 +568,7 @@ char_u *expand_env_save_opt(char_u *src, bool one)
/// @param dstlen Maximum length of the result
void expand_env(char *src, char *dst, int dstlen)
{
- expand_env_esc((char_u *)src, (char_u *)dst, dstlen, false, false, NULL);
+ expand_env_esc(src, dst, dstlen, false, false, NULL);
}
/// Expand environment variable with path name and escaping.
@@ -580,34 +580,34 @@ void expand_env(char *src, char *dst, int dstlen)
/// @param esc Escape spaces in expanded variables
/// @param one `srcp` is a single filename
/// @param prefix Start again after this (can be NULL)
-void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, bool esc, bool one,
- char_u *prefix)
+void expand_env_esc(char *restrict srcp, char *restrict dst, int dstlen, bool esc, bool one,
+ char *prefix)
FUNC_ATTR_NONNULL_ARG(1, 2)
{
- char_u *tail;
- char_u *var;
+ char *tail;
+ char *var;
bool copy_char;
bool mustfree; // var was allocated, need to free it later
bool at_start = true; // at start of a name
- int prefix_len = (prefix == NULL) ? 0 : (int)STRLEN(prefix);
+ int prefix_len = (prefix == NULL) ? 0 : (int)strlen(prefix);
- char *src = skipwhite((char *)srcp);
+ char *src = skipwhite(srcp);
dstlen--; // leave one char space for "\,"
while (*src && dstlen > 0) {
// Skip over `=expr`.
if (src[0] == '`' && src[1] == '=') {
- var = (char_u *)src;
+ var = src;
src += 2;
(void)skip_expr(&src);
if (*src == '`') {
src++;
}
- size_t len = (size_t)(src - (char *)var);
+ size_t len = (size_t)(src - var);
if (len > (size_t)dstlen) {
len = (size_t)dstlen;
}
- memcpy((char *)dst, (char *)var, len);
+ memcpy(dst, var, len);
dst += len;
dstlen -= (int)len;
continue;
@@ -620,7 +620,7 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
// The variable name is copied into dst temporarily, because it may
// be a string in read-only memory and a NUL needs to be appended.
if (*src != '~') { // environment var
- tail = (char_u *)src + 1;
+ tail = src + 1;
var = dst;
int c = dstlen - 1;
@@ -649,7 +649,7 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
}
#endif
*var = NUL;
- var = (char_u *)vim_getenv((char *)dst);
+ var = vim_getenv(dst);
mustfree = true;
#if defined(UNIX)
}
@@ -657,12 +657,12 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
} else if (src[1] == NUL // home directory
|| vim_ispathsep(src[1])
|| vim_strchr(" ,\t\n", src[1]) != NULL) {
- var = (char_u *)homedir;
- tail = (char_u *)src + 1;
+ var = homedir;
+ tail = src + 1;
} else { // user directory
#if defined(UNIX)
// Copy ~user to dst[], so we can put a NUL after it.
- tail = (char_u *)src;
+ tail = src;
var = dst;
int c = dstlen - 1;
while (c-- > 0
@@ -675,15 +675,15 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
// Get the user directory. If this fails the shell is used to expand
// ~user, which is slower and may fail on old versions of /bin/sh.
var = (*dst == NUL) ? NULL
- : (char_u *)os_get_userdir((char *)dst + 1);
+ : os_get_userdir(dst + 1);
mustfree = true;
if (var == NULL) {
expand_T xpc;
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- var = (char_u *)ExpandOne(&xpc, (char *)dst, NULL,
- WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
+ var = ExpandOne(&xpc, dst, NULL,
+ WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE);
mustfree = true;
}
#else
@@ -710,8 +710,8 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
// If "var" contains white space, escape it with a backslash.
// Required for ":e ~/tt" when $HOME includes a space.
- if (esc && var != NULL && strpbrk((char *)var, " \t") != NULL) {
- char_u *p = vim_strsave_escaped(var, (char_u *)" \t");
+ if (esc && var != NULL && strpbrk(var, " \t") != NULL) {
+ char *p = (char *)vim_strsave_escaped((char_u *)var, (char_u *)" \t");
if (mustfree) {
xfree(var);
@@ -721,13 +721,13 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
}
if (var != NULL && *var != NUL
- && (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen)) {
+ && (strlen(var) + strlen(tail) + 1 < (unsigned)dstlen)) {
STRCPY(dst, var);
- dstlen -= (int)STRLEN(var);
- int c = (int)STRLEN(var);
+ dstlen -= (int)strlen(var);
+ int c = (int)strlen(var);
// if var[] ends in a path separator and tail[] starts
// with it, skip a character
- if (after_pathsep((char *)dst, (char *)dst + c)
+ if (after_pathsep(dst, dst + c)
#if defined(BACKSLASH_IN_FILENAME)
&& dst[-1] != ':'
#endif
@@ -735,7 +735,7 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
tail++;
}
dst += c;
- src = (char *)tail;
+ src = tail;
copy_char = false;
}
if (mustfree) {
@@ -749,17 +749,17 @@ void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, boo
// ":edit foo ~ foo".
at_start = false;
if (src[0] == '\\' && src[1] != NUL) {
- *dst++ = (char_u)(*src++);
+ *dst++ = *src++;
dstlen--;
} else if ((src[0] == ' ' || src[0] == ',') && !one) {
at_start = true;
}
if (dstlen > 0) {
- *dst++ = (char_u)(*src++);
+ *dst++ = *src++;
dstlen--;
if (prefix != NULL
- && src - prefix_len >= (char *)srcp
+ && src - prefix_len >= srcp
&& STRNCMP(src - prefix_len, prefix, prefix_len) == 0) {
at_start = true;
}
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 2ae0a81e3d..d694025bc2 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -974,7 +974,7 @@ int os_file_mkdir(char *fname, int32_t mode)
*tail = NUL;
int r;
char *failed_dir;
- if ((r = os_mkdir_recurse(fname, mode, &failed_dir) < 0)) {
+ if (((r = os_mkdir_recurse(fname, mode, &failed_dir)) < 0)) {
semsg(_(e_mkdir), failed_dir, os_strerror(r));
xfree(failed_dir);
}
diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c
index d9273e69da..f4d95e141b 100644
--- a/src/nvim/os/process.c
+++ b/src/nvim/os/process.c
@@ -264,5 +264,16 @@ Dictionary os_proc_info(int pid)
/// Return true if process `pid` is running.
bool os_proc_running(int pid)
{
- return uv_kill(pid, 0) == 0;
+ int err = uv_kill(pid, 0);
+ // If there is no error the process must be running.
+ if (err == 0) {
+ return true;
+ }
+ // If the error is ESRCH then the process is not running.
+ if (err == UV_ESRCH) {
+ return false;
+ }
+ // If the process is running and owned by another user we get EPERM. With
+ // other errors the process might be running, assuming it is then.
+ return true;
}
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index b4bee6e550..c1359d6ece 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -120,15 +120,15 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
{
int i;
size_t len;
- char_u *p;
+ char *p;
bool dir;
char_u *extra_shell_arg = NULL;
ShellOpts shellopts = kShellOptExpand | kShellOptSilent;
int j;
- char_u *tempname;
- char_u *command;
+ char *tempname;
+ char *command;
FILE *fd;
- char_u *buffer;
+ char *buffer;
#define STYLE_ECHO 0 // use "echo", the default
#define STYLE_GLOB 1 // use "glob", for csh
#define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh
@@ -175,7 +175,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
}
// get a name for the temp file
- if ((tempname = (char_u *)vim_tempname()) == NULL) {
+ if ((tempname = vim_tempname()) == NULL) {
emsg(_(e_notmp));
return FAIL;
}
@@ -196,7 +196,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
&& (len = strlen(pat[0])) > 2
&& *(pat[0] + len - 1) == '`') {
shell_style = STYLE_BT;
- } else if ((len = STRLEN(p_sh)) >= 3) {
+ } else if ((len = strlen(p_sh)) >= 3) {
if (strcmp(p_sh + len - 3, "csh") == 0) {
shell_style = STYLE_GLOB;
} else if (strcmp(p_sh + len - 3, "zsh") == 0) {
@@ -211,7 +211,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// Compute the length of the command. We need 2 extra bytes: for the
// optional '&' and for the NUL.
// Worst case: "unset nonomatch; print -N >" plus two is 29
- len = STRLEN(tempname) + 29;
+ len = strlen(tempname) + 29;
if (shell_style == STYLE_VIMGLOB) {
len += strlen(sh_vimglob_func);
}
@@ -248,7 +248,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
STRCPY(command, "(");
}
STRCAT(command, pat[0] + 1); // exclude first backtick
- p = command + STRLEN(command) - 1;
+ p = command + strlen(command) - 1;
if (is_fish_shell) {
*p-- = ';';
STRCAT(command, " end");
@@ -294,7 +294,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// characters, except inside ``.
bool intick = false;
- p = command + STRLEN(command);
+ p = command + strlen(command);
*p++ = ' ';
for (j = 0; pat[i][j] != NUL; j++) {
if (pat[i][j] == '`') {
@@ -319,7 +319,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
}
// Copy one character.
- *p++ = (char_u)pat[i][j];
+ *p++ = pat[i][j];
}
*p = NUL;
}
@@ -347,7 +347,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
}
// execute the shell command
- i = call_shell(command, shellopts, extra_shell_arg);
+ i = call_shell((char_u *)command, shellopts, extra_shell_arg);
// When running in the background, give it some time to create the temp
// file, but don't wait for it to finish.
@@ -358,7 +358,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
xfree(command);
if (i) { // os_call_shell() failed
- os_remove((char *)tempname);
+ os_remove(tempname);
xfree(tempname);
// With interactive completion, the error message is not printed.
if (!(flags & EW_SILENT)) {
@@ -377,7 +377,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
}
// read the names from the file into memory
- fd = fopen((char *)tempname, READBIN);
+ fd = fopen(tempname, READBIN);
if (fd == NULL) {
// Something went wrong, perhaps a file name with a special char.
if (!(flags & EW_SILENT)) {
@@ -407,9 +407,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
buffer = xmalloc(len + 1);
// fread() doesn't terminate buffer with NUL;
// appropriate termination (not always NUL) is done below.
- size_t readlen = fread((char *)buffer, 1, len, fd);
+ size_t readlen = fread(buffer, 1, len, fd);
fclose(fd);
- os_remove((char *)tempname);
+ os_remove(tempname);
if (readlen != len) {
// unexpected read error
semsg(_(e_notread), tempname);
@@ -427,7 +427,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
while (*p != ' ' && *p != '\n') {
p++;
}
- p = (char_u *)skipwhite((char *)p); // skip to next entry
+ p = skipwhite(p); // skip to next entry
}
// file names are separated with NL
} else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
@@ -440,7 +440,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
if (*p != NUL) {
p++;
}
- p = (char_u *)skipwhite((char *)p); // skip leading white space
+ p = skipwhite(p); // skip leading white space
}
// file names are separated with NUL
} else {
@@ -454,7 +454,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
if (shell_style == STYLE_PRINT && !did_find_nul) {
// If there is a NUL, set did_find_nul, else set check_spaces
buffer[len] = NUL;
- if (len && (int)STRLEN(buffer) < (int)len) {
+ if (len && (int)strlen(buffer) < (int)len) {
did_find_nul = true;
} else {
check_spaces = true;
@@ -493,7 +493,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// Isolate the individual file names.
p = buffer;
for (i = 0; i < *num_file; i++) {
- (*file)[i] = (char *)p;
+ (*file)[i] = p;
// Space or NL separates
if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
|| shell_style == STYLE_VIMGLOB) {
@@ -505,7 +505,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
*p = NUL;
} else {
*p++ = NUL;
- p = (char_u *)skipwhite((char *)p); // skip to next entry
+ p = skipwhite(p); // skip to next entry
}
} else { // NUL separates
while (*p && p < buffer + len) { // skip entry
@@ -537,9 +537,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
p = xmalloc(strlen((*file)[i]) + 1 + dir);
STRCPY(p, (*file)[i]);
if (dir) {
- add_pathsep((char *)p); // add '/' to a directory name
+ add_pathsep(p); // add '/' to a directory name
}
- (*file)[j++] = (char *)p;
+ (*file)[j++] = p;
}
xfree(buffer);
*num_file = j;
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 68c4b596d7..49deb821be 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -628,26 +628,26 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
// Make room for file name. When doing encoding conversion the actual
// length may be quite a bit longer, thus use the maximum possible length.
- char_u *buf = xmalloc(MAXPATHL);
+ char *buf = xmalloc(MAXPATHL);
// Find the first part in the path name that contains a wildcard.
// When EW_ICASE is set every letter is considered to be a wildcard.
// Copy it into "buf", including the preceding characters.
- char_u *p = buf;
- char_u *s = buf;
- char_u *e = NULL;
- const char_u *path_end = (char_u *)path;
+ char *p = buf;
+ char *s = buf;
+ char *e = NULL;
+ const char *path_end = path;
while (*path_end != NUL) {
// May ignore a wildcard that has a backslash before it; it will
// be removed by rem_backslash() or file_pat_to_reg_pat() below.
- if (path_end >= (char_u *)path + wildoff && rem_backslash((char *)path_end)) {
+ if (path_end >= path + wildoff && rem_backslash((char *)path_end)) {
*p++ = *path_end++;
} else if (vim_ispathsep_nocolon(*path_end)) {
if (e != NULL) {
break;
}
s = p + 1;
- } else if (path_end >= (char_u *)path + wildoff
+ } else if (path_end >= path + wildoff
&& (vim_strchr("*?[{~$", *path_end) != NULL
#ifndef MSWIN
|| (!p_fic && (flags & EW_ICASE) && mb_isalpha(utf_ptr2char((char *)path_end)))
@@ -667,7 +667,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
// Remove backslashes between "wildoff" and the start of the wildcard
// component.
for (p = buf + wildoff; p < s; p++) {
- if (rem_backslash((char *)p)) {
+ if (rem_backslash(p)) {
STRMOVE(p, p + 1);
e--;
s--;
@@ -683,7 +683,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
// convert the file pattern to a regexp pattern
int starts_with_dot = *s == '.';
- char *pat = file_pat_to_reg_pat((char *)s, (char *)e, NULL, false);
+ char *pat = file_pat_to_reg_pat(s, e, NULL, false);
if (pat == NULL) {
xfree(buf);
return 0;
@@ -717,13 +717,13 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
&& *path_end == '/') {
STRCPY(s, path_end + 1);
stardepth++;
- (void)do_path_expand(gap, (char *)buf, (size_t)(s - buf), flags, true);
+ (void)do_path_expand(gap, buf, (size_t)(s - buf), flags, true);
stardepth--;
}
*s = NUL;
Directory dir;
- char *dirpath = (*buf == NUL ? "." : (char *)buf);
+ char *dirpath = (*buf == NUL ? "." : buf);
if (os_file_is_readable(dirpath) && os_scandir(&dir, dirpath)) {
// Find all matching entries.
char *name;
@@ -738,7 +738,7 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
|| ((flags & EW_NOTWILD)
&& path_fnamencmp(path + (s - buf), name, (size_t)(e - s)) == 0))) {
STRCPY(s, name);
- len = STRLEN(buf);
+ len = strlen(buf);
if (starstar && stardepth < 100) {
// For "**" in the pattern first go deeper in the tree to
@@ -746,27 +746,27 @@ static size_t do_path_expand(garray_T *gap, const char *path, size_t wildoff, in
STRCPY(buf + len, "/**"); // NOLINT
STRCPY(buf + len + 3, path_end);
stardepth++;
- (void)do_path_expand(gap, (char *)buf, len + 1, flags, true);
+ (void)do_path_expand(gap, buf, len + 1, flags, true);
stardepth--;
}
STRCPY(buf + len, path_end);
- if (path_has_exp_wildcard(path_end)) { // handle more wildcards
+ if (path_has_exp_wildcard((char_u *)path_end)) { // handle more wildcards
// need to expand another component of the path
// remove backslashes for the remaining components only
- (void)do_path_expand(gap, (char *)buf, len + 1, flags, false);
+ (void)do_path_expand(gap, buf, len + 1, flags, false);
} else {
FileInfo file_info;
// no more wildcards, check if there is a match
// remove backslashes for the remaining components only
if (*path_end != NUL) {
- backslash_halve((char *)buf + len + 1);
+ backslash_halve(buf + len + 1);
}
// add existing file or symbolic link
if ((flags & EW_ALLLINKS)
- ? os_fileinfo_link((char *)buf, &file_info)
- : os_path_exists((char *)buf)) {
+ ? os_fileinfo_link(buf, &file_info)
+ : os_path_exists(buf)) {
addfile(gap, buf, flags);
}
}
@@ -839,7 +839,7 @@ static bool is_unique(char *maybe_unique, garray_T *gap, int i)
//
// TODO(vim): handle upward search (;) and path limiter (**N) notations by
// expanding each into their equivalent path(s).
-static void expand_path_option(char_u *curdir, garray_T *gap)
+static void expand_path_option(char *curdir, garray_T *gap)
{
char_u *path_option = *curbuf->b_p_path == NUL ? p_path : (char_u *)curbuf->b_p_path;
char *buf = xmalloc(MAXPATHL);
@@ -872,7 +872,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
continue; // URL can't be used here
} else if (!path_is_absolute((char_u *)buf)) {
// Expand relative path to their full path equivalent
- size_t len = STRLEN(curdir);
+ size_t len = strlen(curdir);
if (len + strlen(buf) + 3 > MAXPATHL) {
continue;
}
@@ -927,10 +927,10 @@ static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
return cutoff;
}
-// Sorts, removes duplicates and modifies all the fullpath names in "gap" so
-// that they are unique with respect to each other while conserving the part
-// that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
-static void uniquefy_paths(garray_T *gap, char_u *pattern)
+/// Sorts, removes duplicates and modifies all the fullpath names in "gap" so
+/// that they are unique with respect to each other while conserving the part
+/// that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
+static void uniquefy_paths(garray_T *gap, char *pattern)
{
char **fnames = gap->ga_data;
bool sort_again = false;
@@ -945,7 +945,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
// We need to prepend a '*' at the beginning of file_pattern so that the
// regex matches anywhere in the path. FIXME: is this valid for all
// possible patterns?
- size_t len = STRLEN(pattern);
+ size_t len = strlen(pattern);
char *file_pattern = xmalloc(len + 2);
file_pattern[0] = '*';
file_pattern[1] = NUL;
@@ -965,7 +965,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
char *curdir = xmalloc(MAXPATHL);
os_dirname((char_u *)curdir, MAXPATHL);
- expand_path_option((char_u *)curdir, &path_ga);
+ expand_path_option(curdir, &path_ga);
in_curdir = xcalloc((size_t)gap->ga_len, sizeof(char_u *));
@@ -976,7 +976,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
char *pathsep_p;
char *path_cutoff;
- len = STRLEN(path);
+ len = strlen(path);
is_in_curdir = path_fnamencmp(curdir, path, (size_t)(dir_end - path)) == 0
&& curdir[dir_end - path] == NUL;
if (is_in_curdir) {
@@ -1026,7 +1026,7 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
if (short_name != NULL && short_name > path + 1) {
STRCPY(path, ".");
add_pathsep(path);
- STRMOVE(path + STRLEN(path), short_name);
+ STRMOVE(path + strlen(path), short_name);
}
}
os_breakcheck();
@@ -1121,7 +1121,7 @@ static int expand_in_path(garray_T *const gap, char_u *const pattern, const int
os_dirname(curdir, MAXPATHL);
ga_init(&path_ga, (int)sizeof(char_u *), 1);
- expand_path_option(curdir, &path_ga);
+ expand_path_option((char *)curdir, &path_ga);
xfree(curdir);
if (GA_EMPTY(&path_ga)) {
return 0;
@@ -1232,7 +1232,7 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
// For `=expr` do use the internal function.
for (int i = 0; i < num_pat; i++) {
if (has_special_wildchar((char_u *)pat[i])
- && !(vim_backtick((char_u *)pat[i]) && pat[i][1] == '=')) {
+ && !(vim_backtick(pat[i]) && pat[i][1] == '=')) {
return os_expand_wildcards(num_pat, pat, num_file, file, flags);
}
}
@@ -1247,7 +1247,7 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
add_pat = -1;
p = (char_u *)pat[i];
- if (vim_backtick(p)) {
+ if (vim_backtick((char *)p)) {
add_pat = expand_backtick(&ga, (char *)p, flags);
if (add_pat == -1) {
recursive = false;
@@ -1311,9 +1311,9 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
// When EW_NOTFOUND is used, always add files and dirs. Makes
// "vim c:/" work.
if (flags & EW_NOTFOUND) {
- addfile(&ga, t, flags | EW_DIR | EW_FILE);
+ addfile(&ga, (char *)t, flags | EW_DIR | EW_FILE);
} else {
- addfile(&ga, t, flags);
+ addfile(&ga, (char *)t, flags);
}
if (t != p) {
@@ -1322,7 +1322,7 @@ int gen_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, i
}
if (did_expand_in_path && !GA_EMPTY(&ga) && (flags & EW_PATH)) {
- uniquefy_paths(&ga, p);
+ uniquefy_paths(&ga, (char *)p);
}
if (p != (char_u *)pat[i]) {
xfree(p);
@@ -1349,10 +1349,10 @@ void FreeWild(int count, char **files)
xfree(files);
}
-/// Return true if we can expand this backtick thing here.
-static int vim_backtick(char_u *p)
+/// @return true if we can expand this backtick thing here.
+static int vim_backtick(char *p)
{
- return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`';
+ return *p == '`' && *(p + 1) != NUL && *(p + strlen(p) - 1) == '`';
}
/// Expand an item in `backticks` by executing it as a command.
@@ -1391,7 +1391,7 @@ static int expand_backtick(garray_T *gap, char *pat, int flags)
if (p > cmd) {
char i = *p;
*p = NUL;
- addfile(gap, (char_u *)cmd, flags);
+ addfile(gap, cmd, flags);
*p = i;
cnt++;
}
@@ -1446,7 +1446,7 @@ void slash_adjust(char_u *p)
/// EW_ALLLINKS add symlink also when the referred file does not exist
///
/// @param f filename
-void addfile(garray_T *gap, char_u *f, int flags)
+void addfile(garray_T *gap, char *f, int flags)
{
bool isdir;
FileInfo file_info;
@@ -1454,8 +1454,8 @@ void addfile(garray_T *gap, char_u *f, int flags)
// if the file/dir/link doesn't exist, may not add it
if (!(flags & EW_NOTFOUND)
&& ((flags & EW_ALLLINKS)
- ? !os_fileinfo_link((char *)f, &file_info)
- : !os_path_exists((char *)f))) {
+ ? !os_fileinfo_link(f, &file_info)
+ : !os_path_exists(f))) {
return;
}
@@ -1466,7 +1466,7 @@ void addfile(garray_T *gap, char_u *f, int flags)
}
#endif
- isdir = os_isdir((char *)f);
+ isdir = os_isdir(f);
if ((isdir && !(flags & EW_DIR)) || (!isdir && !(flags & EW_FILE))) {
return;
}
@@ -1474,11 +1474,11 @@ void addfile(garray_T *gap, char_u *f, int flags)
// If the file isn't executable, may not add it. Do accept directories.
// When invoked from expand_shellcmd() do not use $PATH.
if (!isdir && (flags & EW_EXEC)
- && !os_can_exe((char *)f, NULL, !(flags & EW_SHELLCMD))) {
+ && !os_can_exe(f, NULL, !(flags & EW_SHELLCMD))) {
return;
}
- char_u *p = xmalloc(STRLEN(f) + 1 + isdir);
+ char_u *p = xmalloc(strlen(f) + 1 + isdir);
STRCPY(p, f);
#ifdef BACKSLASH_IN_FILENAME
diff --git a/src/nvim/po/zh_CN.UTF-8.po b/src/nvim/po/zh_CN.UTF-8.po
index afa2f29029..87b67c5d97 100644
--- a/src/nvim/po/zh_CN.UTF-8.po
+++ b/src/nvim/po/zh_CN.UTF-8.po
@@ -8,6 +8,9 @@
# TRANSLATORS
# Edyfox <edyfox@gmail.com>
# Yuheng Xie <elephant@linux.net.cn>
+# lilydjwg <lilydjwg@gmail.com>
+# Ada (Haowen) Yu <me@yuhaowen.com>
+# Sizhe Zhao <prc.zhao@outlook.com>
#
# Original translations.
#
@@ -15,1181 +18,1939 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim(Simplified Chinese)\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2006-04-21 14:00+0800\n"
-"Last-Translator: Yuheng Xie <elephant@linux.net.cn>\n"
+"POT-Creation-Date: 2022-11-17 08:00+0800\n"
+"PO-Revision-Date: 2022-11-17 22:29+0800\n"
+"Last-Translator: Sizhe Zhao <prc.zhao@outlook.com>\n"
"Language-Team: Simplified Chinese <i18n-translation@lists.linux.net.cn>\n"
-"Language: \n"
+"Language: zh_CN\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8-bit\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: ../api/private/helpers.c:201
+#: ../arglist.c:67
+msgid "E1156: Cannot change the argument list recursively"
+msgstr "E1156: 不能递归修改参数列表"
+
+#: ../arglist.c:628
+msgid "E163: There is only one file to edit"
+msgstr "E163: 只有一个文件可编辑"
+
+#: ../arglist.c:630
+msgid "E164: Cannot go before first file"
+msgstr "E164: 无法切换,已是第一个文件"
+
+#: ../arglist.c:632
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: 无法切换,已是最后一个文件"
+
+#: ../arglist.c:782
#, fuzzy
-msgid "Unable to get option value"
-msgstr "选项参数后的内容无效"
+msgid "E610: No argument to delete"
+msgstr "E144: :z 不接受非数字的参数"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "内部错误:未知的选项类型"
+#: ../arglist.c:980
+msgid "E249: window layout changed unexpectedly"
+msgstr "E249: 窗口布局意外地改变了"
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Location 列表]"
+#: ../autocmd.c:160
+msgid "--Deleted--"
+msgstr "--已删除--"
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Quickfix 列表]"
+#: ../autocmd.c:451
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "自动删除自动命令: %s <buffer=%d>"
+
+#. the group doesn't exist
+#: ../autocmd.c:501
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: 无此组: \"%s\""
+
+#: ../autocmd.c:505
+#, fuzzy
+msgid "E936: Cannot delete the current group"
+msgstr "E351: 不能在当前的 'foldmethod' 下删除折叠"
+
+#: ../autocmd.c:513
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: 删除依旧在使用中的自动组"
+
+#. Highlight title
+#: ../autocmd.c:896
+msgid ""
+"\n"
+"--- Autocommands ---"
+msgstr ""
+"\n"
+"--- 自动命令 ---"
+
+#: ../autocmd.c:1106
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: 无效的缓冲区号 "
+
+#: ../autocmd.c:1254
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: 不能对所有事件执行自动命令"
+
+#: ../autocmd.c:1276
+#, c-format
+msgid "No matching autocommands: %s"
+msgstr "没有匹配的自动命令:%s"
+
+#: ../autocmd.c:1693
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: 自动命令嵌套层数过深"
+
+#: ../autocmd.c:2040
+#, c-format
+msgid "%s Autocommands for \"%s\""
+msgstr "%s 自动命令 \"%s\""
+
+#: ../autocmd.c:2049
+#, c-format
+msgid "Executing %s"
+msgstr "执行 %s"
+
+#: ../autocmd.c:2178
+#, c-format
+msgid "autocommand %s"
+msgstr "自动命令 %s"
-#: ../buffer.c:94
+#: ../autocmd.c:2617
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: * 后面有无效字符: %s"
+
+#: ../autocmd.c:2625
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: 无此事件: %s"
+
+#: ../autocmd.c:2627
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: 无此组或事件: %s"
+
+#: ../buffer.c:109
msgid "E855: Autocommands caused command to abort"
msgstr "E855: 自动命令导致命令被停止"
-#: ../buffer.c:135
+#: ../buffer.c:111
+#, c-format
+msgid "E937: Attempt to delete a buffer that is in use: %s"
+msgstr "E937: 试图删除使用中的缓冲区:%s"
+
+#: ../buffer.c:219
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: 无法分配任何缓冲区,退出程序..."
-#: ../buffer.c:138
+#: ../buffer.c:227
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: 无法分配缓冲区,使用另一个缓冲区..."
-#: ../buffer.c:763
+#: ../buffer.c:1070
msgid "E515: No buffers were unloaded"
msgstr "E515: 没有释放任何缓冲区"
-#: ../buffer.c:765
+#: ../buffer.c:1072
msgid "E516: No buffers were deleted"
msgstr "E516: 没有删除任何缓冲区"
-#: ../buffer.c:767
+#: ../buffer.c:1074
msgid "E517: No buffers were wiped out"
msgstr "E517: 没有清除任何缓冲区"
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "释放了 1 个缓冲区"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "释放了 %d 个缓冲区"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "删除了 1 个缓冲区"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "删除了 %d 个缓冲区"
+#: ../buffer.c:1079
+#, fuzzy, c-format
+msgid "%d buffer unloaded"
+msgid_plural "%d buffers unloaded"
+msgstr[0] "释放了 %d 个缓冲区"
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "清除了 1 个缓冲区"
+#: ../buffer.c:1082
+#, fuzzy, c-format
+msgid "%d buffer deleted"
+msgid_plural "%d buffers deleted"
+msgstr[0] "删除了 %d 个缓冲区"
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "清除了 %d 个缓冲区"
+#: ../buffer.c:1085
+#, fuzzy, c-format
+msgid "%d buffer wiped out"
+msgid_plural "%d buffers wiped out"
+msgstr[0] "清除了 %d 个缓冲区"
-#: ../buffer.c:806
+#: ../buffer.c:1102
msgid "E90: Cannot unload last buffer"
msgstr "E90: 无法释放最后一个缓冲区"
-#: ../buffer.c:874
+#: ../buffer.c:1191
msgid "E84: No modified buffer found"
msgstr "E84: 没有修改过的缓冲区"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
+#: ../buffer.c:1224
msgid "E85: There is no listed buffer"
msgstr "E85: 没有可列出的缓冲区"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: 缓冲区 %<PRId64> 不存在"
-
-#: ../buffer.c:915
+#: ../buffer.c:1237
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: 无法切换,已是最后一个缓冲区"
-#: ../buffer.c:917
+#: ../buffer.c:1239
msgid "E88: Cannot go before first buffer"
msgstr "E88: 无法切换,已是第一个缓冲区"
-#: ../buffer.c:945
+#: ../buffer.c:1277
#, c-format
msgid ""
"E89: No write since last change for buffer %<PRId64> (add ! to override)"
msgstr "E89: 缓冲区 %<PRId64> 已修改但尚未保存 (请加 ! 强制执行)"
+#: ../buffer.c:1290
+#, c-format
+msgid "E89: %s will be killed (add ! to override)"
+msgstr "E89: \"%s\" 会被结束 (请加 ! 强制执行)"
+
+#: ../buffer.c:1698
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: 任务仍在运行(添加 ! 来结束此任务)"
+
+#: ../buffer.c:1700
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: 已修改但尚未保存 (可用 ! 强制执行)"
+
+#: ../buffer.c:1709
+msgid "E948: Job still running"
+msgstr "E948: 任务仍在运行"
+
+#: ../buffer.c:1711
+msgid "E37: No write since last change"
+msgstr "E37: 已修改但尚未保存"
+
#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
+#: ../buffer.c:1858
msgid "W14: Warning: List of file names overflow"
msgstr "W14: 警告: 文件名过多"
-#: ../buffer.c:1555 ../quickfix.c:3361
+#: ../buffer.c:2032 ../quickfix.c:6290 ../window.c:195
#, c-format
msgid "E92: Buffer %<PRId64> not found"
msgstr "E92: 找不到缓冲区 %<PRId64>"
-#: ../buffer.c:1798
+#: ../buffer.c:2289
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: 找到不止一个 %s"
-#: ../buffer.c:1800
+#: ../buffer.c:2291
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: 没有匹配的缓冲区 %s"
-#: ../buffer.c:2161
+#: ../buffer.c:2786
#, c-format
msgid "line %<PRId64>"
msgstr "第 %<PRId64> 行"
-#: ../buffer.c:2233
+#: ../buffer.c:2856
msgid "E95: Buffer with this name already exists"
msgstr "E95: 已有缓冲区使用该名称"
-#: ../buffer.c:2498
+#: ../buffer.c:3109
msgid " [Modified]"
msgstr " [已修改]"
-#: ../buffer.c:2501
+#: ../buffer.c:3111
msgid "[Not edited]"
msgstr "[未编辑]"
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[新文件]"
-
-#: ../buffer.c:2505
+#: ../buffer.c:3115
msgid "[Read errors]"
msgstr "[读错误]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
+#: ../buffer.c:3117 ../fileio.c:1777 ../statusline.c:122 ../statusline.c:1545
msgid "[RO]"
msgstr "[只读]"
-#: ../buffer.c:2507 ../fileio.c:1807
+#: ../buffer.c:3117 ../fileio.c:1777
msgid "[readonly]"
msgstr "[只读]"
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "1 行 --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> 行 --%d%%--"
+#: ../buffer.c:3136
+#, fuzzy, c-format
+msgid "%<PRId64> line --%d%%--"
+msgid_plural "%<PRId64> lines --%d%%--"
+msgstr[0] "%<PRId64> 行 --%d%%--"
-#: ../buffer.c:2530
+#: ../buffer.c:3142
#, c-format
msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
msgstr "行 %<PRId64> / %<PRId64> --%d%%-- 列 "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
+#: ../buffer.c:3234 ../buffer.c:4143 ../memline.c:1456
msgid "[No Name]"
msgstr "[未命名]"
-#. must be a help buffer
-#: ../buffer.c:2667
+#. Must be a help buffer.
+#: ../buffer.c:3279
msgid "help"
msgstr "帮助"
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[帮助]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[预览]"
-
-#: ../buffer.c:3528
+#: ../buffer.c:3421
msgid "All"
msgstr "全部"
-#: ../buffer.c:3528
+#: ../buffer.c:3421
msgid "Bot"
msgstr "底端"
-#: ../buffer.c:3531
+#: ../buffer.c:3423
msgid "Top"
msgstr "顶端"
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# 缓冲区列表:\n"
+#: ../buffer.c:3912
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 无法写入,已设定选项 'buftype'"
-#: ../buffer.c:4289
+#: ../buffer.c:3954
+msgid "[Prompt]"
+msgstr "[提示符]"
+
+#: ../buffer.c:3956
msgid "[Scratch]"
-msgstr ""
+msgstr "[涂鸦]"
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
+#: ../buffer.h:72
+msgid "[Location List]"
+msgstr "[Location 列表]"
+
+#: ../buffer.h:73
+msgid "[Quickfix List]"
+msgstr "[Quickfix 列表]"
+
+#: ../change.c:68
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: 警告: 正在修改只读文件"
+
+#: ../channel.c:499
+msgid "can only be opened in headless mode"
msgstr ""
-"\n"
-"--- Signs ---"
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "%s 的 Signs:"
+#: ../channel.c:504
+msgid "channel was already open"
+msgstr "channel 已打开"
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " 行=%<PRId64> id=%d 名称=%s"
+#: ../channel.c:550 ../channel.c:564 ../channel.c:574
+msgid "Can't send data to closed stream"
+msgstr "无法将数据发送到关闭的 stream"
+
+#: ../channel.c:560 ../channel.c:579
+msgid "Can't send raw data to rpc channel"
+msgstr "无法将 raw data 发送到 rpc channel"
+
+#: ../cmdexpand.c:925
+msgid "tagname"
+msgstr "tag 名"
-#: ../cursor_shape.c:68
+#: ../cmdexpand.c:928
+msgid " kind file\n"
+msgstr " 类型 文件\n"
+
+#: ../cmdhist.c:616
+msgid "'history' option is zero"
+msgstr "选项 'history' 为零"
+
+#: ../context.c:335
+msgid "E474: Failed to convert list to msgpack string buffer"
+msgstr ""
+
+#: ../cursor_shape.c:136
msgid "E545: Missing colon"
msgstr "E545: 缺少冒号"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
+#: ../cursor_shape.c:139 ../cursor_shape.c:164
msgid "E546: Illegal mode"
msgstr "E546: 无效的模式"
-#: ../cursor_shape.c:134
+#: ../cursor_shape.c:197 ../optionstr.c:510
msgid "E548: digit expected"
msgstr "E548: 此处需要数字"
-#: ../cursor_shape.c:138
+#: ../cursor_shape.c:202
msgid "E549: Illegal percentage"
msgstr "E549: 无效的百分比"
-#: ../diff.c:146
+#: ../debugger.c:106
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "进入调试模式。输入 \"cont\" 继续运行。"
+
+# do not translate
+#: ../debugger.c:109
+#, c-format
+msgid "Oldval = \"%s\""
+msgstr ""
+
+#: ../debugger.c:114
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: 不能比较(diff) %<PRId64> 个以上的缓冲区"
+msgid "Newval = \"%s\""
+msgstr "新值 = \"%s\""
-#: ../diff.c:753
+#: ../debugger.c:124 ../debugger.c:388
+#, c-format
+msgid "line %<PRId64>: %s"
+msgstr "第 %<PRId64> 行: %s"
+
+#: ../debugger.c:126 ../debugger.c:390
+#, c-format
+msgid "cmd: %s"
+msgstr "命令: %s"
+
+#: ../debugger.c:347
#, fuzzy
+msgid "frame is zero"
+msgstr "E726: 步长为零"
+
+#: ../debugger.c:354
+#, c-format
+msgid "frame at highest level: %d"
+msgstr "帧级别最高:%d"
+
+#: ../debugger.c:434
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %<PRId64>"
+msgstr "断点 \"%s%s\" 第 %<PRId64> 行"
+
+#: ../debugger.c:684
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: 找不到断点: %s"
+
+#: ../debugger.c:717
+msgid "No breakpoints defined"
+msgstr "没有定义断点"
+
+#: ../debugger.c:725
+#, c-format
+msgid "%3d %s %s line %<PRId64>"
+msgstr "%3d %s %s 第 %<PRId64> 行"
+
+#: ../debugger.c:731
+#, c-format
+msgid "%3d expr %s"
+msgstr "%3d 表达式 %s"
+
+#: ../diff.c:206
+#, c-format
+msgid "E96: Cannot diff more than %<PRId64> buffers"
+msgstr "E96: 不能比较 %<PRId64> 个以上的缓冲区"
+
+#: ../diff.c:767
+#, c-format
+msgid "Not enough memory to use internal diff for buffer \"%s\""
+msgstr "为缓冲区 \"%s\" 使用内部比对(diff)时无足够的内存"
+
+#: ../diff.c:1082
msgid "E810: Cannot read or write temp files"
-msgstr "E557: 无法打开 termcap 文件"
+msgstr "E810: 无法读写临时文件"
-#: ../diff.c:755
+#: ../diff.c:1084
msgid "E97: Cannot create diffs"
msgstr "E97: 无法创建 diff"
-#: ../diff.c:966
-#, fuzzy
+#: ../diff.c:1125
+msgid "E960: Problem creating the internal diff"
+msgstr "E960: 创建内部 diff 时遇到问题"
+
+#: ../diff.c:1284
msgid "E816: Cannot read patch output"
-msgstr "E98: 无法读取 diff 的输出"
+msgstr "E816: 无法读取 patch 的输出"
-#: ../diff.c:1220
+#: ../diff.c:1740
msgid "E98: Cannot read diff output"
msgstr "E98: 无法读取 diff 的输出"
-#: ../diff.c:2081
+#: ../diff.c:2847
msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: 当前缓冲区不在 diff 模式"
+msgstr "E99: 当前缓冲区不在差异模式"
-#: ../diff.c:2100
-#, fuzzy
+#: ../diff.c:2867
msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E100: 没有其它处于 diff 模式的缓冲区"
+msgstr "E793: 没有其它处于差异模式的缓冲区可修改"
-#: ../diff.c:2102
+#: ../diff.c:2869
msgid "E100: No other buffer in diff mode"
-msgstr "E100: 没有其它处于 diff 模式的缓冲区"
+msgstr "E100: 没有其它处于差异模式的缓冲区"
-#: ../diff.c:2112
+#: ../diff.c:2880
msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: 有两个以上的缓冲区处于 diff 模式,不能决定用哪一个"
+msgstr "E101: 有两个以上的缓冲区处于差异模式,不能决定用哪一个"
-#: ../diff.c:2141
+#: ../diff.c:2909
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: 找不到缓冲区 \"%s\""
-#: ../diff.c:2152
+#: ../diff.c:2920
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: 缓冲区 \"%s\" 不在 diff 模式"
+msgstr "E103: 缓冲区 \"%s\" 不处于差异模式"
-#: ../diff.c:2193
+#: ../diff.c:2960
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: 意外地改变了缓冲区"
-#: ../digraph.c:1598
+#: ../digraph.c:50
+#, c-format
+msgid "E1214: Digraph must be just two characters: %s"
+msgstr "E1214: 二合字符必须只有两个字符:%s"
+
+#: ../digraph.c:52
+#, c-format
+msgid "E1215: Digraph must be one character: %s"
+msgstr "E1215: 二合字符必须是一个字符:%s"
+
+#: ../digraph.c:54
+msgid ""
+"E1216: digraph_setlist() argument must be a list of lists with two items"
+msgstr "E1216: digraph_setlist() 参数必须是包含两项的列表的列表"
+
+#: ../digraph.c:1664
msgid "E104: Escape not allowed in digraph"
-msgstr "E104: 复合字符(digraph)中不能使用 Escape"
+msgstr "E104: 二合字符中不能使用 Escape"
+
+#: ../digraph.c:1737
+msgid "Custom"
+msgstr "自定义"
+
+#: ../digraph.c:1794
+msgid "Latin supplement"
+msgstr "拉丁文补充"
+
+#: ../digraph.c:1795
+msgid "Greek and Coptic"
+msgstr "希腊和科普特文"
+
+#: ../digraph.c:1796
+msgid "Cyrillic"
+msgstr "西里尔文"
+
+#: ../digraph.c:1797
+msgid "Hebrew"
+msgstr "希伯来文"
+
+#: ../digraph.c:1798
+msgid "Arabic"
+msgstr "阿拉伯文"
+
+#: ../digraph.c:1799
+msgid "Latin extended"
+msgstr "拉丁文扩展"
+
+#: ../digraph.c:1800
+msgid "Greek extended"
+msgstr "希腊文扩展"
-#: ../digraph.c:1760
+#: ../digraph.c:1801
+msgid "Punctuation"
+msgstr "标点符号"
+
+#: ../digraph.c:1802
+msgid "Super- and subscripts"
+msgstr "上下标"
+
+#: ../digraph.c:1803
+msgid "Currency"
+msgstr "货币符号"
+
+#: ../digraph.c:1804 ../digraph.c:1809 ../digraph.c:1819
+msgid "Other"
+msgstr "其他"
+
+#: ../digraph.c:1805
+msgid "Roman numbers"
+msgstr "罗马数字"
+
+#: ../digraph.c:1806
+msgid "Arrows"
+msgstr "箭头"
+
+#: ../digraph.c:1807
+msgid "Mathematical operators"
+msgstr "数学运算符"
+
+#: ../digraph.c:1808
+msgid "Technical"
+msgstr "技术符号"
+
+#: ../digraph.c:1810
+msgid "Box drawing"
+msgstr "方框绘图"
+
+#: ../digraph.c:1811
+msgid "Block elements"
+msgstr "块状元素"
+
+#: ../digraph.c:1812
+msgid "Geometric shapes"
+msgstr "几何形状"
+
+#: ../digraph.c:1813
+msgid "Symbols"
+msgstr "符号"
+
+#: ../digraph.c:1814
+msgid "Dingbats"
+msgstr "杂锦字符"
+
+#: ../digraph.c:1815
+msgid "CJK symbols and punctuation"
+msgstr "中日韩标点符号"
+
+#: ../digraph.c:1816
+msgid "Hiragana"
+msgstr "日文平假名"
+
+#: ../digraph.c:1817
+msgid "Katakana"
+msgstr "日文片假名"
+
+#: ../digraph.c:1818
+msgid "Bopomofo"
+msgstr "注音符号"
+
+#: ../digraph.c:2062
msgid "E544: Keymap file not found"
msgstr "E544: 找不到 Keymap 文件"
-#: ../digraph.c:1785
+#: ../digraph.c:2083
msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: 不是在脚本文件中使用 :loadkeymap "
+msgstr "E105: 不是在脚本文件中使用 :loadkeymap"
-#: ../digraph.c:1821
+#: ../digraph.c:2118
msgid "E791: Empty keymap entry"
msgstr "E791: 空的键位映射项"
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " 关键字补全 (^N^P)"
+#. TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
+#. maximum nesting of lists and dicts
+#: ../eval.c:92
+msgid "E111: Missing ']'"
+msgstr "E111: 缺少 ']'"
-#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
-msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-msgstr " ^X 模式 (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+#: ../eval.c:93
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: 不能对 Dictionary 使用 [:]"
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " 整行补全 (^L^N^P)"
+#: ../eval.c:95
+msgid "E274: No white space allowed before parenthesis"
+msgstr "E274: 小括号前不允许空白字符"
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " 文件名补全 (^F^N^P)"
+#: ../eval.c:96
+#, c-format
+msgid "E80: Error while writing: %s"
+msgstr "E80: 写入时出错:%s"
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Tag 补全 (^]^N^P)"
+#: ../eval.c:97
+msgid "E1098: String, List or Blob required"
+msgstr "E1098: 需要字符串、列表或 Blob"
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " 头文件模式补全 (^N^P)"
+#: ../eval.c:98
+#, c-format
+msgid "E1169: Expression too recursive: %s"
+msgstr "E1169: 表达式递归层数过多:%s"
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " 定义补全 (^D^N^P)"
+#: ../eval.c:100
+#, c-format
+msgid "E1203: Dot can only be used on a dictionary: %s"
+msgstr "E1203: 点只能用于字典:%s"
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Dictionary 补全 (^K^N^P)"
+#: ../eval.c:1095
+msgid ""
+"E5700: Expression from 'spellsuggest' must yield lists with exactly two "
+"values"
+msgstr ""
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Thesaurus 补全 (^T^N^P)"
+#: ../eval.c:1327 ../eval/vars.c:1112
+#, c-format
+msgid "E121: Undefined variable: %.*s"
+msgstr "E121: 变量未定义: %.*s"
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " 命令行补全 (^V^N^P)"
+#: ../eval.c:1358
+msgid "E689: Can only index a List, Dictionary or Blob"
+msgstr "E689: 只能索引列表、字典或 Blob"
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " 用户自定义补全 (^U^N^P)"
+#: ../eval.c:1364
+msgid "E708: [:] must come last"
+msgstr "E708: [:] 必须在最后"
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " 全能补全 (^O^N^P)"
+#: ../eval.c:1376
+#, fuzzy
+msgid "E713: Cannot use empty key after ."
+msgstr "E713: Dictionary 的键不能为空"
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " 拼写建议 (s^N^P)"
+#: ../eval.c:1412
+#, fuzzy
+msgid "E709: [:] requires a List or Blob value"
+msgstr "E709: [:] 需要一个 List 值"
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " 关键字局部补全 (^N^P)"
+#: ../eval.c:1665
+msgid "E972: Blob value does not have the right number of bytes"
+msgstr "E972: Blob 值的字节数不对"
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "已到段落结尾"
+#: ../eval.c:1728
+msgid "E996: Cannot lock a range"
+msgstr "E996: 不能锁定范围"
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: 补全函数更改了窗口"
+#: ../eval.c:1771
+msgid "E710: List value has more items than target"
+msgstr "E710: List 值的项比目标多"
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: 补全函数删除了文本"
+#: ../eval.c:1776
+msgid "E711: List value has not enough items"
+msgstr "E711: List 值没有足够多的项"
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "选项 'dictionary' 为空"
+#: ../eval.c:1784
+msgid "E996: Cannot lock a list or dict"
+msgstr "E996: 不能锁定列表或字典"
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "选项 'thesaurus' 为空"
+#: ../eval.c:1866
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: :for 后缺少 \"in\""
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "正在扫描 dictionary: %s"
+#: ../eval.c:2389
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: '?' 后缺少 ':'"
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (插入) Scroll (^E/^Y)"
+#: ../eval.c:2893
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: 不能对浮点数使用 '%'"
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (替换) Scroll (^E/^Y)"
+#: ../eval.c:3037
+msgid "E973: Blob literal should have an even number of hex characters"
+msgstr "E973: Blob 字面量应该有偶数个十六进制字符"
+
+#: ../eval.c:3137
+msgid "E110: Missing ')'"
+msgstr "E110: 缺少 ')'"
+
+#: ../eval.c:3372
+#, fuzzy
+msgid "E260: Missing name after ->"
+msgstr "E526: <%s> 后面缺少数字"
+
+#: ../eval.c:3431
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: 不能索引 Funcref"
-#: ../edit.c:3587
+#: ../eval.c:3442
+msgid "E909: Cannot index a special variable"
+msgstr "E909: 不能索引特殊变量"
+
+#: ../eval.c:3730
#, c-format
-msgid "Scanning: %s"
-msgstr "正在扫描: %s"
+msgid "E112: Option name missing: %s"
+msgstr "E112: 缺少选项名称:%s"
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "扫描标签."
+#: ../eval.c:3751
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: 未知的选项:%s"
-#: ../edit.c:4519
-msgid " Adding"
-msgstr " 增加"
+#: ../eval.c:3798
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: 缺少引号:%s"
-#. showmode might reset the internal line pointers, so it must
-#. * be called before line = ml_get(), or when this address is no
-#. * longer needed. -- Acevedo.
-#.
-#: ../edit.c:4562
-msgid "-- Searching..."
-msgstr "-- 查找中..."
+#: ../eval.c:3936
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: 缺少引号:%s"
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "回到起点"
+#: ../eval.c:4031
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: 列表中缺少逗号:%s"
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "另一行的词"
+#: ../eval.c:4038
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: 列表缺少结束符 ']':%s"
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "唯一匹配"
+#: ../eval.c:4338
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr "没有足够的内存来设置引用,垃圾回收已中止!"
-#: ../edit.c:4680
+#: ../eval.c:4687
#, c-format
-msgid "match %d of %d"
-msgstr "匹配 %d / %d"
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: 字典中缺少冒号:%s"
-#: ../edit.c:4684
+#: ../eval.c:4710
#, c-format
-msgid "match %d"
-msgstr "匹配 %d"
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Dictionary 中出现重复的键: \"%s\""
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: :let 中出现异常字符"
+#: ../eval.c:4728
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: 字典中缺少逗号:%s"
-#: ../eval.c:138
+#: ../eval.c:4735
#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: List 索引超出范围: %<PRId64>"
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: 字典缺少结束符 '}':%s"
-#: ../eval.c:139
+#: ../eval.c:4854
+msgid "map() argument"
+msgstr "map() 参数"
+
+#: ../eval.c:4855
+msgid "filter() argument"
+msgstr "filter() 参数"
+
+#: ../eval.c:5076
#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: 未定义的变量: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: 未知的函数:%s"
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: 缺少 ']'"
+#: ../eval.c:5112
+msgid "E922: expected a dict"
+msgstr "E922: 需要字典"
+
+#: ../eval.c:5122
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: function() 的第二个参数必须是列表或字典"
+
+#: ../eval.c:5397
+msgid "E5050: {opts} must be the only argument"
+msgstr "E5050: {opts} 必须是唯一的参数"
-#: ../eval.c:141
+#: ../eval.c:5794 ../os/shell.c:718
#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s 的参数必须是 List"
+msgid "Executing command: \"%s\""
+msgstr "执行命令:\"%s\""
+
+#: ../eval.c:5902
+msgid "E921: Invalid callback argument"
+msgstr "E921: 回调参数无效"
+
+#: ../eval.c:7603
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: 变量嵌套过深,无法复制"
+
+#: ../eval.c:8078
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t最近修改于 "
+
+#: ../eval.c:8690
+msgid "E5009: $VIMRUNTIME is empty or unset"
+msgstr "E5009: $VIMRUNTIME 为空或未设置"
-#: ../eval.c:143
+#: ../eval.c:8694
#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s 的参数必须是 List 或者 Dictionary"
+msgid "E5009: Invalid $VIMRUNTIME: %s"
+msgstr "E5009: $VIMRUNTIME 无效:%s"
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Dictionary 的键不能为空"
+#: ../eval.c:8696
+msgid "E5009: Invalid 'runtimepath'"
+msgstr "E5009: 'runtimepath' 无效"
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: 需要 List"
+#: ../eval.c:8783
+msgid "E977: Can only compare Blob with Blob"
+msgstr "E977: Blob 只能与 Blob 比较"
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: 需要 Dictionary"
+#: ../eval.c:8806
+msgid "E691: Can only compare List with List"
+msgstr "E691: 列表只能与列表比较"
+
+#: ../eval.c:8808
+msgid "E692: Invalid operation for List"
+msgstr "E692: 操作对列表无效"
+
+#: ../eval.c:8829
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: 字典只能与字典比较"
+
+#: ../eval.c:8831
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: 操作对字典无效"
-#: ../eval.c:147
+#: ../eval.c:8845
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: 操作对 Funcrefs 无效"
+
+#: ../eval/decode.c:132
#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: 函数的参数过多: %s"
+msgid "E474: Expected comma before list item: %s"
+msgstr "E474: 列表项前应有逗号:%s"
-#: ../eval.c:148
+#: ../eval/decode.c:140
#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Dictionary 中不存在键: %s"
+msgid "E474: Expected colon before dictionary value: %s"
+msgstr "E474: 字典值前应有冒号:%s"
-#: ../eval.c:150
+#: ../eval/decode.c:167
#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: 函数 %s 已存在,请加 ! 强制替换"
+msgid "E474: Expected string key: %s"
+msgstr "E474: 需要字符串键:%s"
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Dictionary 项已存在"
+#: ../eval/decode.c:173
+#, c-format
+msgid "E474: Expected comma before dictionary key: %s"
+msgstr "E474: 字典键前应有逗号:%s"
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: 需要 Funcref"
+#: ../eval/decode.c:340
+#, c-format
+msgid "E474: Unfinished escape sequence: %.*s"
+msgstr "E474: 转义序列不完整:%.*s"
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: 不能对 Dictionary 使用 [:]"
+#: ../eval/decode.c:347
+#, c-format
+msgid "E474: Unfinished unicode escape sequence: %.*s"
+msgstr "E474: Unicode 转义序列不完整:%.*s"
-#: ../eval.c:154
+#: ../eval/decode.c:354
#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: %s= 的变量类型不正确"
+msgid "E474: Expected four hex digits after \\u: %.*s"
+msgstr "E474: \\u 之后应有四位十六进制数字:%.*s"
-#: ../eval.c:155
+#: ../eval/decode.c:375
#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: 未知的函数: %s"
+msgid "E474: Unknown escape sequence: %.*s"
+msgstr "E474: 未知的转义序列:%.*s"
-#: ../eval.c:156
+#: ../eval/decode.c:382
#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: 无效的变量名: %s"
+msgid "E474: ASCII control characters cannot be present inside string: %.*s"
+msgstr "E474: 字符串中不能出现 ASCII 控制字符:%.*s"
-#: ../eval.c:157
-#, fuzzy
-msgid "E806: using Float as a String"
-msgstr "E730: 将 List 作 String 使用"
+#: ../eval/decode.c:395
+#, c-format
+msgid "E474: Only UTF-8 strings allowed: %.*s"
+msgstr "E474: 只允许 UTF-8 字符串:%.*s"
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: 目标比 List 项数少"
+#: ../eval/decode.c:398
+#, c-format
+msgid ""
+"E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: "
+"%.*s"
+msgstr ""
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: 目标比 List 项数多"
+#: ../eval/decode.c:409
+#, c-format
+msgid "E474: Expected string end: %.*s"
+msgstr ""
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "变量列表中出现两个 ;"
+#: ../eval/decode.c:555
+#, c-format
+msgid "E474: Leading zeroes are not allowed: %.*s"
+msgstr "E474: 不允许前导零:%.*s"
-#: ../eval.c:2078
+#: ../eval/decode.c:584
#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: 无法列出 %s 的变量"
+msgid "E474: Missing number after minus sign: %.*s"
+msgstr "E474: 负号后缺少数字:%.*s"
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: 只能索引 List 或 Dictionary"
+#: ../eval/decode.c:587
+#, c-format
+msgid "E474: Missing number after decimal dot: %.*s"
+msgstr "E474: 小数点后缺少数字:%.*s"
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] 必须在最后"
+#: ../eval/decode.c:590
+#, c-format
+msgid "E474: Missing exponent: %.*s"
+msgstr "E474: 缺少指数:%.*s"
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] 需要一个 List 值"
+#: ../eval/decode.c:602
+#, c-format
+msgid ""
+"E685: internal error: while converting number \"%.*s\" to float string2float "
+"consumed %zu bytes in place of %zu"
+msgstr ""
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: List 值的项比目标多"
+#: ../eval/decode.c:613
+#, c-format
+msgid ""
+"E685: internal error: while converting number \"%.*s\" to integer vim_str2nr "
+"consumed %i bytes in place of %zu"
+msgstr ""
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: List 值没有足够多的项"
+#: ../eval/decode.c:665
+msgid "E474: Attempt to decode a blank string"
+msgstr "E474: 试图解码空字符串"
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: :for 后缺少 \"in\""
+#: ../eval/decode.c:682
+#, c-format
+msgid "E474: No container to close: %.*s"
+msgstr "E474: 没有容器可以关闭:%.*s"
-#: ../eval.c:3063
+#: ../eval/decode.c:687
#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: 缺少括号: %s"
+msgid "E474: Closing list with curly bracket: %.*s"
+msgstr "E474: 用花括号结束列表:%.*s"
-#: ../eval.c:3263
+#: ../eval/decode.c:690
#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: 无此变量: \"%s\""
+msgid "E474: Closing dictionary with square bracket: %.*s"
+msgstr "E474: 用方括号结束字典:%.*s"
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: (un)lock 的变量嵌套过深"
+#: ../eval/decode.c:694
+#, c-format
+msgid "E474: Trailing comma: %.*s"
+msgstr "E474: 尾随逗号:%.*s"
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: '?' 后缺少 ':'"
+#: ../eval/decode.c:697
+#, c-format
+msgid "E474: Expected value after colon: %.*s"
+msgstr "E474: 冒号后应有值:%.*s"
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: 只能比较 List 和 List"
+#: ../eval/decode.c:701
+#, fuzzy, c-format
+msgid "E474: Expected value: %.*s"
+msgstr "E415: 不该有的等号: %s"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: 对 List 无效的操作"
+#: ../eval/decode.c:720
+#, fuzzy, c-format
+msgid "E474: Comma not inside container: %.*s"
+msgstr "E242: %s 为不能识别的颜色名称"
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: 只能比较 Dictionary 和 Dictionary"
+#: ../eval/decode.c:725
+#, fuzzy, c-format
+msgid "E474: Duplicate comma: %.*s"
+msgstr "E721: Dictionary 中出现重复的键: \"%s\""
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: 对 Dictionary 无效的操作"
+#: ../eval/decode.c:728
+#, c-format
+msgid "E474: Comma after colon: %.*s"
+msgstr "E474: 冒号后有逗号:%.*s"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: 只能比较 Funcref 和 Funcref"
+#: ../eval/decode.c:732
+#, c-format
+msgid "E474: Using comma in place of colon: %.*s"
+msgstr "E474: 应使用冒号,但用了逗号:%.*s"
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: 对 Funcrefs 无效的操作"
+#: ../eval/decode.c:740
+#, c-format
+msgid "E474: Leading comma: %.*s"
+msgstr "E474: 前导逗号:%.*s"
-#: ../eval.c:4277
-#, fuzzy
-msgid "E804: Cannot use '%' with Float"
-msgstr "E719: 不能对 Dictionary 使用 [:]"
+#: ../eval/decode.c:748
+#, fuzzy, c-format
+msgid "E474: Colon not inside container: %.*s"
+msgstr "E242: %s 为不能识别的颜色名称"
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: 缺少 ')'"
+#: ../eval/decode.c:753
+#, c-format
+msgid "E474: Using colon not in dictionary: %.*s"
+msgstr "E474: 在字典之外使用冒号:%.*s"
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: 不能索引一个 Funcref"
+#: ../eval/decode.c:756
+#, fuzzy, c-format
+msgid "E474: Unexpected colon: %.*s"
+msgstr "E415: 不该有的等号: %s"
-#: ../eval.c:4839
+#: ../eval/decode.c:759
#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: 缺少选项名称: %s"
+msgid "E474: Colon after comma: %.*s"
+msgstr "E474: 逗号后有冒号:%.*s"
-#: ../eval.c:4855
+#: ../eval/decode.c:762
#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: 未知的选项: %s"
+msgid "E474: Duplicate colon: %.*s"
+msgstr "E474: 重复的冒号:%.*s"
-#: ../eval.c:4904
+#: ../eval/decode.c:775
+#, fuzzy, c-format
+msgid "E474: Expected null: %.*s"
+msgstr "E415: 不该有的等号: %s"
+
+#: ../eval/decode.c:787
+#, fuzzy, c-format
+msgid "E474: Expected true: %.*s"
+msgstr "E415: 不该有的等号: %s"
+
+#: ../eval/decode.c:799
+#, fuzzy, c-format
+msgid "E474: Expected false: %.*s"
+msgstr "E415: 不该有的等号: %s"
+
+#: ../eval/decode.c:879
+#, fuzzy, c-format
+msgid "E474: Unidentified byte: %.*s"
+msgstr "E121: 未定义的变量: %s"
+
+#: ../eval/decode.c:898
+#, fuzzy, c-format
+msgid "E474: Trailing characters: %.*s"
+msgstr "E488: 多余的尾部字符"
+
+#: ../eval/decode.c:906
#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: 缺少引号: %s"
+msgid "E474: Unexpected end of input: %.*s"
+msgstr "E474: 输入意外结束:%.*s"
-#: ../eval.c:5020
+#: ../eval/encode.c:123
#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: 缺少引号: %s"
+msgid "key %s"
+msgstr ""
-#: ../eval.c:5084
+#: ../eval/encode.c:124
#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: List 中缺少逗号: %s"
+msgid "key %s at index %i from special map"
+msgstr ""
-#: ../eval.c:5091
+#: ../eval/encode.c:125
#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: List 缺少结束符 ']': %s"
+msgid "index %i"
+msgstr "索引 %i"
+
+#: ../eval/encode.c:126
+msgid "partial"
+msgstr "部分"
-#: ../eval.c:6475
+#: ../eval/encode.c:127
#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Dictionary 中缺少冒号: %s"
+msgid "argument %i"
+msgstr "参数 %i"
+
+#: ../eval/encode.c:128
+msgid "partial self dictionary"
+msgstr ""
+
+#: ../eval/encode.c:203
+msgid "itself"
+msgstr ""
+
+#. Only give this message once for a recursive call to avoid
+#. flooding the user with errors.
+#: ../eval/encode.c:453 ../eval/encode.c:533
+msgid "E724: unable to correctly dump variable with self-referencing container"
+msgstr ""
-#: ../eval.c:6499
+#: ../eval/encode.c:563
+msgid "E474: Unable to represent NaN value in JSON"
+msgstr "E474: 在 JSON 中无法表示 NaN 值"
+
+#: ../eval/encode.c:567
+msgid "E474: Unable to represent infinity in JSON"
+msgstr "E474: 在 JSON 中无法表示无穷大"
+
+#: ../eval/encode.c:635
#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Dictionary 中出现重复的键: \"%s\""
+msgid ""
+"E474: String \"%.*s\" contains byte that does not start any UTF-8 character"
+msgstr "E474: 字符串 \"%.*s\" 包含不起始任何 UTF-8 字符的字节"
-#: ../eval.c:6517
+#: ../eval/encode.c:642
#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Dictionary 中缺少逗号: %s"
+msgid ""
+"E474: UTF-8 string contains code point which belongs to a surrogate pair: "
+"%.*s"
+msgstr "E474: UTF-8 字符串包含属于代理对的码点:%.*s"
+
+#: ../eval/encode.c:724
+msgid "E474: Unable to convert EXT string to JSON"
+msgstr "E474: 无法将 EXT 字符串转换为 JSON"
-#: ../eval.c:6524
+#: ../eval/encode.c:752
#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Dictionary 缺少结束符 '}': %s"
+msgid "E474: Error while dumping %s, %s: attempt to dump function reference"
+msgstr ""
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: 变量嵌套过深无法显示"
+#: ../eval/encode.c:797
+#, fuzzy
+msgid "E474: Invalid key in special dictionary"
+msgstr "E736: 对 Dictionary 无效的操作"
-#: ../eval.c:7188
-#, fuzzy, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E118: 函数的参数过多: %s"
+#: ../eval/encode.c:853
+msgid "encode_tv2string() argument"
+msgstr "encode_tv2string() 参数"
-#: ../eval.c:7190
-#, fuzzy, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E118: 函数的参数过多: %s"
+#: ../eval/encode.c:881
+msgid ":echo argument"
+msgstr ":echo 参数"
-#: ../eval.c:7377
-#, fuzzy, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E130: 未知的函数: %s"
+#: ../eval/encode.c:905
+msgid "encode_tv2json() argument"
+msgstr "encode_tv2json() 参数"
-#: ../eval.c:7383
+#: ../eval/encode.c:966
#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: 函数 %s 的参数太少"
+msgid "E5004: Error while dumping %s, %s: attempt to dump function reference"
+msgstr "E5004: dump %s, %s 时出错:试图 dump 函数引用"
-#: ../eval.c:7387
+#: ../eval/encode.c:1018
#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> 不能在 script 上下文外使用: %s"
+msgid "E5005: Unable to dump %s: container references itself in %s"
+msgstr "E5005: 无法 dump %s:容器在 %s 中引用了自己"
-#: ../eval.c:7391
+#: ../eval/executor.c:23
#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: 调用字典函数但是没有字典:%s"
+msgid "E684: list index out of range: %<PRId64>"
+msgstr "E684: List 索引超出范围: %<PRId64>"
-#: ../eval.c:7453
-#, fuzzy
-msgid "E808: Number or Float required"
-msgstr "E521: = 后面需要数字"
+#: ../eval/funcs.c:147
+#, c-format
+msgid "E899: Argument of %s must be a List or Blob"
+msgstr "E899: %s 的参数必须是列表或 Blob"
-#: ../eval.c:7503
-#, fuzzy
+#: ../eval/funcs.c:148 ../match.c:45
+msgid "E957: Invalid window number"
+msgstr "E957: 无效的窗口号"
+
+#: ../eval/funcs.c:149
+#, c-format
+msgid "E998: Reduce of an empty %s with no initial value"
+msgstr "E998: 在没有初始值的情况下 reduce 空的 %s"
+
+#: ../eval/funcs.c:151
+#, c-format
+msgid "E1023: Using a Number as a Bool: %d"
+msgstr "E1023: 将整数作布尔值使用:%d"
+
+#: ../eval/funcs.c:153
+msgid "E1308: Cannot resize a window in another tab page"
+msgstr "E1308: 不能修改其他标签页中窗口的大小"
+
+#: ../eval/funcs.c:328 ../eval/funcs.c:7006
+#, c-format
+msgid "Error converting the call result: %s"
+msgstr "转换调用结果时出错:%s"
+
+#: ../eval/funcs.c:366 ../eval/funcs.c:374
msgid "add() argument"
-msgstr "-c 参数"
+msgstr "add() 参数"
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: 参数过多"
+#: ../eval/funcs.c:679 ../sign.c:1451
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: 缓冲区名无效:%s"
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() 只能在插入模式中使用"
+#: ../eval/funcs.c:814
+#, c-format
+msgid "Invalid channel stream \"%s\""
+msgstr "channel stream \"%s\" 无效"
-#: ../eval.c:8156
+#: ../eval/funcs.c:1109
msgid "&Ok"
msgstr "确定(&O)"
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: 键已存在: %s"
+#: ../eval/funcs.c:1239
+msgid "Context stack is empty"
+msgstr "上下文堆栈为空"
+
+#: ../eval/funcs.c:1483
+msgid "dictwatcheradd() argument"
+msgstr "dictwatcheradd() 参数"
+
+#: ../eval/funcs.c:2178
+msgid "E900: maxdepth must be non-negative number"
+msgstr "E900: maxdepth 必须是非负整数"
-#: ../eval.c:8692
+#: ../eval/funcs.c:2186
+msgid "flatten() argument"
+msgstr "flatten() 参数"
+
+#: ../eval/funcs.c:2197 ../eval/typval.c:2458
msgid "extend() argument"
msgstr "extend() 参数"
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "map() 参数"
+#: ../eval/funcs.c:2877 ../eval/funcs.c:3891
+msgid "E5000: Cannot find tab number."
+msgstr "E5000: 找不到标签页号。"
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "filter() 参数"
+#: ../eval/funcs.c:2885 ../eval/funcs.c:3899
+msgid "E5001: Higher scope cannot be -1 if lower scope is >= 0."
+msgstr "E5001: 低边界 >= 0 时高边界不能为 -1。"
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld line: "
-msgid_plural "+-%s%3ld lines: "
-msgstr[0] "+-%s%3ld 行: "
+#: ../eval/funcs.c:2892 ../eval/funcs.c:3906
+msgid "E5002: Cannot find window number."
+msgstr "E5002: 找不到窗口号。"
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: 未知的函数: %s"
-
-#: ../eval.c:10729
+#: ../eval/funcs.c:4120
msgid "called inputrestore() more often than inputsave()"
msgstr "inputrestore() 的调用次数多于 inputsave()"
-#: ../eval.c:10771
-#, fuzzy
+#: ../eval/funcs.c:4153 ../eval/funcs.c:4190
msgid "insert() argument"
-msgstr "-c 参数"
+msgstr "insert() 参数"
-#: ../eval.c:10841
+#: ../eval/funcs.c:4260
msgid "E786: Range not allowed"
msgstr "E786: 不允许的范围"
-#: ../eval.c:11140
+#: ../eval/funcs.c:4743
+msgid "E474: Failed to convert list to string"
+msgstr "E474: 无法将列表转换为字符串"
+
+#: ../eval/funcs.c:4760
+#, c-format
+msgid "E474: Failed to parse %.*s"
+msgstr "E474: 无法解析 %.*s"
+
+#: ../eval/funcs.c:4826
msgid "E701: Invalid type for len()"
msgstr "E701: len() 的类型无效"
-#: ../eval.c:11980
+#: ../eval/funcs.c:5348
+#, c-format
+msgid "msgpackdump() argument, index %i"
+msgstr "msgpackdump() 参数,索引 %i"
+
+#: ../eval/funcs.c:5517
+msgid "E5070: Character number must not be less than zero"
+msgstr "E5070: 字符数不能小于零"
+
+#: ../eval/funcs.c:5521
+#, c-format
+msgid "E5071: Character number must not be greater than INT_MAX (%i)"
+msgstr "E5071: 字符数不能大于 INT_MAX (%i)"
+
+#: ../eval/funcs.c:5907
msgid "E726: Stride is zero"
msgstr "E726: 步长为零"
-#: ../eval.c:11982
+#: ../eval/funcs.c:5909
msgid "E727: Start past end"
msgstr "E727: 起始值在终止值后"
-#: ../eval.c:12024 ../eval.c:15297
+#: ../eval/funcs.c:6006
msgid "<empty>"
msgstr "<空>"
-#: ../eval.c:12282
-#, fuzzy
+#: ../eval/funcs.c:6329
msgid "remove() argument"
-msgstr "--cmd 参数"
+msgstr "remove() 参数"
-#: ../eval.c:12466
+#: ../eval/funcs.c:6447
msgid "E655: Too many symbolic links (cycle?)"
msgstr "E655: 符号连接过多(循环?)"
-#: ../eval.c:12593
-#, fuzzy
+#: ../eval/funcs.c:6577
msgid "reverse() argument"
-msgstr "-c 参数"
+msgstr "reverse() 参数"
-#: ../eval.c:13721
-#, fuzzy
+#: ../eval/funcs.c:7040
+#, c-format
+msgid "E5010: List item %d of the second argument is not a string"
+msgstr "E5010: 第二个参数的列表项 %d 不是字符串"
+
+#: ../eval/funcs.c:7916
+#, c-format
+msgid "E962: Invalid action: '%s'"
+msgstr "E962: 动作无效:'%s'"
+
+#: ../eval/funcs.c:8056
+#, c-format
+msgid "connection failed: %s"
+msgstr "连接失败:%s"
+
+#: ../eval/funcs.c:8328
+#, fuzzy, c-format
+msgid "E6100: \"%s\" is not a valid stdpath"
+msgstr "E236: 字体 \"%s\" 不是等宽字体"
+
+#: ../eval/funcs.c:8420 ../os/time.c:189
+msgid "(Invalid)"
+msgstr "(无效)"
+
+#: ../eval/funcs.c:8774
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: 子匹配号无效:%d"
+
+#: ../eval/funcs.c:9213
+msgid "Can only call this function in an unmodified buffer"
+msgstr "只能在未修改的缓冲区中调用这个函数"
+
+#: ../eval/funcs.c:10026
+msgid "writefile() first argument must be a List or a Blob"
+msgstr "writefile() 的第一个参数必须是列表或者 blob"
+
+#. Using %s, p and not %c, *p to preserve multibyte characters
+#: ../eval/funcs.c:10053
+#, c-format
+msgid "E5060: Unknown flag: %s"
+msgstr "E5060: 未知的标志:%s"
+
+#: ../eval/funcs.c:10067
+msgid "E482: Can't open file with an empty name"
+msgstr "E482: 无法打开名称为空的文件"
+
+#: ../eval/funcs.c:10072
+#, c-format
+msgid "E482: Can't open file %s for writing: %s"
+msgstr ""
+
+#: ../eval/funcs.c:10085
+#, c-format
+msgid "E80: Error when closing file %s: %s"
+msgstr "E80: 关闭文件 %s 时出错: %s"
+
+#: ../eval/typval.c:44
+#, c-format
+msgid "E1174: String required for argument %d"
+msgstr "E1174: 参数 %d 需要字符串"
+
+#: ../eval/typval.c:46
+#, c-format
+msgid "E1175: Non-empty string required for argument %d"
+msgstr "E1175: 参数 %d 需要非空字符串"
+
+#: ../eval/typval.c:48
+#, c-format
+msgid "E1210: Number required for argument %d"
+msgstr "E1210: 参数 %d 需要整数"
+
+#: ../eval/typval.c:50
+#, c-format
+msgid "E1222: String or List required for argument %d"
+msgstr "E1222: 参数 %d 需要字符串或列表"
+
+#: ../eval/typval.c:76
+#, c-format
+msgid "E5142: Failed to open file %s: %s"
+msgstr "E5142: 无法打开文件 %s:%s"
+
+#: ../eval/typval.c:98
+#, c-format
+msgid "E5143: Failed to write to file %s: %s"
+msgstr "E5143: 无法写入文件 %s:%s"
+
+#: ../eval/typval.c:109
+#, c-format
+msgid "E5144: Failed to close file %s: %s"
+msgstr "E5144: 无法关闭文件 %s:%s"
+
+#: ../eval/typval.c:1150
msgid "sort() argument"
-msgstr "-c 参数"
+msgstr "sort() 参数"
-#: ../eval.c:13721
-#, fuzzy
+#: ../eval/typval.c:1151
msgid "uniq() argument"
-msgstr "-c 参数"
+msgstr "uniq() 参数"
-#: ../eval.c:13776
+#: ../eval/typval.c:1242
msgid "E702: Sort compare function failed"
msgstr "E702: Sort 比较函数失败"
-#: ../eval.c:13806
+#: ../eval/typval.c:1265
msgid "E882: Uniq compare function failed"
msgstr "E882: Uniq 比较函数失败"
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(无效)"
+#: ../eval/typval.c:2198
+msgid "E6000: Argument is not a function or function name"
+msgstr ""
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: 写临时文件出错"
+#: ../eval/typval.c:2476
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: 键已存在:%s"
-#: ../eval.c:16159
-#, fuzzy
-msgid "E805: Using a Float as a Number"
-msgstr "E805: 将浮点数当做数字使用"
+#: ../eval/typval.c:3315
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: 变量嵌套过深,无法锁定/解锁"
+
+#: ../eval/typval.c:3455
+#, c-format
+msgid "E741: Value is locked: %.*s"
+msgstr "E741: 值已锁定:%.*s"
+
+#: ../eval/typval.c:3458
+#, c-format
+msgid "E742: Cannot change value of %.*s"
+msgstr "E742: 无法改变 %.*s 的值"
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: 将函数当做数字使用"
+#: ../eval/typval.c:3464 ../message.c:2469
+msgid "Unknown"
+msgstr "未知"
+
+#: ../eval/typval.c:3591
+msgid "E805: Expected a Number or a String, Float found"
+msgstr "E805: 需要整数或字符串,但是提供了浮点数"
+
+#: ../eval/typval.c:3595
+msgid "E703: Expected a Number or a String, Funcref found"
+msgstr "E703: 需要整数或字符串,但是提供了 Funcref"
+
+#: ../eval/typval.c:3598
+msgid "E745: Expected a Number or a String, List found"
+msgstr "E745: 需要整数或字符串,但是提供了列表"
+
+#: ../eval/typval.c:3601
+msgid "E728: Expected a Number or a String, Dictionary found"
+msgstr "E728: 需要整数或字符串,但是提供了字典"
-#: ../eval.c:16170
+#: ../eval/typval.c:3604
+msgid "E974: Expected a Number or a String, Blob found"
+msgstr "E974: 需要整数或字符串,但是提供了 Blob"
+
+#: ../eval/typval.c:3607
+msgid "E5299: Expected a Number or a String, Boolean found"
+msgstr "E5299: 需要整数或字符串,但是提供了布尔值"
+
+#: ../eval/typval.c:3610
+msgid "E5300: Expected a Number or a String"
+msgstr "E5300: 需要整数或字符串"
+
+#: ../eval/typval.c:3625
msgid "E745: Using a List as a Number"
-msgstr "E745: 将列表当做数字使用"
+msgstr "E745: 将列表当作整数使用"
-#: ../eval.c:16173
+#: ../eval/typval.c:3626
msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: 将字典当做数字使用"
+msgstr "E728: 将字典当作整数使用"
+
+#: ../eval/typval.c:3627
+msgid "E805: Using a Float as a Number"
+msgstr "E805: 将浮点数当作整数使用"
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: 将函数当做字符串使用"
+#: ../eval/typval.c:3628
+msgid "E974: Using a Blob as a Number"
+msgstr "E974: 将 Blob 当作整数使用"
-#: ../eval.c:16262
+#: ../eval/typval.c:3629
+msgid "E685: using an invalid value as a Number"
+msgstr "E685: 将无效值当作整数使用"
+
+#: ../eval/typval.c:3670
msgid "E730: using List as a String"
-msgstr "E730: 将列表当做字符串使用"
+msgstr "E730: 将列表当作字符串使用"
-#: ../eval.c:16265
+#: ../eval/typval.c:3671
msgid "E731: using Dictionary as a String"
-msgstr "E731: 将字典当做字符串使用"
+msgstr "E731: 将字典当作字符串使用"
+
+#: ../eval/typval.c:3673
+msgid "E976: using Blob as a String"
+msgstr "E976: 将 Blob 当作字符串使用"
+
+#: ../eval/typval.c:3674
+msgid "E908: using an invalid value as a String"
+msgstr "E908: 将无效值当作字符串使用"
+
+#: ../eval/typval.c:3815
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: 将 Funcref 当作浮点数使用"
+
+#: ../eval/typval.c:3818
+msgid "E892: Using a String as a Float"
+msgstr "E892: 将字符串当作浮点数使用"
+
+#: ../eval/typval.c:3821
+msgid "E893: Using a List as a Float"
+msgstr "E893: 将列表当作浮点数使用"
+
+#: ../eval/typval.c:3824
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: 将字典当作浮点数使用"
+
+#: ../eval/typval.c:3827
+msgid "E362: Using a boolean value as a Float"
+msgstr "E362: 将布尔值当作浮点数使用"
+
+#: ../eval/typval.c:3830
+msgid "E907: Using a special value as a Float"
+msgstr "E907: 将特殊值当作浮点数使用"
+
+#: ../eval/typval.c:3833
+msgid "E975: Using a Blob as a Float"
+msgstr "E975: 将 Blob 当作浮点数使用"
-#: ../eval.c:16619
+#: ../eval/typval.h:515
+msgid "E808: Number or Float required"
+msgstr "E808: 需要整数或浮点数"
+
+#: ../eval/userfunc.c:67
#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: 变量类型不匹配: %s"
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: 函数 %s 已存在,请加 ! 强制替换"
-#: ../eval.c:16705
-#, fuzzy, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E738: 无法列出 %s 的变量"
+#: ../eval/userfunc.c:68
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: 字典项已存在"
+
+#: ../eval/userfunc.c:69
+msgid "E718: Funcref required"
+msgstr "E718: 需要 Funcref"
-#: ../eval.c:16724
+#: ../eval/userfunc.c:70
#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Funcref 变量名必须以大写字母开头: %s"
+msgid "E130: Unknown function: %s"
+msgstr "E130: 函数未知: %s"
-#: ../eval.c:16732
+#: ../eval/userfunc.c:72
#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: 变量名与已有函数名冲突: %s"
+msgid "E1068: No white space allowed before '%s': %s"
+msgstr "E1068: '%s' 前不允许有空白:%s"
-#: ../eval.c:16763
+#: ../eval/userfunc.c:124
#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: 值已锁定: %s"
+msgid "E125: Illegal argument: %s"
+msgstr "E125: 参数无效: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "未知"
+#: ../eval/userfunc.c:137
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: 参数名重复:%s"
-#: ../eval.c:16768
+#: ../eval/userfunc.c:171
+msgid "E989: Non-default argument follows default argument"
+msgstr "E989: 默认参数后有非默认参数"
+
+#: ../eval/userfunc.c:498
#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: 无法改变 %s 的值"
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: 函数 %s 的参数过多"
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: 变量嵌套过深无法复制"
+#: ../eval/userfunc.c:500
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: 函数 %s 的参数无效"
+
+#: ../eval/userfunc.c:859
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: 函数调用深度超出 'maxfuncdepth'"
+
+#: ../eval/userfunc.c:1039
+#, c-format
+msgid "calling %s"
+msgstr "调用 %s"
+
+#: ../eval/userfunc.c:1154
+#, c-format
+msgid "%s aborted"
+msgstr "%s 已中止"
+
+#: ../eval/userfunc.c:1156
+#, c-format
+msgid "%s returning #%<PRId64>"
+msgstr "%s 返回 #%<PRId64> "
+
+#: ../eval/userfunc.c:1173
+#, c-format
+msgid "%s returning %s"
+msgstr "%s 返回 %s"
+
+#: ../eval/userfunc.c:1196 ../runtime.c:2083
+#, c-format
+msgid "continuing in %s"
+msgstr "在 %s 中继续"
+
+#: ../eval/userfunc.c:1391
+msgid "E699: Too many arguments"
+msgstr "E699: 参数过多"
+
+#: ../eval/userfunc.c:1441
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: 未知的函数:%s"
+
+#: ../eval/userfunc.c:1444
+#, c-format
+msgid "E276: Cannot use function as a method: %s"
+msgstr "E276: 不能将函数用作方法:%s"
+
+#: ../eval/userfunc.c:1447
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: 函数已被删除:%s"
+
+#: ../eval/userfunc.c:1453
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: 函数 %s 的参数不足"
-#: ../eval.c:17249
+#: ../eval/userfunc.c:1457
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> 不能在 script 上下文外使用:%s"
+
+#: ../eval/userfunc.c:1461
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: 调用字典函数但是没有字典:%s"
+
+#: ../eval/userfunc.c:1759
+msgid "E129: Function name required"
+msgstr "E129: 需要函数名"
+
+#: ../eval/userfunc.c:1895
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: 函数名必须以大写字母或 \"s:\" 开头:%s"
+
+#: ../eval/userfunc.c:1904
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: 函数名不能包含冒号:%s"
+
+#: ../eval/userfunc.c:1972
+msgid "E454: function list was modified"
+msgstr "E454: 函数列表已被修改"
+
+#: ../eval/userfunc.c:2125
#, c-format
msgid "E123: Undefined function: %s"
-msgstr "E123: 函数 %s 尚未定义"
+msgstr "E123: 函数未定义:%s"
-#: ../eval.c:17260
+#: ../eval/userfunc.c:2135
#, c-format
msgid "E124: Missing '(': %s"
-msgstr "E124: 缺少 '(': %s"
+msgstr "E124: 缺少 '(':%s"
-#: ../eval.c:17293
-#, fuzzy
+#: ../eval/userfunc.c:2167
msgid "E862: Cannot use g: here"
-msgstr "E284: 不能设定 IC 值"
+msgstr "E862: 此处不能使用 g:"
-#: ../eval.c:17312
+#: ../eval/userfunc.c:2197
#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: 无效的参数: %s"
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: 闭包函数不能位于顶层:%s"
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E125: 无效的参数: %s"
-
-#: ../eval.c:17416
+#: ../eval/userfunc.c:2272
msgid "E126: Missing :endfunction"
msgstr "E126: 缺少 :endfunction"
-#: ../eval.c:17537
-#, fuzzy, c-format
+#: ../eval/userfunc.c:2327
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: :endfunction 后有文本:%s"
+
+#: ../eval/userfunc.c:2363
+msgid "E1058: function nesting too deep"
+msgstr "E1058: 函数嵌套层数过深"
+
+#: ../eval/userfunc.c:2472
+#, c-format
msgid "E707: Function name conflicts with variable: %s"
-msgstr "E746: 函数名与脚本文件名不匹配: %s"
+msgstr "E707: 函数名与变量名冲突:%s"
-#: ../eval.c:17549
+#: ../eval/userfunc.c:2488
#, c-format
msgid "E127: Cannot redefine function %s: It is in use"
msgstr "E127: 函数 %s 正在使用中,不能重新定义"
-#: ../eval.c:17604
+#: ../eval/userfunc.c:2555
#, c-format
msgid "E746: Function name does not match script file name: %s"
msgstr "E746: 函数名与脚本文件名不匹配: %s"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: 需要函数名"
+#: ../eval/userfunc.c:2778
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: 函数 %s 正在使用中,不能删除"
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: 函数名必须以大写字母开头或者包含冒号: %s"
+#: ../eval/userfunc.c:2784
+#, c-format
+msgid "Cannot delete function %s: It is being used internally"
+msgstr "无法删除函数 %s,内部使用这个函数"
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: 函数名必须以大写字母开头或者包含冒号: %s"
+#: ../eval/userfunc.c:2916
+msgid "E133: :return not inside a function"
+msgstr "E133: :return 在函数外"
+
+#. TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
+#. maximum nesting of lists and dicts
+#: ../eval/vars.c:52
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: :let 中出现异常字符"
-#: ../eval.c:18336
+#: ../eval/vars.c:53
#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: 无法删除函数 %s: 正在使用中"
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: 不能锁定或解锁变量 %s"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: 函数调用深度超出 'maxfuncdepth'"
+#: ../eval/vars.c:77
+msgid "E991: cannot use =<< here"
+msgstr "E991: 此处不能使用 =<<"
-#: ../eval.c:18568
+#: ../eval/vars.c:109
+msgid "E221: Marker cannot start with lower case letter"
+msgstr "E221: 标记不能以小写字母开头"
+
+#: ../eval/vars.c:113
+msgid "E172: Missing marker"
+msgstr "E172: 缺少标记"
+
+#: ../eval/vars.c:124
#, c-format
-msgid "calling %s"
-msgstr "调用 %s"
+msgid "E990: Missing end marker '%s'"
+msgstr "E990: 缺少结束标记 '%s'"
-#: ../eval.c:18651
+#: ../eval/vars.c:311
+msgid "E687: Less targets than List items"
+msgstr "E687: 目标比 List 项数少"
+
+#: ../eval/vars.c:315
+msgid "E688: More targets than List items"
+msgstr "E688: 目标比 List 项数多"
+
+#: ../eval/vars.c:391
+msgid "E452: Double ; in list of variables"
+msgstr "E452: 变量列表中有两个 ;"
+
+#: ../eval/vars.c:532
#, c-format
-msgid "%s aborted"
-msgstr "%s 已中止"
+msgid "E738: Can't list variables for %s"
+msgstr "E738: 无法列出 %s 的变量"
+
+#: ../eval/vars.c:584
+msgid "E996: Cannot lock an environment variable"
+msgstr "E996: 不能锁定环境变量"
+
+#: ../eval/vars.c:625
+msgid "E996: Cannot lock an option"
+msgstr "E996: 不能锁定选项"
+
+#: ../eval/vars.c:716
+msgid "E996: Cannot lock a register"
+msgstr "E996: 不能锁定寄存器"
-#: ../eval.c:18653
+#: ../eval/vars.c:1015
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s 返回 #%<PRId64> "
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: 无此变量:\"%s\""
-#: ../eval.c:18670
+#: ../eval/vars.c:1331
#, c-format
-msgid "%s returning %s"
-msgstr "%s 返回 %s"
+msgid "E963: setting %s to value with wrong type"
+msgstr "E963: 将 %s 设置为类型错误的值"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
+#: ../eval/vars.c:1414
#, c-format
-msgid "continuing in %s"
-msgstr "在 %s 中继续"
+msgid "E794: Cannot set variable in the sandbox: \"%.*s\""
+msgstr "E794: 不能在沙盒中设置变量:\"%.*s\""
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return 不在函数中"
+#: ../eval/vars.c:1460
+#, c-format
+msgid "E795: Cannot delete variable %.*s"
+msgstr "E795: 无法删除变量 %.*s"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# 全局变量:\n"
+#: ../eval/vars.c:1483
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Funcref 变量名必须以大写字母开头: %s"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\t最近修改于 "
+#: ../eval/vars.c:1490
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: 变量名与已有函数名冲突: %s"
-#: ../eval.c:19272
-#, fuzzy
-msgid "No old files"
-msgstr "没有包含文件"
+#: ../event/socket.c:220
+msgid "tcp address must be host:port"
+msgstr "TCP 地址必须为 host:port"
+
+#: ../event/socket.c:231
+msgid "failed to lookup host or port"
+msgstr "无法查找主机或端口"
-#: ../ex_cmds.c:122
+#: ../event/socket.c:256
+msgid "connection refused"
+msgstr "连接被拒绝"
+
+#: ../ex_cmds.c:164
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, 十六进制 %02x, 八进制 %03o, 二合字符 %s"
+
+#: ../ex_cmds.c:169
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, 十六进制 %02x, 八进制 %03o"
-#: ../ex_cmds.c:145
+#: ../ex_cmds.c:213
+#, c-format
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, 十六进制 %04x, 八进制 %o, 二合字符 %s"
+
+#: ../ex_cmds.c:214
+#, c-format
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, 十六进制 %08x, 八进制 %o, 二合字符 %s"
+
+#: ../ex_cmds.c:220
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, 十六进制 %04x, 八进制 %o"
-#: ../ex_cmds.c:146
+#: ../ex_cmds.c:221
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, 十六进制 %08x, 八进制 %o"
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: 把行移动到自已中"
+#: ../ex_cmds.c:914
+msgid "E134: Cannot move a range of lines into itself"
+msgstr "E134: 不能把一系列行移动到自身当中"
-#: ../ex_cmds.c:747
+#: ../ex_cmds.c:1021
+#, c-format
msgid "1 line moved"
-msgstr "移动了 1 行"
+msgid_plural "%<PRId64> lines moved"
+msgstr[0] "移动了 %<PRId64> 行"
-#: ../ex_cmds.c:749
+#. will call wait_return()
+#: ../ex_cmds.c:1335
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "移动了 %<PRId64> 行"
+msgid "E482: Can't create file %s"
+msgstr "E482: 无法创建文件 %s"
-#: ../ex_cmds.c:1175
+#: ../ex_cmds.c:1436
#, c-format
msgid "%<PRId64> lines filtered"
msgstr "过滤了 %<PRId64> 行"
-#: ../ex_cmds.c:1194
+#: ../ex_cmds.c:1458
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *Filter* 自动命令不可以改变当前缓冲区"
-#: ../ex_cmds.c:1244
+#: ../ex_cmds.c:1498
msgid "[No write since last change]\n"
msgstr "[已修改但尚未保存]\n"
-# bad to translate
-#: ../ex_cmds.c:1424
-#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s 位于行: "
-
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: 错误过多,忽略文件的剩余部分"
-
-#: ../ex_cmds.c:1458
-#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "读取 viminfo 文件 \"%s\"%s%s%s"
-
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " 信息"
-
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " 标记"
-
-#: ../ex_cmds.c:1462
-#, fuzzy
-msgid " oldfiles"
-msgstr "没有包含文件"
-
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " 失败"
-
-#. avoid a wait_return for this message, it's annoying
-#: ../ex_cmds.c:1541
-#, c-format
-msgid "E137: Viminfo file is not writable: %s"
-msgstr "E137: Viminfo 文件不可写入: %s"
-
-#: ../ex_cmds.c:1626
-#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: 无法写入 viminfo 文件 %s!"
-
-#: ../ex_cmds.c:1635
+#: ../ex_cmds.c:1793
#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "写入 viminfo 文件 \"%s\""
-
-# do not translate to avoid writing Chinese in files
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, fuzzy, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# 这个 viminfo 文件是由 Vim %s 生成的。\n"
+msgid "E503: \"%s\" is not a file or writable device"
+msgstr "E503: \"%s\" 不是文件或可写的设备"
-# do not translate to avoid writing Chinese in files
-#: ../ex_cmds.c:1722
-#, fuzzy
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# 如果要自行修改请特别小心!\n"
-"\n"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_cmds.c:1723
-#, fuzzy
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# 'encoding' 在此文件建立时的值\n"
-
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "无效的启动字符"
-
-#: ../ex_cmds.c:2162
+#: ../ex_cmds.c:1877
msgid "Write partial file?"
msgstr "要写入部分文件吗?"
-#: ../ex_cmds.c:2166
+#: ../ex_cmds.c:1882
msgid "E140: Use ! to write partial buffer"
msgstr "E140: 请使用 ! 来写入部分缓冲区"
-#: ../ex_cmds.c:2281
+#: ../ex_cmds.c:2006
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "覆盖已存在的文件 \"%s\" 吗?"
-#: ../ex_cmds.c:2317
+#: ../ex_cmds.c:2043
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "交换文件 \"%s\" 已存在,确实要覆盖吗?"
-#: ../ex_cmds.c:2326
+#: ../ex_cmds.c:2052
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: 交换文件已存在: %s (:silent! 强制执行)"
-#: ../ex_cmds.c:2381
+#: ../ex_cmds.c:2110
#, c-format
msgid "E141: No file name for buffer %<PRId64>"
msgstr "E141: 缓冲区 %<PRId64> 没有文件名"
-#: ../ex_cmds.c:2412
+#: ../ex_cmds.c:2144
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: 文件未写入: 写入被 'write' 选项禁用"
-#: ../ex_cmds.c:2434
+#: ../ex_cmds.c:2163
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1198,7 +1959,7 @@ msgstr ""
"\"%s\" 已设定 'readonly' 选项。\n"
"确实要覆盖吗?"
-#: ../ex_cmds.c:2439
+#: ../ex_cmds.c:2167
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1209,1069 +1970,744 @@ msgstr ""
"它仍然有可能被写入。\n"
"你想继续尝试吗?"
-#: ../ex_cmds.c:2451
-#, fuzzy, c-format
+#: ../ex_cmds.c:2181
+#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "只读 (请加 ! 强制执行)"
+msgstr "E505: \"%s\" 只读 (请加 ! 强制执行)"
-#: ../ex_cmds.c:3120
+#: ../ex_cmds.c:2902
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: 自动命令意外地删除了新缓冲区 %s"
-#: ../ex_cmds.c:3313
+#: ../ex_cmds.c:3118
msgid "E144: non-numeric argument to :z"
msgstr "E144: :z 不接受非数字的参数"
-#: ../ex_cmds.c:3498
+#: ../ex_cmds.c:3429
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: 正则表达式不能用字母作分界"
-#: ../ex_cmds.c:3964
+#. Same highlight as wait_return().
+#: ../ex_cmds.c:3952
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "替换为 %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
+#: ../ex_cmds.c:4462
msgid "(Interrupted) "
msgstr "(已中断) "
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "1 个匹配,"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "1 次替换,"
-
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> 个匹配,"
+#: ../ex_cmds.c:4468
+#, fuzzy, c-format
+msgid "%<PRId64> match on %<PRId64> line"
+msgid_plural "%<PRId64> matches on %<PRId64> line"
+msgstr[0] "共 %<PRId64> 行"
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> 次替换,"
+#: ../ex_cmds.c:4470
+#, fuzzy, c-format
+msgid "%<PRId64> substitution on %<PRId64> line"
+msgid_plural "%<PRId64> substitutions on %<PRId64> line"
+msgstr[0] "%<PRId64> 次替换,"
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr "共 1 行"
+#: ../ex_cmds.c:4473
+#, fuzzy, c-format
+msgid "%<PRId64> match on %<PRId64> lines"
+msgid_plural "%<PRId64> matches on %<PRId64> lines"
+msgstr[0] "共 %<PRId64> 行"
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr "共 %<PRId64> 行"
+#: ../ex_cmds.c:4475
+#, fuzzy, c-format
+msgid "%<PRId64> substitution on %<PRId64> lines"
+msgid_plural "%<PRId64> substitutions on %<PRId64> lines"
+msgstr[0] "%<PRId64> 次替换,"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global 不能递归执行"
+#. will increment global_busy to break out of the loop
+#: ../ex_cmds.c:4536
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: 不能带范围递归执行 :global"
-#: ../ex_cmds.c:4467
+#: ../ex_cmds.c:4565
msgid "E148: Regular expression missing from global"
msgstr "E148: global 缺少正则表达式"
-#: ../ex_cmds.c:4508
+#: ../ex_cmds.c:4610
#, c-format
msgid "Pattern found in every line: %s"
msgstr "每行都匹配表达式: %s"
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
-msgid "Pattern not found: %s"
-msgstr "找不到模式"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_cmds.c:4587
-#, fuzzy
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# 最近的替换字符串:\n"
-"$"
-
-#: ../ex_cmds.c:4679
-msgid "E478: Don't panic!"
-msgstr "E478: 不要慌!"
-
-#: ../ex_cmds.c:4717
-#, c-format
-msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: 抱歉,没有 '%s' 的 %s 的说明"
-
-#: ../ex_cmds.c:4719
-#, c-format
-msgid "E149: Sorry, no help for %s"
-msgstr "E149: 抱歉,没有 %s 的说明"
-
-#: ../ex_cmds.c:4751
-#, c-format
-msgid "Sorry, help file \"%s\" not found"
-msgstr "抱歉,找不到帮助文件 \"%s\""
-
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: 不是目录: %s"
-
-#: ../ex_cmds.c:5446
-#, c-format
-msgid "E152: Cannot open %s for writing"
-msgstr "E152: 无法打开并写入 %s"
-
-#: ../ex_cmds.c:5471
-#, c-format
-msgid "E153: Unable to open %s for reading"
-msgstr "E153: 无法打开并读取 %s"
-
-#: ../ex_cmds.c:5500
-#, c-format
-msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: 在一种语言中混合了多种帮助文件编码: %s"
-
-#: ../ex_cmds.c:5565
-#, c-format
-msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: Tag \"%s\" 在文件 %s/%s 中重复出现"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: 未知的 sign 命令: %s"
-
-#: ../ex_cmds.c:5704
-msgid "E156: Missing sign name"
-msgstr "E156: 缺少 sign 名称"
-
-#: ../ex_cmds.c:5746
-msgid "E612: Too many signs defined"
-msgstr "E612: Signs 定义过多"
-
-#: ../ex_cmds.c:5813
+#: ../ex_cmds.c:4612
#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: 无效的 sign 文字: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: 未知的 sign: %s"
-
-#: ../ex_cmds.c:5877
-msgid "E159: Missing sign number"
-msgstr "E159: 缺少 sign 号"
-
-#: ../ex_cmds.c:5971
-#, c-format
-msgid "E158: Invalid buffer name: %s"
-msgstr "E158: 无效的缓冲区名: %s"
-
-#: ../ex_cmds.c:6008
-#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: 无效的 sign ID: %<PRId64>"
-
-#: ../ex_cmds.c:6066
-msgid " (not supported)"
-msgstr " (不支持)"
-
-#: ../ex_cmds.c:6169
-msgid "[Deleted]"
-msgstr "[已删除]"
-
-#: ../ex_cmds2.c:139
-msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "进入调试模式。输入 \"cont\" 继续运行。"
-
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
-#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "第 %<PRId64> 行: %s"
-
-#: ../ex_cmds2.c:145
-#, c-format
-msgid "cmd: %s"
-msgstr "命令: %s"
+msgid "Pattern not found: %s"
+msgstr "找不到模式:%s"
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "断点 \"%s%s\" 第 %<PRId64> 行"
+#: ../ex_cmds.c:4921
+msgid "No old files"
+msgstr "没有旧文件"
-#: ../ex_cmds2.c:581
+#: ../ex_cmds2.c:204
#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: 找不到断点: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "没有定义断点"
+msgid "Save changes to \"%s\"?"
+msgstr "将改变保存到 \"%s\" 吗?"
-#: ../ex_cmds2.c:617
+#: ../ex_cmds2.c:255
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s 第 %<PRId64> 行"
+msgid "Close \"%s\"?"
+msgstr "关闭 \"%s\"?"
-#: ../ex_cmds2.c:942
-#, fuzzy
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: 请先使用 :profile start <fname>"
-
-#: ../ex_cmds2.c:1269
+#: ../ex_cmds2.c:380
#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "将改变保存到 \"%s\" 吗?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "未命名"
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: 任务仍在缓冲区 \"%s\" 中运行"
-#: ../ex_cmds2.c:1421
+#: ../ex_cmds2.c:381
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: 缓冲区 \"%s\" 已修改但尚未保存"
-#: ../ex_cmds2.c:1480
+#: ../ex_cmds2.c:441
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "警告: 意外地进入了其它缓冲区 (请检查自动命令)"
-#: ../ex_cmds2.c:1826
-msgid "E163: There is only one file to edit"
-msgstr "E163: 只有一个文件可编辑"
-
-#: ../ex_cmds2.c:1828
-msgid "E164: Cannot go before first file"
-msgstr "E164: 无法切换,已是第一个文件"
-
-#: ../ex_cmds2.c:1830
-msgid "E165: Cannot go beyond last file"
-msgstr "E165: 无法切换,已是最后一个文件"
-
-#: ../ex_cmds2.c:2175
+#: ../ex_cmds2.c:735
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: 不支持编译器: %s"
-#: ../ex_cmds2.c:2257
-#, c-format
-msgid "Searching for \"%s\" in \"%s\""
-msgstr "正在查找 \"%s\",在 \"%s\" 中"
-
-#: ../ex_cmds2.c:2284
-#, c-format
-msgid "Searching for \"%s\""
-msgstr "正在查找 \"%s\""
-
-#: ../ex_cmds2.c:2307
-#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "在 'runtimepath' 中找不到 \"%s\""
-
-#: ../ex_cmds2.c:2472
-#, c-format
-msgid "Cannot source a directory: \"%s\""
-msgstr "不能执行目录: \"%s\""
-
-#: ../ex_cmds2.c:2518
-#, c-format
-msgid "could not source \"%s\""
-msgstr "不能执行 \"%s\""
-
-#: ../ex_cmds2.c:2520
-#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "第 %<PRId64> 行: 不能执行 \"%s\""
-
-#: ../ex_cmds2.c:2535
-#, c-format
-msgid "sourcing \"%s\""
-msgstr "执行 \"%s\""
-
-#: ../ex_cmds2.c:2537
-#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "第 %<PRId64> 行: 执行 \"%s\""
-
-#: ../ex_cmds2.c:2693
-#, c-format
-msgid "finished sourcing %s"
-msgstr "结束执行 %s"
-
-#: ../ex_cmds2.c:2765
-msgid "modeline"
-msgstr "modeline"
-
-#: ../ex_cmds2.c:2767
-msgid "--cmd argument"
-msgstr "--cmd 参数"
-
-#: ../ex_cmds2.c:2769
-msgid "-c argument"
-msgstr "-c 参数"
-
-#: ../ex_cmds2.c:2771
-msgid "environment variable"
-msgstr "环境变量"
-
-#: ../ex_cmds2.c:2773
-msgid "error handler"
-msgstr "错误的处理程序"
-
-#: ../ex_cmds2.c:3020
-msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: 警告: 错误的行分隔符,可能是少了 ^M"
+#: ../ex_docmd.c:90
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: 不确定的用户自定义命令"
-#: ../ex_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: 在脚本文件外使用了 :scriptencoding"
+#: ../ex_docmd.c:92
+msgid "E492: Not an editor command"
+msgstr "E492: 不是编辑器的命令"
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: 在脚本文件外使用了 :finish"
+#: ../ex_docmd.c:94
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: 没有用于替换 \"<sfile>\" 的 :source 文件名"
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "当前的 %s语言: \"%s\""
+#: ../ex_docmd.c:96
+msgid "E489: no call stack to substitute for \"<stack>\""
+msgstr "E489: 没有用于替换 \"<stack>\" 的调用栈"
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: 不能设定语言为 \"%s\""
+#: ../ex_docmd.c:98
+msgid "E1274: No script file name to substitute for \"<script>\""
+msgstr "E1274: 没有脚本文件名可用于替换 \"<script>\""
#. don't redisplay the window
#. don't wait for return
-#: ../ex_docmd.c:387
+#: ../ex_docmd.c:203
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "进入 Ex 模式。输入 \"visual\" 回到正常模式。"
-#: ../ex_docmd.c:428
+#: ../ex_docmd.c:244
msgid "E501: At end-of-file"
msgstr "E501: 已到文件末尾"
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: 命令递归层数过多"
+#: ../ex_docmd.c:267
+#, c-format
+msgid "Executing: %s"
+msgstr "执行:%s"
-#: ../ex_docmd.c:1006
+#: ../ex_docmd.c:269
+msgid "line %"
+msgstr "在行号 %"
+
+#: ../ex_docmd.c:781
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: 异常没有被捕获: %s"
-#: ../ex_docmd.c:1085
+#: ../ex_docmd.c:853
msgid "End of sourced file"
msgstr "脚本文件结束"
-#: ../ex_docmd.c:1086
+#: ../ex_docmd.c:854
msgid "End of function"
msgstr "函数结束"
-#: ../ex_docmd.c:1628
-msgid "E464: Ambiguous use of user-defined command"
-msgstr "E464: 不确定的用户自定义命令"
-
-#: ../ex_docmd.c:1638
-msgid "E492: Not an editor command"
-msgstr "E492: 不是编辑器的命令"
+#: ../ex_docmd.c:1279
+msgid ""
+"INTERNAL: Cannot use EX_DFLALL with ADDR_NONE, ADDR_UNSIGNED or ADDR_QUICKFIX"
+msgstr ""
+"内部信息:不能使用 EX_DFLALL 与 ADDR_NONE, ADDR_UNSIGNED 或 ADDR_QUICKFIX"
-#: ../ex_docmd.c:1729
+#: ../ex_docmd.c:2118
msgid "E493: Backwards range given"
msgstr "E493: 使用了逆向的范围"
-#: ../ex_docmd.c:1733
+#: ../ex_docmd.c:2121
msgid "Backwards range given, OK to swap"
msgstr "使用了逆向的范围,确定交换吗"
#. append
#. typed wrong
-#: ../ex_docmd.c:1787
+#: ../ex_docmd.c:2179
msgid "E494: Use w or w>>"
msgstr "E494: 请使用 w 或 w>>"
-#: ../ex_docmd.c:3454
+#: ../ex_docmd.c:2957
+msgid "E943: Command table needs to be updated, run 'make'"
+msgstr "E943: 命令表需要更新,请执行 'make'"
+
+#: ../ex_docmd.c:3542
msgid "E319: The command is not available in this version"
msgstr "E319: 抱歉,命令在此版本中不可用"
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: 只允许一个文件名"
-
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "还有 1 个文件未编辑。确实要退出吗?"
-
-#: ../ex_docmd.c:4242
-#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "还有 %d 个文件未编辑。确实要退出吗?"
-
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: 还有 1 个文件未编辑"
-
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: 还有 %<PRId64> 个文件未编辑"
-
-#: ../ex_docmd.c:4320
-msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: 命令已存在: 请加 ! 强制替换"
-
-#: ../ex_docmd.c:4432
-msgid ""
-"\n"
-" Name Args Range Complete Definition"
-msgstr ""
-"\n"
-" 名称 参数 范围 补全 定义 "
-
-#: ../ex_docmd.c:4516
-msgid "No user-defined commands found"
-msgstr "找不到用户自定义命令"
-
-#: ../ex_docmd.c:4538
-msgid "E175: No attribute specified"
-msgstr "E175: 没有指定属性"
-
-#: ../ex_docmd.c:4583
-msgid "E176: Invalid number of arguments"
-msgstr "E176: 无效的参数个数"
-
-#: ../ex_docmd.c:4594
-msgid "E177: Count cannot be specified twice"
-msgstr "E177: 不能指定两次计数"
-
-#: ../ex_docmd.c:4603
-msgid "E178: Invalid default value for count"
-msgstr "E178: 无效的计数默认值"
-
-#: ../ex_docmd.c:4625
-msgid "E179: argument required for -complete"
-msgstr "E179: -complete 需要参数"
-
-#: ../ex_docmd.c:4635
-#, c-format
-msgid "E181: Invalid attribute: %s"
-msgstr "E181: 无效的属性: %s"
-
-#: ../ex_docmd.c:4678
-msgid "E182: Invalid command name"
-msgstr "E182: 无效的命令名"
-
-#: ../ex_docmd.c:4691
-msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: 用户自定义命令必须以大写字母开头"
-
-#: ../ex_docmd.c:4696
-#, fuzzy
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: 不确定的用户自定义命令"
+#: ../ex_docmd.c:4388
+#, fuzzy, c-format
+msgid "%d more file to edit. Quit anyway?"
+msgid_plural "%d more files to edit. Quit anyway?"
+msgstr[0] "还有 %d 个文件未编辑。确实要退出吗?"
-#: ../ex_docmd.c:4751
+#: ../ex_docmd.c:4395
#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: 没有这个用户自定义命令: %s"
+msgid "E173: %<PRId64> more file to edit"
+msgid_plural "E173: %<PRId64> more files to edit"
+msgstr[0] "E173: 还有 %<PRId64> 个文件未编辑"
-#: ../ex_docmd.c:5219
+#: ../ex_docmd.c:4430
#, c-format
-msgid "E180: Invalid complete value: %s"
-msgstr "E180: 无效的补全类型: %s"
-
-#: ../ex_docmd.c:5225
-msgid "E468: Completion argument only allowed for custom completion"
-msgstr "E468: 只有 custom 补全才允许参数"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Custom 补全需要一个函数参数"
-
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: 找不到配色方案 %s"
+msgstr "E185: 找不到配色方案 '%s'"
-#: ../ex_docmd.c:5263
+#: ../ex_docmd.c:4437
msgid "Greetings, Vim user!"
msgstr "您好,Vim 用户!"
-#: ../ex_docmd.c:5431
+#: ../ex_docmd.c:4662
msgid "E784: Cannot close last tab page"
msgstr "E784: 不能关闭最后一个 tab 页"
-#: ../ex_docmd.c:5462
+#: ../ex_docmd.c:4687
msgid "Already only one tab page"
msgstr "已经只剩一个 tab 页了"
-#: ../ex_docmd.c:6004
+#: ../ex_docmd.c:5072
#, c-format
msgid "Tab page %d"
msgstr "Tab 页 %d"
-#: ../ex_docmd.c:6295
+#: ../ex_docmd.c:5296
+msgid "E25: Nvim does not have a built-in GUI"
+msgstr "E25: 无法使用图形界面: 编译时没有启用"
+
+#: ../ex_docmd.c:5307
msgid "No swap file"
msgstr "无交换文件"
-#: ../ex_docmd.c:6478
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr "E747: 不能改变目录,缓冲区已修改 (请加 ! 强制执行)"
-
-#: ../ex_docmd.c:6485
+#: ../ex_docmd.c:5518
msgid "E186: No previous directory"
msgstr "E186: 前一个目录不存在"
-#: ../ex_docmd.c:6530
+#: ../ex_docmd.c:5624
msgid "E187: Unknown"
msgstr "E187: 未知"
-#: ../ex_docmd.c:6610
+#: ../ex_docmd.c:5689
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize 需要两个数字参数"
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr "E188: 在此平台上不能获得窗口位置"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos 需要两个数字参数"
-
-#: ../ex_docmd.c:7241
-#, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "E739: 无法创建目录: %s"
-
-#: ../ex_docmd.c:7268
+#: ../ex_docmd.c:6207
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" 已存在 (请加 ! 强制执行)"
-#: ../ex_docmd.c:7273
+#: ../ex_docmd.c:6213
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: 无法打开并写入 \"%s\""
#. set mark
-#: ../ex_docmd.c:7294
+#: ../ex_docmd.c:6231
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: 参数必须是一个字母或者正/反引号"
-#: ../ex_docmd.c:7333
+#: ../ex_docmd.c:6315
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: :normal 递归层数过深"
-#: ../ex_docmd.c:7807
+#: ../ex_docmd.c:6795
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: 没有用于替换 '#' 的交替文件名"
-#: ../ex_docmd.c:7841
+#: ../ex_docmd.c:6834
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: 没有用于替换 \"<afile>\" 的自动命令文件名"
-#: ../ex_docmd.c:7850
+#: ../ex_docmd.c:6842
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: 没有用于替换 \"<abuf>\" 的自动命令缓冲区号"
-#: ../ex_docmd.c:7861
+#: ../ex_docmd.c:6852
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: 没有用于替换 \"<amatch>\" 的自动命令匹配名"
-#: ../ex_docmd.c:7870
-msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: 没有用于替换 \"<sfile>\" 的 :source 文件名"
-
-#: ../ex_docmd.c:7876
-#, fuzzy
+#: ../ex_docmd.c:6884
msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: 没有用于替换 \"<sfile>\" 的 :source 文件名"
+msgstr "E842: 没有行号可用于替换 \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#: ../ex_docmd.c:6893
+msgid "E961: no line number to use for \"<sflnum>\""
+msgstr "E961: 没有用于替换 \"<sflnum>\" 的行号"
+
+#: ../ex_docmd.c:6942
+#, fuzzy, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: '%' 或 '#' 为空文件名,只能用于 \":p:h\""
-#: ../ex_docmd.c:7905
+#: ../ex_docmd.c:6944
msgid "E500: Evaluates to an empty string"
msgstr "E500: 结果为空字符串"
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: 无法打开并读取 viminfo 文件"
+#: ../ex_docmd.c:7018
+msgid "Untitled"
+msgstr "未命名"
-#: ../ex_eval.c:464
+#: ../ex_eval.c:456
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: 不能 :throw 前缀为 'Vim' 的异常"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
+#: ../ex_eval.c:500
#, c-format
msgid "Exception thrown: %s"
msgstr "抛出异常: %s"
-#: ../ex_eval.c:545
+#: ../ex_eval.c:553
#, c-format
msgid "Exception finished: %s"
msgstr "完成异常: %s"
-#: ../ex_eval.c:546
+#: ../ex_eval.c:553
#, c-format
msgid "Exception discarded: %s"
msgstr "丢弃异常: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
+#: ../ex_eval.c:597 ../ex_eval.c:647
#, c-format
msgid "%s, line %<PRId64>"
msgstr "%s,第 %<PRId64> 行"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
+#: ../ex_eval.c:620
#, c-format
msgid "Exception caught: %s"
msgstr "捕获异常: %s"
-#: ../ex_eval.c:676
+#: ../ex_eval.c:688
#, c-format
msgid "%s made pending"
msgstr "%s 待定"
-#: ../ex_eval.c:679
-#, fuzzy, c-format
+#: ../ex_eval.c:691
+#, c-format
msgid "%s resumed"
-msgstr " 已返回\n"
+msgstr "%s 已恢复"
-#: ../ex_eval.c:683
+#: ../ex_eval.c:695
#, c-format
msgid "%s discarded"
msgstr "%s 舍弃"
-#: ../ex_eval.c:708
+#: ../ex_eval.c:720
msgid "Exception"
msgstr "异常"
-#: ../ex_eval.c:713
+#: ../ex_eval.c:724
msgid "Error and interrupt"
msgstr "错误和中断"
-#: ../ex_eval.c:715
+#: ../ex_eval.c:726
msgid "Error"
msgstr "错误"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
+#: ../ex_eval.c:728
msgid "Interrupt"
msgstr "中断"
-#: ../ex_eval.c:795
+#: ../ex_eval.c:816
msgid "E579: :if nesting too deep"
msgstr "E579: :if 嵌套层数过深"
-#: ../ex_eval.c:830
+#: ../ex_eval.c:844
msgid "E580: :endif without :if"
msgstr "E580: :endif 缺少对应的 :if"
-#: ../ex_eval.c:873
+#: ../ex_eval.c:874
msgid "E581: :else without :if"
msgstr "E581: :else 缺少对应的 :if"
-#: ../ex_eval.c:876
+#: ../ex_eval.c:877
msgid "E582: :elseif without :if"
msgstr "E582: :elseif 缺少对应的 :if"
-#: ../ex_eval.c:880
+#: ../ex_eval.c:881
msgid "E583: multiple :else"
msgstr "E583: 多个 :else"
-#: ../ex_eval.c:883
+#: ../ex_eval.c:884
msgid "E584: :elseif after :else"
msgstr "E584: :elseif 在 :else 后面"
-#: ../ex_eval.c:941
+#: ../ex_eval.c:951
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while/:for 嵌套层数过深"
-#: ../ex_eval.c:1028
+#: ../ex_eval.c:1022
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue 缺少对应的 :while 或 :for"
-#: ../ex_eval.c:1061
+#: ../ex_eval.c:1052
msgid "E587: :break without :while or :for"
msgstr "E587: :break 缺少对应的 :while 或 :for"
-#: ../ex_eval.c:1102
+#: ../ex_eval.c:1091
msgid "E732: Using :endfor with :while"
msgstr "E732: :while 以 :endfor 结尾"
-#: ../ex_eval.c:1104
+#: ../ex_eval.c:1093
msgid "E733: Using :endwhile with :for"
msgstr "E733: :for 以 :endwhile 结尾"
-#: ../ex_eval.c:1247
+#: ../ex_eval.c:1229
msgid "E601: :try nesting too deep"
msgstr "E601: :try 嵌套层数过深"
-#: ../ex_eval.c:1317
+#: ../ex_eval.c:1286
msgid "E603: :catch without :try"
msgstr "E603: :catch 缺少对应的 :try"
#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
+#. Just parse.
+#: ../ex_eval.c:1303
msgid "E604: :catch after :finally"
msgstr "E604: :catch 在 :finally 后面"
-#: ../ex_eval.c:1451
+#: ../ex_eval.c:1426
msgid "E606: :finally without :try"
msgstr "E606: :finally 缺少对应的 :try"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
+#: ../ex_eval.c:1445
msgid "E607: multiple :finally"
msgstr "E607: 多个 :finally"
-#: ../ex_eval.c:1571
+#: ../ex_eval.c:1540
msgid "E602: :endtry without :try"
msgstr "E602: :endtry 缺少对应的 :try"
-#: ../ex_eval.c:2026
+#: ../ex_eval.c:1984
msgid "E193: :endfunction not inside a function"
msgstr "E193: :endfunction 不在函数内"
-#: ../ex_getln.c:1643
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E788: 目前不允许编辑别的缓冲区"
-
-#: ../ex_getln.c:1656
-#, fuzzy
+#: ../ex_getln.c:2661
msgid "E811: Not allowed to change buffer information now"
-msgstr "E788: 目前不允许编辑别的缓冲区"
+msgstr "E811: 目前不允许更改缓冲区的信息"
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "tag 名"
+#: ../ex_getln.c:2939
+#, c-format
+msgid "E5408: Unable to get g:Nvim_color_cmdline callback: %s"
+msgstr ""
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " 类型 文件\n"
+#: ../ex_getln.c:2973
+#, c-format
+msgid "E5407: Callback has thrown an exception: %s"
+msgstr ""
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "选项 'history' 为零"
+#: ../ex_getln.c:2986
+msgid "E5400: Callback should return list"
+msgstr "E5400: 回调应返回列表"
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5046
-#, fuzzy, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
+#: ../ex_getln.c:2996
+#, c-format
+msgid "E5401: List item %i is not a List"
+msgstr "E5401: 列表项 %i 不是列表"
+
+#: ../ex_getln.c:3001
+#, c-format
+msgid "E5402: List item %i has incorrect length: %d /= 3"
msgstr ""
-"\n"
-"# %s 历史记录 (从新到旧):\n"
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5047
-#, fuzzy
-msgid "Command Line"
-msgstr "命令行"
+#: ../ex_getln.c:3011
+msgid "E5403: Chunk %i start %"
+msgstr ""
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5048
-#, fuzzy
-msgid "Search String"
-msgstr "查找字符串"
+#: ../ex_getln.c:3016
+msgid "E5405: Chunk %i start %"
+msgstr ""
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5049
-#, fuzzy
-msgid "Expression"
-msgstr "表达式"
+#: ../ex_getln.c:3032
+msgid "E5404: Chunk %i end %"
+msgstr ""
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5050
-#, fuzzy
-msgid "Input Line"
-msgstr "输入行"
+#: ../ex_getln.c:3039
+msgid "E5406: Chunk %i end %"
+msgstr ""
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar 超过命令长度"
+# do not translate to avoid writing Chinese in files
+#. Create empty command-line buffer.
+#: ../ex_getln.c:4223
+msgid "[Command Line]"
+msgstr ""
-#: ../ex_getln.c:5279
+#: ../ex_getln.c:4331
msgid "E199: Active window or buffer deleted"
msgstr "E199: 活动窗口或缓冲区已被删除"
-#: ../file_search.c:203
+#: ../file_search.c:185
msgid "E854: path too long for completion"
msgstr "E854: 补全用的路径太长"
-#: ../file_search.c:446
+#: ../file_search.c:419
#, c-format
msgid ""
"E343: Invalid path: '**[number]' must be at the end of the path or be "
"followed by '%s'."
msgstr "E343: 无效的路径: '**[number]' 必须在路径末尾或者后面接 '%s'。"
-#: ../file_search.c:1505
+#: ../file_search.c:1486
#, c-format
msgid "E344: Can't find directory \"%s\" in cdpath"
msgstr "E344: cdpath 中找不到目录 \"%s\""
-#: ../file_search.c:1508
+#: ../file_search.c:1489
#, c-format
msgid "E345: Can't find file \"%s\" in path"
msgstr "E345: 在路径中找不到文件 \"%s\""
-#: ../file_search.c:1512
+#: ../file_search.c:1494
#, c-format
msgid "E346: No more directory \"%s\" found in cdpath"
msgstr "E346: 在路径中找不到更多的文件 \"%s\""
-#: ../file_search.c:1515
+#: ../file_search.c:1497
#, c-format
msgid "E347: No more file \"%s\" found in path"
msgstr "E347: 在路径中找不到更多的文件 \"%s\""
-#: ../fileio.c:137
-#, fuzzy
+#: ../fileio.c:126
msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E135: *Filter* 自动命令不可以改变当前缓冲区"
+msgstr "E812: 自动命令改变了缓冲区或者缓冲区名称"
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "无效的文件名"
+#: ../fileio.c:128
+#, c-format
+msgid "E676: No matching autocommands for buftype=%s buffer"
+msgstr ""
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
+#: ../fileio.c:262 ../fileio.c:2499 ../fileio.c:2529
msgid "is a directory"
msgstr "是目录"
-#: ../fileio.c:397
+#: ../fileio.c:363
+msgid "Illegal file name"
+msgstr "无效的文件名"
+
+#: ../fileio.c:399
msgid "is not a file"
msgstr "不是文件"
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[新文件]"
-
-#: ../fileio.c:511
+#: ../fileio.c:490
msgid "[New DIRECTORY]"
msgstr "[新目录]"
-#: ../fileio.c:529 ../fileio.c:532
+#. libuv only returns -errno
+#. in Unix and in Windows
+#. open() does not set
+#. EOVERFLOW
+#: ../fileio.c:510 ../fileio.c:516
msgid "[File too big]"
msgstr "[文件过大]"
-#: ../fileio.c:534
+#: ../fileio.c:518
msgid "[Permission Denied]"
msgstr "[权限不足]"
-#: ../fileio.c:653
+#: ../fileio.c:661
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre 自动命令导致文件不可读"
-#: ../fileio.c:655
+#: ../fileio.c:663
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: *ReadPre 自动命令不允许改变当前缓冲区"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: 从标准输入读取...\n"
-
#. Re-opening the original file failed!
-#: ../fileio.c:909
+#: ../fileio.c:865
msgid "E202: Conversion made file unreadable!"
-msgstr "E202: 转换导致文件不可读"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
+msgstr "E202: 转换导致文件不可读!"
#. fifo
-#: ../fileio.c:1788
+#: ../fileio.c:1762
msgid "[fifo]"
msgstr "[fifo]"
#. or socket
-#: ../fileio.c:1794
+#: ../fileio.c:1766
msgid "[socket]"
msgstr "[socket]"
#. or character special
-#: ../fileio.c:1801
-#, fuzzy
+#: ../fileio.c:1771
msgid "[character special]"
-msgstr "1 个字符"
+msgstr "[字符设备]"
-#: ../fileio.c:1815
+#: ../fileio.c:1785
msgid "[CR missing]"
msgstr "[缺少 CR]'"
-#: ../fileio.c:1819
+#: ../fileio.c:1789
msgid "[long lines split]"
msgstr "[长行分割]"
-#: ../fileio.c:1823 ../fileio.c:3512
+#: ../fileio.c:1793 ../fileio.c:3427
msgid "[NOT converted]"
msgstr "[未转换]"
-#: ../fileio.c:1826 ../fileio.c:3515
+#: ../fileio.c:1796 ../fileio.c:3430
msgid "[converted]"
msgstr "[已转换]"
-#: ../fileio.c:1831
+#: ../fileio.c:1801
#, c-format
msgid "[CONVERSION ERROR in line %<PRId64>]"
msgstr "[第 %<PRId64> 行转换错误]"
-#: ../fileio.c:1835
+#: ../fileio.c:1805
#, c-format
msgid "[ILLEGAL BYTE in line %<PRId64>]"
msgstr "[第 %<PRId64> 行无效字符]"
-#: ../fileio.c:1838
+#: ../fileio.c:1808
msgid "[READ ERRORS]"
msgstr "[读错误]"
-#: ../fileio.c:2104
+#: ../fileio.c:2069
msgid "Can't find temp file for conversion"
msgstr "找不到用于转换的临时文件"
-#: ../fileio.c:2110
+#: ../fileio.c:2075
msgid "Conversion with 'charconvert' failed"
msgstr "'charconvert' 转换失败"
-#: ../fileio.c:2113
+#: ../fileio.c:2078
msgid "can't read output of 'charconvert'"
msgstr "无法读取 'charconvert' 的输出"
-#: ../fileio.c:2437
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "E676: 找不到 acwrite 缓冲区对应的自动命令"
+#: ../fileio.c:2116
+msgid "[New]"
+msgstr "[新]"
+
+#: ../fileio.c:2116
+msgid "[New File]"
+msgstr "[新文件]"
-#: ../fileio.c:2466
+#: ../fileio.c:2416
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: 自动命令删除或释放了要写入的缓冲区"
-#: ../fileio.c:2486
+#: ../fileio.c:2435
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: 自动命令意外地改变了行数"
-#: ../fileio.c:2548 ../fileio.c:2565
+#: ../fileio.c:2503 ../fileio.c:2517
msgid "is not a file or writable device"
msgstr "不是文件或可写的设备"
-#: ../fileio.c:2601
+#: ../fileio.c:2547
msgid "is read-only (add ! to override)"
msgstr "只读 (请加 ! 强制执行)"
-#: ../fileio.c:2886
-msgid "E506: Can't write to backup file (add ! to override)"
-msgstr "E506: 无法写入备份文件 (请加 ! 强制执行)"
-
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr "E507: 关闭备份文件出错 (请加 ! 强制执行)"
-
-#: ../fileio.c:2901
-msgid "E508: Can't read file for backup (add ! to override)"
-msgstr "E508: 无法读取文件以供备份 (请加 ! 强制执行)"
+#: ../fileio.c:2701 ../fileio.c:2852
+#, c-format
+msgid "E303: Unable to create directory \"%s\" for backup file: %s"
+msgstr "E303: 无法为备份文件创建目录 \"%s\":%s"
-#: ../fileio.c:2923
+#: ../fileio.c:2792 ../fileio.c:2813
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: 无法创建备份文件 (请加 ! 强制执行)"
-#: ../fileio.c:3008
+#: ../fileio.c:2912
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: 无法生成备份文件 (请加 ! 强制执行)"
#. Can't write without a tempfile!
-#: ../fileio.c:3121
+#: ../fileio.c:3015
msgid "E214: Can't find temp file for writing"
msgstr "E214: 找不到用于写入的临时文件"
-#: ../fileio.c:3134
+#: ../fileio.c:3031
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: 无法转换 (请加 ! 强制不转换写入)"
-#: ../fileio.c:3169
+#: ../fileio.c:3081
msgid "E166: Can't open linked file for writing"
msgstr "E166: 无法打开并写入链接文件"
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: 无法打开并写入文件"
-
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: 同步失败"
+#: ../fileio.c:3084
+#, c-format
+msgid "E212: Can't open file for writing: %s"
+msgstr "E212: 无法打开并写入文件:%s"
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: 关闭失败"
+#: ../fileio.c:3324
+#, c-format
+msgid "E512: Close failed: %s"
+msgstr "E512: 关闭失败:%s"
-#: ../fileio.c:3436
+#: ../fileio.c:3363
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr "E513: 写入错误,转换失败 (请将 'fenc' 置空以强制执行)"
-#: ../fileio.c:3441
-#, fuzzy, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr "E513: 写入错误,转换失败 (请将 'fenc' 置空以强制执行)"
+#. NOLINT(runtime/printf)
+#: ../fileio.c:3369
+msgid "E513: write error, conversion failed in line %"
+msgstr ""
-#: ../fileio.c:3448
+#: ../fileio.c:3376
msgid "E514: write error (file system full?)"
msgstr "E514: 写入错误 (文件系统已满?)"
-#: ../fileio.c:3506
+#: ../fileio.c:3420
msgid " CONVERSION ERROR"
msgstr " 转换错误"
-#: ../fileio.c:3509
+#: ../fileio.c:3423
#, fuzzy, c-format
msgid " in line %<PRId64>;"
msgstr "第 %<PRId64> 行"
-#: ../fileio.c:3519
+#: ../fileio.c:3434
msgid "[Device]"
msgstr "[设备]"
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[新]"
-
-#: ../fileio.c:3535
+#: ../fileio.c:3451
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
+#: ../fileio.c:3451
msgid " appended"
msgstr " 已追加"
-#: ../fileio.c:3537
+#: ../fileio.c:3453
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
+#: ../fileio.c:3453
msgid " written"
msgstr " 已写入"
-#: ../fileio.c:3579
+#: ../fileio.c:3496
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode: 无法保存原始文件"
-#: ../fileio.c:3602
+#: ../fileio.c:3515
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: Patchmode: 无法生成空的原始文件"
-#: ../fileio.c:3616
+#: ../fileio.c:3530
msgid "E207: Can't delete backup file"
msgstr "E207: 无法删除备份文件"
-#: ../fileio.c:3672
+#. Set highlight for error messages.
+#: ../fileio.c:3584
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2279,1309 +2715,1631 @@ msgstr ""
"\n"
"警告: 原始文件可能已丢失或损坏\n"
-#: ../fileio.c:3675
+#: ../fileio.c:3586
msgid "don't quit the editor until the file is successfully written!"
msgstr "在文件正确写入前请勿退出编辑器!"
-#: ../fileio.c:3795
+#: ../fileio.c:3721
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
+#: ../fileio.c:3721
msgid "[dos format]"
msgstr "[dos 格式]"
-#: ../fileio.c:3801
+#: ../fileio.c:3726
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
+#: ../fileio.c:3726
msgid "[mac format]"
msgstr "[mac 格式]"
-#: ../fileio.c:3807
+#: ../fileio.c:3731
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
+#: ../fileio.c:3731
msgid "[unix format]"
msgstr "[unix 格式]"
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 行,"
-
-#: ../fileio.c:3833
+#: ../fileio.c:3753
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> 行,"
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 个字符"
+msgid "%<PRId64> line, "
+msgid_plural "%<PRId64> lines, "
+msgstr[0] "%<PRId64> 行,"
-#: ../fileio.c:3838
+#: ../fileio.c:3757
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> 个字符"
+msgid "%<PRId64> byte"
+msgid_plural "%<PRId64> bytes"
+msgstr[0] "%<PRId64> 字节"
-#: ../fileio.c:3849
+#: ../fileio.c:3766
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
+#: ../fileio.c:3766
msgid "[Incomplete last line]"
msgstr "[最后一行不完整]"
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
+#. Don't overwrite messages here.
+#. Must give this prompt.
+#. Don't use emsg() here, don't want to flush the buffers.
+#: ../fileio.c:3779
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "警告: 此文件自读入后已发生变动!!!"
-#: ../fileio.c:3867
+#: ../fileio.c:3781
msgid "Do you really want to write to it"
msgstr "确实要写入吗"
-#: ../fileio.c:4648
+#: ../fileio.c:4629
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: 写入文件 \"%s\" 出错"
-#: ../fileio.c:4655
+#: ../fileio.c:4637
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: 关闭文件 \"%s\" 出错"
-#: ../fileio.c:4657
+#: ../fileio.c:4640
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: 读取文件 \"%s\" 出错"
-#: ../fileio.c:4883
+#: ../fileio.c:4859
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: FileChangedShell 自动命令删除了缓冲区"
-#: ../fileio.c:4894
+#: ../fileio.c:4876
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: 文件 \"%s\" 已经不存在"
-#: ../fileio.c:4906
+#: ../fileio.c:4888
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
"well"
msgstr "W12: 警告: 文件 \"%s\" 已变动,并且在 Vim 中的缓冲区也已变动"
-#: ../fileio.c:4907
+#: ../fileio.c:4889
msgid "See \":help W12\" for more info."
msgstr "进一步说明请见 \":help W12\""
-#: ../fileio.c:4910
+#: ../fileio.c:4891
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: 警告: 编辑开始后,文件 \"%s\" 已变动"
-#: ../fileio.c:4911
+#: ../fileio.c:4892
msgid "See \":help W11\" for more info."
msgstr "进一步说明请见 \":help W11\""
-#: ../fileio.c:4914
+#: ../fileio.c:4894
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: 警告: 编辑开始后,文件 \"%s\" 的模式已变动"
-#: ../fileio.c:4915
+#: ../fileio.c:4895
msgid "See \":help W16\" for more info."
msgstr "进一步说明请见 \":help W16\""
-#: ../fileio.c:4927
+#: ../fileio.c:4908
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: 警告: 编辑开始后,文件 \"%s\" 已被创建"
-#: ../fileio.c:4947
+#: ../fileio.c:4929
msgid "Warning"
msgstr "警告"
-#: ../fileio.c:4948
+#: ../fileio.c:4930
msgid ""
"&OK\n"
-"&Load File"
+"&Load File\n"
+"Load File &and Options"
msgstr ""
"确定(&O)\n"
-"加载文件(&L)"
+"加载文件(&L)\n"
+"加载文件和选项(&A)"
-#: ../fileio.c:5065
+#: ../fileio.c:5050
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: 无法为重新加载 \"%s\" 做准备"
-#: ../fileio.c:5078
+#: ../fileio.c:5062
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: 无法重新加载 \"%s\""
-#: ../fileio.c:5601
-msgid "--Deleted--"
-msgstr "--已删除--"
-
-#: ../fileio.c:5732
-#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr "自动删除自动命令: %s <buffer=%d>"
-
-#. the group doesn't exist
-#: ../fileio.c:5772
-#, c-format
-msgid "E367: No such group: \"%s\""
-msgstr "E367: 无此组: \"%s\""
-
-#: ../fileio.c:5897
-#, c-format
-msgid "E215: Illegal character after *: %s"
-msgstr "E215: * 后面有无效字符: %s"
-
-#: ../fileio.c:5905
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: 无此事件: %s"
-
-#: ../fileio.c:5907
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: 无此组或事件: %s"
-
-#. Highlight title
-#: ../fileio.c:6090
-msgid ""
-"\n"
-"--- Autocommands ---"
-msgstr ""
-"\n"
-"--- 自动命令 ---"
-
-#: ../fileio.c:6293
-#, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "E680: <buffer=%d>: 无效的缓冲区号 "
-
-#: ../fileio.c:6370
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: 不能对所有事件执行自动命令"
-
-#: ../fileio.c:6393
-msgid "No matching autocommands"
-msgstr "没有匹配的自动命令"
-
-#: ../fileio.c:6831
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: 自动命令嵌套层数过深"
-
-#: ../fileio.c:7143
-#, c-format
-msgid "%s Autocommands for \"%s\""
-msgstr "%s 自动命令 \"%s\""
-
-#: ../fileio.c:7149
-#, c-format
-msgid "Executing %s"
-msgstr "执行 %s"
-
-#: ../fileio.c:7211
-#, c-format
-msgid "autocommand %s"
-msgstr "自动命令 %s"
-
-#: ../fileio.c:7795
+#: ../fileio.c:5680
msgid "E219: Missing {."
msgstr "E219: 缺少 {。"
-#: ../fileio.c:7797
+#: ../fileio.c:5682
msgid "E220: Missing }."
msgstr "E220: 缺少 }。"
-#: ../fold.c:93
+#: ../fold.c:104
msgid "E490: No fold found"
msgstr "E490: 找不到折叠"
-#: ../fold.c:544
+#: ../fold.c:520
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: 不能在当前的 'foldmethod' 下创建折叠"
-#: ../fold.c:546
+#: ../fold.c:522
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: 不能在当前的 'foldmethod' 下删除折叠"
-#: ../fold.c:1784
+#: ../fold.c:1789
+#, c-format
+msgid "+--%3ld line folded"
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--已折叠 %3ld 行"
+
+#: ../fold.c:3275
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--已折叠 %3ld 行"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld 行: "
#. buffer has already been read
-#: ../getchar.c:273
+#: ../getchar.c:235
msgid "E222: Add to read buffer"
msgstr "E222: 添加到已读缓冲区中"
-#: ../getchar.c:2040
+#: ../getchar.c:2172
msgid "E223: recursive mapping"
msgstr "E223: 递归映射"
-#: ../getchar.c:2849
-#, c-format
-msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: 全局缩写 %s 已存在"
-
-#: ../getchar.c:2852
-#, c-format
-msgid "E225: global mapping already exists for %s"
-msgstr "E225: 全局映射 %s 已存在"
-
-#: ../getchar.c:2952
-#, c-format
-msgid "E226: abbreviation already exists for %s"
-msgstr "E226: 缩写 %s 已存在"
-
-#: ../getchar.c:2955
-#, c-format
-msgid "E227: mapping already exists for %s"
-msgstr "E227: 映射 %s 已存在"
-
-#: ../getchar.c:3008
-msgid "No abbreviation found"
-msgstr "找不到缩写"
-
-#: ../getchar.c:3010
-msgid "No mapping found"
-msgstr "找不到映射"
-
-#: ../getchar.c:3974
-msgid "E228: makemap: Illegal mode"
-msgstr "E228: makemap: 无效的模式"
-
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
+#. /< type of cmdline window or 0
+#. /< result of cmdline window or 0
+#. /< cmdline recursion level
+#: ../globals.h:815
msgid "--No lines in buffer--"
msgstr "--缓冲区无内容--"
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
+#. uncrustify:off
+#. The error messages that can be shared are included here.
+#. Excluded are errors that are only used once and debugging messages.
+#: ../globals.h:861
msgid "E470: Command aborted"
msgstr "E470: 命令被中止"
-#: ../globals.h:997
+#: ../globals.h:862
+msgid "E905: Cannot set this option after startup"
+msgstr "E905: 启动后不能设置这个选项"
+
+#: ../globals.h:863
+msgid "E903: Could not spawn API job"
+msgstr "E903: 无法生成 API 任务"
+
+#: ../globals.h:864
msgid "E471: Argument required"
msgstr "E471: 需要参数"
-#: ../globals.h:998
+#: ../globals.h:865
msgid "E10: \\ should be followed by /, ? or &"
msgstr "E10: \\ 后面应该跟有 /、? 或 &"
-#: ../globals.h:1000
+#: ../globals.h:866
msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
msgstr "E11: 在命令行窗口中无效;<CR> 执行,CTRL-C 退出"
-#: ../globals.h:1002
+#: ../globals.h:867
msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
msgstr "E12: 当前目录中的 exrc/vimrc 或 tag 查找中不允许此命令"
-#: ../globals.h:1003
+#: ../globals.h:868
+msgid "E169: Command too recursive"
+msgstr "E169: 命令递归层数过多"
+
+#: ../globals.h:869
msgid "E171: Missing :endif"
msgstr "E171: 缺少 :endif"
-#: ../globals.h:1004
+#: ../globals.h:870
msgid "E600: Missing :endtry"
msgstr "E600: 缺少 :endtry"
-#: ../globals.h:1005
+#: ../globals.h:871
msgid "E170: Missing :endwhile"
msgstr "E170: 缺少 :endwhile"
-#: ../globals.h:1006
+#: ../globals.h:872
msgid "E170: Missing :endfor"
msgstr "E170: 缺少 :endfor"
-#: ../globals.h:1007
+#: ../globals.h:873
msgid "E588: :endwhile without :while"
msgstr "E588: :endwhile 缺少对应的 :while"
-#: ../globals.h:1008
+#: ../globals.h:874
msgid "E588: :endfor without :for"
msgstr "E588: :endfor 缺少对应的 :for"
-#: ../globals.h:1009
+#: ../globals.h:875
msgid "E13: File exists (add ! to override)"
msgstr "E13: 文件已存在 (请加 ! 强制执行)"
-#: ../globals.h:1010
+#: ../globals.h:876
msgid "E472: Command failed"
msgstr "E472: 命令执行失败"
-#: ../globals.h:1011
+#: ../globals.h:877
msgid "E473: Internal error"
msgstr "E473: 内部错误"
-#: ../globals.h:1012
+#: ../globals.h:878
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: 内部错误: %s"
+
+#: ../globals.h:879
msgid "Interrupted"
msgstr "已中断"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: 无效的地址"
-
-#: ../globals.h:1014
+#: ../globals.h:880
msgid "E474: Invalid argument"
msgstr "E474: 无效的参数"
-#: ../globals.h:1015
+#: ../globals.h:881
#, c-format
msgid "E475: Invalid argument: %s"
msgstr "E475: 无效的参数: %s"
-#: ../globals.h:1016
+#: ../globals.h:882
+#, c-format
+msgid "E475: Invalid value for argument %s"
+msgstr "E475: 参数 %s 的值无效"
+
+#: ../globals.h:883
+#, c-format
+msgid "E475: Invalid value for argument %s: %s"
+msgstr "E475: 参数 %s 的值无效:%s"
+
+#: ../globals.h:884
+#, c-format
+msgid "E983: Duplicate argument: %s"
+msgstr "E983: 重复的参数:%s"
+
+#: ../globals.h:885
#, c-format
msgid "E15: Invalid expression: %s"
msgstr "E15: 无效的表达式: %s"
-#: ../globals.h:1017
+#: ../globals.h:886
msgid "E16: Invalid range"
msgstr "E16: 无效的范围"
-#: ../globals.h:1018
+#: ../globals.h:887
msgid "E476: Invalid command"
msgstr "E476: 无效的命令"
-#: ../globals.h:1019
+#: ../globals.h:888
#, c-format
msgid "E17: \"%s\" is a directory"
msgstr "E17: \"%s\" 是目录"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: 无效的滚动大小"
+#: ../globals.h:889
+msgid "E756: Spell checking is not possible"
+msgstr "E756: 拼写检查不可能"
-#: ../globals.h:1021
+#: ../globals.h:890
+msgid "E900: Invalid channel id"
+msgstr "E900: channel id 无效"
+
+#: ../globals.h:891
+msgid "E900: Invalid channel id: not a job"
+msgstr "E900: channel id 无效:不是任务"
+
+#: ../globals.h:892
msgid "E901: Job table is full"
-msgstr "E901: 任务表已经满"
+msgstr "E901: 任务表已满"
+
+#: ../globals.h:893
+#, c-format
+msgid "E903: Process failed to start: %s: \"%s\""
+msgstr "E903: 进程启动失败:%s:\"%s\""
+
+#: ../globals.h:894
+msgid "E904: channel is not a pty"
+msgstr "E664: channel 不是 pty"
+
+#: ../globals.h:895
+#, c-format
+msgid "E905: Couldn't open stdio channel: %s"
+msgstr "E905: 无法打开 stdio channel:%s"
+
+#: ../globals.h:896
+msgid "E906: invalid stream for channel"
+msgstr "E906: stream 对 channel 无效"
+
+#: ../globals.h:897
+msgid "E906: invalid stream for rpc channel, use 'rpc'"
+msgstr "E906: stream 对 rpc channel 无效,请使用 'rpc'"
+
+#: ../globals.h:898
+#, c-format
+msgid ""
+"E5210: dict key '%s' already set for buffered stream in channel %<PRIu64>"
+msgstr ""
-#: ../globals.h:1024
+#: ../globals.h:899
#, c-format
msgid "E364: Library call failed for \"%s()\""
msgstr "E364: 调用函数库 \"%s()\" 失败"
-#: ../globals.h:1026
+#: ../globals.h:900
+#, c-format
+msgid "E667: Fsync failed: %s"
+msgstr "E667: Fsync 失败:%s"
+
+#: ../globals.h:901
+#, c-format
+msgid "E739: Cannot create directory %s: %s"
+msgstr "E739: 无法创建目录 %s:%s"
+
+#: ../globals.h:902
msgid "E19: Mark has invalid line number"
msgstr "E19: 标记的行号无效"
-#: ../globals.h:1027
+#: ../globals.h:903
msgid "E20: Mark not set"
msgstr "E20: 没有设定标记"
-#: ../globals.h:1029
+#: ../globals.h:904
msgid "E21: Cannot make changes, 'modifiable' is off"
msgstr "E21: 不能修改,因为选项 'modifiable' 是关的"
-#: ../globals.h:1030
+#: ../globals.h:905
msgid "E22: Scripts nested too deep"
msgstr "E22: 脚本嵌套过深"
-#: ../globals.h:1031
+#: ../globals.h:906
msgid "E23: No alternate file"
msgstr "E23: 没有交替文件"
-#: ../globals.h:1032
+#: ../globals.h:907
msgid "E24: No such abbreviation"
msgstr "E24: 没有这个缩写"
-#: ../globals.h:1033
+#: ../globals.h:908
msgid "E477: No ! allowed"
msgstr "E477: 不能使用 \"!\""
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: 无法使用图形界面: 编译时没有启用"
-
-#: ../globals.h:1036
+#: ../globals.h:909
#, c-format
msgid "E28: No such highlight group name: %s"
msgstr "E28: 没有这个高亮群组名: %s"
-#: ../globals.h:1037
+#: ../globals.h:910
msgid "E29: No inserted text yet"
msgstr "E29: 没有插入过文字"
-#: ../globals.h:1038
+#: ../globals.h:911
msgid "E30: No previous command line"
msgstr "E30: 没有前一个命令行"
-#: ../globals.h:1039
+#: ../globals.h:912
msgid "E31: No such mapping"
msgstr "E31: 没有这个映射"
-#: ../globals.h:1040
+#: ../globals.h:913
msgid "E479: No match"
msgstr "E479: 没有匹配"
-#: ../globals.h:1041
+#: ../globals.h:914
#, c-format
msgid "E480: No match: %s"
msgstr "E480: 没有匹配: %s"
-#: ../globals.h:1042
+#: ../globals.h:915
msgid "E32: No file name"
msgstr "E32: 没有文件名"
-#: ../globals.h:1044
+#: ../globals.h:916
msgid "E33: No previous substitute regular expression"
msgstr "E33: 没有前一个替换正则表达式"
-#: ../globals.h:1045
+#: ../globals.h:917
msgid "E34: No previous command"
msgstr "E34: 没有前一个命令"
-#: ../globals.h:1046
+#: ../globals.h:918
msgid "E35: No previous regular expression"
msgstr "E35: 没有前一个正则表达式"
-#: ../globals.h:1047
+#: ../globals.h:919
msgid "E481: No range allowed"
msgstr "E481: 不能使用范围"
-#: ../globals.h:1048
+#: ../globals.h:920
msgid "E36: Not enough room"
msgstr "E36: 没有足够的空间"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: 无法创建文件 %s"
-
-#: ../globals.h:1050
+#: ../globals.h:921
msgid "E483: Can't get temp file name"
msgstr "E483: 无法获取临时文件名"
-#: ../globals.h:1051
+#: ../globals.h:922
#, c-format
msgid "E484: Can't open file %s"
msgstr "E484: 无法打开文件 %s"
-#: ../globals.h:1052
+#: ../globals.h:923
+#, c-format
+msgid "E484: Can't open file %s: %s"
+msgstr "E484: 无法打开文件 %s:%s"
+
+#: ../globals.h:924
#, c-format
msgid "E485: Can't read file %s"
msgstr "E485: 无法读取文件 %s"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: 已修改但尚未保存 (可用 ! 强制执行)"
-
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[已修改但尚未保存]\n"
-
-#: ../globals.h:1056
+#: ../globals.h:925
msgid "E38: Null argument"
msgstr "E38: 空的参数"
-#: ../globals.h:1057
+#: ../globals.h:926
msgid "E39: Number expected"
msgstr "E39: 此处需要数字"
-#: ../globals.h:1058
+#: ../globals.h:927
#, c-format
msgid "E40: Can't open errorfile %s"
msgstr "E40: 无法打开错误文件 %s"
-#: ../globals.h:1059
+#: ../globals.h:928
msgid "E41: Out of memory!"
msgstr "E41: 内存不足!"
-#: ../globals.h:1060
+#: ../globals.h:929
msgid "Pattern not found"
msgstr "找不到模式"
-#: ../globals.h:1061
+#: ../globals.h:930
#, c-format
msgid "E486: Pattern not found: %s"
msgstr "E486: 找不到模式: %s"
-#: ../globals.h:1062
+#: ../globals.h:931
msgid "E487: Argument must be positive"
msgstr "E487: 参数必须是正数"
-#: ../globals.h:1064
+#: ../globals.h:932
msgid "E459: Cannot go back to previous directory"
msgstr "E459: 无法回到前一个目录"
-#: ../globals.h:1066
+#: ../globals.h:934
msgid "E42: No Errors"
msgstr "E42: 没有错误"
-#: ../globals.h:1067
+#: ../globals.h:935
msgid "E776: No location list"
-msgstr "E776: 没有 location 列表"
+msgstr "E776: 没有位置列表"
-#: ../globals.h:1068
+#: ../globals.h:936
msgid "E43: Damaged match string"
msgstr "E43: 已损坏的匹配字符串"
-#: ../globals.h:1069
+#: ../globals.h:937
msgid "E44: Corrupted regexp program"
msgstr "E44: 已损坏的正则表达式程序"
-#: ../globals.h:1071
+#: ../globals.h:938
msgid "E45: 'readonly' option is set (add ! to override)"
msgstr "E45: 已设定选项 'readonly' (请加 ! 强制执行)"
-#: ../globals.h:1073
+#: ../globals.h:939
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: 不能改变只读变量 \"%s\""
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: %s= 的变量类型不正确"
-#: ../globals.h:1075
-#, fuzzy, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E46: 不能在 sandbox 中设定变量: \"%s\""
+#: ../globals.h:940
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: 变量名无效: %s"
-#: ../globals.h:1076
+#: ../globals.h:941
+msgid "E995: Cannot modify existing variable"
+msgstr "E995: 不能修改已有变量"
+
+#: ../globals.h:942
+#, c-format
+msgid "E46: Cannot change read-only variable \"%.*s\""
+msgstr "E46: 不能改变只读变量 \"%.*s\""
+
+#: ../globals.h:943
+msgid "E928: String required"
+msgstr "E928: 需要字符串"
+
+#: ../globals.h:944
+msgid "E715: Dictionary required"
+msgstr "E715: 需要字典"
+
+#: ../globals.h:945
+#, c-format
+msgid "E979: Blob index out of range: %<PRId64>"
+msgstr "E979: Blob 索引超出范围:%<PRId64>"
+
+#: ../globals.h:946
+msgid "E978: Invalid operation for Blob"
+msgstr "E978: 操作对 Blob 无效"
+
+#: ../globals.h:947
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: 函数 %s 的参数过多"
+
+#: ../globals.h:948
+#, c-format
+msgid "E716: Key not present in Dictionary: \"%s\""
+msgstr "E716: 字典中不存在键:\"%s\""
+
+#: ../globals.h:949
+msgid "E714: List required"
+msgstr "E714: 需要列表"
+
+#: ../globals.h:950
+msgid "E897: List or Blob required"
+msgstr "E897: 需要列表或 Blob"
+
+#: ../globals.h:951
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s 的参数必须是 List 或者 Dictionary"
+
+#: ../globals.h:952
+#, c-format
+msgid "E896: Argument of %s must be a List, Dictionary or Blob"
+msgstr "E896: %s 的参数必须是列表、字典或 Blob"
+
+#: ../globals.h:953
msgid "E47: Error while reading errorfile"
msgstr "E47: 读取错误文件失败"
-#: ../globals.h:1078
+#: ../globals.h:954
msgid "E48: Not allowed in sandbox"
msgstr "E48: 不允许在 sandbox 中使用"
-#: ../globals.h:1080
+#: ../globals.h:955
msgid "E523: Not allowed here"
msgstr "E523: 不允许在此使用"
-#: ../globals.h:1082
+#: ../globals.h:956
+msgid "E565: Not allowed to change text or change window"
+msgstr "E565: 不允许改变文本或窗口"
+
+#: ../globals.h:957
msgid "E359: Screen mode setting not supported"
msgstr "E359: 不支持设定屏幕模式"
-#: ../globals.h:1083
+#: ../globals.h:958
msgid "E49: Invalid scroll size"
-msgstr "E49: 无效的滚动大小"
+msgstr "E49: 滚动大小无效"
-#: ../globals.h:1084
+#: ../globals.h:959
msgid "E91: 'shell' option is empty"
-msgstr "E91: 选项 'shell' 为空"
+msgstr "E91: 'shell' 选项为空"
-#: ../globals.h:1085
+#: ../globals.h:960
msgid "E255: Couldn't read in sign data!"
msgstr "E255: 无法读取 sign 数据!"
-#: ../globals.h:1086
+#: ../globals.h:961
msgid "E72: Close error on swap file"
msgstr "E72: 交换文件关闭错误"
-#: ../globals.h:1087
+#: ../globals.h:962
msgid "E73: tag stack empty"
msgstr "E73: tag 堆栈为空"
-#: ../globals.h:1088
+#: ../globals.h:963
msgid "E74: Command too complex"
-msgstr "E74: 命令过复杂"
+msgstr "E74: 命令过于复杂"
-#: ../globals.h:1089
+#: ../globals.h:964
msgid "E75: Name too long"
msgstr "E75: 名字过长"
-#: ../globals.h:1090
+#: ../globals.h:965
msgid "E76: Too many ["
msgstr "E76: [ 过多"
-#: ../globals.h:1091
+#: ../globals.h:966
msgid "E77: Too many file names"
msgstr "E77: 文件名过多"
-#: ../globals.h:1092
+#: ../globals.h:967
msgid "E488: Trailing characters"
msgstr "E488: 多余的尾部字符"
-#: ../globals.h:1093
+#: ../globals.h:968
+#, c-format
+msgid "E488: Trailing characters: %s"
+msgstr "E488: 多余的尾部字符:%s"
+
+#: ../globals.h:969
msgid "E78: Unknown mark"
msgstr "E78: 未知的标记"
-#: ../globals.h:1094
+#: ../globals.h:970
msgid "E79: Cannot expand wildcards"
msgstr "E79: 无法扩展通配符"
-#: ../globals.h:1096
+#: ../globals.h:971
msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
msgstr "E591: 'winheight' 不能小于 'winminheight'"
-#: ../globals.h:1098
+#: ../globals.h:972
msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
msgstr "E592: 'winwidth' 不能小于 'winminwidth'"
-#: ../globals.h:1099
+#: ../globals.h:973
msgid "E80: Error while writing"
msgstr "E80: 写入出错"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "计数为零"
+#: ../globals.h:974
+msgid "E939: Positive count required"
+msgstr "E939: 需要正的计数"
-#: ../globals.h:1101
+#: ../globals.h:975
msgid "E81: Using <SID> not in a script context"
msgstr "E81: 在脚本环境外使用了 <SID>"
-#: ../globals.h:1102
+#: ../globals.h:976
#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: 内部错误: %s"
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: 缺少括号:%s"
-#: ../globals.h:1104
+#: ../globals.h:977
msgid "E363: pattern uses more memory than 'maxmempattern'"
msgstr "E363: 表达式的内存使用超出 'maxmempattern'"
-#: ../globals.h:1105
+#: ../globals.h:978
msgid "E749: empty buffer"
msgstr "E749: 空的缓冲区"
-#: ../globals.h:1108
+#: ../globals.h:979
+#, c-format
+msgid "E86: Buffer %<PRId64> does not exist"
+msgstr "E86: 缓冲区 %<PRId64> 不存在"
+
+#: ../globals.h:981
msgid "E682: Invalid search pattern or delimiter"
msgstr "E682: 无效的搜索表达式或分隔符"
-#: ../globals.h:1109
+#: ../globals.h:982
msgid "E139: File is loaded in another buffer"
msgstr "E139: 文件已在另一个缓冲区中被加载"
-#: ../globals.h:1110
+#: ../globals.h:983
#, c-format
msgid "E764: Option '%s' is not set"
msgstr "E764: 没有设定选项 '%s'"
-#: ../globals.h:1111
-#, fuzzy
+#: ../globals.h:984
msgid "E850: Invalid register name"
-msgstr "E354: 无效的寄存器名: '%s'"
+msgstr "E850: 寄存器名无效"
-#: ../globals.h:1114
+#: ../globals.h:985
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: '%s' 中未找到目录:\"%s\""
+
+#: ../globals.h:986
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: 自动命令导致了递归行为"
+
+#: ../globals.h:987
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: 菜单只在其它模式中存在"
+
+#: ../globals.h:988
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: 不能关闭自动命令窗口"
+
+#: ../globals.h:989
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s 的参数必须是列表"
+
+#: ../globals.h:990
+msgid "E519: Option not supported"
+msgstr "E519: 不支持该选项"
+
+#: ../globals.h:991
+msgid "E856: Filename too long"
+msgstr "E856: 文件名过长"
+
+#: ../globals.h:992
+msgid "E806: using Float as a String"
+msgstr "E806: 将浮点数当作字符串使用"
+
+#: ../globals.h:993
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: 目前不允许编辑别的缓冲区"
+
+#: ../globals.h:995
+#, c-format
+msgid "E5500: autocmd has thrown an exception: %s"
+msgstr "E5500: 自动命令抛出了异常:%s"
+
+#: ../globals.h:996
+msgid "E5520: <Cmd> mapping must end with <CR>"
+msgstr "E5520: <Cmd> 映射必须以 <CR> 结束"
+
+#: ../globals.h:998
+msgid "E5521: <Cmd> mapping must end with <CR> before second <Cmd>"
+msgstr ""
+
+#: ../globals.h:1000
+#, c-format
+msgid "E5555: API call: %s"
+msgstr ""
+
+#: ../globals.h:1002
+#, c-format
+msgid "E5560: %s must not be called in a lua loop callback"
+msgstr "E5560: Lua 循环回调中不能调用 %s"
+
+#: ../globals.h:1004
+msgid "E5601: Cannot close window, only floating window would remain"
+msgstr "E5601: 无法关闭窗口,不然就只剩下浮动窗口了"
+
+#: ../globals.h:1005
+msgid "E5602: Cannot exchange or rotate float"
+msgstr ""
+
+#: ../globals.h:1007
+msgid "E1155: Cannot define autocommands for ALL events"
+msgstr "E1155: 不能对所有事件定义自动命令"
+
+#: ../globals.h:1009
+msgid "E1240: Resulting text too long"
+msgstr "E1240: 得到的文本过长"
+
+#: ../globals.h:1011
+msgid "E1247: Line number out of range"
+msgstr "E1247: 行号超出范围"
+
+#: ../globals.h:1013
+msgid "E5248: Invalid character in group name"
+msgstr "E5248: 组名中含有无效字符"
+
+#: ../globals.h:1015
+msgid "E1249: Highlight group name too long"
+msgstr "E1249: 高亮组名称过长"
+
+#: ../globals.h:1018
+msgid "E5767: Cannot use :undo! to redo or move to a different undo branch"
+msgstr ""
+
+#: ../globals.h:1020
msgid "search hit TOP, continuing at BOTTOM"
msgstr "已查找到文件开头,再从结尾继续查找"
-#: ../globals.h:1115
+#: ../globals.h:1021
msgid "search hit BOTTOM, continuing at TOP"
msgstr "已查找到文件结尾,再从开头继续查找"
-#: ../hardcopy.c:240
+#: ../globals.h:1023
+msgid " line "
+msgstr " 行 "
+
+#: ../hardcopy.c:309
msgid "E550: Missing colon"
msgstr "E550: 缺少冒号"
-#: ../hardcopy.c:252
+#: ../hardcopy.c:326
msgid "E551: Illegal component"
msgstr "E551: 无效的部分"
-#: ../hardcopy.c:259
+#: ../hardcopy.c:335
msgid "E552: digit expected"
msgstr "E552: 应该要有数字"
-#: ../hardcopy.c:473
+#: ../hardcopy.c:561
#, c-format
msgid "Page %d"
msgstr "第 %d 页"
-#: ../hardcopy.c:597
+#: ../hardcopy.c:679
msgid "No text to be printed"
msgstr "没有要打印的文字"
-#: ../hardcopy.c:668
+#: ../hardcopy.c:744
#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "正在打印第 %d 页 (%d%%)"
+msgid "Printing page %d (%zu%%)"
+msgstr "正在打印第 %d 页 (%zu%%)"
-#: ../hardcopy.c:680
+#: ../hardcopy.c:753
#, c-format
msgid " Copy %d of %d"
-msgstr "复制 %d / %d"
+msgstr " 副本 %d / %d"
-#: ../hardcopy.c:733
+#: ../hardcopy.c:808
#, c-format
msgid "Printed: %s"
msgstr "已打印: %s"
-#: ../hardcopy.c:740
+#: ../hardcopy.c:815
msgid "Printing aborted"
msgstr "打印中止"
-#: ../hardcopy.c:1365
+#: ../hardcopy.c:1284
msgid "E455: Error writing to PostScript output file"
msgstr "E455: 写入 PostScript 输出文件出错"
-#: ../hardcopy.c:1747
+#: ../hardcopy.c:1642
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: 无法打开文件 \"%s\""
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
+#: ../hardcopy.c:1651 ../hardcopy.c:2372
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: 无法读取 PostScript 资源文件 \"%s\""
-#: ../hardcopy.c:1772
+#: ../hardcopy.c:1667
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: 文件 \"%s\" 不是 PostScript 资源文件"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
+#: ../hardcopy.c:1684 ../hardcopy.c:1701 ../hardcopy.c:1742
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: 文件 \"%s\" 不是已支持的 PostScript 资源文件"
-#: ../hardcopy.c:1856
+#: ../hardcopy.c:1755
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: \"%s\" 资源文件版本不正确"
-#: ../hardcopy.c:2225
+#: ../hardcopy.c:2128
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: 不兼容的多字节编码和字符集。"
-#: ../hardcopy.c:2238
+#: ../hardcopy.c:2140
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr "E674: printmbcharset 在多字节编码下不能为空"
-#: ../hardcopy.c:2254
+#: ../hardcopy.c:2156
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: 没有指定多字节打印的默认字体"
-#: ../hardcopy.c:2426
+#: ../hardcopy.c:2319
msgid "E324: Can't open PostScript output file"
msgstr "E324: 无法打开 PostScript 输出文件"
-#: ../hardcopy.c:2458
+#: ../hardcopy.c:2352
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: 无法打开文件 \"%s\""
-#: ../hardcopy.c:2583
+#: ../hardcopy.c:2476
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: 找不到 PostScript 资源文件 \"prolog.ps\""
-#: ../hardcopy.c:2593
+#: ../hardcopy.c:2488
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: 找不到 PostScript 资源文件 \"cidfont.ps\""
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
+#: ../hardcopy.c:2518 ../hardcopy.c:2537 ../hardcopy.c:2563
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: 找不到 PostScript 资源文件 \"%s.ps\""
-#: ../hardcopy.c:2654
+#: ../hardcopy.c:2553
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: 无法转换至打印编码 \"%s\""
-#: ../hardcopy.c:2877
+#: ../hardcopy.c:2773
msgid "Sending to printer..."
msgstr "发送到打印机……"
-#: ../hardcopy.c:2881
+#: ../hardcopy.c:2778
msgid "E365: Failed to print PostScript file"
msgstr "E365: 无法打印 PostScript 文件"
-#: ../hardcopy.c:2883
+#: ../hardcopy.c:2780
msgid "Print job sent."
msgstr "打印任务已被发送。"
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "添加一个新的数据库"
+#: ../help.c:79
+msgid "E478: Don't panic!"
+msgstr "E478: 不要慌!"
+
+#: ../help.c:120
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: 抱歉,没有 '%s' 的 %s 的说明"
+
+#: ../help.c:122
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: 抱歉,没有 %s 的说明"
+
+#: ../help.c:154
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "抱歉,找不到帮助文件 \"%s\""
+
+#: ../help.c:900 ../help.c:1094
+#, c-format
+msgid "E151: No match: %s"
+msgstr "E151: 没有匹配:%s"
+
+#: ../help.c:920
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: 无法打开并写入 %s"
+
+#: ../help.c:941
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: 无法打开并读取 %s"
+
+#: ../help.c:969
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: 在一种语言中混合了多种帮助文件编码: %s"
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "查询一个模式"
+#: ../help.c:1026
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Tag \"%s\" 在文件 %s/%s 中重复出现"
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "显示此信息"
+#: ../help.c:1185
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: 不是目录: %s"
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "结束一个连接"
+#: ../highlight.c:95
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: 使用了太多不同的高亮度属性"
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "重置所有连接"
+#: ../highlight_group.c:910
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: 找不到 highlight group: %s"
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "显示连接"
+#: ../highlight_group.c:933
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: 参数太少: \":highlight link %s\""
-#: ../if_cscope.c:101
+#: ../highlight_group.c:939
#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: 用法: cs[cope] %s"
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: 参数过多: \":highlight link %s\""
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "这个 cscope 命令不支持分割窗口。\n"
+#: ../highlight_group.c:966
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: 已设定组, 忽略 highlight link"
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: 用法: cstag <ident>"
+#: ../highlight_group.c:1039
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: 不该有的等号: %s"
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: 找不到 tag"
+#: ../highlight_group.c:1051 ../highlight_group.c:1099
+msgid "E423: Illegal argument"
+msgstr "E423: 无效的参数"
+
+#: ../highlight_group.c:1072
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: 缺少等号: %s"
-#: ../if_cscope.c:461
+#: ../highlight_group.c:1093
#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) 错误: %d"
+msgid "E417: missing argument: %s"
+msgstr "E417: 缺少参数: %s"
-#: ../if_cscope.c:551
+#: ../highlight_group.c:1127
#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s 不是目录或有效的 cscope 数据库"
+msgid "E418: Illegal value: %s"
+msgstr "E418: 不合法的值: %s"
+
+#: ../highlight_group.c:1175
+msgid "E419: FG color unknown"
+msgstr "E419: 错误的前景颜色"
+
+#: ../highlight_group.c:1183
+msgid "E420: BG color unknown"
+msgstr "E420: 错误的背景颜色"
-#: ../if_cscope.c:566
+#: ../highlight_group.c:1198
#, c-format
-msgid "Added cscope database %s"
-msgstr "添加了 cscope 数据库 %s"
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: 错误的颜色名称或数值: %s"
-#: ../if_cscope.c:616
+#: ../highlight_group.c:1330
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: 读取 cscope 连接 %<PRId64> 出错"
+msgid "E423: Illegal argument: %s"
+msgstr "E423: 无效的参数: %s"
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: 未知的 cscope 查找类型"
+#: ../highlight_group.c:1845
+msgid "E669: Unprintable character in group name"
+msgstr "E669: 组名中存在不可显示字符"
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: 无法创建 cscope 管道"
+#: ../highlight_group.c:1872
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: 高亮和语法组过多"
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: 无法对 cscope 进行 fork"
+#: ../input.c:232
+msgid "Type number and <Enter> or click with the mouse (q or empty cancels): "
+msgstr "输入数字并按 <Enter> 或点击鼠标(q 或空取消):"
-#: ../if_cscope.c:849
-#, fuzzy
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection 执行失败"
+#: ../input.c:235
+msgid "Type number and <Enter> (q or empty cancels): "
+msgstr "输入数字并按 <Enter>(q 或空取消):"
+
+#: ../insexpand.c:99
+msgid " Keyword completion (^N^P)"
+msgstr " 关键字补全 (^N^P)"
+
+#. CTRL_X_NORMAL, ^P/^N compl.
+#: ../insexpand.c:100
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " ^X 模式 (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+#. CTRL_X_SCROLL: depends on state
+#: ../insexpand.c:102
+msgid " Whole line completion (^L^N^P)"
+msgstr " 整行补全 (^L^N^P)"
+
+#: ../insexpand.c:103
+msgid " File name completion (^F^N^P)"
+msgstr " 文件名补全 (^F^N^P)"
+
+#: ../insexpand.c:104
+msgid " Tag completion (^]^N^P)"
+msgstr " Tag 补全 (^]^N^P)"
+
+#: ../insexpand.c:105
+msgid " Path pattern completion (^N^P)"
+msgstr " 头文件模式补全 (^N^P)"
+
+#: ../insexpand.c:106
+msgid " Definition completion (^D^N^P)"
+msgstr " 定义补全 (^D^N^P)"
+
+#. CTRL_X_FINISHED
+#: ../insexpand.c:108
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Dictionary 补全 (^K^N^P)"
+
+#: ../insexpand.c:109
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Thesaurus 补全 (^T^N^P)"
+
+#. CTRL_X_EVAL doesn't use msg.
+#: ../insexpand.c:110 ../insexpand.c:116
+msgid " Command-line completion (^V^N^P)"
+msgstr " 命令行补全 (^V^N^P)"
+
+#: ../insexpand.c:111
+msgid " User defined completion (^U^N^P)"
+msgstr " 用户自定义补全 (^U^N^P)"
+
+#: ../insexpand.c:112
+msgid " Omni completion (^O^N^P)"
+msgstr " 全能补全 (^O^N^P)"
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection 执行失败"
+#: ../insexpand.c:113
+msgid " Spelling suggestion (s^N^P)"
+msgstr " 拼写建议 (s^N^P)"
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen to_fp 失败"
+#: ../insexpand.c:114
+msgid " Keyword Local completion (^N^P)"
+msgstr " 关键字局部补全 (^N^P)"
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen fr_fp 失败"
+#: ../insexpand.c:190
+msgid "Hit end of paragraph"
+msgstr "已到段落结尾"
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: 无法生成 cscope 进程"
+#: ../insexpand.c:191
+msgid "E840: Completion function deleted text"
+msgstr "E840: 补全函数删除了文本"
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: 没有 cscope 连接"
+#: ../insexpand.c:469
+msgid "'dictionary' option is empty"
+msgstr "选项 'dictionary' 为空"
-#: ../if_cscope.c:1009
+#: ../insexpand.c:470
+msgid "'thesaurus' option is empty"
+msgstr "选项 'thesaurus' 为空"
+
+#: ../insexpand.c:1456
#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: cscopequickfix 标志 %c 对 %c 无效"
+msgid "Scanning dictionary: %s"
+msgstr "正在扫描 dictionary: %s"
-#: ../if_cscope.c:1058
+#: ../insexpand.c:1854
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (插入) Scroll (^E/^Y)"
+
+#: ../insexpand.c:1856
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (替换) Scroll (^E/^Y)"
+
+#: ../insexpand.c:2600
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() 只能在插入模式中使用"
+
+#. reset in msg_trunc_attr()
+#: ../insexpand.c:2881
#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: cscope 查询 %s %s 没有找到匹配的结果"
+msgid "Scanning: %s"
+msgstr "正在扫描: %s"
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "cscope 命令:\n"
+#. reset in msg_trunc_attr()
+#: ../insexpand.c:2912
+msgid "Scanning tags."
+msgstr "扫描标签."
-#: ../if_cscope.c:1150
-#, fuzzy, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %-30s (用法: %s)"
+#: ../insexpand.c:3465
+msgid "match in file"
+msgstr "在文件中匹配"
-#: ../if_cscope.c:1155
-msgid ""
-"\n"
-" a: Find assignments to this symbol\n"
-" c: Find functions calling this function\n"
-" d: Find functions called by this function\n"
-" e: Find this egrep pattern\n"
-" f: Find this file\n"
-" g: Find this definition\n"
-" i: Find files #including this file\n"
-" s: Find this C symbol\n"
-" t: Find this text string\n"
-msgstr ""
-"\n"
-" a: 搜索对此符号的赋值\n"
-" c: 搜索调用此函数的函数\n"
-" d: 搜索此函数调用的函数\n"
-" e: 搜索此 egrep 模式\n"
-" f: 搜索此文件\n"
-" g: 搜索此定义\n"
-" i: 搜索包含此文件的文件\n"
-" s: 搜索此 C 符号\n"
-" t: 搜索此文本字符串\n"
+#: ../insexpand.c:4198
+msgid " Adding"
+msgstr " 增加"
+
+#. showmode might reset the internal line pointers, so it must
+#. be called before line = ml_get(), or when this address is no
+#. longer needed. -- Acevedo.
+#: ../insexpand.c:4243
+msgid "-- Searching..."
+msgstr "-- 查找中..."
+
+#: ../insexpand.c:4263
+msgid "Back at original"
+msgstr "回到起点"
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: 重复的 cscope 数据库未被加入"
+#: ../insexpand.c:4266
+msgid "Word from other line"
+msgstr "另一行的词"
-#: ../if_cscope.c:1335
+#: ../insexpand.c:4269
+msgid "The only match"
+msgstr "唯一匹配"
+
+#: ../insexpand.c:4287
#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: 找不到 cscope 连接 %s"
+msgid "match %d of %d"
+msgstr "匹配 %d / %d"
-#: ../if_cscope.c:1364
+#: ../insexpand.c:4291
#, c-format
-msgid "cscope connection %s closed"
-msgstr "cscope 连接 %s 已关闭"
+msgid "match %d"
+msgstr "匹配 %d"
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: cs_manage_matches 严重错误"
+#: ../locale.c:227
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "当前的 %s语言: \"%s\""
+
+#: ../locale.c:243
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: 不能设定语言为 \"%s\""
-#: ../if_cscope.c:1693
+#: ../lua/converter.c:68 ../lua/converter.c:204 ../lua/converter.c:621
#, c-format
-msgid "Cscope tag: %s"
-msgstr "Cscope tag: %s"
+msgid "E1502: Lua failed to grow stack to %i"
+msgstr ""
-#: ../if_cscope.c:1711
+#: ../lua/converter.c:380
msgid ""
-"\n"
-" # line"
+"E5100: Cannot convert given lua table: table should either have a sequence "
+"of positive integer keys or contain only string keys"
msgstr ""
-"\n"
-" # 行 "
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "文件名 / 上下文 / 行\n"
+#: ../lua/converter.c:409 ../lua/converter.c:415
+msgid "E5101: Cannot convert given lua type"
+msgstr ""
-#: ../if_cscope.c:1809
+#: ../lua/converter.c:509 ../lua/converter.c:532
#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Cscope 错误: %s"
+msgid "E5102: Lua failed to grow stack to %i"
+msgstr ""
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "所有 cscope 数据库已被重置"
+#: ../lua/executor.c:333
+#, c-format
+msgid "Error executing vim.schedule lua callback: %.*s"
+msgstr ""
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "没有 cscope 连接\n"
+#: ../lua/executor.c:782
+msgid "E970: Failed to initialize lua interpreter\n"
+msgstr "E970: 无法初始化 Lua 解释器\n"
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid 数据库名 prepend path\n"
+#: ../lua/executor.c:787
+msgid "E970: Failed to initialize builtin lua modules\n"
+msgstr "E970: 无法初始化内置 Lua 模块\n"
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "未知的选项参数"
+#: ../lua/executor.c:972
+#, c-format
+msgid "E5114: Error while converting print argument #%i: %.*s"
+msgstr ""
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "编辑参数过多"
+#: ../lua/executor.c:1066
+#, fuzzy, c-format
+msgid "E5115: Error while loading debug string: %.*s"
+msgstr "E782: 当读取.sug 文件时错误"
+
+#: ../lua/executor.c:1068
+#, fuzzy, c-format
+msgid "E5116: Error while calling debug string: %.*s"
+msgstr "E782: 当读取.sug 文件时错误"
+
+#: ../lua/executor.c:1370
+#, fuzzy, c-format
+msgid "E5108: Error executing Lua function: %.*s"
+msgstr "E208: 写入文件 \"%s\" 出错"
+
+#: ../lua/executor.c:1390
+#, fuzzy, c-format
+msgid "E5107: Error loading lua %.*s"
+msgstr "E210: 读取文件 \"%s\" 出错"
+
+#: ../lua/executor.c:1397
+#, fuzzy, c-format
+msgid "E5108: Error executing lua %.*s"
+msgstr "E208: 写入文件 \"%s\" 出错"
+
+#: ../lua/executor.c:1539
+#, c-format
+msgid "Error executing lua callback: %.*s"
+msgstr ""
+
+#: ../lua/executor.c:1605
+msgid "cannot save undo information"
+msgstr "无法保存撤销信息"
+
+#: ../lua/executor.c:1631
+#, fuzzy, c-format
+msgid "E5109: Error loading lua: %.*s"
+msgstr "E209: 关闭文件 \"%s\" 出错"
-#: ../main.c:148
+#: ../lua/executor.c:1641
+#, fuzzy, c-format
+msgid "E5110: Error executing lua: %.*s"
+msgstr "E210: 读取文件 \"%s\" 出错"
+
+#: ../lua/executor.c:1653 ../lua/executor.c:1705
+#, fuzzy, c-format
+msgid "E5111: Error calling lua: %.*s"
+msgstr "E209: 关闭文件 \"%s\" 出错"
+
+#. 1
+#: ../lua/executor.c:1715
+#, fuzzy, c-format
+msgid "E5112: Error while creating lua chunk: %.*s"
+msgstr "E782: 当读取.sug 文件时错误"
+
+#: ../lua/executor.c:1726
+#, fuzzy, c-format
+msgid "E5113: Error while calling lua chunk: %.*s"
+msgstr "E782: 当读取.sug 文件时错误"
+
+#: ../lua/executor.c:1791
+#, c-format
+msgid "Error executing vim._expand_pat: %.*s"
+msgstr ""
+
+#: ../lua/executor.c:1928
+#, c-format
+msgid "Error executing vim.on_key Lua callback: %.*s"
+msgstr ""
+
+#: ../lua/executor.c:2149
+#, c-format
+msgid "Error executing Lua callback: %.*s"
+msgstr ""
+
+#. Error messages
+#: ../main.c:126
msgid "Argument missing after"
msgstr "缺少必要的参数"
-#: ../main.c:150
+#: ../main.c:127
msgid "Garbage after option argument"
msgstr "选项参数后的内容无效"
-#: ../main.c:152
+#: ../main.c:128
+msgid "Unknown option argument"
+msgstr "未知的选项参数"
+
+#: ../main.c:129
+msgid "Too many edit arguments"
+msgstr "编辑参数过多"
+
+#: ../main.c:131
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "\"+command\"、\"-c command\" 或 \"--cmd command\" 参数过多"
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "无效的参数"
-
-#: ../main.c:294
+#: ../main.c:1004
#, c-format
-msgid "%d files to edit\n"
-msgstr "还有 %d 个文件等待编辑\n"
+msgid "E5421: Failed to open stdin: %s"
+msgstr "E5421: 无法打开标准输入:%s"
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "试图再次打开脚本文件: \""
+#: ../main.c:1284
+#, c-format
+msgid "Attempt to open script file again: \"%s %s\"\n"
+msgstr "试图再次打开脚本文件:\"%s %s\"\n"
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "无法打开并读取: \""
+#: ../main.c:1303
+#, c-format
+msgid "Cannot open for reading: \"%s\": %s\n"
+msgstr "无法打开并读取:\"%s\":%s\n"
-#: ../main.c:1393
+#: ../main.c:1337
msgid "Cannot open for script output: \""
msgstr "无法打开并输出脚本: \""
-#: ../main.c:1622
-msgid "Vim: Warning: Output is not to a terminal\n"
-msgstr "Vim: 警告: 输出不是到终端(屏幕)\n"
-
-#: ../main.c:1624
-msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: 警告: 输入不是来自终端(键盘)\n"
+#: ../main.c:1388
+msgid "--embed conflicts with -es/-Es"
+msgstr ""
#. just in case..
-#: ../main.c:1891
+#: ../main.c:1795
msgid "pre-vimrc command line"
msgstr "pre-vimrc 命令行"
-#: ../main.c:1964
+#: ../main.c:1916
+#, c-format
+msgid "E5422: Conflicting configs: \"%s\" \"%s\""
+msgstr ""
+
+#: ../main.c:1985
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: 无法读取 \"%s\""
-#: ../main.c:2149
+#: ../main.c:2071
+#, fuzzy
msgid ""
"\n"
-"More info with: \"vim -h\"\n"
+"More info with \""
msgstr ""
"\n"
"更多信息请见: \"vim -h\"\n"
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[文件 ..] 编辑指定的文件"
+#. kill us with CTRL-C here, if you like
+#: ../main.c:2094
+msgid "Usage:\n"
+msgstr "用法:\n"
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- 从标准输入(stdin)读取文本"
+#: ../main.c:2095
+msgid " nvim [options] [file ...] Edit file(s)\n"
+msgstr " nvim [options] [文件 ..] 编辑指定的文件\n"
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tag 编辑 tag 定义处的文件"
+#: ../main.c:2096
+msgid " nvim [options] -t <tag> Edit file where tag is defined\n"
+msgstr " nvim [options] -t tag 编辑 tag 定义处的文件\n"
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] 编辑第一个出错处的文件"
+#: ../main.c:2097
+msgid " nvim [options] -q [errorfile] Edit file with first error\n"
+msgstr " nvim [options] -q [errorfile] 编辑第一个出错处的文件\n"
-#: ../main.c:2187
+#: ../main.c:2098
msgid ""
"\n"
-"\n"
-"Usage:"
+"Options:\n"
msgstr ""
"\n"
-"\n"
-"用法:"
+"选项:\n"
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [参数] "
+#: ../main.c:2099
+msgid " -- Only file names after this\n"
+msgstr " -- 在这以后只有文件名\n"
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" 或:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"参数:\n"
+#: ../main.c:2100
+msgid " + Start at end of file\n"
+msgstr " + 从文件末尾开始\n"
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\t在这以后只有文件名"
+#: ../main.c:2101
+msgid " --cmd <cmd> Execute <cmd> before any config\n"
+msgstr " --cmd <cmd> 加载任何配置前执行 <cmd>\n"
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\t不扩展通配符"
+#: ../main.c:2102
+msgid " +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"
+msgstr " +<cmd>, -c <cmd> 加载第一个配置和第一个文件后执行 <cmd>\n"
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi 模式 (同 \"vi\")"
+#: ../main.c:2104
+msgid " -b Binary mode\n"
+msgstr " -b 二进制模式\n"
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx 模式 (同 \"ex\")"
+#: ../main.c:2105
+msgid " -d Diff mode\n"
+msgstr " -d 差异模式\n"
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
+#: ../main.c:2106
+msgid " -e, -E Ex mode\n"
+msgstr " -e, -E Ex 模式\n"
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\t安静(批处理)模式 (只能与 \"ex\" 一起使用)"
+#: ../main.c:2107
+msgid " -es, -Es Silent (batch) mode\n"
+msgstr " -es, -Es 安静(批处理)模式\n"
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff 模式 (同 \"vimdiff\")"
+#: ../main.c:2108
+msgid " -h, --help Print this help message\n"
+msgstr " -h, --help 打印此帮助信息\n"
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\t容易模式 (同 \"evim\",无模式)"
+#: ../main.c:2109
+msgid " -i <shada> Use this shada file\n"
+msgstr " -i <shada> 使用这个 shada 文件\n"
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\t只读模式 (同 \"view\")"
+#: ../main.c:2110
+msgid " -m Modifications (writing files) not allowed\n"
+msgstr " -m 不可修改(写入文件)\n"
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\t不可修改(写入文件)"
+#: ../main.c:2111
+msgid " -M Modifications in text not allowed\n"
+msgstr " -M 文本不可修改\n"
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\t文本不可修改"
+#: ../main.c:2112
+msgid " -n No swap file, use memory only\n"
+msgstr " -n 不使用交换文件,只使用内存\n"
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\t二进制模式"
+#: ../main.c:2113
+msgid " -o[N] Open N windows (default: one per file)\n"
+msgstr " -o[N] 打开 N 个窗口(默认:每个文件一个)\n"
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp 模式"
+#: ../main.c:2114
+#, fuzzy
+msgid ""
+" -O[N] Open N vertical windows (default: one per file)\n"
+msgstr "-o[N]\t\t打开 N 个窗口 (默认值: 每个文件一个)"
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\t兼容传统的 Vi: 'compatible'"
+#: ../main.c:2115
+msgid " -p[N] Open N tab pages (default: one per file)\n"
+msgstr " -p[N] 打开 N 个标签页(默认:每个文件一个)\n"
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\t不完全兼容传统的 Vi: 'nocompatible'"
+#: ../main.c:2116
+msgid " -r, -L List swap files\n"
+msgstr " -r, -L 列出交换文件\n"
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr "-V[N][fname]\t\t详细 [level N] [log messages to fname]"
+#: ../main.c:2117
+msgid " -r <file> Recover edit state for this file\n"
+msgstr " -r <file> 恢复这个文件的编辑状态\n"
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\t调试模式"
+#: ../main.c:2118
+msgid " -R Read-only mode\n"
+msgstr " -R 只读模式\n"
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\t不使用交换文件,只使用内存"
+#: ../main.c:2119
+msgid " -S <session> Source <session> after loading the first file\n"
+msgstr " -S <session> 加载第一个文件后执行文件 <session>\n"
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\t列出交换文件并退出"
+#: ../main.c:2120
+msgid " -s <scriptin> Read Normal mode commands from <scriptin>\n"
+msgstr " -s <scriptin> 从文件 <scriptin> 读入正常模式的命令\n"
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (跟文件名)\t\t恢复崩溃的会话"
+#: ../main.c:2121
+msgid " -u <config> Use this config file\n"
+msgstr " -u <config> 使用此配置文件\n"
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\t同 -r"
+#: ../main.c:2122
+msgid " -v, --version Print version information\n"
+msgstr " -v, --version 打印版本信息\n"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\t以 Arabic 模式启动"
+#: ../main.c:2123
+msgid " -V[N][file] Verbose [level][file]\n"
+msgstr " -V[N][file] 啰嗦 [等级][文件]\n"
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\t以 Hebrew 模式启动"
+#: ../main.c:2125
+msgid " --api-info Write msgpack-encoded API metadata to stdout\n"
+msgstr " --api-info 将 msgpack 编码的 API 元数据写入标准输出\n"
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\t以 Farsi 模式启动"
+#: ../main.c:2126
+msgid ""
+" --clean \"Factory defaults\" (skip user config and plugins, "
+"shada)\n"
+msgstr ""
+" --clean \"出厂设置\"(跳过用户配置、plugin 和 shada)\n"
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\t设定终端类型为 <terminal>"
+#: ../main.c:2127
+msgid " --embed Use stdin/stdout as a msgpack-rpc channel\n"
+msgstr ""
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\t使用 <vimrc> 替代任何 .vimrc"
+#: ../main.c:2128
+msgid " --headless Don't start a user interface\n"
+msgstr " --headless 不要启动用户界面\n"
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\t不加载 plugin 脚本"
+#: ../main.c:2129
+msgid " --listen <address> Serve RPC API from this address\n"
+msgstr " --listen <address> 在这个地址提供 RPC API\n"
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-P[N]\t\t打开 N 个标签页 (默认值: 每个文件一个)"
+#: ../main.c:2130
+msgid " --noplugin Don't load plugins\n"
+msgstr " --noplugin 不加载 plugin 脚本\n"
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\t打开 N 个窗口 (默认值: 每个文件一个)"
+#: ../main.c:2131
+msgid " --remote[-subcommand] Execute commands remotely on a server\n"
+msgstr ""
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\t同 -o 但垂直分割"
+#: ../main.c:2132
+msgid " --server <address> Specify RPC server to send commands to\n"
+msgstr ""
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\t启动后跳到文件末尾"
+#: ../main.c:2133
+msgid " --startuptime <file> Write startup timing messages to <file>\n"
+msgstr " --startuptime <file> 将启动时间信息写入到文件 <file>\n"
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\t启动后跳到第 <lnum> 行"
+#: ../main.c:2134
+msgid ""
+"\n"
+"See \":help startup-options\" for all options.\n"
+msgstr ""
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <command>\t加载任何 vimrc 文件前执行 <command>"
+#: ../mapping.c:645
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: 全局缩写 %s 已存在"
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <command>\t\t加载第一个文件后执行 <command>"
+#: ../mapping.c:648
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: 全局映射 %s 已存在"
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <session>\t\t加载第一个文件后执行文件 <session>"
+#: ../mapping.c:762
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: 缩写 %s 已存在"
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\t从文件 <scriptin> 读入正常模式的命令"
+#: ../mapping.c:764
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: 映射 %s 已存在"
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <scriptout>\t将所有输入的命令追加到文件 <scriptout>"
+#: ../mapping.c:844
+msgid "No abbreviation found"
+msgstr "找不到缩写"
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <scriptout>\t将所有输入的命令写入到文件 <scriptout>"
+#: ../mapping.c:846
+msgid "No mapping found"
+msgstr "找不到映射"
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr "--startuptime <file>\t将启动时间信息写入到文件 <file>"
+#: ../mapping.c:1751
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: 无效的模式"
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\t使用 <viminfo> 取代 .viminfo"
+#: ../mapping.c:2181
+msgid "E460: entries missing in mapset() dict argument"
+msgstr "E460: mapset() dict 参数缺少项"
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h 或 --help\t打印帮助(本信息)并退出"
+#: ../mapping.c:2389
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': 找不到 %s 对应的字符"
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\t打印版本信息并退出"
+#: ../mapping.c:2409
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': 分号后有多余的字符: %s"
-#: ../mark.c:676
+#: ../mark.c:879
msgid "No marks set"
msgstr "没有设定标记"
-#: ../mark.c:678
+#: ../mark.c:881
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: 没有匹配 \"%s\" 的标记"
#. Highlight title
-#: ../mark.c:687
+#: ../mark.c:895
msgid ""
"\n"
"mark line col file/text"
@@ -3590,7 +4348,7 @@ msgstr ""
"标记 行 列 文件/文本"
#. Highlight title
-#: ../mark.c:789
+#: ../mark.c:1002
msgid ""
"\n"
" jump line col file/text"
@@ -3599,7 +4357,7 @@ msgstr ""
" 跳转 行 列 文件/文本"
#. Highlight title
-#: ../mark.c:831
+#: ../mark.c:1054
msgid ""
"\n"
"change line col text"
@@ -3607,109 +4365,159 @@ msgstr ""
"\n"
" 改变 行 列 文本"
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
+#: ../match.c:73
+#, c-format
+msgid "E799: Invalid ID: %<PRId64> (must be greater than or equal to 1)"
+msgstr "E799: ID 无效:%<PRId64>(必须大于等于 1)"
+
+#: ../match.c:85
+#, c-format
+msgid "E801: ID already taken: %<PRId64>"
+msgstr "E801: ID 已被使用:%<PRId64>"
+
+#: ../match.c:140
+#, c-format
+msgid "E5030: Empty list at position %d"
msgstr ""
-"\n"
-"# 文件标记:\n"
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
+#: ../match.c:182
+#, c-format
+msgid "E5031: List or number required at position %d"
+msgstr "E5031: 位置 %d 需要列表或整数"
+
+#: ../match.c:252
+#, c-format
+msgid "E802: Invalid ID: %<PRId64> (must be greater than or equal to 1)"
+msgstr "E802: 无效的 ID:%<PRId64>(必须大于等于 1)"
+
+#: ../match.c:263
+#, c-format
+msgid "E803: ID not found: %<PRId64>"
+msgstr "E803: 找不到 ID:%<PRId64>"
+
+#: ../match.c:978
+#, c-format
+msgid "E474: List item %d is either not a dictionary or an empty one"
msgstr ""
-"\n"
-"# 跳转列表 (从新到旧):\n"
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
+#: ../match.c:987
+#, c-format
+msgid "E474: List item %d is missing one of the required keys"
msgstr ""
-"\n"
-"# 文件内的标记历史记录 (从新到旧):\n"
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "缺少 '>'"
+#: ../match.c:1093
+#, c-format
+msgid "E798: ID is reserved for \":match\": %<PRId64>"
+msgstr "E798: ID 为 \":match\" 保留:%<PRId64>"
+
+#: ../match.c:1144
+#, c-format
+msgid "E798: ID is reserved for \"match\": %<PRId64>"
+msgstr "E798: ID 为 \"match\" 保留:%<PRId64>"
+
+#: ../mbyte.c:98
+#, c-format
+msgid "E1109: List item %d is not a List"
+msgstr "E1109: 列表项 %d 不是列表"
+
+#: ../mbyte.c:100
+#, c-format
+msgid "E1110: List item %d does not contain 3 numbers"
+msgstr "E1110: 列表项 %d 不包含三个整数"
-#: ../memfile.c:426
+#: ../mbyte.c:102
+#, c-format
+msgid "E1111: List item %d range invalid"
+msgstr "E1111: 列表项 %d 范围无效"
+
+#: ../mbyte.c:104
+#, c-format
+msgid "E1112: List item %d cell width invalid"
+msgstr "E1112: 列表项 %d 单元格宽度无效"
+
+#: ../mbyte.c:106
+#, c-format
+msgid "E1113: Overlapping ranges for 0x%lx"
+msgstr "E1113: 重叠范围为 0x%lx"
+
+#: ../mbyte.c:108
+msgid "E1114: Only values of 0x100 and higher supported"
+msgstr "E1114: 只支持 0x100 或更高的值"
+
+#: ../memfile.c:334
msgid "E293: block was not locked"
msgstr "E293: 块未被锁定"
-#: ../memfile.c:799
+#: ../memfile.c:582
msgid "E294: Seek error in swap file read"
msgstr "E294: 交换文件读取定位错误"
-#: ../memfile.c:803
+#: ../memfile.c:589
msgid "E295: Read error in swap file"
msgstr "E295: 交换文件读取错误"
-#: ../memfile.c:849
+#: ../memfile.c:641
msgid "E296: Seek error in swap file write"
msgstr "E296: 交换文件写入定位错误"
-#: ../memfile.c:865
+#: ../memfile.c:657
msgid "E297: Write error in swap file"
msgstr "E297: 交换文件写入错误"
-#: ../memfile.c:1036
+#: ../memfile.c:801
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: 交换文件已存在 (符号连接攻击?)"
-#: ../memline.c:318
+#: ../memline.c:288
msgid "E298: Didn't get block nr 0?"
msgstr "E298: 找不到块 0?"
-#: ../memline.c:361
+#: ../memline.c:328
msgid "E298: Didn't get block nr 1?"
msgstr "E298: 找不到块 1?"
-#: ../memline.c:377
+#: ../memline.c:342
msgid "E298: Didn't get block nr 2?"
msgstr "E298: 找不到块 2?"
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
+#: ../memline.c:424
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: 噢,交换文件不见了!!!"
-#: ../memline.c:477
+#: ../memline.c:430
msgid "E302: Could not rename swap file"
msgstr "E302: 无法重命名交换文件"
-#: ../memline.c:554
+#: ../memline.c:504
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: 无法打开 \"%s\" 的交换文件,恢复将不可能"
-#: ../memline.c:666
+#: ../memline.c:609
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): 找不到块 0?"
#. no swap files found
-#: ../memline.c:830
+#: ../memline.c:745
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: 找不到 %s 的交换文件"
-#: ../memline.c:839
+#: ../memline.c:755
msgid "Enter number of swap file to use (0 to quit): "
msgstr "请输入要使用的交换文件编号 (0 退出): "
-#: ../memline.c:879
+#: ../memline.c:791
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: 无法打开 %s"
-#: ../memline.c:897
+#: ../memline.c:805
msgid "Unable to read block 0 from "
msgstr "无法读取块 0: "
-#: ../memline.c:900
+#: ../memline.c:807
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3717,28 +4525,28 @@ msgstr ""
"\n"
"可能你没做过任何修改或是 Vim 还来不及更新交换文件。"
-#: ../memline.c:909
+#: ../memline.c:816
msgid " cannot be used with this version of Vim.\n"
msgstr " 不能在该版本的 Vim 中使用。\n"
-#: ../memline.c:911
+#: ../memline.c:818
msgid "Use Vim version 3.0.\n"
msgstr "使用 Vim 3.0。\n"
-#: ../memline.c:916
+#: ../memline.c:823
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s 看起来不像是 Vim 交换文件"
-#: ../memline.c:922
+#: ../memline.c:829
msgid " cannot be used on this computer.\n"
msgstr " 不能在这台电脑上使用。\n"
-#: ../memline.c:924
+#: ../memline.c:831
msgid "The file was created on "
msgstr "此文件创建于 "
-#: ../memline.c:928
+#: ../memline.c:835
msgid ""
",\n"
"or the file has been damaged."
@@ -3746,100 +4554,92 @@ msgstr ""
",\n"
"或是此文件已损坏。"
-#: ../memline.c:945
+#: ../memline.c:849
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr "已损坏(页面大小小于最小值)。\n"
-#: ../memline.c:974
+#: ../memline.c:879
#, c-format
msgid "Using swap file \"%s\""
msgstr "使用交换文件 \"%s\""
-#: ../memline.c:980
+#: ../memline.c:886
#, c-format
msgid "Original file \"%s\""
msgstr "原始文件 \"%s\""
-#: ../memline.c:995
+#: ../memline.c:899
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: 警告: 原始文件可能已被修改"
-#: ../memline.c:1061
+#: ../memline.c:958
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: 无法从 %s 读取块 1"
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1065
-#, fuzzy
+#: ../memline.c:962
msgid "???MANY LINES MISSING"
-msgstr "???缺少了太多行"
+msgstr ""
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1076
-#, fuzzy
+#: ../memline.c:974
msgid "???LINE COUNT WRONG"
-msgstr "???行数错误"
+msgstr ""
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1082
-#, fuzzy
+#: ../memline.c:980
msgid "???EMPTY BLOCK"
-msgstr "???空的块"
+msgstr ""
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1103
-#, fuzzy
+#: ../memline.c:1000
msgid "???LINES MISSING"
-msgstr "???缺少了一些行"
+msgstr ""
-#: ../memline.c:1128
+#: ../memline.c:1023
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: 块 1 ID 错误 (%s 不是交换文件?)"
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1133
-#, fuzzy
+#: ../memline.c:1028
msgid "???BLOCK MISSING"
-msgstr "???缺少块"
+msgstr ""
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1147
-#, fuzzy
+#: ../memline.c:1038
msgid "??? from here until ???END lines may be messed up"
-msgstr "??? 从这里到 ???END 的行可能已混乱"
+msgstr ""
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1164
-#, fuzzy
+#: ../memline.c:1052
msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? 从这里到 ???END 的行可能已被插入/删除过"
+msgstr ""
# do not translate to avoid writing Chinese in files
-#: ../memline.c:1181
-#, fuzzy
+#: ../memline.c:1071
msgid "???END"
-msgstr "???END"
+msgstr ""
-#: ../memline.c:1238
+#: ../memline.c:1125
msgid "E311: Recovery Interrupted"
msgstr "E311: 恢复已被中断"
-#: ../memline.c:1243
+#: ../memline.c:1129
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr "E312: 恢复时发生错误;请注意开头为 ??? 的行"
-#: ../memline.c:1245
+#: ../memline.c:1131
msgid "See \":help E312\" for more information."
msgstr "更多信息请见 \":help E312\""
-#: ../memline.c:1249
+#: ../memline.c:1135
msgid "Recovery completed. You should check if everything is OK."
msgstr "恢复完毕。请确定一切正常。"
-#: ../memline.c:1251
+#: ../memline.c:1136
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3847,71 +4647,74 @@ msgstr ""
"\n"
"(你可能想要将这个文件另存为别的文件名\n"
-#: ../memline.c:1252
-#, fuzzy
+#: ../memline.c:1137
msgid "and run diff with the original file to check for changes)"
-msgstr "再运行 diff 与原文件比较以检查是否有改变)\n"
+msgstr "再运行 diff 与原文件比较以检查是否有改变)"
-#: ../memline.c:1254
+#: ../memline.c:1139
msgid "Recovery completed. Buffer contents equals file contents."
msgstr "恢复完成。缓冲区内容与文件内容相同。"
-#: ../memline.c:1255
-#, fuzzy
+#: ../memline.c:1141
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
"\n"
msgstr ""
-"然后把 .swp 文件删掉。\n"
+"\n"
+"你现在可以删除 .swp 文件了。\n"
"\n"
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
+#: ../memline.c:1206
msgid "Swap files found:"
msgstr "找到交换文件:"
-#: ../memline.c:1446
+#: ../memline.c:1311
msgid " In current directory:\n"
msgstr " 位于当前目录:\n"
-#: ../memline.c:1448
+#: ../memline.c:1313
msgid " Using specified name:\n"
msgstr " 使用指定的名字:\n"
-#: ../memline.c:1450
+#: ../memline.c:1316
msgid " In directory "
msgstr " 位于目录 "
-#: ../memline.c:1465
+#: ../memline.c:1331
msgid " -- none --\n"
msgstr " -- 无 --\n"
-#: ../memline.c:1527
+#: ../memline.c:1429
msgid " owned by: "
msgstr " 所有者: "
-#: ../memline.c:1529
+#: ../memline.c:1431
msgid " dated: "
msgstr " 日期: "
-#: ../memline.c:1532 ../memline.c:3231
+#: ../memline.c:1433 ../memline.c:1436 ../memline.c:3084
msgid " dated: "
msgstr " 日期: "
-#: ../memline.c:1548
+#: ../memline.c:1448
msgid " [from Vim version 3.0]"
msgstr " [来自 Vim 版本 3.0]"
-#: ../memline.c:1550
+#: ../memline.c:1450
msgid " [does not look like a Vim swap file]"
msgstr " [不像是 Vim 交换文件]"
-#: ../memline.c:1552
+#: ../memline.c:1452
+msgid " [garbled strings (not nul terminated)]"
+msgstr ""
+
+#: ../memline.c:1454
msgid " file name: "
msgstr " 文件名: "
-#: ../memline.c:1558
+#: ../memline.c:1461
msgid ""
"\n"
" modified: "
@@ -3919,15 +4722,15 @@ msgstr ""
"\n"
" 修改过: "
-#: ../memline.c:1559
+#: ../memline.c:1462
msgid "YES"
msgstr "是"
-#: ../memline.c:1559
+#: ../memline.c:1462
msgid "no"
msgstr "否"
-#: ../memline.c:1562
+#: ../memline.c:1465
msgid ""
"\n"
" user name: "
@@ -3935,11 +4738,11 @@ msgstr ""
"\n"
" 用户名: "
-#: ../memline.c:1568
+#: ../memline.c:1471
msgid " host name: "
msgstr " 主机名: "
-#: ../memline.c:1570
+#: ../memline.c:1473
msgid ""
"\n"
" host name: "
@@ -3947,7 +4750,7 @@ msgstr ""
"\n"
" 主机名: "
-#: ../memline.c:1575
+#: ../memline.c:1479
msgid ""
"\n"
" process ID: "
@@ -3955,11 +4758,11 @@ msgstr ""
"\n"
" 进程 ID: "
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (仍在运行)"
+#: ../memline.c:1482
+msgid " (STILL RUNNING)"
+msgstr " (还!在!运!行!)"
-#: ../memline.c:1586
+#: ../memline.c:1488
msgid ""
"\n"
" [not usable on this computer]"
@@ -3967,97 +4770,97 @@ msgstr ""
"\n"
" [不能在本机上使用]"
-#: ../memline.c:1590
+#: ../memline.c:1492
msgid " [cannot be read]"
msgstr " [无法读取]"
-#: ../memline.c:1593
+#: ../memline.c:1496
msgid " [cannot be opened]"
msgstr " [无法打开]"
-#: ../memline.c:1698
+#: ../memline.c:1638
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: 无法保留,没有交换文件"
-#: ../memline.c:1747
+#: ../memline.c:1687
msgid "File preserved"
msgstr "文件已保留"
-#: ../memline.c:1749
+#: ../memline.c:1689
msgid "E314: Preserve failed"
msgstr "E314: 保留失败"
-#: ../memline.c:1819
+#: ../memline.c:1741
#, c-format
msgid "E315: ml_get: invalid lnum: %<PRId64>"
msgstr "E315: ml_get: 无效的 lnum: %<PRId64>"
-#: ../memline.c:1851
-#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
+#: ../memline.c:1777
+#, fuzzy, c-format
+msgid "E316: ml_get: cannot find line %<PRId64> in buffer %d %s"
msgstr "E316: ml_get: 找不到第 %<PRId64> 行"
-#: ../memline.c:2236
+#: ../memline.c:2128
msgid "E317: pointer block id wrong 3"
msgstr "E317: 指针块 id 错误 3"
-#: ../memline.c:2311
+#: ../memline.c:2202
msgid "stack_idx should be 0"
msgstr "stack_idx 应该是 0"
-#: ../memline.c:2369
+#: ../memline.c:2257
msgid "E318: Updated too many blocks?"
msgstr "E318: 更新了太多的块?"
-#: ../memline.c:2511
+#: ../memline.c:2432
msgid "E317: pointer block id wrong 4"
msgstr "E317: 指针块 id 错误 4"
-#: ../memline.c:2536
+#: ../memline.c:2458
msgid "deleted block 1?"
msgstr "删除了块 1?"
-#: ../memline.c:2707
+#: ../memline.c:2603
#, c-format
msgid "E320: Cannot find line %<PRId64>"
msgstr "E320: 找不到第 %<PRId64> 行"
-#: ../memline.c:2916
+#: ../memline.c:2795
msgid "E317: pointer block id wrong"
msgstr "E317: 指针块 id 错误"
-#: ../memline.c:2930
+#: ../memline.c:2810
msgid "pe_line_count is zero"
msgstr "pe_line_count 为零"
-#: ../memline.c:2955
+#: ../memline.c:2833
#, c-format
msgid "E322: line number out of range: %<PRId64> past the end"
msgstr "E322: 行号超出范围: %<PRId64> 超出结尾"
-#: ../memline.c:2959
+#: ../memline.c:2836
#, c-format
msgid "E323: line count wrong in block %<PRId64>"
msgstr "E323: 块 %<PRId64> 行数错误"
-#: ../memline.c:2999
+#: ../memline.c:2874
msgid "Stack size increases"
msgstr "堆栈大小增加"
-#: ../memline.c:3038
+#: ../memline.c:2906
msgid "E317: pointer block id wrong 2"
msgstr "E317: 指针块 id 错误 2"
-#: ../memline.c:3070
+#: ../memline.c:2938
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: \"%s\" 符号连接出现循环"
-#: ../memline.c:3221
+#: ../memline.c:3072
msgid "E325: ATTENTION"
msgstr "E325: 注意"
-#: ../memline.c:3222
+#: ../memline.c:3073
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4065,44 +4868,42 @@ msgstr ""
"\n"
"发现交换文件 \""
-#: ../memline.c:3226
+#: ../memline.c:3077
msgid "While opening file \""
msgstr "正在打开文件 \""
-#: ../memline.c:3239
+#: ../memline.c:3082
+#, fuzzy
+msgid " CANNOT BE FOUND"
+msgstr " 找不到"
+
+#: ../memline.c:3089
msgid " NEWER than swap file!\n"
msgstr " 比交换文件新!\n"
-#: ../memline.c:3244
-#, fuzzy
+#. Some of these messages are long to allow translation to
+#. other languages.
+#: ../memline.c:3094
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
" be careful not to end up with two different instances of the same\n"
-" file when making changes."
+" file when making changes. Quit, or continue with caution.\n"
msgstr ""
"\n"
"(1) 另一个程序可能也在编辑同一个文件。\n"
" 如果是这样,修改时请注意避免同一个文件产生两个不同的版本。\n"
-"\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " 退出,或小心地继续。\n"
+" 退出,或者小心地继续。\n"
-#: ../memline.c:3246
-#, fuzzy
+#: ../memline.c:3098
msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) 上次编辑此文件时崩溃。\n"
+msgstr "(2) 上次编辑此文件时崩溃。\n"
-#: ../memline.c:3247
+#: ../memline.c:3099
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " 如果是这样,请用 \":recover\" 或 \"vim -r "
-#: ../memline.c:3249
+#: ../memline.c:3101
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4110,11 +4911,11 @@ msgstr ""
"\"\n"
" 恢复修改的内容 (请见 \":help recovery\")。\n"
-#: ../memline.c:3250
+#: ../memline.c:3102
msgid " If you did this already, delete the swap file \""
msgstr " 如果你已经进行了恢复,请删除交换文件 \""
-#: ../memline.c:3252
+#: ../memline.c:3104
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4122,23 +4923,23 @@ msgstr ""
"\"\n"
" 以避免再看到此消息。\n"
-#: ../memline.c:3450 ../memline.c:3452
+#: ../memline.c:3270
+msgid "Found a swap file that is not useful, deleting it"
+msgstr "找到一个没用的交换文件,删了"
+
+#: ../memline.c:3296
msgid "Swap file \""
msgstr "交换文件 \""
-#: ../memline.c:3451 ../memline.c:3455
+#: ../memline.c:3297
msgid "\" already exists!"
msgstr "\" 已存在!"
-#: ../memline.c:3457
+#: ../memline.c:3309
msgid "VIM - ATTENTION"
msgstr "VIM - 注意"
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "交换文件已存在!"
-
-#: ../memline.c:3464
+#: ../memline.c:3312
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4152,7 +4953,7 @@ msgstr ""
"退出(&Q)\n"
"中止(&A)"
-#: ../memline.c:3467
+#: ../memline.c:3314
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4168,56 +4969,62 @@ msgstr ""
"退出(&Q)\n"
"中止(&A)"
-#.
-#. * Change the ".swp" extension to find another file that can be used.
-#. * First decrement the last char: ".swo", ".swn", etc.
-#. * If that still isn't enough decrement the last but one char: ".svz"
-#. * Can happen when editing many "No Name" buffers.
-#.
+#. Change the ".swp" extension to find another file that can be used.
+#. First decrement the last char: ".swo", ".swn", etc.
+#. If that still isn't enough decrement the last but one char: ".svz"
+#. Can happen when editing many "No Name" buffers.
#. ".s?a"
#. ".saa": tried enough, give up
-#: ../memline.c:3528
+#: ../memline.c:3370
msgid "E326: Too many swap files found"
msgstr "E326: 找到太多交换文件"
-#: ../memory.c:227
+#: ../memline.c:3386
+#, c-format
+msgid ""
+"E303: Unable to create directory \"%s\" for swap file, recovery impossible: "
+"%s"
+msgstr "E303: 无法为交换文件创建目录 \"%s\",恢复将不可能:%s"
+
+#: ../memory.c:197
+msgid "Vim: Data too large to fit into virtual memory space\n"
+msgstr "Vim:数据太大无法放入虚拟内存空间\n"
+
+#: ../memory.c:527
#, c-format
msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
msgstr "E342: 内存不足!(分配 %<PRIu64> 字节)"
-#: ../menu.c:62
+#: ../menu.c:52
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: 菜单项的某部分路径不是子菜单"
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: 菜单只在其它模式中存在"
-
-#: ../menu.c:64
+#: ../menu.c:53
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: 没有菜单 \"%s\""
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
+#: ../menu.c:310
msgid "E792: Empty menu name"
msgstr "E792: 空的菜单名称"
-#: ../menu.c:340
+#: ../menu.c:321
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: 菜单路径不能指向子菜单"
-#: ../menu.c:365
+#: ../menu.c:347
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: 不能把菜单项直接加到菜单栏中"
-#: ../menu.c:370
+#: ../menu.c:352
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: 分隔线不能是菜单路径的一部分"
+#. When there are no menus at all, the title still needs to be shown.
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
+#: ../menu.c:805
msgid ""
"\n"
"--- Menus ---"
@@ -4225,69 +5032,85 @@ msgstr ""
"\n"
"--- 菜单 ---"
-#: ../menu.c:1313
+#: ../menu.c:1568
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %s 模式中菜单未定义"
+
+#: ../menu.c:1588
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: 菜单路径必须指向菜单项"
-#: ../menu.c:1330
+#: ../menu.c:1608
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: 找不到菜单: %s"
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: %s 模式中菜单未定义"
-
-#: ../menu.c:1426
+#: ../menu.c:1670
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: 菜单路径必须指向子菜单"
-#: ../menu.c:1447
+#: ../menu.c:1694
msgid "E337: Menu not found - check menu names"
msgstr "E337: 找不到菜单 - 请检查菜单名称"
-#: ../message.c:423
+#: ../message.c:562
#, c-format
msgid "Error detected while processing %s:"
msgstr "处理 %s 时发生错误:"
-#: ../message.c:445
+#: ../message.c:584
#, c-format
msgid "line %4ld:"
msgstr "第 %4ld 行:"
-#: ../message.c:617
+#: ../message.c:777
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: 无效的寄存器名: '%s'"
-#: ../message.c:986
+#: ../message.c:1319
msgid "Interrupt: "
msgstr "已中断: "
-#: ../message.c:988
+#: ../message.c:1322
msgid "Press ENTER or type command to continue"
msgstr "请按 ENTER 或其它命令继续"
-#: ../message.c:1843
+#: ../message.c:1367
+#, c-format
+msgid "%ld more line"
+msgid_plural "%ld more lines"
+msgstr[0] "多了 %ld 行"
+
+#: ../message.c:1371
+#, c-format
+msgid "%ld line less"
+msgid_plural "%ld fewer lines"
+msgstr[0] "少了 %ld 行"
+
+#: ../message.c:1375
+msgid " (Interrupted)"
+msgstr " (已中断)"
+
+#: ../message.c:2473
#, c-format
msgid "%s line %<PRId64>"
msgstr "%s 第 %<PRId64> 行"
-#: ../message.c:2392
+#: ../message.c:3057
msgid "-- More --"
msgstr "-- 更多 --"
-#: ../message.c:2398
+#: ../message.c:3062
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " 空格/d/j: 屏幕/页/行 下翻,b/u/k: 上翻,q: 退出 "
-#: ../message.c:3021 ../message.c:3031
+#: ../message.c:3768 ../message.c:3779
msgid "Question"
msgstr "问题"
-#: ../message.c:3023
+#: ../message.c:3770
msgid ""
"&Yes\n"
"&No"
@@ -4295,7 +5118,7 @@ msgstr ""
"是(&Y)\n"
"否(&N)"
-#: ../message.c:3033
+#: ../message.c:3781
msgid ""
"&Yes\n"
"&No\n"
@@ -4305,7 +5128,7 @@ msgstr ""
"否(&N)\n"
"取消(&C)"
-#: ../message.c:3045
+#: ../message.c:3795
msgid ""
"&Yes\n"
"&No\n"
@@ -4319,206 +5142,123 @@ msgstr ""
"全部丢弃(&D)\n"
"取消(&C)"
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf() 的参数不足"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr "E807: 期盼浮点数作为printf()参数"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: printf() 的参数过多"
-
-#: ../misc1.c:2256
-msgid "W10: Warning: Changing a readonly file"
-msgstr "W10: 警告: 正在修改一个只读文件"
-
-#: ../misc1.c:2537
-#, fuzzy
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "请输入数字或点击鼠标 (<Enter> 取消): "
-
-#: ../misc1.c:2539
-#, fuzzy
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "请选择数字 (<Enter> 取消): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "多了 1 行"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "少了 1 行"
-
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "多了 %<PRId64> 行"
-
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "少了 %<PRId64> 行"
-
-#: ../misc1.c:2599
-msgid " (Interrupted)"
-msgstr " (已中断)"
-
-#: ../misc1.c:2635
-msgid "Beep!"
-msgstr "Beep!"
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "调用 shell 执行: \"%s\""
-
-#: ../normal.c:183
+#. nv_*(): functions called to handle Normal and Visual mode commands.
+#. n_*(): functions called to handle Normal mode commands.
+#. v_*(): functions called to handle Visual mode commands.
+#: ../normal.c:120
msgid "E349: No identifier under cursor"
msgstr "E349: 光标处没有识别字"
-#: ../normal.c:1866
-msgid "E774: 'operatorfunc' is empty"
-msgstr "E774: 'operatorfunc' 为空"
-
-#: ../normal.c:2637
-msgid "Warning: terminal cannot highlight"
-msgstr "警告: 你的终端不能显示高亮"
-
-#: ../normal.c:2807
+#: ../normal.c:1633
msgid "E348: No string under cursor"
msgstr "E348: 光标处没有字符串"
-#: ../normal.c:3937
+#: ../normal.c:2983
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: 不能在当前的 'foldmethod' 下删除 fold"
-#: ../normal.c:5897
+#: ../normal.c:4915
msgid "E664: changelist is empty"
msgstr "E664: 改变列表为空"
-#: ../normal.c:5899
+#: ../normal.c:4917
msgid "E662: At start of changelist"
msgstr "E662: 已在改变列表的开始处"
-#: ../normal.c:5901
+#: ../normal.c:4919
msgid "E663: At end of changelist"
msgstr "E663: 已在改变列表的末尾处"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "输入 :quit<Enter> 退出 Vim"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 行 %s 了 1 次"
+#: ../normal.c:6081
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Nvim"
+msgstr "输入 :qa! 并按 <Enter> 来放弃所有更改并退出 Nvim"
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 行 %s 了 %d 次"
+#: ../normal.c:6084
+msgid "Type :qa and press <Enter> to exit Nvim"
+msgstr "输入 :qa 并按 <Enter> 退出 Nvim"
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> 行 %s 了 1 次"
+#: ../ops.c:263
+#, fuzzy, c-format
+msgid "%<PRId64> line %sed %d time"
+msgid_plural "%<PRId64> line %sed %d times"
+msgstr[0] "%<PRId64> 行 %s 了 %d 次"
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> 行 %s 了 %d 次"
+#: ../ops.c:265
+#, fuzzy, c-format
+msgid "%<PRId64> lines %sed %d time"
+msgid_plural "%<PRId64> lines %sed %d times"
+msgstr[0] "%<PRId64> 行 %s 了 %d 次"
-#: ../ops.c:592
+#: ../ops.c:662
#, c-format
msgid "%<PRId64> lines to indent... "
msgstr "缩进 %<PRId64> 行…… "
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "缩进了 1 行 "
-
-#: ../ops.c:636
+#: ../ops.c:705
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "缩进了 %<PRId64> 行 "
+msgid "%<PRId64> line indented "
+msgid_plural "%<PRId64> lines indented "
+msgstr[0] "缩进了 %<PRId64> 行 "
-#: ../ops.c:938
+#: ../ops.c:1088
msgid "E748: No previously used register"
msgstr "E748: 没有前一个使用的寄存器"
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "无法复制;改为删除"
-
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "改变了 1 行"
-
-#: ../ops.c:1931
+#: ../ops.c:2122
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "改变了 %<PRId64> 行"
+msgid "%<PRId64> line changed"
+msgid_plural "%<PRId64> lines changed"
+msgstr[0] "改变了 %<PRId64> 行"
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "复制了 1 行的块"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "复制了 1 行"
-
-#: ../ops.c:2525
+#: ../ops.c:2786
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "复制了 %<PRId64> 行的块"
+msgid " into \"%c"
+msgstr "进 \"%c "
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "复制了 %<PRId64> 行"
+#: ../ops.c:2795
+#, fuzzy, c-format
+msgid "block of %<PRId64> line yanked%s"
+msgid_plural "block of %<PRId64> lines yanked%s"
+msgstr[0] "复制了 %<PRId64> 行的块"
+
+#: ../ops.c:2799
+#, fuzzy, c-format
+msgid "%<PRId64> line yanked%s"
+msgid_plural "%<PRId64> lines yanked%s"
+msgstr[0] "复制了 %<PRId64> 行"
-#: ../ops.c:2710
+#: ../ops.c:3148
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: 寄存器 %s 里没有东西"
#. Highlight title
-#: ../ops.c:3185
+#: ../ops.c:3779
msgid ""
"\n"
-"--- Registers ---"
+"Type Name Content"
msgstr ""
"\n"
-"--- 寄存器 ---"
+"类型 名称 内容"
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "无效的寄存器名"
+#: ../ops.c:4453
+#, c-format
+msgid "%<PRId64> lines changed"
+msgid_plural "%<PRId64> lines changed"
+msgstr[0] "改变了 %<PRId64> 行"
-#: ../ops.c:4533
+#: ../ops.c:5034
msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# 寄存器:\n"
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr "E883: 搜索模式和表达式寄存器只能包含一行文本"
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: 未知的寄存器类型 %d"
-
-#: ../ops.c:5089
+#: ../ops.c:5462
#, c-format
msgid "%<PRId64> Cols; "
msgstr "%<PRId64> 列; "
-#: ../ops.c:5097
+#: ../ops.c:5471
#, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
@@ -4527,7 +5267,7 @@ msgstr ""
"选择了 %s%<PRId64>/%<PRId64> 行; %<PRId64>/%<PRId64> 个词; %<PRId64>/"
"%<PRId64> 个字节"
-#: ../ops.c:5105
+#: ../ops.c:5480
#, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
@@ -4536,7 +5276,7 @@ msgstr ""
"选择了 %s%<PRId64>/%<PRId64> 行; %<PRId64>/%<PRId64> 个词; %<PRId64>/"
"%<PRId64> 个字符; %<PRId64>/%<PRId64> 个字节"
-#: ../ops.c:5123
+#: ../ops.c:5500
#, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
@@ -4545,7 +5285,7 @@ msgstr ""
"第 %s/%s 列; 第 %<PRId64>/%<PRId64> 行; 第 %<PRId64>/%<PRId64> 个词; 第 "
"%<PRId64>/%<PRId64> 个字节"
-#: ../ops.c:5133
+#: ../ops.c:5510
#, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
@@ -4554,156 +5294,67 @@ msgstr ""
"第 %s/%s 列; 第 %<PRId64>/%<PRId64> 行; 第 %<PRId64>/%<PRId64> 个词; 第 "
"%<PRId64>/%<PRId64> 个字符; 第 %<PRId64>/%<PRId64> 个字节"
-#: ../ops.c:5146
+#: ../ops.c:5528
#, c-format
msgid "(+%<PRId64> for BOM)"
msgstr ""
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=页 %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "感谢您选择 Vim"
+#: ../ops.c:5648
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' 为空"
-#. found a mismatch: skip
-#: ../option.c:2698
+#: ../option.c:107
msgid "E518: Unknown option"
msgstr "E518: 未知的选项"
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: 不支持该选项"
-
-#: ../option.c:2740
+#: ../option.c:109
msgid "E520: Not allowed in a modeline"
msgstr "E520: 不允许在 modeline 中使用"
-#: ../option.c:2815
+#: ../option.c:111
+msgid "E992: Not allowed in a modeline when 'modelineexpr' is off"
+msgstr "E992: 当 'modelineexpr' 关闭时不允许在 modeline 中使用"
+
+#: ../option.c:113
msgid "E846: Key code not set"
msgstr "E846: 未设置键位代码"
-#: ../option.c:2924
+#: ../option.c:115
msgid "E521: Number required after ="
msgstr "E521: = 后面需要数字"
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Termcap 里面找不到"
-
-#: ../option.c:3335
-#, c-format
-msgid "E539: Illegal character <%s>"
-msgstr "E539: 无效的字符 <%s>"
-
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: 不能设定 'term' 为空字符串"
-
-#: ../option.c:3885
-msgid "E589: 'backupext' and 'patchmode' are equal"
-msgstr "E589: 'backupext' 和 'patchmode' 相等"
-
-#: ../option.c:3964
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr "E834: 与'listchars'中的值发生冲突"
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr "E835: 与'fillchars'中的值冲突"
-
-#: ../option.c:4163
-msgid "E524: Missing colon"
-msgstr "E524: 缺少冒号"
-
-#: ../option.c:4165
-msgid "E525: Zero length string"
-msgstr "E525: 字符串长度为零"
-
-#: ../option.c:4220
-#, c-format
-msgid "E526: Missing number after <%s>"
-msgstr "E526: <%s> 后面缺少数字"
-
-#: ../option.c:4232
-msgid "E527: Missing comma"
-msgstr "E527: 缺少逗号"
-
-#: ../option.c:4239
-msgid "E528: Must specify a ' value"
-msgstr "E528: 必须指定一个 ' 值"
-
-#: ../option.c:4271
-msgid "E595: contains unprintable or wide character"
-msgstr "E595: 包含不可显示字符或宽字符"
-
-#: ../option.c:4469
-#, c-format
-msgid "E535: Illegal character after <%c>"
-msgstr "E535: <%c> 后面有无效的字符"
-
-#: ../option.c:4534
-msgid "E536: comma required"
-msgstr "E536: 需要逗号"
-
-#: ../option.c:4543
-#, c-format
-msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: 'commentstring' 必须为空或包含 %s"
-
-#: ../option.c:4928
-msgid "E540: Unclosed expression sequence"
-msgstr "E540: 没有结束的表达式序列"
-
-#: ../option.c:4932
-msgid "E541: too many items"
-msgstr "E541: 项目过多"
-
-#: ../option.c:4934
-msgid "E542: unbalanced groups"
-msgstr "E542: 错乱的组"
-
-#: ../option.c:5148
+#: ../option.c:117
msgid "E590: A preview window already exists"
msgstr "E590: 预览窗口已存在"
-#: ../option.c:5311
+#: ../option.c:2116
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr "W17: Arabic 需要 UTF-8,请执行 ':set encoding=utf-8'"
-#: ../option.c:5623
+#: ../option.c:2523
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: 至少需要 %d 行"
-#: ../option.c:5631
+#: ../option.c:2531
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: 至少需要 %d 列"
-#: ../option.c:6011
+#: ../option.c:3064 ../option.c:3616
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: 未知的选项: %s"
#. There's another character after zeros or the string
-#. * is empty. In both cases, we are trying to set a
-#. * num option using a string.
-#: ../option.c:6037
-#, fuzzy, c-format
+#. is empty. In both cases, we are trying to set a
+#. num option using a string.
+#: ../option.c:3092
+#, c-format
msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: = 后面需要数字"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- 终端编码 ---"
+msgstr "E521: 需要整数:&%s = '%s'"
-#: ../option.c:6151
+#: ../option.c:3198
msgid ""
"\n"
"--- Global option values ---"
@@ -4711,7 +5362,7 @@ msgstr ""
"\n"
"--- 全局选项值 ---"
-#: ../option.c:6153
+#: ../option.c:3200
msgid ""
"\n"
"--- Local option values ---"
@@ -4719,7 +5370,7 @@ msgstr ""
"\n"
"--- 局部选项值 ---"
-#: ../option.c:6155
+#: ../option.c:3202
msgid ""
"\n"
"--- Options ---"
@@ -4727,653 +5378,1070 @@ msgstr ""
"\n"
"--- 选项 ---"
-#: ../option.c:6816
+#: ../option.c:4096
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp 错误"
-#: ../option.c:7696
+#: ../optionstr.c:62
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: 没有结束的表达式序列"
+
+#: ../optionstr.c:64
+msgid "E542: unbalanced groups"
+msgstr "E542: 错乱的组"
+
+#: ../optionstr.c:66
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' 和 'patchmode' 相等"
+
+#: ../optionstr.c:68
+msgid "E595: 'showbreak' contains unprintable or wide character"
+msgstr "E595: 'showbreak' 包含不可显示字符或宽字符"
+
+#: ../optionstr.c:205
#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': 找不到 %s 对应的字符"
+msgid "E539: Illegal character <%s>"
+msgstr "E539: 无效的字符 <%s>"
-#: ../option.c:7715
+#: ../optionstr.c:337
#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': 分号后有多余的字符: %s"
+msgid "For option %s"
+msgstr "对选项 %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
+#: ../optionstr.c:959
+msgid "E524: Missing colon"
+msgstr "E524: 缺少冒号"
+
+#: ../optionstr.c:961
+msgid "E525: Zero length string"
+msgstr "E525: 字符串长度为零"
+
+#: ../optionstr.c:1040
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: <%s> 后面缺少数字"
+
+#: ../optionstr.c:1053
+msgid "E527: Missing comma"
+msgstr "E527: 缺少逗号"
+
+#: ../optionstr.c:1061
+msgid "E528: Must specify a ' value"
+msgstr "E528: 必须指定一个 ' 值"
+
+#: ../optionstr.c:1243
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: <%c> 后面有无效的字符"
+
+#: ../optionstr.c:1351
+msgid "E536: comma required"
+msgstr "E536: 需要逗号"
+
+#: ../optionstr.c:1359
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' 必须为空或包含 %s"
+
+# do not translate
+#: ../os/dl.c:53 ../os/dl.c:61
+#, c-format
+msgid "dlerror = \"%s\""
msgstr ""
-"\n"
-"无法执行 shell"
-#: ../os/shell.c:439
+#: ../os/fileio.c:434
+#, c-format
+msgid "E5420: Failed to write to file: %s"
+msgstr "E5420: 无法写入文件:%s"
+
+#: ../os/input.c:564
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim:读取输入时出错,正在退出……\n"
+
+#: ../os/shell.c:696
msgid ""
"\n"
"shell returned "
msgstr ""
"\n"
-"Shell 已返回"
+"Shell 返回了 "
-#: ../os_unix.c:465 ../os_unix.c:471
+#: ../os/shell.c:878
msgid ""
"\n"
-"Could not get security context for "
+"shell failed to start: "
msgstr ""
-
-#: ../os_unix.c:479
-msgid ""
"\n"
-"Could not set security context for "
-msgstr ""
+"Shell 无法启动:"
-# do not translate
-#: ../os_unix.c:1558 ../os_unix.c:1647
+#. Can happen if system() tries to send input to a shell command that was
+#. backgrounded (:call system("cat - &", "foo")). #3529 #5241
+#: ../os/shell.c:1316
#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
+msgid "E5677: Error writing input to shell-command: %s"
+msgstr "E5677: 向 Shell 命令输入时出错:%s"
+
+#: ../os/time.c:191
+msgid "%a %b %d %H:%M:%S %Y"
+msgstr "%Y-%m-%d %H:%M:%S"
-#: ../path.c:1449
+#: ../path.c:1711
#, c-format
msgid "E447: Can't find file \"%s\" in path"
msgstr "E447: 在路径中找不到文件 \"%s\""
-#: ../quickfix.c:359
+#: ../profile.c:307
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: 请先使用 \":profile start {fname}\""
+
+#: ../quickfix.c:246
+msgid "E553: No more items"
+msgstr "E553: 没有更多的项"
+
+#: ../quickfix.c:278
+msgid "E925: Current quickfix list was changed"
+msgstr "E925: 当前 quickfix 列表已改变"
+
+#: ../quickfix.c:280
+msgid "E926: Current location list was changed"
+msgstr "E926: 当前位置列表已改变"
+
+#. Each errorformat pattern can occur only once
+#: ../quickfix.c:382
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: 格式化字符串里有太多 %%%c "
-#: ../quickfix.c:371
+#: ../quickfix.c:389
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: 格式化字符串不应该出现 %%%c "
-#: ../quickfix.c:420
+#: ../quickfix.c:447
msgid "E374: Missing ] in format string"
-msgstr "E374: 格式化字符串里少了 ]"
+msgstr "E374: 格式化字符串中缺少 ]"
-#: ../quickfix.c:431
+#: ../quickfix.c:457
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: 格式化字符串里有不支持的 %%%c "
-#: ../quickfix.c:448
+#: ../quickfix.c:476
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: 格式化字符串开头里有不正确的 %%%c "
-#: ../quickfix.c:454
+#: ../quickfix.c:526
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: 格式化字符串里有不正确的 %%%c "
#. nothing found
-#: ../quickfix.c:477
+#: ../quickfix.c:629
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' 未设定"
-#: ../quickfix.c:695
+#: ../quickfix.c:1564
msgid "E379: Missing or empty directory name"
msgstr "E379: 找不到目录名称或是空的目录名称"
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: 没有更多的项"
+#: ../quickfix.c:2737
+msgid "E924: Current window was closed"
+msgstr "E924: 当前窗口已关闭"
-#: ../quickfix.c:1674
+#: ../quickfix.c:2809
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d / %d)%s%s: "
-#: ../quickfix.c:1676
+#: ../quickfix.c:2811
msgid " (line deleted)"
msgstr " (行已删除)"
-#: ../quickfix.c:1863
+#: ../quickfix.c:3252
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%s 错误列表 %d / %d;共 %d 个错误"
+
+#: ../quickfix.c:3287
msgid "E380: At bottom of quickfix stack"
msgstr "E380: Quickfix 堆栈底端"
-#: ../quickfix.c:1869
+#: ../quickfix.c:3293
msgid "E381: At top of quickfix stack"
msgstr "E381: Quickfix 堆栈顶端"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "错误列表 %d / %d;共 %d 个错误"
-
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: 无法写入,已设定选项 'buftype'"
+#: ../quickfix.c:3327
+msgid "No entries"
+msgstr "没有项目"
-#: ../quickfix.c:2812
+#: ../quickfix.c:5335
msgid "E683: File name missing or invalid pattern"
msgstr "E683: 缺少文件名或模式无效"
-#: ../quickfix.c:2911
+#: ../quickfix.c:5398
#, c-format
msgid "Cannot open file \"%s\""
msgstr "无法打开文件 \"%s\""
-#: ../quickfix.c:3429
+#: ../quickfix.c:6680
+msgid "cannot have both a list and a \"what\" argument"
+msgstr "不能同时有列表和 \"what\" 参数"
+
+#: ../quickfix.c:6796
msgid "E681: Buffer is not loaded"
msgstr "E681: 缓冲区未加载"
-#: ../quickfix.c:3487
+#: ../quickfix.c:6959
msgid "E777: String or List expected"
-msgstr "E777: 此处需要 String 或者 List"
+msgstr "E777: 此处需要字符串或列表"
+
+#: ../quickfix.c:7246
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: 动作无效:'%s'"
-#: ../regexp.c:359
+#: ../regexp.c:103
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: %s%%[] 中有无效的项"
-#: ../regexp.c:374
+#: ../regexp.c:107
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: %s[ 后缺少 ]"
-#: ../regexp.c:375
+#: ../regexp.c:108
+msgid "E944: Reverse range in character class"
+msgstr "E944: 字符类中有逆向范围"
+
+#: ../regexp.c:109
+msgid "E945: Range too large in character class"
+msgstr "E945: 字符类中的范围太大了"
+
+#: ../regexp.c:110
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: 不匹配的 %s%%("
-#: ../regexp.c:376
+#: ../regexp.c:111
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: 不匹配的 %s("
-#: ../regexp.c:377
+#: ../regexp.c:112
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: 不匹配的 %s)"
-#: ../regexp.c:378
+#: ../regexp.c:113
msgid "E66: \\z( not allowed here"
msgstr "E66: 此处不允许 \\z("
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: 此处不允许 \\z1 等"
+#: ../regexp.c:114
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: 此处不允许 \\z1 - \\z9"
-#: ../regexp.c:380
+#: ../regexp.c:115
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: %s%%[ 后缺少 ]"
-#: ../regexp.c:381
+#: ../regexp.c:116
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: 空的 %s%%[]"
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: 模式太长"
+#: ../regexp.c:117
+msgid "E956: Cannot use pattern recursively"
+msgstr "E956: 不能递归地使用模式"
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: 太多 \\z("
-
-#: ../regexp.c:1378
+#: ../regexp.c:119
#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: 太多 %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: 不匹配的 \\z("
+msgid "E1204: No Number allowed after .: '\\%%%c'"
+msgstr "E1204: . 后不能加整数: '\\%%%c'"
-#: ../regexp.c:1637
+#: ../regexp.c:121
#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: %s@ 后面有无效的字符"
+msgid "E1273: (NFA regexp) missing value in '\\%%%c'"
+msgstr "E1273: (NFA 正则) '\\%%%c' 中缺少值"
-#: ../regexp.c:1672
+#: ../regexp.c:123
#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: 太多复杂的 %s{...}s"
+msgid "E1281: Atom '\\%%#=%c' must be at the start of the pattern"
+msgstr "E1281: 原子 '\\%%#=%c' 必须位于模式的开头"
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: 嵌套的 %s*"
+#: ../regexp.c:124
+msgid "E1290: substitute nesting too deep"
+msgstr "E1290: 替换嵌套层数过深"
-#: ../regexp.c:1690
+#: ../regexp.c:498
#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: 嵌套的 %s%c"
+msgid "E654: missing delimiter after search pattern: %s"
+msgstr "E654: 搜索模式后缺少分割符:%s"
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: 不正确地使用 \\_"
+#: ../regexp.c:919
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: %s{...} 中语法错误"
-#: ../regexp.c:1850
+#: ../regexp.c:1294
#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c 前面无内容"
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA regexp) 不能重复 %s"
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: 无效的回引"
+#: ../regexp.c:2302
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr "E864: \\%#= 后面只能是0,1,或者2。自动引擎将会被使用"
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: \\z 后面有无效的字符"
+#: ../regexp.c:2383
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "为此模式切换到回溯正则引擎:"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
+#: ../runtime.c:266
#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: %s%%[dxouU] 后面有无效的字符"
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "正在查找 \"%s\",在 \"%s\" 中"
-#: ../regexp.c:2107
+#: ../runtime.c:303 ../runtime.c:436
#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: %s%% 后面有无效的字符"
+msgid "Searching for \"%s\""
+msgstr "正在查找 \"%s\""
-#: ../regexp.c:3017
+#: ../runtime.c:334
#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: %s{...} 中语法错误"
+msgid "not found in '%s': \"%s\""
+msgstr "在 '%s' 中找不到:\"%s\""
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "外部符合:\n"
+#: ../runtime.c:400
+#, c-format
+msgid "Searching for \"%s\" in runtime path"
+msgstr "正在查找 \"%s\",在 runtime path 中"
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-"E864: \\%#= 后面只能是0,1,或者2。自动引擎将会被使用"
+#: ../runtime.c:464
+#, c-format
+msgid "not found in runtime path: \"%s\""
+msgstr "在 runtime path 中找不到:\"%s\""
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (NFA) 过早地遇到了正则表达式的结尾"
+#: ../runtime.c:1912
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "不能执行目录: \"%s\""
-#: ../regexp_nfa.c:240
+#: ../runtime.c:1947
#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (NFA regexp) %c 放错了位置"
+msgid "could not source \"%s\""
+msgstr "不能执行 \"%s\""
-#: ../regexp_nfa.c:242
+#: ../runtime.c:1949
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA regexp) 不可用的字符类: %<PRId64>"
+msgid "line %<PRId64>: could not source \"%s\""
+msgstr "第 %<PRId64> 行: 不能执行 \"%s\""
-#: ../regexp_nfa.c:1261
+#: ../runtime.c:1963
#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (NFA) 未知的操作符 '\\z%c'"
+msgid "sourcing \"%s\""
+msgstr "执行 \"%s\""
-#: ../regexp_nfa.c:1387
+#: ../runtime.c:1965
#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) 未知的操作符 '\\%%%c'"
+msgid "line %<PRId64>: sourcing \"%s\""
+msgstr "第 %<PRId64> 行: 执行 \"%s\""
-#: ../regexp_nfa.c:1802
+#: ../runtime.c:2081
#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (NFA) 未知的操作符 '\\@%c'"
+msgid "finished sourcing %s"
+msgstr "结束执行 %s"
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr "E870: (NFA regexp) 读取重复限制时出错"
+#: ../runtime.c:2210
+msgid "modeline"
+msgstr "modeline"
-#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
-msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
-msgstr "E871: (NFA regexp) 不能多个跟多个!"
+#: ../runtime.c:2212
+msgid "--cmd argument"
+msgstr "--cmd 参数"
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (NFA regexp) 太多 '('"
+#: ../runtime.c:2214
+msgid "-c argument"
+msgstr "-c 参数"
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: 太多 \\z("
+#: ../runtime.c:2216
+msgid "environment variable"
+msgstr "环境变量"
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (NFA regexp) 未适当终止"
+#: ../runtime.c:2218
+msgid "error handler"
+msgstr "错误的处理程序"
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (NFA) 无法出栈!"
+#: ../runtime.c:2220
+msgid "changed window size"
+msgstr "改变了窗口大小"
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr "E875: (NFA regexp) (从后缀转换到 NFA 时),栈上遗留了太多状态"
+#: ../runtime.c:2222
+msgid "Lua"
+msgstr "Lua"
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (NFA regexp) 没有足够的空间存储整个NFA "
+#: ../runtime.c:2224
+#, c-format
+msgid "API client (channel id %<PRIu64>)"
+msgstr ""
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
+#: ../runtime.c:2227
+msgid "anonymous :source"
msgstr ""
-"无法打开临时日志文件进行写入,显示在 stderr 中..."
-#: ../regexp_nfa.c:4840
+#: ../runtime.c:2231
#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) 不能打开 %s !"
+msgid "anonymous :source (script id %d)"
+msgstr ""
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E214: 找不到用于写入的临时文件"
+#: ../runtime.c:2417
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: 警告: 错误的行分隔符,可能是少了 ^M"
-#: ../screen.c:7435
+#: ../runtime.c:2457
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: 在脚本文件外使用了 :scriptencoding"
+
+#: ../runtime.c:2482
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: 在脚本文件外使用了 :finish"
+
+#: ../screen.c:57
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: 与'listchars'中的值发生冲突"
+
+#: ../screen.c:58
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: 与'fillchars'中的值冲突"
+
+#: ../screen.c:521
+msgid " TERMINAL"
+msgstr " 终端"
+
+#: ../screen.c:523
msgid " VREPLACE"
msgstr " V-替换"
-#: ../screen.c:7437
+#: ../screen.c:525
msgid " REPLACE"
msgstr " 替换"
-#: ../screen.c:7440
+#: ../screen.c:528
msgid " REVERSE"
msgstr " 反向"
-#: ../screen.c:7441
+#: ../screen.c:530
msgid " INSERT"
msgstr " 插入"
-#: ../screen.c:7443
+#: ../screen.c:534
+msgid " (terminal)"
+msgstr " (终端)"
+
+#: ../screen.c:536
msgid " (insert)"
msgstr " (插入)"
-#: ../screen.c:7445
+#: ../screen.c:539
msgid " (replace)"
msgstr " (替换)"
-#: ../screen.c:7447
+#: ../screen.c:541
msgid " (vreplace)"
msgstr " (V-替换)"
-#: ../screen.c:7449
+#: ../screen.c:544
msgid " Hebrew"
-msgstr " Hebrew"
+msgstr " 希伯来文"
-#: ../screen.c:7454
+#: ../screen.c:548
msgid " Arabic"
-msgstr " Arabic"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (语言)"
+msgstr " 阿拉伯文"
-#: ../screen.c:7459
+#: ../screen.c:555
msgid " (paste)"
msgstr " (粘帖)"
-#: ../screen.c:7469
+#: ../screen.c:567
msgid " VISUAL"
msgstr " 可视"
-#: ../screen.c:7470
+#: ../screen.c:569
msgid " VISUAL LINE"
msgstr " 可视 行"
-#: ../screen.c:7471
+#: ../screen.c:571
msgid " VISUAL BLOCK"
msgstr " 可视 块"
-#: ../screen.c:7472
+#: ../screen.c:573
msgid " SELECT"
msgstr " 选择"
-#: ../screen.c:7473
+#: ../screen.c:575
msgid " SELECT LINE"
msgstr " 选择 行"
-#: ../screen.c:7474
+#: ../screen.c:577
msgid " SELECT BLOCK"
msgstr " 选择 块"
-#: ../screen.c:7486 ../screen.c:7541
+#: ../screen.c:673
msgid "recording"
msgstr "记录中"
-#: ../search.c:487
+#: ../search.c:563
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: 无效的查找字符串: %s"
-#: ../search.c:832
+#: ../search.c:928
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: 已查找到文件开头仍找不到 %s"
-#: ../search.c:835
+#: ../search.c:931
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: 已查找到文件结尾仍找不到 %s"
-#: ../search.c:1200
+#: ../search.c:1382
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: 在 ';' 后面应该有 '?' 或 '/'"
-#: ../search.c:4085
+#: ../search.c:3540
msgid " (includes previously listed match)"
msgstr " (包括上次列出符合项)"
#. cursor at status line
-#: ../search.c:4104
+#: ../search.c:3557
msgid "--- Included files "
msgstr "--- 包含文件 "
-#: ../search.c:4106
+#: ../search.c:3559
msgid "not found "
msgstr "找不到 "
-#: ../search.c:4107
+#: ../search.c:3561
msgid "in path ---\n"
msgstr "在路径 ---\n"
-#: ../search.c:4168
+#: ../search.c:3620
msgid " (Already listed)"
msgstr " (已列出)"
-#: ../search.c:4170
+#: ../search.c:3622
msgid " NOT FOUND"
msgstr " 找不到"
-#: ../search.c:4211
+#: ../search.c:3664
#, c-format
msgid "Scanning included file: %s"
msgstr "查找包含文件: %s"
-#: ../search.c:4216
+#: ../search.c:3669
#, c-format
msgid "Searching included file %s"
msgstr "查找包含的文件 %s"
-#: ../search.c:4405
+#: ../search.c:3862
msgid "E387: Match is on current line"
msgstr "E387: 当前行匹配"
-#: ../search.c:4517
+#: ../search.c:3988
msgid "All included files were found"
msgstr "所有包含文件都已找到"
-#: ../search.c:4519
+#: ../search.c:3990
msgid "No included files"
msgstr "没有包含文件"
-#: ../search.c:4527
+#: ../search.c:3998
msgid "E388: Couldn't find definition"
msgstr "E388: 找不到定义"
-#: ../search.c:4529
+#: ../search.c:4000
msgid "E389: Couldn't find pattern"
msgstr "E389: 找不到 pattern"
-#: ../search.c:4668
-#, fuzzy
-msgid "Substitute "
-msgstr "1 次替换,"
+#: ../shada.c:699
+msgid "too few bytes read"
+msgstr ""
+
+#: ../shada.c:721
+#, c-format
+msgid "System error while skipping in ShaDa file: %s"
+msgstr ""
+
+#: ../shada.c:725 ../shada.c:3271
+#, c-format
+msgid ""
+"Error while reading ShaDa file: last entry specified that it occupies "
+"%<PRIu64> bytes, but file ended earlier"
+msgstr ""
+
+#: ../shada.c:770
+#, c-format
+msgid "System error while closing ShaDa file: %s"
+msgstr ""
+
+#: ../shada.c:805
+#, c-format
+msgid "System error while writing ShaDa file: %s"
+msgstr ""
+
+#: ../shada.c:841
+#, c-format
+msgid "Reading ShaDa file \"%s\"%s%s%s%s"
+msgstr "读取 ShaDa 文件 \"%s\"%s%s%s%s"
+
+#: ../shada.c:843
+msgid " info"
+msgstr " 信息"
-#: ../search.c:4681
+#: ../shada.c:844
+msgid " marks"
+msgstr " 标记"
+
+#: ../shada.c:845
+msgid " oldfiles"
+msgstr " 旧文件"
+
+#: ../shada.c:846
+msgid " FAILED"
+msgstr " 失败"
+
+#: ../shada.c:852
+#, c-format
+msgid "System error while opening ShaDa file %s for reading: %s"
+msgstr ""
+
+#: ../shada.c:1536
+msgid "additional elements of ShaDa "
+msgstr ""
+
+#: ../shada.c:1556
+msgid "additional data of ShaDa "
+msgstr ""
+
+#: ../shada.c:1625
+#, c-format
+msgid "Failed to write variable %s"
+msgstr ""
+
+#: ../shada.c:1914
+#, c-format
+msgid ""
+"Failed to parse ShaDa file due to a msgpack parser error at position "
+"%<PRIu64>"
+msgstr ""
+
+#: ../shada.c:1929
+#, c-format
+msgid ""
+"Failed to parse ShaDa file: incomplete msgpack string at position %<PRIu64>"
+msgstr ""
+
+#: ../shada.c:1936
+#, c-format
+msgid ""
+"Failed to parse ShaDa file: extra bytes in msgpack string at position "
+"%<PRIu64>"
+msgstr ""
+
+#: ../shada.c:2989
+#, c-format
+msgid ""
+"System error while opening ShaDa file %s for reading to merge before writing "
+"it: %s"
+msgstr ""
+
+#. Tried names from .tmp.a to .tmp.z, all failed. Something must be
+#. wrong then.
+#: ../shada.c:3021
+#, c-format
+msgid "E138: All %s.tmp.X files exist, cannot write ShaDa file!"
+msgstr ""
+
+#: ../shada.c:3032
+#, c-format
+msgid "System error while opening temporary ShaDa file %s for writing: %s"
+msgstr ""
+
+#: ../shada.c:3047
+#, c-format
+msgid "Failed to create directory %s for writing ShaDa file: %s"
+msgstr ""
+
+#: ../shada.c:3061
+#, c-format
+msgid "System error while opening ShaDa file %s for writing: %s"
+msgstr ""
+
+#: ../shada.c:3077
+#, c-format
+msgid "Writing ShaDa file \"%s\""
+msgstr "写入 ShaDa 文件 \"%s\""
+
+#: ../shada.c:3104
+#, c-format
+msgid "E137: ShaDa file is not writable: %s"
+msgstr "E137: ShaDa 文件不可写入:%s"
+
+#: ../shada.c:3116
+#, c-format
+msgid "Failed setting uid and gid for file %s: %s"
+msgstr "无法为文件 %s 设置 uid 和 gid:%s"
+
+#: ../shada.c:3124
+#, c-format
+msgid "Can't rename ShaDa file from %s to %s!"
+msgstr ""
+
+#: ../shada.c:3132
+#, c-format
+msgid "Did not rename %s because %s does not look like a ShaDa file"
+msgstr ""
+
+#: ../shada.c:3135
+#, c-format
+msgid "Did not rename %s to %s because there were errors during writing it"
+msgstr ""
+
+#: ../shada.c:3141
+#, c-format
+msgid "Do not forget to remove %s or rename it manually to %s."
+msgstr ""
+
+#: ../shada.c:3267
+#, c-format
+msgid "System error while reading ShaDa file: %s"
+msgstr ""
+
+#: ../shada.c:3304
+#, c-format
+msgid "System error while reading integer from ShaDa file: %s"
+msgstr ""
+
+#: ../shada.c:3308
+#, c-format
+msgid ""
+"Error while reading ShaDa file: expected positive integer at position "
+"%<PRIu64>, but got nothing"
+msgstr ""
+
+#: ../shada.c:3335
+#, c-format
+msgid ""
+"Error while reading ShaDa file: expected positive integer at position "
+"%<PRIu64>"
+msgstr ""
+
+#: ../shada.c:3530
+#, c-format
+msgid ""
+"Error while reading ShaDa file: there is an item at position %<PRIu64> that "
+"is stated to be too long"
+msgstr ""
+
+#. kSDItemUnknown cannot possibly pass that far because it is -1 and that
+#. will fail in msgpack_read_uint64. But kSDItemMissing may and it will
+#. otherwise be skipped because (1 << 0) will never appear in flags.
+#: ../shada.c:3544
#, c-format
msgid ""
+"Error while reading ShaDa file: there is an item at position %<PRIu64> that "
+"must not be there: Missing items are for internal uses only"
+msgstr ""
+
+#: ../shada.c:3914
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry that is not a dictionary"
+msgstr ""
+
+#: ../shada.c:3941
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry with invalid line number"
+msgstr ""
+
+#: ../shada.c:3948
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry with invalid column number"
+msgstr ""
+
+#: ../shada.c:3955
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry that does not have a file name"
+msgstr ""
+
+#: ../sign.c:292
+msgid "[Deleted]"
+msgstr "[已删除]"
+
+#: ../sign.c:709
+msgid ""
"\n"
-"# Last %sSearch Pattern:\n"
-"~"
+"--- Signs ---"
msgstr ""
"\n"
-"# 最后 %s搜索模式:\n"
-"~"
+"--- Signs ---"
+
+#: ../sign.c:718
+#, c-format
+msgid "Signs for %s:"
+msgstr "%s 的 Signs:"
+
+#: ../sign.c:730
+#, c-format
+msgid " group=%s"
+msgstr " 组=%s"
+
+#: ../sign.c:736
+#, c-format
+msgid " line=%ld id=%d%s name=%s priority=%d"
+msgstr " 行=%ld id=%d%s 名称=%s 优先级=%d"
+
+#: ../sign.c:879
+msgid "E612: Too many signs defined"
+msgstr "E612: Signs 定义过多"
+
+#: ../sign.c:933
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: 无效的 sign 文字: %s"
+
+#: ../sign.c:1036 ../sign.c:1053 ../sign.c:1085
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: 未知的 sign: %s"
+
+#: ../sign.c:1114
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: 不可能改变标号 %s"
+
+#: ../sign.c:1161
+msgid "E159: Missing sign number"
+msgstr "E159: 缺少 sign 号"
+
+#: ../sign.c:1171
+#, c-format
+msgid "E157: Invalid sign ID: %<PRId64>"
+msgstr "E157: 无效的 sign ID: %<PRId64>"
-#: ../spell.c:951
+#: ../sign.c:1182
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: 无法跳转到没有名字的缓冲区"
+
+#: ../sign.c:1476
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: 未知的 sign 命令: %s"
+
+#: ../sign.c:1489
+msgid "E156: Missing sign name"
+msgstr "E156: 缺少 sign 名称"
+
+#: ../sign.c:1676
+msgid " (not supported)"
+msgstr " (不支持)"
+
+#. mode values for find_word
+#. find word case-folded
+#. find keep-case word
+#. find word after prefix
+#. find case-folded compound word
+#. find keep-case compound word
+#: ../spell.c:194
msgid "E759: Format error in spell file"
msgstr "E759: 拼写文件格式错误"
-#: ../spell.c:952
+#: ../spell.c:1553
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "警告: 找不到单词列表 \"%s.%s.spl\" or \"%s.ascii.spl\""
+
+#: ../spell.c:1968
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: SpellFileMissing 自动命令删除了缓冲区"
+
+#. This is probably an error. Give a warning and
+#. accept the words anyway.
+#: ../spell.c:1992
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "警告: 区域 %s 不支持"
+
+#: ../spell.c:2579
+msgid "E752: No previous spell replacement"
+msgstr "E752: 之前没有拼写替换"
+
+#: ../spell.c:2624
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: 找不到: %s"
+
+#: ../spellfile.c:329
msgid "E758: Truncated spell file"
msgstr "E758: 已截断的拼写文件"
-#: ../spell.c:953
+#: ../spellfile.c:330
+msgid "E1280: Illegal character in word"
+msgstr "E1280: 词中有非法字符"
+
+#: ../spellfile.c:331
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "%s 第 %d 行,多余的后续字符: %s"
-#: ../spell.c:954
+#: ../spellfile.c:332
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "%s 第 %d 行,附加项名字太长: %s"
-#: ../spell.c:955
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr "E761: 附加文件 FOL、LOW 或 UPP 中格式错误"
-
-#: ../spell.c:957
-msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr "E762: FOL、LOW 或 UPP 中字符超出范围"
-
-#: ../spell.c:958
+#: ../spellfile.c:333
msgid "Compressing word tree..."
msgstr "压缩单词树……"
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: 拼写检查未启用"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "警告: 找不到单词列表 \"%s.%s.spl\" or \"%s.ascii.spl\""
-
-#: ../spell.c:2473
+#: ../spellfile.c:622
#, c-format
msgid "Reading spell file \"%s\""
msgstr "读取拼写文件 \"%s\""
-#: ../spell.c:2496
+#: ../spellfile.c:647
msgid "E757: This does not look like a spell file"
msgstr "E757: 这看起来不像是拼写文件"
-#: ../spell.c:2501
+#: ../spellfile.c:650
+#, c-format
+msgid "E5042: Failed to read spell file %s: %s"
+msgstr "E5042: 无法读取拼写文件 %s:%s"
+
+#: ../spellfile.c:658
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: 旧版本的拼写文件,需要更新"
-#: ../spell.c:2504
+#: ../spellfile.c:661
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: 为更高版本的 Vim 所用的拼写文件"
-#: ../spell.c:2602
+#: ../spellfile.c:769
msgid "E770: Unsupported section in spell file"
msgstr "E770: 拼写文件中存在不支持的节"
-#: ../spell.c:3762
+#: ../spellfile.c:935
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "警告: 区域 %s 不支持"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: 看起来不像是 .sug 文件: %s"
-#: ../spell.c:4550
+#: ../spellfile.c:941
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: 旧的.sug 文件,需要更新: %s"
+
+#: ../spellfile.c:945
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug 文件适用于较新的vim 版本: %s"
+
+#: ../spellfile.c:954
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug 文件不能匹配 .spl 文件: %s"
+
+#: ../spellfile.c:964
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: 读取 .sug 文件时出错:%s"
+
+#: ../spellfile.c:2067
#, c-format
msgid "Reading affix file %s..."
msgstr "读取附加文件 %s ……"
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
+#: ../spellfile.c:2103 ../spellfile.c:3177
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "单词 %s 转换失败,第 %d 行: %s"
-#: ../spell.c:4630 ../spell.c:6170
+#: ../spellfile.c:2150 ../spellfile.c:3750
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "不支持 %s 中的转换: 从 %s 到 %s"
-#: ../spell.c:4642
+#: ../spellfile.c:2163
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "%s 第 %d 行,FLAG 的值无效: %s"
-#: ../spell.c:4655
+#: ../spellfile.c:2177
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "%s 第 %d 行,在使用标志后出现 FLAG: %s"
-#: ../spell.c:4723
+#: ../spellfile.c:2238
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
"%d"
-msgstr "在 PFX 项之后定义 COMPOUNDFORBIDFLAG (%s 第%d行)可能会给出错误的结果"
-"%d"
+msgstr ""
+"在 PFX 项之后定义 COMPOUNDFORBIDFLAG (%s 第 %d 行)可能会给出错误的结果"
-#: ../spell.c:4731
+#: ../spellfile.c:2246
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
"%d"
-msgstr "在 PFX 项之后定义 COMPOUNDPERMITFLAG (%s 第%d行)可能会给出错误的结果"
-"%d"
+msgstr ""
+"在 PFX 项之后定义 COMPOUNDPERMITFLAG (%s 第 %d 行)可能会给出错误的结果"
-#: ../spell.c:4747
-#, fuzzy, c-format
+#: ../spellfile.c:2261
+#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "%s 第 %d 行,错误的 COMPOUNDMIN 值: %s"
+msgstr "%s 第 %d 行,错误的 COMPOUNDRULES 值: %s"
-#: ../spell.c:4771
+#: ../spellfile.c:2285
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "%s 第 %d 行,错误的 COMPOUNDWORDMAX 值: %s"
-#: ../spell.c:4777
+#: ../spellfile.c:2292
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "%s 第 %d 行,错误的 COMPOUNDMIN 值: %s"
-#: ../spell.c:4783
+#: ../spellfile.c:2299
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "%s 第 %d 行,错误的 COMPOUNDSYLMAX 值: %s"
-#: ../spell.c:4795
+#: ../spellfile.c:2312
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "%s 第 %d 行,错误的 CHECKCOMPOUNDPATTERN 值: %s"
-#: ../spell.c:4847
+#: ../spellfile.c:2368
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr "%s 第 %d 行,在连续的附加块中出现不同的组合标志: %s"
-#: ../spell.c:4850
+#: ../spellfile.c:2372
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "%s 第 %d 行,重复的附加项: %s"
-#: ../spell.c:4871
+#: ../spellfile.c:2391
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5382,334 +6450,337 @@ msgstr ""
"%s 第 %d 行,附加项被 BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST 使"
"用: %s"
-#: ../spell.c:4893
+#: ../spellfile.c:2421
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "%s 第 %d 行,此处需要 Y 或 N: %s"
-#: ../spell.c:4968
+#: ../spellfile.c:2497
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "%s 第 %d 行,错误的条件: %s"
-#: ../spell.c:5091
+#: ../spellfile.c:2613
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "%s 第 %d 行,此处需要 REP(SAL) 计数"
-#: ../spell.c:5120
+#: ../spellfile.c:2648
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "%s 第 %d 行,此处需要 MAP 计数"
-#: ../spell.c:5132
+#: ../spellfile.c:2661
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "%s 第 %d 行,MAP 中存在重复的字符"
-#: ../spell.c:5176
+#: ../spellfile.c:2706
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "%s 第 %d 行,无法识别或重复的项: %s"
-#: ../spell.c:5197
-#, c-format
-msgid "Missing FOL/LOW/UPP line in %s"
-msgstr "%s 中缺少 FOL/LOW/UPP 行"
-
-#: ../spell.c:5220
+#: ../spellfile.c:2738
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "在没有 SYLLABLE 的情况下使用了 COMPOUNDSYLMAX"
-#: ../spell.c:5236
+#: ../spellfile.c:2756
msgid "Too many postponed prefixes"
msgstr "太多延迟前缀"
-#: ../spell.c:5238
+#: ../spellfile.c:2758
msgid "Too many compound flags"
msgstr "太多组合标志"
-#: ../spell.c:5240
+#: ../spellfile.c:2760
msgid "Too many postponed prefixes and/or compound flags"
msgstr "太多延迟前缀和/或组合标志"
-#: ../spell.c:5250
+#: ../spellfile.c:2771
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "%s 中缺少 SOFO%s 行"
-#: ../spell.c:5253
+#: ../spellfile.c:2774
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "%s 同时出现 SQL 和 SOFO 行"
-#: ../spell.c:5331
+#: ../spellfile.c:2855
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "%s 第 %d 行,标志不是数字: %s"
-#: ../spell.c:5334
+#: ../spellfile.c:2858
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "%s 第 %d 行,无效的标志: %s"
-#: ../spell.c:5493 ../spell.c:5501
+#: ../spellfile.c:3029 ../spellfile.c:3038
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "%s 的值与另一个 .aff 文件中使用的值不相同"
-#: ../spell.c:5602
+#: ../spellfile.c:3142
#, c-format
msgid "Reading dictionary file %s..."
msgstr "读取字典文件 %s ……"
-#: ../spell.c:5611
+#: ../spellfile.c:3150
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: %s 中没有单词计数"
-#: ../spell.c:5669
+#: ../spellfile.c:3214
#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "第 %6d 行,第 %6d 个单词 - %s"
+msgid "line %6d, word %6ld - %s"
+msgstr "第 %6d 行,第 %6ld 个单词 - %s"
-#: ../spell.c:5691
+#: ../spellfile.c:3237
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "%s 第 %d 行,重复的单词: %s"
-#: ../spell.c:5694
+#: ../spellfile.c:3240
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "%s 第 %d 行,首次重复的单词: %s"
-#: ../spell.c:5746
+#: ../spellfile.c:3301
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "存在 %d 个重复的单词,在 %s 中"
-#: ../spell.c:5748
+#: ../spellfile.c:3304
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "忽略了含有非 ASCII 字符的 %d 个单词,在 %s 中"
-#: ../spell.c:6115
+#: ../spellfile.c:3695
#, c-format
msgid "Reading word file %s..."
msgstr "读取单词文件 %s ……"
-#: ../spell.c:6155
+#: ../spellfile.c:3723
+#, c-format
+msgid "Conversion failure for word in %s line %ld: %s"
+msgstr "单词 %s 转换失败,第 %ld 行: %s"
+
+#: ../spellfile.c:3737
#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgid "Duplicate /encoding= line ignored in %s line %ld: %s"
msgstr "%s 第 %ld 行,重复的 /encoding= 行已被忽略: %s"
-#: ../spell.c:6159
+#: ../spellfile.c:3740
#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "%s 第 %d 行,单词后的 /encoding= 行已被忽略: %s"
+msgid "/encoding= line after word ignored in %s line %ld: %s"
+msgstr "%s 第 %ld 行,单词后的 /encoding= 行已被忽略: %s"
-#: ../spell.c:6180
+#: ../spellfile.c:3761
#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "%s 第 %d 行,重复的 /regions= 行已被忽略: %s"
+msgid "Duplicate /regions= line ignored in %s line %ld: %s"
+msgstr "%s 第 %ld 行,重复的 /regions= 行已被忽略: %s"
-#: ../spell.c:6185
+#: ../spellfile.c:3766
#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "%s 第 %d 行,太多区域: %s"
+msgid "Too many regions in %s line %ld: %s"
+msgstr "%s 第 %ld 行,太多区域: %s"
-#: ../spell.c:6198
+#: ../spellfile.c:3779
#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "%s 第 %d 行,/ 行已被忽略: %s"
+msgid "/ line ignored in %s line %ld: %s"
+msgstr "%s 第 %ld 行,/ 行已被忽略: %s"
-#: ../spell.c:6224
+#: ../spellfile.c:3806
#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "%s 第 %d 行,无效的区域号: %s"
+msgid "Invalid region nr in %s line %ld: %s"
+msgstr "%s 第 %ld 行,区域号无效:%s"
-#: ../spell.c:6230
+#: ../spellfile.c:3812
#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "%s 第 %d 行,不可识别的标志: %s"
+msgid "Unrecognized flags in %s line %ld: %s"
+msgstr "%s 第 %ld 行,不可识别的标志: %s"
-#: ../spell.c:6257
+#: ../spellfile.c:3839
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "忽略了含有非 ASCII 字符的 %d 个单词"
-#: ../spell.c:6656
+#: ../spellfile.c:4231
#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "压缩了 %d/%d 个节点;剩余 %d (%d%%)"
+msgid "Compressed %s of %ld nodes; %ld (%ld%%) remaining"
+msgstr "压缩了 %s / %ld 个节点;剩余 %ld (%ld%%)"
-#: ../spell.c:7340
+#: ../spellfile.c:4933
msgid "Reading back spell file..."
msgstr "读取拼写文件……"
#. Go through the trie of good words, soundfold each word and add it to
#. the soundfold trie.
-#: ../spell.c:7357
+#: ../spellfile.c:4951
msgid "Performing soundfolding..."
msgstr "正在 soundfolding……"
-#: ../spell.c:7368
+#: ../spellfile.c:4964
#, c-format
msgid "Number of words after soundfolding: %<PRId64>"
msgstr "soundfolding 后的单词数: %<PRId64>"
-#: ../spell.c:7476
+#: ../spellfile.c:5072
#, c-format
msgid "Total number of words: %d"
msgstr "单词总数: %d"
-#: ../spell.c:7655
+#: ../spellfile.c:5213
#, c-format
msgid "Writing suggestion file %s..."
msgstr "写入建议文件 %s ……"
-#: ../spell.c:7707 ../spell.c:7927
+#: ../spellfile.c:5269 ../spellfile.c:5457
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "估计运行时内存用量: %d 字节"
-#: ../spell.c:7820
+#: ../spellfile.c:5353
msgid "E751: Output file name must not have region name"
msgstr "E751: 输出文件名不能含有区域名"
-#: ../spell.c:7822
-msgid "E754: Only up to 8 regions supported"
-msgstr "E754: 最多只支持 8 个区域"
+#: ../spellfile.c:5355
+#, c-format
+msgid "E754: Only up to %d regions supported"
+msgstr "E754: 最多只支持 %d 个区域"
-#: ../spell.c:7846
+#: ../spellfile.c:5379
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: %s 出现无效的范围"
-#: ../spell.c:7907
+#: ../spellfile.c:5436
msgid "Warning: both compounding and NOBREAK specified"
msgstr "警告: 同时指定了 compounding 和 NOBREAK"
-#: ../spell.c:7920
+#: ../spellfile.c:5450
#, c-format
msgid "Writing spell file %s..."
msgstr "写入拼写文件 %s ……"
-#: ../spell.c:7925
+#: ../spellfile.c:5455
msgid "Done!"
msgstr "完成!"
-#: ../spell.c:8034
+#: ../spellfile.c:5576
#, c-format
msgid "E765: 'spellfile' does not have %<PRId64> entries"
msgstr "E765: 'spellfile' 没有 %<PRId64> 项"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#: ../spellfile.c:5621
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "从 %s 中删除了单词"
+msgstr "单词 '%.*s' 从 %s 中删除了"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#: ../spellfile.c:5625
+msgid "Seek error in spellfile"
+msgstr "拼写文件中定位错误"
+
+#: ../spellfile.c:5671
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "向 %s 中添加了单词"
+msgstr "单词 '%.*s' 添加到了 %s"
-#: ../spell.c:8381
+#: ../spellfile.c:5803
msgid "E763: Word characters differ between spell files"
msgstr "E763: 拼写文件之间的字符不相同"
-#: ../spell.c:8684
+#. This should have been checked when generating the .spl
+#. file.
+#: ../spellfile.c:5899
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP 条目中有重复的字符"
+
+#: ../spellsuggest.c:530
msgid "Sorry, no suggestions"
msgstr "抱歉,没有建议"
-#: ../spell.c:8687
+#: ../spellsuggest.c:533
#, c-format
msgid "Sorry, only %<PRId64> suggestions"
msgstr "抱歉,只有 %<PRId64> 条建议"
#. for when 'cmdheight' > 1
#. avoid more prompt
-#: ../spell.c:8704
+#: ../spellsuggest.c:547
#, c-format
msgid "Change \"%.*s\" to:"
msgstr "将 \"%.*s\" 改为:"
-#: ../spell.c:8737
+#: ../spellsuggest.c:581
#, c-format
msgid " < \"%.*s\""
msgstr " < \"%.*s\""
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: 之前没有拼写替换"
+#: ../statusline.c:110 ../statusline.c:1553
+msgid "[Help]"
+msgstr "[帮助]"
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: 找不到: %s"
+#: ../statusline.c:114 ../statusline.c:1588
+msgid "[Preview]"
+msgstr "[预览]"
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: 看起来不像是 .sug 文件: %s"
+#: ../strings.c:496
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf() 的参数不足"
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: 旧的.sug 文件,需要更新: %s"
+#: ../strings.c:618
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: 期盼浮点数作为printf()参数"
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: .sug 文件适用于较新的vim 版本: %s"
+#: ../strings.c:1400
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf() 的参数过多"
-#: ../spell.c:9295
+#: ../syntax.c:61
#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug 文件不能匹配 .spl 文件: %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: 当读取.sug 文件时错误"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: MAP 条目中有重复的字符"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: 无效的参数: %s"
-#: ../syntax.c:266
+#: ../syntax.c:241
msgid "No Syntax items defined for this buffer"
msgstr "这个缓冲区没有定义任何语法项"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: 无效的参数: %s"
+#: ../syntax.c:2706
+msgid "'redrawtime' exceeded, syntax highlighting disabled"
+msgstr "'redrawtime' 已过,语法高亮被禁用"
+
+#: ../syntax.c:2941
+msgid "syntax iskeyword not set"
+msgstr "syntax iskeyword 未设置"
-#: ../syntax.c:3299
+#: ../syntax.c:3118
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: 无此语法 cluster: \"%s\""
-#: ../syntax.c:3433
+#: ../syntax.c:3234
msgid "syncing on C-style comments"
msgstr "C风格注释同步中"
-#: ../syntax.c:3439
+#: ../syntax.c:3240
msgid "no syncing"
msgstr "没有同步"
-#: ../syntax.c:3441
+#: ../syntax.c:3243
+msgid "syncing starts at the first line"
+msgstr "同步开始于第一行"
+
+#: ../syntax.c:3245
msgid "syncing starts "
msgstr "同步开始"
-#: ../syntax.c:3443 ../syntax.c:3506
+#: ../syntax.c:3247 ../syntax.c:3316
msgid " lines before top line"
msgstr "行号超出范围"
-#: ../syntax.c:3448
+#: ../syntax.c:3253
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5717,7 +6788,7 @@ msgstr ""
"\n"
"--- 语法同步项目 (Syntax sync items) ---"
-#: ../syntax.c:3452
+#: ../syntax.c:3257
msgid ""
"\n"
"syncing on items"
@@ -5725,7 +6796,7 @@ msgstr ""
"\n"
"同步中:"
-#: ../syntax.c:3457
+#: ../syntax.c:3262
msgid ""
"\n"
"--- Syntax items ---"
@@ -5733,277 +6804,211 @@ msgstr ""
"\n"
"--- 语法项目 ---"
-#: ../syntax.c:3475
+#: ../syntax.c:3279
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: 无此语法 cluster: \"%s\""
-#: ../syntax.c:3497
+#: ../syntax.c:3303
+msgid "from the first line"
+msgstr "从第一行"
+
+#: ../syntax.c:3306
msgid "minimal "
msgstr "最小"
-#: ../syntax.c:3503
+#: ../syntax.c:3313
msgid "maximal "
msgstr "最大"
-#: ../syntax.c:3513
-#, fuzzy
+#: ../syntax.c:3324
msgid "; match "
-msgstr "匹配 %d"
+msgstr ";匹配 "
-#: ../syntax.c:3515
-#, fuzzy
+#: ../syntax.c:3326
msgid " line breaks"
-msgstr "少于一行"
+msgstr " 个换行"
-#: ../syntax.c:4076
+#: ../syntax.c:3875
msgid "E395: contains argument not accepted here"
msgstr "E395: 使用了不正确的参数"
-#: ../syntax.c:4096
-#, fuzzy
+#: ../syntax.c:3894
msgid "E844: invalid cchar value"
-msgstr "E474: 无效的参数"
+msgstr "E844: cchar 值无效"
-#: ../syntax.c:4107
+#: ../syntax.c:3905
msgid "E393: group[t]here not accepted here"
msgstr "E393: 使用了不正确的参数"
-#: ../syntax.c:4126
+#: ../syntax.c:3927
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: 找不到 %s 的 region item"
-#: ../syntax.c:4188
+#: ../syntax.c:3988
msgid "E397: Filename required"
msgstr "E397: 需要文件名称"
-#: ../syntax.c:4221
-#, fuzzy
+#: ../syntax.c:4019
msgid "E847: Too many syntax includes"
-msgstr "E77: 文件名过多"
+msgstr "E847: syntax include 过多"
-#: ../syntax.c:4303
-#, fuzzy, c-format
+#: ../syntax.c:4107
+#, c-format
msgid "E789: Missing ']': %s"
-msgstr "E747: 缺少 ']': %s"
+msgstr "E789: 缺少 ']':%s"
+
+#: ../syntax.c:4112
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: ']' 后有尾随的字符:%s]%s"
-#: ../syntax.c:4531
+#: ../syntax.c:4320
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: 缺少 '=': %s"
-#: ../syntax.c:4666
+#: ../syntax.c:4450
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: syntax region %s 的参数太少"
-#: ../syntax.c:4870
-#, fuzzy
+#: ../syntax.c:4629
msgid "E848: Too many syntax clusters"
-msgstr "E391: 无此语法 cluster: \"%s\""
+msgstr "E848: syntax cluster 过多"
-#: ../syntax.c:4954
+#: ../syntax.c:4714
msgid "E400: No cluster specified"
msgstr "E400: 没有指定的属性"
#. end delimiter not found
-#: ../syntax.c:4986
+#: ../syntax.c:4746
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: 找不到分隔符号: %s"
-#: ../syntax.c:5049
+#: ../syntax.c:4816
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: '%s' 后面的东西不能识别"
-#: ../syntax.c:5120
+#: ../syntax.c:4893
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: 语法同步: 连接行符号指定了两次"
-#: ../syntax.c:5169
+#: ../syntax.c:4942
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: 无效的参数: %s"
-#: ../syntax.c:5217
+#: ../syntax.c:4978
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: 缺少等号: %s"
-#: ../syntax.c:5222
+#: ../syntax.c:4983
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: 空的参数: %s"
-#: ../syntax.c:5240
+#: ../syntax.c:4998
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s 不能在此出现"
-#: ../syntax.c:5246
+#: ../syntax.c:5004
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s 必须是列表里的第一个"
-#: ../syntax.c:5304
+#: ../syntax.c:5067
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: 不正确的组名: %s"
-#: ../syntax.c:5512
+#: ../syntax.c:5272
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: 不正确的 :syntax 子命令: %s"
-#: ../syntax.c:5854
+#: ../syntax.c:5660
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
" 总 计 计 数 匹 配 最 慢 的 平 均 名 字 模 式"
-#: ../syntax.c:6146
-msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: 加载 syncolor.vim 时出现嵌套循环"
-
-#: ../syntax.c:6256
-#, c-format
-msgid "E411: highlight group not found: %s"
-msgstr "E411: 找不到 highlight group: %s"
-
-#: ../syntax.c:6278
-#, c-format
-msgid "E412: Not enough arguments: \":highlight link %s\""
-msgstr "E412: 参数太少: \":highlight link %s\""
-
-#: ../syntax.c:6284
-#, c-format
-msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: 参数过多: \":highlight link %s\""
-
-#: ../syntax.c:6302
-msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: 已设定组, 忽略 highlight link"
-
-#: ../syntax.c:6367
-#, c-format
-msgid "E415: unexpected equal sign: %s"
-msgstr "E415: 不该有的等号: %s"
-
-#: ../syntax.c:6395
-#, c-format
-msgid "E416: missing equal sign: %s"
-msgstr "E416: 缺少等号: %s"
-
-#: ../syntax.c:6418
-#, c-format
-msgid "E417: missing argument: %s"
-msgstr "E417: 缺少参数: %s"
-
-#: ../syntax.c:6446
-#, c-format
-msgid "E418: Illegal value: %s"
-msgstr "E418: 不合法的值: %s"
-
-#: ../syntax.c:6496
-msgid "E419: FG color unknown"
-msgstr "E419: 错误的前景颜色"
-
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: 错误的背景颜色"
-
-#: ../syntax.c:6564
-#, c-format
-msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: 错误的颜色名称或数值: %s"
-
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: 终端编码太长: %s"
-
-#: ../syntax.c:6753
-#, c-format
-msgid "E423: Illegal argument: %s"
-msgstr "E423: 无效的参数: %s"
-
-#: ../syntax.c:6925
-msgid "E424: Too many different highlighting attributes in use"
-msgstr "E424: 使用了太多不同的高亮度属性"
-
-#: ../syntax.c:7427
-msgid "E669: Unprintable character in group name"
-msgstr "E669: 组名中存在不可显示字符"
-
-#: ../highlight_group.c:1756
-msgid "E5248: Invalid character in group name"
-msgstr "E5248: 组名中含有无效字符"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr "E849: 高亮和语法组过多"
-
-#: ../tag.c:104
+#: ../tag.c:117
msgid "E555: at bottom of tag stack"
msgstr "E555: 已在 tag 堆栈底部"
-#: ../tag.c:105
+#: ../tag.c:118
msgid "E556: at top of tag stack"
msgstr "E556: 已在 tag 堆栈顶部"
-#: ../tag.c:380
+#: ../tag.c:120
+msgid "E986: cannot modify the tag stack within tagfunc"
+msgstr "E986: 在 tagfunc 中不能修改 tag 堆栈"
+
+#: ../tag.c:122
+msgid "E987: invalid return value from tagfunc"
+msgstr "E987: tagfunc 返回了无效的值"
+
+#: ../tag.c:124
+msgid "E1299: Window unexpectedly closed while searching for tags"
+msgstr "E1299: 搜索 tag 时窗口意外关闭"
+
+#: ../tag.c:427
msgid "E425: Cannot go before first matching tag"
msgstr "E425: 已到第一个匹配的 tag"
-#: ../tag.c:504
+#: ../tag.c:568
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: 找不到 tag: %s"
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # pri kind tag"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "文件\n"
-
-#: ../tag.c:829
+#: ../tag.c:610
msgid "E427: There is only one matching tag"
msgstr "E427: 只有一个匹配的 tag"
-#: ../tag.c:831
+#: ../tag.c:612
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: 己到最后一个匹配的 tag"
-#: ../tag.c:850
+#: ../tag.c:641
#, c-format
msgid "File \"%s\" does not exist"
msgstr "文件 \"%s\" 不存在"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
+#: ../tag.c:649
#, c-format
msgid "tag %d of %d%s"
msgstr "找到 tag: %d / %d%s"
-#: ../tag.c:862
+#: ../tag.c:652
msgid " or more"
msgstr " 或更多"
-#: ../tag.c:864
+#: ../tag.c:654
msgid " Using tag with different case!"
msgstr " 以不同大小写来使用 tag!"
-#: ../tag.c:909
+#: ../tag.c:701
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: 文件 \"%s\" 不存在"
+#: ../tag.c:749
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+#: ../tag.c:752
+msgid "file\n"
+msgstr "文件\n"
+
#. Highlight title
-#: ../tag.c:960
+#: ../tag.c:1064
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6011,1619 +7016,2530 @@ msgstr ""
"\n"
" # 到 tag 从 行 在 文件/文本"
-#: ../tag.c:1303
+#: ../tag.c:1635
#, c-format
msgid "Searching tags file %s"
msgstr "查找 tag 文件 %s"
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "忽略较长的行在 tags 文件中"
-
-#: ../tag.c:1915
+#: ../tag.c:2155
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Tag 文件 \"%s\" 格式错误"
-#: ../tag.c:1917
+#: ../tag.c:2156
#, c-format
msgid "Before byte %<PRId64>"
msgstr "在第 %<PRId64> 字节之前"
-#: ../tag.c:1929
+#: ../tag.c:2168
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Tag 文件未排序: %s"
#. never opened any tags file
-#: ../tag.c:1960
+#: ../tag.c:2195
msgid "E433: No tags file"
msgstr "E433: 没有 tag 文件"
-#: ../tag.c:2536
+#: ../tag.c:2794
msgid "E434: Can't find tag pattern"
msgstr "E434: 找不到 tag 模式"
-#: ../tag.c:2544
+#: ../tag.c:2800
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: 找不到 tag,试着猜!"
-#: ../tag.c:2797
-#, fuzzy, c-format
+#: ../tag.c:3070
+#, c-format
msgid "Duplicate field name: %s"
-msgstr "%s 第 %d 行,重复的附加项: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' 未知。可用的内建终端有:"
+msgstr "字段名重复:%s"
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "默认值为: '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: 无法打开 termcap 文件"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: 在 terminfo 中找不到终端项"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: 在 termcap 中找不到终端项"
+#: ../testing.c:38
+msgid ""
+"E856: assert_fails() second argument must be a string or a list with one or "
+"two strings"
+msgstr ""
+"E856: assert_fails() 的第二个参数必须是字符串或包含一或两个字符串的列表"
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: termcap 中没有 \"%s\" 项"
+#: ../testing.c:40
+msgid "E1115: assert_fails() fourth argument must be a number"
+msgstr "E1115: assert_fails() 的第四个参数必须是整数"
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: 终端需要能力 \"cm\""
+#: ../testing.c:42
+msgid "E1116: assert_fails() fifth argument must be a string"
+msgstr "E1116: assert_fails() 的第五个参数必须是字符串"
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- 终端按键 ---"
+#: ../testing.c:44
+msgid "E1142: Calling test_garbagecollect_now() while v:testing is not set"
+msgstr "E1142: 调用 test_garbagecollect_now(),但 v:testing 未设置"
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: 读错误,退出中...\n"
+#: ../ui.c:342
+msgid "Beep!"
+msgstr "Beep!"
#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
+#. file in a way it becomes shorter.
+#: ../undo.c:357
msgid "E881: Line count changed unexpectedly"
msgstr "E881: 行数意外地改变了"
-#: ../undo.c:627
+#: ../undo.c:628
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: 无法打开撤销文件去写入"
+msgstr "E828: 无法打开并写入撤销文件:%s"
+
+#: ../undo.c:710
+#, c-format
+msgid "E5003: Unable to create directory \"%s\" for undo file: %s"
+msgstr "E303: 无法为交换文件创建目录 \"%s\":%s"
-#: ../undo.c:717
+#: ../undo.c:749
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: 已损坏的撤销文件 (%s): %s"
-#: ../undo.c:1039
+#: ../undo.c:1169
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "不能写入撤销文件到 'undodir' 中的任何文件夹"
-#: ../undo.c:1074
+#: ../undo.c:1205
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "不能重写撤销文件, 不可读取: %s"
-#: ../undo.c:1092
+#: ../undo.c:1222
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "这个文件: %s 不是撤销文件,不可以重写"
-#: ../undo.c:1108
+#: ../undo.c:1239
msgid "Skipping undo file write, nothing to undo"
msgstr "跳过写入撤销文件,没有任何撤销"
-#: ../undo.c:1121
-#, fuzzy, c-format
+#: ../undo.c:1252
+#, c-format
msgid "Writing undo file: %s"
-msgstr "写入 viminfo 文件 \"%s\""
+msgstr "写入撤销文件:%s"
-#: ../undo.c:1213
-#, fuzzy, c-format
+#: ../undo.c:1340
+#, c-format
msgid "E829: write error in undo file: %s"
-msgstr "E297: 交换文件写入错误"
+msgstr "E829: 撤销文件写入错误:%s"
-#: ../undo.c:1280
+#: ../undo.c:1387
#, c-format
msgid "Not reading undo file, owner differs: %s"
-msgstr "不能读取撤销文件, 所有者不同: %s"
+msgstr "不能读取撤销文件,所有者不同:%s"
-#: ../undo.c:1292
-#, fuzzy, c-format
+#: ../undo.c:1400
+#, c-format
msgid "Reading undo file: %s"
-msgstr "读取单词文件 %s ……"
+msgstr "读取撤销文件:%s"
-#: ../undo.c:1299
-#, fuzzy, c-format
+#: ../undo.c:1407
+#, c-format
msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: 无法打开并读取 viminfo 文件"
+msgstr "E822: 无法打开并读取撤销文件:%s"
-#: ../undo.c:1308
-#, fuzzy, c-format
+#: ../undo.c:1421
+#, c-format
msgid "E823: Not an undo file: %s"
-msgstr "E753: 找不到: %s"
+msgstr "E823: 不是撤销文件:%s"
-#: ../undo.c:1313
-#, fuzzy, c-format
+#: ../undo.c:1426
+#, c-format
msgid "E824: Incompatible undo file: %s"
-msgstr "E484: 无法打开文件 %s"
+msgstr "E824: 不兼容的撤销文件:%s"
-#: ../undo.c:1328
+#: ../undo.c:1442
msgid "File contents changed, cannot use undo info"
msgstr "文件内容已改变,不能使用撤销信息"
-#: ../undo.c:1497
-#, fuzzy, c-format
+#: ../undo.c:1636
+#, c-format
msgid "Finished reading undo file %s"
-msgstr "结束执行 %s"
+msgstr "读取撤销文件 %s 结束"
-#: ../undo.c:1586 ../undo.c:1812
+#: ../undo.c:1871 ../undo.c:2106
msgid "Already at oldest change"
msgstr "已位于最旧的改变"
-#: ../undo.c:1597 ../undo.c:1814
+#: ../undo.c:1882 ../undo.c:2108
msgid "Already at newest change"
msgstr "已位于最新的改变"
-#: ../undo.c:1806
-#, fuzzy, c-format
+#: ../undo.c:2100
+#, c-format
msgid "E830: Undo number %<PRId64> not found"
-msgstr "找不到撤销号 %<PRId64>"
+msgstr "E830: 找不到撤销号 %<PRId64>"
-#: ../undo.c:1979
+#: ../undo.c:2280
msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: 行号错误"
+msgstr "E438: u_undo:行号错误"
-#: ../undo.c:2183
+#: ../undo.c:2538
msgid "more line"
msgstr "行被加入"
-#: ../undo.c:2185
+#: ../undo.c:2540
msgid "more lines"
msgstr "行被加入"
-#: ../undo.c:2187
+#: ../undo.c:2542
msgid "line less"
msgstr "行被去掉"
-#: ../undo.c:2189
+#: ../undo.c:2544
msgid "fewer lines"
msgstr "行被去掉"
-#: ../undo.c:2193
+#: ../undo.c:2548
msgid "change"
msgstr "行发生改变"
-#: ../undo.c:2195
+#: ../undo.c:2550
msgid "changes"
msgstr "行发生改变"
-#: ../undo.c:2225
+#: ../undo.c:2589
#, c-format
msgid "%<PRId64> %s; %s #%<PRId64> %s"
msgstr "%<PRId64> %s;%s #%<PRId64> %s"
-#: ../undo.c:2228
+#: ../undo.c:2592
msgid "before"
msgstr "before"
-#: ../undo.c:2228
+#: ../undo.c:2592
msgid "after"
msgstr "after"
-#: ../undo.c:2325
+#: ../undo.c:2613
+#, c-format
+msgid "%<PRId64> second ago"
+msgid_plural "%<PRId64> seconds ago"
+msgstr[0] "%<PRId64> 秒前"
+
+#: ../undo.c:2697
msgid "Nothing to undo"
msgstr "无可撤销"
-#: ../undo.c:2330
+#: ../undo.c:2702
msgid "number changes when saved"
msgstr " 编号 变更 时间 保存"
-#: ../undo.c:2360
-#, fuzzy, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> 列; "
-
-#: ../undo.c:2372
-#, fuzzy
+#: ../undo.c:2724
msgid "E790: undojoin is not allowed after undo"
-msgstr "E407: %s 不能在此出现"
+msgstr "E790: undo 后不允许 undojoin"
-#: ../undo.c:2466
+#: ../undo.c:2807
msgid "E439: undo list corrupt"
msgstr "E439: 撤销列表损坏"
-#: ../undo.c:2495
+#: ../undo.c:2830
msgid "E440: undo line missing"
msgstr "E440: 找不到要撤销的行"
-#: ../version.c:600
+#: ../usercmd.c:46
+msgid "E1208: -complete used without allowing arguments"
+msgstr "E1208: 用了 -complete 却不允许使用参数"
+
+#: ../usercmd.c:48
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: 没有这个用户自定义命令: %s"
+
+#: ../usercmd.c:50
+#, c-format
+msgid "E1237: No such user-defined command in current buffer: %s"
+msgstr "E1237: 当前缓冲区中无此用户定义命令:%s"
+
+#: ../usercmd.c:416
msgid ""
"\n"
-"Included patches: "
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-"包含补丁: "
+" 名称 参数 范围 补全 定义 "
-#: ../version.c:627
-#, fuzzy
-msgid ""
-"\n"
-"Extra patches: "
-msgstr "外部符合:\n"
+#: ../usercmd.c:561
+msgid "No user-defined commands found"
+msgstr "找不到用户自定义命令"
+
+#: ../usercmd.c:585
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: 无效的地址类型:%s"
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "修改者 "
+#: ../usercmd.c:633
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: 无效的补全类型:%s"
-#: ../version.c:646
+#: ../usercmd.c:639
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: 只有 custom 补全才允许参数"
+
+#: ../usercmd.c:645
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Custom 补全需要一个函数参数"
+
+#: ../usercmd.c:662
+msgid "E175: No attribute specified"
+msgstr "E175: 没有指定属性"
+
+#: ../usercmd.c:710
+msgid "E176: Invalid number of arguments"
+msgstr "E176: 无效的参数个数"
+
+#: ../usercmd.c:721
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: 不能指定两次计数"
+
+#: ../usercmd.c:730
+msgid "E178: Invalid default value for count"
+msgstr "E178: 无效的计数默认值"
+
+#: ../usercmd.c:763
+msgid "E179: argument required for -complete"
+msgstr "E179: -complete 需要参数"
+
+#: ../usercmd.c:774
+msgid "E179: argument required for -addr"
+msgstr "E179: -addr 需要参数"
+
+#: ../usercmd.c:786
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: 无效的属性: %s"
+
+#: ../usercmd.c:866
+#, c-format
+msgid "E174: Command already exists: add ! to replace it: %s"
+msgstr "E174: 命令已存在:请加 ! 强制替换:%s"
+
+#: ../usercmd.c:955
+msgid "E182: Invalid command name"
+msgstr "E182: 无效的命令名"
+
+#: ../usercmd.c:966
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: 用户自定义命令必须以大写字母开头"
+
+#: ../usercmd.c:968
+msgid "E841: Reserved name, cannot be used for user defined command"
+msgstr "E841: 名称已被保留,不能用于用户自定义命令"
+
+#: ../version.c:2636
msgid ""
"\n"
-"Compiled "
+"\n"
+"Features: "
msgstr ""
"\n"
-"编译"
-
-#: ../version.c:649
-msgid "by "
-msgstr "者 "
+"\n"
+"功能: "
-#: ../version.c:660
+#: ../version.c:2740
msgid ""
"\n"
-"Huge version "
+"Compiled "
msgstr ""
"\n"
-"巨型版本 "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "无图形界面。"
+"编译"
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " 可使用(+)与不可使用(-)的功能:\n"
+#: ../version.c:2743
+msgid "by "
+msgstr "者 "
-#: ../version.c:667
+#: ../version.c:2757
msgid " system vimrc file: \""
msgstr " 系统 vimrc 文件: \""
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " 用户 vimrc 文件: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " 第二用户 vimrc 文件: \""
-
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " 第三用户 vimrc 文件: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " 用户 exrc 文件: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " 第二用户 exrc 文件: \""
-
-#: ../version.c:699
+#: ../version.c:2764
msgid " fall-back for $VIM: \""
msgstr " $VIM 预设值: \""
-#: ../version.c:705
+#: ../version.c:2770
msgid " f-b for $VIMRUNTIME: \""
msgstr " $VIMRUNTIME 预设值: \""
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "编译方式: "
+#: ../version.c:2805
+msgid "Nvim is open source and freely distributable"
+msgstr "Nvim 是可自由分发的开放源代码软件"
-#: ../version.c:712
-msgid "Linking: "
-msgstr "链接方式: "
+#: ../version.c:2806
+msgid "https://neovim.io/#chat"
+msgstr ""
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " 调试版本"
+#: ../version.c:2808
+msgid "type :help nvim<Enter> if you are new! "
+msgstr ""
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
+#: ../version.c:2809
+msgid "type :checkhealth<Enter> to optimize Nvim"
+msgstr ""
-#: ../version.c:769
-msgid "version "
-msgstr "版本 "
+#: ../version.c:2810
+msgid "type :q<Enter> to exit "
+msgstr "输入 :q<Enter> 退出 "
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "维护人 Bram Moolenaar 等"
+#: ../version.c:2811
+msgid "type :help<Enter> for help "
+msgstr ""
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim 是可自由分发的开放源代码软件"
+#: ../version.c:2813
+msgid "type :help news<Enter> to see changes in"
+msgstr ""
-#: ../version.c:776
+#: ../version.c:2816
msgid "Help poor children in Uganda!"
msgstr "帮助乌干达的可怜儿童!"
-#: ../version.c:777
+#: ../version.c:2817
msgid "type :help iccf<Enter> for information "
msgstr "输入 :help iccf<Enter> 查看说明 "
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "输入 :q<Enter> 退出 "
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "输入 :help<Enter> 或 <F1> 查看在线帮助 "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "输入 :help version7<Enter> 查看版本信息 "
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "运行于 Vi 兼容模式"
-
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "输入 :set nocp<Enter> 恢复默认的 Vim "
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "输入 :help cp-default<Enter> 查看相关说明 "
-
-#: ../version.c:827
+#: ../version.c:2850
msgid "Sponsor Vim development!"
msgstr "赞助 Vim 的开发!"
-#: ../version.c:828
+#: ../version.c:2851
msgid "Become a registered Vim user!"
msgstr "成为 Vim 的注册用户!"
-#: ../version.c:831
+#: ../version.c:2854
msgid "type :help sponsor<Enter> for information "
msgstr "输入 :help sponsor<Enter> 查看说明 "
-#: ../version.c:832
+#: ../version.c:2855
msgid "type :help register<Enter> for information "
msgstr "输入 :help register<Enter> 查看说明 "
-#: ../version.c:834
+#: ../version.c:2857
msgid "menu Help->Sponsor/Register for information "
msgstr "菜单 Help->Sponsor/Register 查看说明 "
-#: ../window.c:119
+#: ../viml/parser/expressions.c:292
+#, c-format
+msgid "E15: Invalid control character present in input: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:519
+#, c-format
+msgid "E112: Option name missing: %.*s"
+msgstr "E112: 缺少选项名称:%.*s"
+
+#: ../viml/parser/expressions.c:678 ../viml/parser/expressions.c:694
+#, c-format
+msgid "E15: Unexpected EOC character: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:706
+#, c-format
+msgid "E15: Unidentified character: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:1335
+#, c-format
+msgid "E15: Operator is not associative: %.*s"
+msgstr ""
+
+#. / Record missing operator: for things like
+#. /
+#. / :echo @a @a
+#. /
+#. / (allowed) or
+#. /
+#. / :echo (@a @a)
+#. /
+#. / (parsed as OpMissing(@a, @a)).
+#. Multiple expressions allowed, return without calling
+#. viml_parser_advance().
+#: ../viml/parser/expressions.c:1440
+#, c-format
+msgid "E15: Missing operator: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2081
+#, c-format
+msgid "E15: Expected lambda arguments list or arrow: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2101
+#, c-format
+msgid "E15: Expected value part of assignment lvalue: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2120
+#, c-format
+msgid "E15: Expected assignment operator or subscript: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2171
+msgid "E15: Unexpected "
+msgstr ""
+
+#: ../viml/parser/expressions.c:2181
+#, c-format
+msgid "E15: Unexpected multiplication-like operator: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2241
+msgid "E15: Environment variable name missing"
+msgstr "E15: 缺少环境变量名称"
+
+#: ../viml/parser/expressions.c:2259
+#, c-format
+msgid "E15: Expected value, got comparison operator: %.*s"
+msgstr ""
+
+#. Value level: comma appearing here is not valid.
+#. Note: in Vim string(,x) will give E116, this is not the case here.
+#: ../viml/parser/expressions.c:2286
+#, c-format
+msgid "E15: Expected value, got comma: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2320
+#, c-format
+msgid "E15: Comma outside of call, lambda or literal: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2404
+#, c-format
+msgid "E15: Colon outside of dictionary or ternary operator: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2451
+#, c-format
+msgid "E15: Expected value, got closing bracket: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2464
+#, c-format
+msgid "E475: Unable to assign to empty list: %.*s"
+msgstr "E475: 无法赋值给空列表:%.*s"
+
+#: ../viml/parser/expressions.c:2474 ../viml/parser/expressions.c:2609
+#, c-format
+msgid "E15: Unexpected closing figure brace: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2507
+#, c-format
+msgid "E475: Nested lists not allowed when assigning: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2557
+#, c-format
+msgid "E15: Expected value, got closing figure brace: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2587
+#, c-format
+msgid "E15: Don't know what figure brace means: %.*s"
+msgstr ""
+
+#. Only first branch is valid.
+#: ../viml/parser/expressions.c:2706
+#, c-format
+msgid "E15: Unexpected arrow: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2707
+#, c-format
+msgid "E15: Arrow outside of lambda: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2788
+#, c-format
+msgid "E15: Unexpected dot: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2791
+#, c-format
+msgid "E15: Cannot concatenate in assignments: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2813
+#, c-format
+msgid "E15: Expected value, got parenthesis: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2846
+#, c-format
+msgid "E15: Unexpected closing parenthesis: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2889
+#, c-format
+msgid "E15: Expected value, got question mark: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2911
+#, c-format
+msgid "E114: Missing double quote: %.*s"
+msgstr "E114: 缺少双引号:%.*s"
+
+#: ../viml/parser/expressions.c:2912
+#, c-format
+msgid "E115: Missing single quote: %.*s"
+msgstr "E115: 缺少单引号:%.*s"
+
+#: ../viml/parser/expressions.c:2931
+#, c-format
+msgid "E475: Expected closing bracket to end list assignment lvalue: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2934
+#, c-format
+msgid "E15: Misplaced assignment: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2938
+#, c-format
+msgid "E15: Unexpected assignment: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2965
+#, c-format
+msgid "E15: Expected value, got EOC: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:2988
+#, c-format
+msgid "E116: Missing closing parenthesis for function call: %.*s"
+msgstr "E116: 函数调用缺少结束括号:%.*s"
+
+#: ../viml/parser/expressions.c:2993
+#, c-format
+msgid "E110: Missing closing parenthesis for nested expression: %.*s"
+msgstr "E110: 嵌套表达式缺少结束括号:%.*s"
+
+#: ../viml/parser/expressions.c:3001
+#, c-format
+msgid "E697: Missing end of List ']': %.*s"
+msgstr "E697: List 缺少结束符 ']': %.*s"
+
+#: ../viml/parser/expressions.c:3008
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %.*s"
+msgstr "E723: 字典缺少结束符 '}':%.*s"
+
+#: ../viml/parser/expressions.c:3013
+#, c-format
+msgid "E15: Missing closing figure brace: %.*s"
+msgstr ""
+
+#: ../viml/parser/expressions.c:3018
+#, c-format
+msgid "E15: Missing closing figure brace for lambda: %.*s"
+msgstr ""
+
+#. Actually Vim throws E109 in more cases.
+#: ../viml/parser/expressions.c:3068
+#, c-format
+msgid "E109: Missing ':' after '?': %.*s"
+msgstr "E109: '?' 后缺少 ':':%.*s"
+
+#: ../window.c:97
+msgid "E1159: Cannot split a window when closing the buffer"
+msgstr "E1159: 关闭缓冲区时不能分割窗口"
+
+#: ../window.c:99
msgid "Already only one window"
msgstr "已经只剩一个窗口了"
-#: ../window.c:224
+#: ../window.c:259
msgid "E441: There is no preview window"
msgstr "E441: 没有预览窗口"
-#: ../window.c:559
+#: ../window.c:988
+msgid "E242: Can't split a window while closing another"
+msgstr "E242: 在关闭窗口时不能分割另一个窗口"
+
+#: ../window.c:1025
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: 不能同时进行 topleft 和 botright 分割"
-#: ../window.c:1228
+#: ../window.c:1868
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: 有其它分割窗口时不能旋转"
-#: ../window.c:1803
+#: ../window.c:2657
msgid "E444: Cannot close last window"
msgstr "E444: 不能关闭最后一个窗口"
-#: ../window.c:1810
-#, fuzzy
-msgid "E813: Cannot close autocmd window"
-msgstr "E444: 不能关闭最后一个窗口"
-
-#: ../window.c:1814
-#, fuzzy
+#: ../window.c:2671
msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E444: 不能关闭最后一个窗口"
+msgstr "E814: 无法关闭窗口,不然就只剩下自动命令窗口了"
-#: ../window.c:2717
+#: ../window.c:3867
msgid "E445: Other window contains changes"
msgstr "E445: 其它窗口有改变的内容"
-#: ../window.c:4805
+#: ../window.c:6498
msgid "E446: No file name under cursor"
msgstr "E446: 光标处没有文件名"
-#~ msgid "Patch file"
-#~ msgstr "Patch 文件"
+#: ../../../runtime/optwin.vim:72
+msgid "(local to window)"
+msgstr "(局部于窗口)"
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "确定(&O)\n"
-#~ "取消(&C)"
+#: ../../../runtime/optwin.vim:73
+msgid "(local to buffer)"
+msgstr "(局部于缓冲区)"
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: 没有到 Vim 服务器的连接"
+#: ../../../runtime/optwin.vim:74
+msgid "(global or local to buffer)"
+msgstr "(全局或局部于缓冲区)"
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: 无法发送到 %s"
+#: ../../../runtime/optwin.vim:153
+msgid ""
+"\" Each \"set\" line shows the current value of an option (on the left)."
+msgstr "\" 每个 \"set\" 行显示左侧选项的当前值"
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: 无法读取服务器响应"
+#: ../../../runtime/optwin.vim:154
+msgid "\" Hit <Enter> on a \"set\" line to execute it."
+msgstr "\" 在 \"set\" 行上按 <回车> 来执行。"
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: 无法发送到客户端"
+#: ../../../runtime/optwin.vim:155
+msgid "\" A boolean option will be toggled."
+msgstr "\" 布尔选项将被切换。"
-#~ msgid "Save As"
-#~ msgstr "另存为"
+#: ../../../runtime/optwin.vim:156
+msgid ""
+"\" For other options you can edit the value before hitting "
+"<Enter>."
+msgstr "\" 对于其他选项,您可以在按 <回车> 之前编辑该值。"
-#~ msgid "Edit File"
-#~ msgstr "编辑文件"
+#: ../../../runtime/optwin.vim:157
+msgid "\" Hit <Enter> on a help line to open a help window on this option."
+msgstr "\" 在帮助行上按 <回车> 来打开关于此选项的帮助窗口。"
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (找不到)"
+#: ../../../runtime/optwin.vim:158
+msgid "\" Hit <Enter> on an index line to jump there."
+msgstr "\" 在索引行上按 <回车> 来跳转到那里。"
-#~ msgid "Source Vim script"
-#~ msgstr "执行 Vim 脚本"
+#: ../../../runtime/optwin.vim:159
+msgid "\" Hit <Space> on a \"set\" line to refresh it."
+msgstr "\" 在 \"set\" 行上按 <空格> 来刷新。 "
-#~ msgid "Edit File in new window"
-#~ msgstr "在新窗口编辑文件"
+#: ../../../runtime/optwin.vim:228
+msgid "important"
+msgstr "重要选项"
-#~ msgid "Append File"
-#~ msgstr "追加文件"
+#: ../../../runtime/optwin.vim:229
+msgid "behave very Vi compatible (not advisable)"
+msgstr "非常兼容 Vi(不建议)"
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "窗口位置: X %d, Y %d"
+#: ../../../runtime/optwin.vim:231
+msgid "list of flags to specify Vi compatibility"
+msgstr "指定 Vi 兼容性的标志列表"
-#~ msgid "Save Redirection"
-#~ msgstr "保存重定向"
+#: ../../../runtime/optwin.vim:233
+msgid "paste mode, insert typed text literally"
+msgstr "粘贴模式,按本义插入输入的文本"
-#~ msgid "Save View"
-#~ msgstr "保存视图"
+#: ../../../runtime/optwin.vim:235
+msgid "key sequence to toggle paste mode"
+msgstr "切换粘贴模式的按键序列"
-#~ msgid "Save Session"
-#~ msgstr "保存会话"
+#: ../../../runtime/optwin.vim:241
+msgid "list of directories used for runtime files and plugins"
+msgstr "运行时文件和插件使用的目录列表"
-#~ msgid "Save Setup"
-#~ msgstr "保存设定"
+#: ../../../runtime/optwin.vim:243
+msgid "list of directories used for plugin packages"
+msgstr "插件包使用的目录列表"
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: 此版本无复合字符(digraph)"
+#: ../../../runtime/optwin.vim:245
+msgid "name of the main help file"
+msgstr "主帮助文件的名称"
-#~ msgid "Reading from stdin..."
-#~ msgstr "从标准输入读取..."
+#: ../../../runtime/optwin.vim:249
+msgid "moving around, searching and patterns"
+msgstr "移动、搜索以及正则表达式"
-#~ msgid "[NL found]"
-#~ msgstr "[找到 NL]"
+#: ../../../runtime/optwin.vim:250
+msgid "list of flags specifying which commands wrap to another line"
+msgstr "指定哪些命令折行的标志列表"
-#~ msgid "[crypted]"
-#~ msgstr "[已加密]"
+#: ../../../runtime/optwin.vim:252
+msgid ""
+"many jump commands move the cursor to the first non-blank\n"
+"character of a line"
+msgstr "许多跳转命令将光标移动到第一个非空的位置行中的字符"
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans 不允许未修改的缓冲区写入"
+#: ../../../runtime/optwin.vim:254
+msgid "nroff macro names that separate paragraphs"
+msgstr "用于分隔段落的 nroff 宏名"
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeans 不允许缓冲区部分写入"
+#: ../../../runtime/optwin.vim:256
+msgid "nroff macro names that separate sections"
+msgstr "用于分隔小节的 nroff 宏名"
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Resource fork 会丢失 (请加 ! 强制执行)"
+#: ../../../runtime/optwin.vim:258
+msgid "list of directory names used for file searching"
+msgstr "用于文件搜索的目录名称列表"
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: 无法启动图形界面"
+#: ../../../runtime/optwin.vim:261
+msgid ":cd without argument goes to the home directory"
+msgstr "不带参数的 :cd 进入主目录"
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: 无法读取文件 \"%s\""
+#: ../../../runtime/optwin.vim:263
+msgid "list of directory names used for :cd"
+msgstr "目录名称列表用于 :cd"
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: 无法启动图形界面,找不到有效的字体"
+#: ../../../runtime/optwin.vim:266
+msgid "change to directory of file in buffer"
+msgstr "切换到缓冲区的文件所在的目录"
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 无效的 'guifontwide'"
+#: ../../../runtime/optwin.vim:269
+msgid "search commands wrap around the end of the buffer"
+msgstr "搜索在缓冲区折行的命令"
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' 的值无效"
+#: ../../../runtime/optwin.vim:271
+msgid "show match for partly typed search command"
+msgstr "显示匹配部分键入的搜索命令"
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: 无法分配颜色 %s"
+#: ../../../runtime/optwin.vim:273
+msgid "change the way backslashes are used in search patterns"
+msgstr "改变反斜杠在搜索模式中的使用方式"
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "在光标处没有匹配,查找下一个"
+#: ../../../runtime/optwin.vim:275
+msgid "select the default regexp engine used"
+msgstr "选择默认的正则表达式引擎"
-#~ msgid "<cannot open> "
-#~ msgstr "<无法打开>"
+#: ../../../runtime/optwin.vim:277
+msgid "ignore case when using a search pattern"
+msgstr "使用搜索模式时忽略大小写"
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: 无法获取字体 %s"
+#: ../../../runtime/optwin.vim:279
+msgid "override 'ignorecase' when pattern has upper case characters"
+msgstr "当模式包含大写字符时,覆盖 'ignorecase'"
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: 无法返回当前目录"
+#: ../../../runtime/optwin.vim:281
+msgid "what method to use for changing case of letters"
+msgstr "用什么方法来改变字母的大小写"
-#~ msgid "Pathname:"
-#~ msgstr "路径:"
+#: ../../../runtime/optwin.vim:283
+msgid "maximum amount of memory in Kbyte used for pattern matching"
+msgstr "模式匹配使用的最大内存(以千字节为单位)"
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: 无法获取当前目录"
+#: ../../../runtime/optwin.vim:285
+msgid "pattern for a macro definition line"
+msgstr "宏定义行的模式"
-#~ msgid "OK"
-#~ msgstr "确定"
+#: ../../../runtime/optwin.vim:289
+msgid "pattern for an include-file line"
+msgstr "包含文件行的模式"
-#~ msgid "Cancel"
-#~ msgstr "取消"
+#: ../../../runtime/optwin.vim:292
+msgid "expression used to transform an include line to a file name"
+msgstr "用于将包含行转换为文件名的表达式"
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "滚动条部件: 无法获取滑块图像的几何大小"
+#: ../../../runtime/optwin.vim:298
+msgid "tags"
+msgstr "标签"
-#~ msgid "Vim dialog"
-#~ msgstr "Vim 对话框"
+#: ../../../runtime/optwin.vim:299
+msgid "use binary searching in tags files"
+msgstr "在标签文件中使用二分法查找"
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: 不能同时使用消息和回调函数来创建 BalloonEval"
+#: ../../../runtime/optwin.vim:301
+msgid "number of significant characters in a tag name or zero"
+msgstr "标签名称中的有效字符数,默认为零"
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim 对话框..."
+#: ../../../runtime/optwin.vim:303
+msgid "list of file names to search for tags"
+msgstr "用于搜索标签的文件名列表"
-#~ msgid "Input _Methods"
-#~ msgstr "输入法(_M)"
+#: ../../../runtime/optwin.vim:306
+msgid ""
+"how to handle case when searching in tags files:\n"
+"\"followic\" to follow 'ignorecase', \"ignore\" or \"match\""
+msgstr ""
+"在标签文件中搜索如何处理大小写: \"followic\" 跟随 'ignorecase', \"ignore\" 或"
+"者 \"match\""
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - 查找和替换..."
+#: ../../../runtime/optwin.vim:309
+msgid "file names in a tags file are relative to the tags file"
+msgstr "标签文件里的文件名是相对于标签文件的路径"
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - 查找..."
+#: ../../../runtime/optwin.vim:311
+msgid "a :tag command will use the tagstack"
+msgstr ":tag 命令将使用 tagstack"
-#~ msgid "Find what:"
-#~ msgstr "查找内容:"
+#: ../../../runtime/optwin.vim:313
+msgid "when completing tags in Insert mode show more info"
+msgstr "在插入模式补全标签时显示更多信息"
-#~ msgid "Replace with:"
-#~ msgstr "替换为:"
+#: ../../../runtime/optwin.vim:316
+msgid "a function to be used to perform tag searches"
+msgstr "用于执行标签搜索的函数"
-#~ msgid "Match whole word only"
-#~ msgstr "匹配完整的词"
+#: ../../../runtime/optwin.vim:322
+msgid "displaying text"
+msgstr "显示文本"
-#~ msgid "Match case"
-#~ msgstr "匹配大小写"
+#: ../../../runtime/optwin.vim:323
+msgid "number of lines to scroll for CTRL-U and CTRL-D"
+msgstr "按 CTRL-U 和 CTRL-D 滚动的行数"
-#~ msgid "Direction"
-#~ msgstr "方向"
+#: ../../../runtime/optwin.vim:326
+msgid "number of screen lines to show around the cursor"
+msgstr "在光标周围显示的屏幕行数"
-#~ msgid "Up"
-#~ msgstr "向上"
+#: ../../../runtime/optwin.vim:328
+msgid "long lines wrap"
+msgstr "长行自动换行"
-#~ msgid "Down"
-#~ msgstr "向下"
+#: ../../../runtime/optwin.vim:331
+msgid "wrap long lines at a character in 'breakat'"
+msgstr "在 'breakat' 中的字符处对长行折行"
-#~ msgid "Find Next"
-#~ msgstr "查找下一个"
+#: ../../../runtime/optwin.vim:334
+msgid "preserve indentation in wrapped text"
+msgstr "在折行文本中保持缩进"
-#~ msgid "Replace"
-#~ msgstr "替换"
+#: ../../../runtime/optwin.vim:337
+msgid "adjust breakindent behaviour"
+msgstr "调整 breakindent 的行为"
-#~ msgid "Replace All"
-#~ msgstr "全部替换"
+#: ../../../runtime/optwin.vim:340
+msgid "which characters might cause a line break"
+msgstr "哪些字符可能导致换行"
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: 从会话管理器收到 \"die\" 请求\n"
+#: ../../../runtime/optwin.vim:342
+msgid "string to put before wrapped screen lines"
+msgstr "放在折回的屏幕行之前的字符串"
-#~ msgid "Close"
-#~ msgstr "关闭"
+#: ../../../runtime/optwin.vim:344
+msgid "minimal number of columns to scroll horizontally"
+msgstr "水平滚动的最小列数"
-#~ msgid "New tab"
-#~ msgstr "新建标签"
+#: ../../../runtime/optwin.vim:346
+msgid "minimal number of columns to keep left and right of the cursor"
+msgstr "保留在光标左右的最小列数"
-#~ msgid "Open Tab..."
-#~ msgstr "打开标签..."
+#: ../../../runtime/optwin.vim:348
+msgid ""
+"include \"lastline\" to show the last line even if it doesn't fit\n"
+"include \"uhex\" to show unprintable characters as a hex number"
+msgstr ""
+"包含 \"lastline\" 来显示最后一行,即使它显示不下\n"
+"包含 \"uhex\" 以十六进制显示不可打印字符"
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: 主窗口被意外地摧毁\n"
+#: ../../../runtime/optwin.vim:350
+msgid "characters to use for the status line, folds and filler lines"
+msgstr "用于状态行、折叠和填充行的字符"
-#~ msgid "Font Selection"
-#~ msgstr "选择字体"
+#: ../../../runtime/optwin.vim:352
+msgid "number of lines used for the command-line"
+msgstr "用于命令行的行数"
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "使用 CUT_BUFFER0 来取代空选择"
+#: ../../../runtime/optwin.vim:354
+msgid "width of the display"
+msgstr "显示的宽度"
-#~ msgid "&Filter"
-#~ msgstr "过滤(&F)"
+#: ../../../runtime/optwin.vim:356
+msgid "number of lines in the display"
+msgstr "显示的行数"
-#~ msgid "&Cancel"
-#~ msgstr "取消(&C)"
+#: ../../../runtime/optwin.vim:358
+msgid "number of lines to scroll for CTRL-F and CTRL-B"
+msgstr "按 CTRL-F 和 CTRL-B 滚动的行数"
-#~ msgid "Directories"
-#~ msgstr "目录"
+#: ../../../runtime/optwin.vim:360
+msgid "don't redraw while executing macros"
+msgstr "在执行宏时不要重新绘制"
-#~ msgid "Filter"
-#~ msgstr "过滤器"
+#: ../../../runtime/optwin.vim:363
+msgid "timeout for 'hlsearch' and :match highlighting in msec"
+msgstr "'hlsearch' 和 :match 高亮的超时时间(以毫秒计)"
-#~ msgid "&Help"
-#~ msgstr "帮助(&H)"
+#: ../../../runtime/optwin.vim:366
+msgid ""
+"delay in msec for each char written to the display\n"
+"(for debugging)"
+msgstr "每个字符写到显示的延时(以毫秒计;用于调试)"
-#~ msgid "Files"
-#~ msgstr "文件"
+#: ../../../runtime/optwin.vim:368
+msgid "show <Tab> as ^I and end-of-line as $"
+msgstr "以 ^I 显示 <Tab>, 以 $ 显示行尾"
-#~ msgid "&OK"
-#~ msgstr "确定(&O)"
+#: ../../../runtime/optwin.vim:371
+msgid "list of strings used for list mode"
+msgstr "用于 list 模式的字符串列表"
-#~ msgid "Selection"
-#~ msgstr "选择"
+#: ../../../runtime/optwin.vim:373
+msgid "show the line number for each line"
+msgstr "对每一行显示行号"
-#~ msgid "Find &Next"
-#~ msgstr "查找下一个(&N)"
+#: ../../../runtime/optwin.vim:376
+msgid "show the relative line number for each line"
+msgstr "显示每行的相对行号"
-#~ msgid "&Replace"
-#~ msgstr "替换(&R)"
+#: ../../../runtime/optwin.vim:380
+msgid "number of columns to use for the line number"
+msgstr "用于行号的列数"
-#~ msgid "Replace &All"
-#~ msgstr "全部替换(&A)"
+#: ../../../runtime/optwin.vim:385
+msgid "controls whether concealable text is hidden"
+msgstr "控制是否隐藏可隐藏文本"
-#~ msgid "&Undo"
-#~ msgstr "撤销(&U)"
+#: ../../../runtime/optwin.vim:388
+msgid "modes in which text in the cursor line can be concealed"
+msgstr "可隐藏光标行的文本的模式"
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: 找不到窗口标题 \"%s\""
+#: ../../../runtime/optwin.vim:394
+msgid "syntax, highlighting and spelling"
+msgstr "语法、高亮和拼写"
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: 不支持的参数: \"-%s\";请使用 OLE 版本。"
+#: ../../../runtime/optwin.vim:395
+msgid "\"dark\" or \"light\"; the background color brightness"
+msgstr "\"dark\" 或者 \"light\";背景色亮度"
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: 无法在 MDI 应用程序中打开窗口"
+#: ../../../runtime/optwin.vim:397
+msgid "type of file; triggers the FileType event when set"
+msgstr "文件类型; 在设置时触发 FileType 事件"
-#~ msgid "Close tab"
-#~ msgstr "关闭标签"
+#: ../../../runtime/optwin.vim:401
+msgid "name of syntax highlighting used"
+msgstr "使用中的语法高亮显示的名称"
-#~ msgid "Open tab..."
-#~ msgstr "打开标签..."
+#: ../../../runtime/optwin.vim:404
+msgid "maximum column to look for syntax items"
+msgstr "寻找语法项的最大列"
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "查找字符串 (使用 '\\\\' 来查找 '\\')"
+#: ../../../runtime/optwin.vim:408
+msgid "which highlighting to use for various occasions"
+msgstr "在不同场合使用哪些高亮提示"
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "查找和替换字符串 (使用 '\\\\' 来查找 '\\')"
+#: ../../../runtime/optwin.vim:410
+msgid "highlight all matches for the last used search pattern"
+msgstr "高亮显示最后使用的搜索模式的所有匹配项"
-#~ msgid "Not Used"
-#~ msgstr "未使用"
+#: ../../../runtime/optwin.vim:413
+msgid "use GUI colors for the terminal"
+msgstr "为终端使用 GUI 颜色"
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "目录\t*.nothing\n"
+#: ../../../runtime/optwin.vim:417
+msgid "highlight the screen column of the cursor"
+msgstr "突出显示光标的屏幕列"
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: 无法分配颜色表项,某些颜色可能不正确"
+#: ../../../runtime/optwin.vim:420
+msgid "highlight the screen line of the cursor"
+msgstr "突出显示光标的屏幕行"
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Fontset %s 缺少下列字符集的字体:"
+#: ../../../runtime/optwin.vim:423
+msgid "specifies which area 'cursorline' highlights"
+msgstr "指定 'cursorline' 高亮显示的区域"
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Fontset 名称: %s"
+#: ../../../runtime/optwin.vim:426
+msgid "columns to highlight"
+msgstr "要高亮的列"
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "'%s' 不是固定宽度的字体"
+#: ../../../runtime/optwin.vim:429
+msgid "highlight spelling mistakes"
+msgstr "高亮拼写错误"
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Fontset 名称: %s\n"
+#: ../../../runtime/optwin.vim:432
+msgid "list of accepted languages"
+msgstr "接受的语言列表"
-#~ msgid "Font0: %s\n"
-#~ msgstr "字体0: %s\n"
+#: ../../../runtime/optwin.vim:435
+msgid "file that \"zg\" adds good words to"
+msgstr "\"zg\" 添加正确单词的文件"
-#~ msgid "Font1: %s\n"
-#~ msgstr "字体1: %s\n"
+#: ../../../runtime/optwin.vim:438
+msgid "pattern to locate the end of a sentence"
+msgstr "定位句子尾部的模式"
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "字体%<PRId64>的宽度不是字体0的两倍\n"
+#: ../../../runtime/optwin.vim:441
+msgid "flags to change how spell checking works"
+msgstr "更改拼写检查工作方式的标志"
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "字体0的宽度:%<PRId64>\n"
+#: ../../../runtime/optwin.vim:444
+msgid "methods used to suggest corrections"
+msgstr "用于建议修正的方法"
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "字体1的宽度: %<PRId64>\n"
-#~ "\n"
+#: ../../../runtime/optwin.vim:446
+msgid "amount of memory used by :mkspell before compressing"
+msgstr ":mkspell 在压缩前使用的内存量"
-#~ msgid "Invalid font specification"
-#~ msgstr "指定了无效的字体"
+#: ../../../runtime/optwin.vim:451
+msgid "multiple windows"
+msgstr "多个窗口"
-#~ msgid "&Dismiss"
-#~ msgstr "取消(&D)"
+#: ../../../runtime/optwin.vim:452
+msgid "0, 1, 2 or 3; when to use a status line for the last window"
+msgstr "0、1、2 或 3;何时为最后一个窗口使用状态行"
-#~ msgid "no specific match"
-#~ msgstr "找不到匹配的项"
+#: ../../../runtime/optwin.vim:455
+msgid "alternate format to be used for a status line"
+msgstr "用于状态行的替代格式"
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - 字体选择器"
+#: ../../../runtime/optwin.vim:458
+msgid "make all windows the same size when adding/removing windows"
+msgstr "当添加/删除窗口时,使所有窗口的大小相同"
-#~ msgid "Name:"
-#~ msgstr "名称:"
+#: ../../../runtime/optwin.vim:460
+msgid "in which direction 'equalalways' works: \"ver\", \"hor\" or \"both\""
+msgstr "'equalalways' 的工作方向:\"ver\", \"hor\" 或者 \"both\""
-#~ msgid "Encoding:"
-#~ msgstr "编码:"
+#: ../../../runtime/optwin.vim:462
+msgid "minimal number of lines used for the current window"
+msgstr "当前窗口的最小行数"
-#~ msgid "Font:"
-#~ msgstr "字体:"
+#: ../../../runtime/optwin.vim:464
+msgid "minimal number of lines used for any window"
+msgstr "任何窗口的最小行数"
-#~ msgid "Style:"
-#~ msgstr "风格:"
+#: ../../../runtime/optwin.vim:466
+msgid "keep the height of the window"
+msgstr "保持窗口的高度"
-#~ msgid "Size:"
-#~ msgstr "尺寸:"
+#: ../../../runtime/optwin.vim:469
+msgid "keep the width of the window"
+msgstr "保持窗口的宽度"
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangul automata 错误"
+#: ../../../runtime/optwin.vim:472
+msgid "minimal number of columns used for the current window"
+msgstr "当前窗口的最小列数"
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat 错误"
+#: ../../../runtime/optwin.vim:474
+msgid "minimal number of columns used for any window"
+msgstr "任何窗口的最小列数"
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: 无法打开 cscope 数据库: %s"
+#: ../../../runtime/optwin.vim:476
+msgid "initial height of the help window"
+msgstr "帮助窗口的初始高度"
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: 无法获取 cscope 数据库信息"
+#: ../../../runtime/optwin.vim:481
+msgid "default height for the preview window"
+msgstr "预览窗口的默认高度"
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: 已达到 cscope 的最大连接数"
+#: ../../../runtime/optwin.vim:483
+msgid "identifies the preview window"
+msgstr "标识预览窗口"
-#~ msgid ""
-#~ "???: Sorry, this command is disabled, the MzScheme library could not be "
-#~ "loaded."
-#~ msgstr "???: 抱歉,此命令不可用,无法加载 MzScheme 库"
+#: ../../../runtime/optwin.vim:487
+msgid "don't unload a buffer when no longer shown in a window"
+msgstr "当缓冲区不再显示在窗口中时,不要卸载它"
-#~ msgid "invalid expression"
-#~ msgstr "无效的表达式"
+#: ../../../runtime/optwin.vim:489
+msgid ""
+"\"useopen\" and/or \"split\"; which window to use when jumping\n"
+"to a buffer"
+msgstr "当向缓冲区跳转时可使用窗口: \"useopen\" 和/或 \"split\""
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "编译时没有启用表达式"
+#: ../../../runtime/optwin.vim:491
+msgid "a new window is put below the current one"
+msgstr "新窗口放在当前窗口的下面"
-#~ msgid "hidden option"
-#~ msgstr "隐藏的选项"
+#: ../../../runtime/optwin.vim:493
+msgid "determines scroll behavior for split windows"
+msgstr ""
-#~ msgid "unknown option"
-#~ msgstr "未知的选项"
+#: ../../../runtime/optwin.vim:495
+msgid "a new window is put right of the current one"
+msgstr "新窗口放在当前窗口的右边"
-#~ msgid "window index is out of range"
-#~ msgstr "窗口索引超出范围"
+#: ../../../runtime/optwin.vim:497
+msgid "this window scrolls together with other bound windows"
+msgstr "此窗口与其他已绑定的窗口一起滚动"
-#~ msgid "couldn't open buffer"
-#~ msgstr "无法打开缓冲区"
+#: ../../../runtime/optwin.vim:500
+msgid "\"ver\", \"hor\" and/or \"jump\"; list of options for 'scrollbind'"
+msgstr "'scrollbind' 的选项列表: \"ver\", \"hor\" 和/或 \"jump\""
-#~ msgid "cannot save undo information"
-#~ msgstr "无法保存撤销信息"
+#: ../../../runtime/optwin.vim:502
+msgid "this window's cursor moves together with other bound windows"
+msgstr "此窗口的光标与其他已绑定的窗口一起移动"
-#~ msgid "cannot delete line"
-#~ msgstr "无法删除行"
+#: ../../../runtime/optwin.vim:506
+msgid "size of a terminal window"
+msgstr "终端窗口的大小"
-#~ msgid "cannot replace line"
-#~ msgstr "无法替换行"
+#: ../../../runtime/optwin.vim:509
+msgid "key that precedes Vim commands in a terminal window"
+msgstr "终端窗口中 Vim 命令的前导键"
-#~ msgid "cannot insert line"
-#~ msgstr "无法插入行"
+#: ../../../runtime/optwin.vim:515
+msgid "multiple tab pages"
+msgstr "多个标签页"
-#~ msgid "string cannot contain newlines"
-#~ msgstr "字符串不能包含换行(NL)"
+#: ../../../runtime/optwin.vim:516
+msgid "0, 1 or 2; when to use a tab pages line"
+msgstr "0, 1 或 2; 何时使用标签页行"
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim 错误: ~a"
+#: ../../../runtime/optwin.vim:518
+msgid "maximum number of tab pages to open for -p and \"tab all\""
+msgstr "-p 和 \"tab all\" 打开的最大标签页数"
-#~ msgid "Vim error"
-#~ msgstr "Vim 错误"
+#: ../../../runtime/optwin.vim:520
+msgid "custom tab pages line"
+msgstr "自定义标签页行"
-#~ msgid "buffer is invalid"
-#~ msgstr "缓冲区无效"
+#: ../../../runtime/optwin.vim:523
+msgid "custom tab page label for the GUI"
+msgstr "为 GUI 自定义标签页的标签"
-#~ msgid "window is invalid"
-#~ msgstr "窗口无效"
+#: ../../../runtime/optwin.vim:525
+msgid "custom tab page tooltip for the GUI"
+msgstr "为 GUI 自定义标签页的工具提示"
-#~ msgid "linenr out of range"
-#~ msgstr "行号超出范围"
+#: ../../../runtime/optwin.vim:530
+msgid "terminal"
+msgstr "终端"
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "不允许在 sandbox 中使用"
+#: ../../../runtime/optwin.vim:531
+msgid "minimal number of lines to scroll at a time"
+msgstr "一次滚动的最少行数"
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr "E263: 抱歉,此命令不可用,无法加载 Python 库。"
+#: ../../../runtime/optwin.vim:534
+msgid "specifies what the cursor looks like in different modes"
+msgstr "指定光标在不同模式下的样子"
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: 不能递归调用 Python"
+#: ../../../runtime/optwin.vim:539
+msgid "show info in the window title"
+msgstr "在窗口标题中显示信息"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "不能删除 OutputObject 属性"
+#: ../../../runtime/optwin.vim:542
+msgid "percentage of 'columns' used for the window title"
+msgstr "窗口标题的 'columns' 的百分比"
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace 必须是整数"
+#: ../../../runtime/optwin.vim:544
+msgid "when not empty, string to be used for the window title"
+msgstr "非空时,用于窗口标题的字符串"
-#~ msgid "invalid attribute"
-#~ msgstr "无效的属性"
+#: ../../../runtime/optwin.vim:546
+msgid "string to restore the title to when exiting Vim"
+msgstr "退出 Vim 时用于恢复标题的字符串"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() 需要字符串列表作参数"
+#: ../../../runtime/optwin.vim:549
+msgid "set the text of the icon for this window"
+msgstr "设置此窗口图标的文本"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: 初始化 I/O 对象出错"
+#: ../../../runtime/optwin.vim:552
+msgid "when not empty, text for the icon of this window"
+msgstr "非空时,设置此窗口图标的文本"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "试图引用已被删除的缓冲区"
+#: ../../../runtime/optwin.vim:557
+msgid "using the mouse"
+msgstr "使用鼠标"
-#~ msgid "line number out of range"
-#~ msgstr "行号超出范围"
+#: ../../../runtime/optwin.vim:558
+msgid "list of flags for using the mouse"
+msgstr "使用鼠标时的标志列表"
-#~ msgid "<buffer object (deleted) at %8lX>"
-#~ msgstr "<缓冲区对象(已删除): %8lX>"
+#: ../../../runtime/optwin.vim:561
+msgid "the window with the mouse pointer becomes the current one"
+msgstr "带有鼠标指针的窗口成为当前窗口"
-#~ msgid "invalid mark name"
-#~ msgstr "无效的标记名称"
+#: ../../../runtime/optwin.vim:563
+msgid "hide the mouse pointer while typing"
+msgstr "在输入时隐藏鼠标指针"
-#~ msgid "no such buffer"
-#~ msgstr "无此缓冲区"
+#: ../../../runtime/optwin.vim:566
+msgid ""
+"\"extend\", \"popup\" or \"popup_setpos\"; what the right\n"
+"mouse button is used for"
+msgstr "\"extend\", \"popup\" 或 \"popup_setpos\"; 鼠标右键用于什么"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "试图引用已被删除的窗口"
+#: ../../../runtime/optwin.vim:568
+msgid "maximum time in msec to recognize a double-click"
+msgstr "识别双击的最大时间(以毫秒计)"
-#~ msgid "readonly attribute"
-#~ msgstr "只读属性"
+#: ../../../runtime/optwin.vim:571
+msgid "what the mouse pointer looks like in different modes"
+msgstr "鼠标指针在不同模式下的样子"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "光标位置在缓冲区外"
+#: ../../../runtime/optwin.vim:577
+msgid "GUI"
+msgstr "图形用户界面"
-#~ msgid "<window object (deleted) at %.8lX>"
-#~ msgstr "<窗口对象(已删除): %.8lX>"
+#: ../../../runtime/optwin.vim:578
+msgid "list of font names to be used in the GUI"
+msgstr "在 GUI 中使用的字体名称列表"
-#~ msgid "<window object (unknown) at %.8lX>"
-#~ msgstr "<窗口对象(未知): %.8lX>"
+#: ../../../runtime/optwin.vim:581
+msgid "pair of fonts to be used, for multibyte editing"
+msgstr "用于多字节编辑的字体对"
-#~ msgid "<window %d>"
-#~ msgstr "<窗口 %d>"
+#: ../../../runtime/optwin.vim:584
+msgid "list of font names to be used for double-wide characters"
+msgstr "用于双宽度字符的字体名称列表"
-#~ msgid "no such window"
-#~ msgstr "无此窗口"
+#: ../../../runtime/optwin.vim:586
+msgid "list of flags that specify how the GUI works"
+msgstr "指定 GUI 工作方式的标志列表"
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr "E266: 抱歉,此命令不可用,无法加载 Ruby 库"
+#: ../../../runtime/optwin.vim:589
+msgid "\"icons\", \"text\" and/or \"tooltips\"; how to show the toolbar"
+msgstr "\"icons\", \"text\" 和/或 \"tooltips\"; 如何显示工具栏"
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: 未知的 longjmp 状态 %d"
+#: ../../../runtime/optwin.vim:592
+msgid "size of toolbar icons"
+msgstr "工具栏图标大小"
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "切换实现/定义"
+#: ../../../runtime/optwin.vim:597
+msgid ""
+"\"last\", \"buffer\" or \"current\": which directory used for the file "
+"browser"
+msgstr "\"last\", \"buffer\" 或 \"current\"; 文件浏览器使用哪个目录"
-#~ msgid "Show base class of"
-#~ msgstr "显示 base class of:"
+#: ../../../runtime/optwin.vim:601
+msgid "language to be used for the menus"
+msgstr "菜单使用的语言"
-#~ msgid "Show overridden member function"
-#~ msgstr "显示被覆盖的成员函数"
+#: ../../../runtime/optwin.vim:604
+msgid "maximum number of items in one menu"
+msgstr "单个菜单中的最大项目数量"
-#~ msgid "Retrieve from file"
-#~ msgstr "恢复: 从文件"
+#: ../../../runtime/optwin.vim:607
+msgid "\"no\", \"yes\" or \"menu\"; how to use the ALT key"
+msgstr "\"no\", \"yes\" 或 \"menu\"; 如何使用 ALT 键"
-#~ msgid "Retrieve from project"
-#~ msgstr "恢复: 从对象"
+#: ../../../runtime/optwin.vim:610
+msgid "number of pixel lines to use between characters"
+msgstr "字符之间使用的像素行数"
-#~ msgid "Retrieve from all projects"
-#~ msgstr "恢复: 从所有项目"
+#: ../../../runtime/optwin.vim:613
+msgid "delay in milliseconds before a balloon may pop up"
+msgstr "延迟指定毫秒后,气泡可能会弹出"
-#~ msgid "Retrieve"
-#~ msgstr "恢复"
+#: ../../../runtime/optwin.vim:616
+msgid "use balloon evaluation in the GUI"
+msgstr "在 GUI 中使用气泡求值"
-#~ msgid "Show source of"
-#~ msgstr "显示源代码: "
+#: ../../../runtime/optwin.vim:620
+msgid "use balloon evaluation in the terminal"
+msgstr "在终端中使用气泡求值"
-#~ msgid "Find symbol"
-#~ msgstr "查找 symbol"
+#: ../../../runtime/optwin.vim:624
+msgid "expression to show in balloon eval"
+msgstr "在气泡求值中显示的表达式"
-#~ msgid "Browse class"
-#~ msgstr "浏览 class"
+#: ../../../runtime/optwin.vim:631
+msgid "printing"
+msgstr "打印"
-#~ msgid "Show class in hierarchy"
-#~ msgstr "显示层次关系的类"
+#: ../../../runtime/optwin.vim:632
+msgid "list of items that control the format of :hardcopy output"
+msgstr "控制 :hardcopy 输出格式的项目列表"
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "显示 restricted 层次关系的 class"
+#: ../../../runtime/optwin.vim:634
+msgid "name of the printer to be used for :hardcopy"
+msgstr "用于 :hardcopy 的打印机名称"
-#~ msgid "Xref refers to"
-#~ msgstr "Xref 参考到"
+#: ../../../runtime/optwin.vim:637
+msgid "expression used to print the PostScript file for :hardcopy"
+msgstr "用于 :hardcopy 打印 PostScript 文件的表达式"
-#~ msgid "Xref referred by"
-#~ msgstr "Xref 被谁参考:"
+#: ../../../runtime/optwin.vim:640
+msgid "name of the font to be used for :hardcopy"
+msgstr ":hardcopy 使用的字体名称"
-#~ msgid "Xref has a"
-#~ msgstr "Xref 有"
+#: ../../../runtime/optwin.vim:642
+msgid "format of the header used for :hardcopy"
+msgstr "用于 :hardcopy 的标头格式"
-#~ msgid "Xref used by"
-#~ msgstr "Xref 被谁使用:"
+#: ../../../runtime/optwin.vim:645
+msgid "encoding used to print the PostScript file for :hardcopy"
+msgstr "用于 :hardcopy 打印 PostScript 文件的编码"
-#~ msgid "Show docu of"
-#~ msgstr "显示文件: "
+#: ../../../runtime/optwin.vim:648
+msgid "the CJK character set to be used for CJK output from :hardcopy"
+msgstr ":hardcopy 用于 CJK 输出的 CJK 字符集"
-#~ msgid "Generate docu for"
-#~ msgstr "产生文件: "
+#: ../../../runtime/optwin.vim:650
+msgid "list of font names to be used for CJK output from :hardcopy"
+msgstr ":hardcopy 用于 CJK 输出的字体名称列表"
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "不能连接到 SNiFF+。请检查环境变量 ($PATH 里必需可以找到 sniffemacs)\n"
+#: ../../../runtime/optwin.vim:654
+msgid "messages and info"
+msgstr "消息和信息"
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: 读取错误. 取消连接"
+#: ../../../runtime/optwin.vim:655
+msgid "add 's' flag in 'shortmess' (don't show search message)"
+msgstr "在 'shortmess' 中添加 's' 标志(不显示搜索消息)"
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ 目前"
+#: ../../../runtime/optwin.vim:657
+msgid "list of flags to make messages shorter"
+msgstr "使消息更短的标志列表"
-#~ msgid "not "
-#~ msgstr "未"
+#: ../../../runtime/optwin.vim:659
+msgid "show (partial) command keys in the status line"
+msgstr "在状态行中显示(不完整的)命令键"
-#~ msgid "connected"
-#~ msgstr "连接中"
+#: ../../../runtime/optwin.vim:663
+msgid "display the current mode in the status line"
+msgstr "在状态行中显示当前模式"
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: 不正确的 SNiff+ 调用: %s"
+#: ../../../runtime/optwin.vim:665
+msgid "show cursor position below each window"
+msgstr "在每个窗口下方显示光标的位置"
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: 连接到 SNiFF+ 失败"
+#: ../../../runtime/optwin.vim:670
+msgid "alternate format to be used for the ruler"
+msgstr "ruler 的替代格式"
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: 未连接到 SNiFF+"
+#: ../../../runtime/optwin.vim:673
+msgid "threshold for reporting number of changed lines"
+msgstr "报告已更改行数的阈值"
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: 不是 SNiFF+ 的缓冲区"
+#: ../../../runtime/optwin.vim:675
+msgid "the higher the more messages are given"
+msgstr "等级越高,给出的信息越多"
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: 写入错误。结束连接"
+#: ../../../runtime/optwin.vim:677
+msgid "file to write messages in"
+msgstr "用于写入消息的文件"
-#~ msgid "invalid buffer number"
-#~ msgstr "无效的缓冲区号"
+#: ../../../runtime/optwin.vim:679
+msgid "pause listings when the screen is full"
+msgstr "当屏幕满时暂停显示清单"
-#~ msgid "not implemented yet"
-#~ msgstr "尚未实现"
+#: ../../../runtime/optwin.vim:682
+msgid "start a dialog when a command fails"
+msgstr "当命令失败时开启对话框"
-#~ msgid "cannot set line(s)"
-#~ msgstr "无法设定行"
+#: ../../../runtime/optwin.vim:685
+msgid "ring the bell for error messages"
+msgstr "错误信息响铃"
-#~ msgid "mark not set"
-#~ msgstr "没有设定标记"
+#: ../../../runtime/optwin.vim:687
+msgid "use a visual bell instead of beeping"
+msgstr "使用视觉铃声代替响铃"
-#~ msgid "row %d column %d"
-#~ msgstr "第 %d 行 第 %d 列"
+#: ../../../runtime/optwin.vim:689
+msgid "do not ring the bell for these reasons"
+msgstr "不要为这些原因响铃"
-#~ msgid "cannot insert/append line"
-#~ msgstr "无法插入/追加行"
+#: ../../../runtime/optwin.vim:692
+msgid "list of preferred languages for finding help"
+msgstr "查找帮助的首选语言列表"
-#~ msgid "unknown flag: "
-#~ msgstr "未知的标志: "
+#: ../../../runtime/optwin.vim:697
+msgid "selecting text"
+msgstr "选择文本"
-#~ msgid "unknown vimOption"
-#~ msgstr "未知的 vim 选项"
+#: ../../../runtime/optwin.vim:698
+msgid "\"old\", \"inclusive\" or \"exclusive\"; how selecting text behaves"
+msgstr "\"old\", \"inclusive\" 或 \"exclusive\"; 如何选择文本"
-#~ msgid "keyboard interrupt"
-#~ msgstr "键盘中断"
+#: ../../../runtime/optwin.vim:700
+msgid ""
+"\"mouse\", \"key\" and/or \"cmd\"; when to start Select mode\n"
+"instead of Visual mode"
+msgstr "\"mouse\", \"key\" 和/或 \"cmd\"; 何时启动选择模式而不是可视模式"
-#~ msgid "vim error"
-#~ msgstr "vim 错误"
+#: ../../../runtime/optwin.vim:703
+msgid ""
+"\"unnamed\" to use the * register like unnamed register\n"
+"\"autoselect\" to always put selected text on the clipboard"
+msgstr ""
+"\"unnamed\": 像无名寄存器一样使用 * 寄存器\n"
+"\"autoselect\": 将选择的文本始终放在剪贴板上"
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "无法创建缓冲区/窗口命令: 对象将被删除"
+#: ../../../runtime/optwin.vim:706
+msgid "\"startsel\" and/or \"stopsel\"; what special keys can do"
+msgstr "\"startsel\" 和/或 \"stopsel\"; 特殊键可以做"
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "无法注册回调命令: 缓冲区/窗口已被删除"
+#: ../../../runtime/optwin.vim:710
+msgid "editing text"
+msgstr "编辑文本"
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr "E280: TCL 严重错误: reflist 损坏!?请报告给 vim-dev@vim.org"
+#: ../../../runtime/optwin.vim:711
+msgid "maximum number of changes that can be undone"
+msgstr "可以撤销的最大更改数"
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr "无法注册回调命令: 找不到缓冲区/窗口引用"
+#: ../../../runtime/optwin.vim:714
+msgid "automatically save and restore undo history"
+msgstr "自动保存和恢复撤销历史"
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr "E571: 抱歉,此命令不可用,无法加载 Tcl 库"
+#: ../../../runtime/optwin.vim:716
+msgid "list of directories for undo files"
+msgstr "撤销文件的目录列表"
-#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
-#~ msgstr "E281: TCL 错误: 退出返回值不是整数!?请报告给 vim-dev@vim.org"
+#: ../../../runtime/optwin.vim:718
+msgid "maximum number lines to save for undo on a buffer reload"
+msgstr "缓冲区重新加载时为撤销保存的最大行数"
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: 退出返回值 %d"
+#: ../../../runtime/optwin.vim:720
+msgid "changes have been made and not written to a file"
+msgstr "已经做出了修改,但没有被写入文件"
-#~ msgid "cannot get line"
-#~ msgstr "无法获取行"
+#: ../../../runtime/optwin.vim:723
+msgid "buffer is not to be written"
+msgstr "缓冲区不会被写入"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "无法注册命令服务器名"
+#: ../../../runtime/optwin.vim:726
+msgid "changes to the text are possible"
+msgstr "可以对文本进行更改"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: 无法发送命令到目的程序"
+#: ../../../runtime/optwin.vim:729
+msgid "line length above which to break a line"
+msgstr "超过行长度就断行"
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: 使用了无效的服务器 id: %s"
+#: ../../../runtime/optwin.vim:732
+msgid "margin from the right in which to break a line"
+msgstr "断行开始的右边距"
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM 实例注册属性有误。已删除!"
+#: ../../../runtime/optwin.vim:735
+msgid "specifies what <BS>, CTRL-W, etc. can do in Insert mode"
+msgstr "指定 <BS>, CTRL-W 等在插入模式下可以做什么"
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "此 Vim 编译时没有加入 diff 功能"
+#: ../../../runtime/optwin.vim:737
+msgid "definition of what comment lines look like"
+msgstr "定义注释行长什么样"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: 错误: 无法从 NetBeans 中启动 gvim\n"
+#: ../../../runtime/optwin.vim:740
+msgid "list of flags that tell how automatic formatting works"
+msgstr "控制自动格式化如何工作的标志列表"
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\t注册此 gvim 到 OLE"
+#: ../../../runtime/optwin.vim:743
+msgid "pattern to recognize a numbered list"
+msgstr "识别编号列表的模式"
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\t取消 OLE 中的 gvim 注册"
+#: ../../../runtime/optwin.vim:747
+msgid "expression used for \"gq\" to format lines"
+msgstr "用 \"gq\" 格式化行时使用的表达式"
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\t使用图形界面 (同 \"gvim\")"
+#: ../../../runtime/optwin.vim:752
+msgid "specifies how Insert mode completion works for CTRL-N and CTRL-P"
+msgstr "指定使用 CTRL-N 和 CTRL-P 进行插入模式补全的工作方式"
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f 或 --nofork\t前台: 启动图形界面时不 fork"
+#: ../../../runtime/optwin.vim:755
+msgid "whether to use a popup menu for Insert mode completion"
+msgstr "是否在插入模式补全时使用弹出菜单"
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tVerbose 等级"
+#: ../../../runtime/optwin.vim:757
+msgid "maximum height of the popup menu"
+msgstr "弹出菜单的最大高度"
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\t不使用 newcli 来打开窗口"
+#: ../../../runtime/optwin.vim:759
+msgid "minimum width of the popup menu"
+msgstr "弹出菜单的最小宽度"
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\t使用 <device> 进行输入输出"
+#: ../../../runtime/optwin.vim:761
+msgid "user defined function for Insert mode completion"
+msgstr "用于插入模式补全的用户定义函数"
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t使用 <gvimrc> 替代任何 .gvimrc"
+#: ../../../runtime/optwin.vim:764
+msgid "function for filetype-specific Insert mode completion"
+msgstr "用于特定文件类型的插入模式补全的函数"
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t编辑加密的文件"
+#: ../../../runtime/optwin.vim:767
+msgid "list of dictionary files for keyword completion"
+msgstr "用于关键字补全的字典文件列表"
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\t将 vim 与指定的 X-server 连接"
+#: ../../../runtime/optwin.vim:770
+msgid "list of thesaurus files for keyword completion"
+msgstr "用于关键字补全的同义词字典文件列表"
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\t不连接到 X Server"
+#: ../../../runtime/optwin.vim:773
+msgid "function used for thesaurus completion"
+msgstr "用于同义词字典补全的函数"
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\t如有可能,在 Vim 服务器上编辑文件 <files>"
+#: ../../../runtime/optwin.vim:777
+msgid "adjust case of a keyword completion match"
+msgstr "调整关键字补全匹配的大小写"
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> 同上,找不到服务器时不抱怨"
+#: ../../../runtime/optwin.vim:781
+msgid "enable entering digraphs with c1 <BS> c2"
+msgstr "支持使用 c1 <BS> c2 输入二合字符"
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files> 同 --remote 但会等待文件完成编辑"
+#: ../../../runtime/optwin.vim:784
+msgid "the \"~\" command behaves like an operator"
+msgstr "\"~\"命令表现得像操作符"
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-wait-silent <files> 同上,找不到服务器时不抱怨"
+#: ../../../runtime/optwin.vim:786
+msgid "function called for the \"g@\" operator"
+msgstr "\"g@\" 操作符调用的函数"
-#~ msgid "--remote-tab <files> As --remote but open tab page for each file"
-#~ msgstr "--remote-tab <files> 同 --remote 但对每个文件打开一个标签页"
+#: ../../../runtime/optwin.vim:788
+msgid "when inserting a bracket, briefly jump to its match"
+msgstr "当插入括号时,短暂地跳转到匹配它的括号"
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\t送出 <keys> 到 Vim 服务器并退出"
+#: ../../../runtime/optwin.vim:790
+msgid "tenth of a second to show a match for 'showmatch'"
+msgstr "显示 'showmatch' 的匹配的时长(以十分之一秒计)"
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\t在 Vim 服务器上求 <expr> 的值并打印结果"
+#: ../../../runtime/optwin.vim:792
+msgid "list of pairs that match for the \"%\" command"
+msgstr "\"%\" 命令匹配的对列表"
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\t列出可用的 Vim 服务器名称并退出"
+#: ../../../runtime/optwin.vim:795
+msgid "use two spaces after '.' when joining a line"
+msgstr "连接行时,在 '.' 后面添加两个空格"
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\t发送到或成为 Vim 服务器 <name>"
+#: ../../../runtime/optwin.vim:797
+msgid ""
+"\"alpha\", \"octal\", \"hex\", \"bin\" and/or \"unsigned\"; number formats\n"
+"recognized for CTRL-A and CTRL-X commands"
+msgstr ""
+"\"alpha\", \"octal\", \"hex\", \"bin\" 和/或 \"unsigned\"\n"
+"CTRL-A 和 CTRL-X 命令识别的数字的格式"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (Motif 版本) 可识别的参数:\n"
+#: ../../../runtime/optwin.vim:802
+msgid "tabs and indenting"
+msgstr "Tab 和缩进"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (neXtaw 版本) 可识别的参数:\n"
+#: ../../../runtime/optwin.vim:803
+msgid "number of spaces a <Tab> in the text stands for"
+msgstr "<Tab> 在文本中代表的空格数"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (Athena 版本) 可识别的参数:\n"
+#: ../../../runtime/optwin.vim:806
+msgid "number of spaces used for each step of (auto)indent"
+msgstr "每步(自动)缩进所使用的空格数"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t在 <display> 上运行 vim"
+#: ../../../runtime/optwin.vim:810
+msgid "list of number of spaces a tab counts for"
+msgstr "tab 代表的空格数的列表"
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\t启动后最小化"
+#: ../../../runtime/optwin.vim:813
+msgid "list of number of spaces a soft tabsstop counts for"
+msgstr "软制表符代表的空格数的列表"
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <name>\t\t读取 Resource 时把 vim 视为 <name>"
+#: ../../../runtime/optwin.vim:817
+msgid "a <Tab> in an indent inserts 'shiftwidth' spaces"
+msgstr "用 <Tab> 键缩进时插入 'shiftwidth' 个空格"
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (尚未实现)\n"
+#: ../../../runtime/optwin.vim:819
+msgid "if non-zero, number of spaces to insert for a <Tab>"
+msgstr "如果非零,为 <Tab> 插入的空格数"
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\t使用 <color> 作为背景色 (也可用 -bg)"
+#: ../../../runtime/optwin.vim:822
+msgid "round to 'shiftwidth' for \"<<\" and \">>\""
+msgstr "用 \"<<\" 和 \">>\" 缩进时,插入 'shiftwidth' 整数倍个空格"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\t使用 <color> 作为一般文字颜色 (也可用 -fg)"
+#: ../../../runtime/optwin.vim:824
+msgid "expand <Tab> to spaces in Insert mode"
+msgstr "在插入模式下将 <Tab> 展开为空格"
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t使用 <font> 作为一般字体 (也可用 -fn)"
+#: ../../../runtime/optwin.vim:827
+msgid "automatically set the indent of a new line"
+msgstr "自动设置新行缩进"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\t使用 <font> 作为粗体字体"
+#: ../../../runtime/optwin.vim:831
+msgid "do clever autoindenting"
+msgstr "智能自动缩进"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\t使用 <font> 作为斜体字体"
+#: ../../../runtime/optwin.vim:836
+msgid "enable specific indenting for C code"
+msgstr "为 C 代码启用特定的缩进"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\t使用 <geom> 作为初始位置 (也可用 -geom)"
+#: ../../../runtime/optwin.vim:839
+msgid "options for C-indenting"
+msgstr "C 风格缩进的选项"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t设定边框宽度为 <width> (也可用 -bw)"
+#: ../../../runtime/optwin.vim:842
+msgid "keys that trigger C-indenting in Insert mode"
+msgstr "在插入模式下触发 C 风格缩进的键"
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr "-scrollbarwidth <width> 设定滚动条宽度为 <width> (也可用 -sw)"
+#: ../../../runtime/optwin.vim:845
+msgid "list of words that cause more C-indent"
+msgstr "导致更多 C 风格缩进的单词列表"
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <height>\t设定菜单栏高度为 <height> (也可用 -mh)"
+#: ../../../runtime/optwin.vim:848
+msgid "list of scope declaration names used by cino-g"
+msgstr "cino-g 使用的作用域声明名称列表"
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\t使用反显 (也可用 -rv)"
+#: ../../../runtime/optwin.vim:851
+msgid "expression used to obtain the indent of a line"
+msgstr "用于获取一行缩进的表达式"
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\t不使用反显 (也可用 +rv)"
+#: ../../../runtime/optwin.vim:854
+msgid "keys that trigger indenting with 'indentexpr' in Insert mode"
+msgstr "在插入模式下使用 'indentexpr' 触发缩进的键"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\t设定指定的资源"
+#: ../../../runtime/optwin.vim:858
+msgid "copy whitespace for indenting from previous line"
+msgstr "为缩进从上一行复制空白字符"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (RISC OS 版本) 可识别的参数:\n"
+#: ../../../runtime/optwin.vim:861
+msgid "preserve kind of whitespace when changing indent"
+msgstr "在更改缩进时保留空白类型"
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <number>\t窗口初始宽度"
+#: ../../../runtime/optwin.vim:865
+msgid "enable lisp mode"
+msgstr "启用 lisp 模式"
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <number>\t窗口初始高度"
+#: ../../../runtime/optwin.vim:868
+msgid "words that change how lisp indenting works"
+msgstr "改变 lisp 如何缩进的单词"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (GTK+ 版本) 可识别的参数:\n"
+#: ../../../runtime/optwin.vim:870
+msgid "options for Lisp indenting"
+msgstr "Lisp 缩进选项"
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t在 <display> 上运行 vim (也可用 --display)"
+#: ../../../runtime/optwin.vim:876
+msgid "folding"
+msgstr "折叠"
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\t设置用于区分主窗口的窗口角色名"
+#: ../../../runtime/optwin.vim:877
+msgid "unset to display all folds open"
+msgstr "取消设置以打开所有折叠"
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\t在另一个 GTK 部件中打开 Vim"
+#: ../../../runtime/optwin.vim:880
+msgid "folds with a level higher than this number will be closed"
+msgstr "等级比这个数字高的折叠将被关闭"
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <parent title>\t在父应用程序中打开 Vim"
+#: ../../../runtime/optwin.vim:883
+msgid "value for 'foldlevel' when starting to edit a file"
+msgstr "开始编辑文件时,'foldlevel' 的值"
-#~ msgid "No display"
-#~ msgstr "没有 display"
+#: ../../../runtime/optwin.vim:885
+msgid "width of the column used to indicate folds"
+msgstr "用来指示折叠的列的宽度"
-#~ msgid ": Send failed.\n"
-#~ msgstr ": 发送失败。\n"
+#: ../../../runtime/optwin.vim:888
+msgid "expression used to display the text of a closed fold"
+msgstr "用于显示已关闭折叠的表达式"
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": 发送失败。尝试本地执行\n"
+#: ../../../runtime/optwin.vim:891
+msgid "set to \"all\" to close a fold when the cursor leaves it"
+msgstr "设置为 \"all\" 来在光标离开时关闭折叠"
-#~ msgid "%d of %d edited"
-#~ msgstr "%d 中 %d 已编辑"
+#: ../../../runtime/optwin.vim:893
+msgid "specifies for which commands a fold will be opened"
+msgstr "指定会打开折叠的命令"
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "没有 display: 发送表达式失败。\n"
+#: ../../../runtime/optwin.vim:895
+msgid "minimum number of screen lines for a fold to be closed"
+msgstr "可关闭折叠所需的最小屏幕行数"
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": 发送表达式失败。\n"
+#: ../../../runtime/optwin.vim:898
+msgid "template for comments; used to put the marker in"
+msgstr "注释的模板,用于放置折叠标记"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: 无效的代码页"
+#: ../../../runtime/optwin.vim:900
+msgid ""
+"folding type: \"manual\", \"indent\", \"expr\", \"marker\",\n"
+"\"syntax\" or \"diff\""
+msgstr ""
+"折叠类型:\"manual\", \"indent\", \"expr\", \"marker\", \n"
+"\"syntax\" 或者 \"diff\""
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: 无法创建输入上下文"
+#: ../../../runtime/optwin.vim:903
+msgid "expression used when 'foldmethod' is \"expr\""
+msgstr "当 'foldmethod' 为 \"expr\" 时使用的表达式"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: 无法打开输入法"
+#: ../../../runtime/optwin.vim:906
+msgid "used to ignore lines when 'foldmethod' is \"indent\""
+msgstr "当 'foldmethod' 为 \"indent\" 时用于忽略行"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: 警告: 无法设定输入法的释放回调函数"
+#: ../../../runtime/optwin.vim:909
+msgid "markers used when 'foldmethod' is \"marker\""
+msgstr "当 'foldmethod' 为 \"marker\" 时所使用的标记"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: 输入法不支持任何风格"
+#: ../../../runtime/optwin.vim:912
+msgid "maximum fold depth for when 'foldmethod' is \"indent\" or \"syntax\""
+msgstr "当 'foldmethod' 为 \"indent\" 或 \"syntax\" 时的最大折叠深度"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: 输入法不支持我的预编辑类型"
+#: ../../../runtime/optwin.vim:919
+msgid "diff mode"
+msgstr "差异模式"
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: over-the-spot 风格需要 Fontset"
+#: ../../../runtime/optwin.vim:920
+msgid "use diff mode for the current window"
+msgstr "对当前窗口使用差异模式"
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: 你的 GTK+ 比 1.2.3 旧。状态区不可用。"
+#: ../../../runtime/optwin.vim:923
+msgid "options for using diff mode"
+msgstr "使用差异模式的选项"
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: 输入法服务器未运行"
+#: ../../../runtime/optwin.vim:925
+msgid "expression used to obtain a diff file"
+msgstr "用于获取差异文件的表达式"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [不能在该版本的 Vim 上使用]"
+#: ../../../runtime/optwin.vim:927
+msgid "expression used to patch a file"
+msgstr "用于给文件打补丁的表达式"
-#~ msgid "Tear off this menu"
-#~ msgstr "撕下此菜单"
+#: ../../../runtime/optwin.vim:932
+msgid "mapping"
+msgstr "映射"
-#~ msgid "Select Directory dialog"
-#~ msgstr "选择目录对话框"
+#: ../../../runtime/optwin.vim:933
+msgid "maximum depth of mapping"
+msgstr "最大映射深度"
-#~ msgid "Save File dialog"
-#~ msgstr "保存文件对话框"
+#: ../../../runtime/optwin.vim:935
+msgid "allow timing out halfway into a mapping"
+msgstr "允许在映射中途超时"
-#~ msgid "Open File dialog"
-#~ msgstr "打开文件对话框"
+#: ../../../runtime/optwin.vim:937
+msgid "allow timing out halfway into a key code"
+msgstr "允许在键码中途超时"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: 抱歉,控制台模式下没有文件浏览器"
+#: ../../../runtime/optwin.vim:939
+msgid "time in msec for 'timeout'"
+msgstr "'timeout' 的时间(以毫秒计)"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: 正在保留文件……\n"
+#: ../../../runtime/optwin.vim:941
+msgid "time in msec for 'ttimeout'"
+msgstr "'ttimeout' 的时间(以毫秒计)"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: 结束。\n"
+#: ../../../runtime/optwin.vim:945
+msgid "reading and writing files"
+msgstr "读写文件"
-#~ msgid "ERROR: "
-#~ msgstr "错误: "
+#: ../../../runtime/optwin.vim:946
+msgid "enable using settings from modelines when reading a file"
+msgstr "读取文件时是否使用 modeline 里的设置"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[字节] 总共 alloc-free %<PRIu64>-%<PRIu64>,使用中 %<PRIu64>,高峰使用 "
-#~ "%<PRIu64>\n"
+#: ../../../runtime/optwin.vim:949
+msgid "allow setting expression options from a modeline"
+msgstr "允许从 modeline 中设置表达式选项"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[调用] 总共 re/malloc(): %<PRIu64>,总共 free()': %<PRIu64>\n"
-#~ "\n"
+#: ../../../runtime/optwin.vim:951
+msgid "number of lines to check for modelines"
+msgstr "为 modeline 而检查的行数"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: 此行过长"
+#: ../../../runtime/optwin.vim:953
+msgid "binary file editing"
+msgstr "二进制文件编辑"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: 内部错误: lalloc(%<PRId64>, )"
+#: ../../../runtime/optwin.vim:956
+msgid "last line in the file has an end-of-line"
+msgstr "文件的最后一行有换行符"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: 无效的鼠标形状"
+#: ../../../runtime/optwin.vim:959
+msgid "last line in the file followed by CTRL-Z"
+msgstr ""
-#~ msgid "Enter encryption key: "
-#~ msgstr "输入密码: "
+#: ../../../runtime/optwin.vim:962
+msgid "fixes missing end-of-line at end of text file"
+msgstr "修复文本文件末尾缺少换行符的问题"
-#~ msgid "Enter same key again: "
-#~ msgstr "请再输入一次: "
+#: ../../../runtime/optwin.vim:965
+msgid "prepend a Byte Order Mark to the file"
+msgstr "在文件前加上字节顺序标记"
-#~ msgid "Keys don't match!"
-#~ msgstr "两次密码不匹配!"
+#: ../../../runtime/optwin.vim:968
+msgid "end-of-line format: \"dos\", \"unix\" or \"mac\""
+msgstr "换行符格式: \"dos\", \"unix\" 或 \"mac\""
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "无法连接到 Netbeans #2"
+#: ../../../runtime/optwin.vim:971
+msgid "list of file formats to look for when editing a file"
+msgstr "编辑文件时要检查的文件格式列表"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "无法连接到 Netbeans"
+#: ../../../runtime/optwin.vim:973
+msgid "writing files is allowed"
+msgstr "允许写入文件"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: NetBeans 连接信息文件中错误的访问模式: \"%s\""
+#: ../../../runtime/optwin.vim:975
+msgid "write a backup file before overwriting a file"
+msgstr "覆盖文件前先写入备份文件"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "从 Netbeans 套接字读取"
+#: ../../../runtime/optwin.vim:977
+msgid "keep a backup after overwriting a file"
+msgstr "覆盖文件后保留备份"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: 缓冲区 %<PRId64> 丢失 NetBeans 连接"
+#: ../../../runtime/optwin.vim:979
+msgid "patterns that specify for which files a backup is not made"
+msgstr "不备份的文件的模式"
-#~ msgid "E505: "
-#~ msgstr "E505: "
+#: ../../../runtime/optwin.vim:981
+msgid "whether to make the backup as a copy or rename the existing file"
+msgstr "通过复制还是重命名已有文件进行备份"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: 求值功能不可用"
+#: ../../../runtime/optwin.vim:984
+msgid "list of directories to put backup files in"
+msgstr "存放备份文件的目录列表"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "释放了 %<PRId64> 行"
+#: ../../../runtime/optwin.vim:986
+msgid "file name extension for the backup file"
+msgstr "备份文件使用的扩展名"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: 在图形界面中不能改变终端"
+#: ../../../runtime/optwin.vim:988
+msgid "automatically write a file when leaving a modified buffer"
+msgstr "在离开修改过的缓冲区时自动写入文件"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: 请用 \":gui\" 启动图形界面"
+#: ../../../runtime/optwin.vim:990
+msgid "as 'autowrite', but works with more commands"
+msgstr "类似于 'autowrite',但适用于更多命令"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: 在 GTK+ 2 图形界面中不能更改"
+#: ../../../runtime/optwin.vim:992
+msgid "always write without asking for confirmation"
+msgstr "写文件时总是不需要确认"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: 无效的字体"
+#: ../../../runtime/optwin.vim:994
+msgid "automatically read a file when it was modified outside of Vim"
+msgstr "在 Vim 之外修改了文件时,自动读取文件"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: 无法选择 Fontset"
+#: ../../../runtime/optwin.vim:997
+msgid "keep oldest version of a file; specifies file name extension"
+msgstr "保存最旧版本的文件;指定文件扩展名"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: 无效的 Fontset"
+#: ../../../runtime/optwin.vim:999
+msgid "forcibly sync the file to disk after writing it"
+msgstr "文件写入后强制同步到磁盘"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: 无法选择宽字体"
+#: ../../../runtime/optwin.vim:1003
+msgid "the swap file"
+msgstr "交换文件"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: 无效的宽字体"
+#: ../../../runtime/optwin.vim:1004
+msgid "list of directories for the swap file"
+msgstr "交换文件的目录列表"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: 不支持鼠标"
+#: ../../../runtime/optwin.vim:1006
+msgid "use a swap file for this buffer"
+msgstr "对这个缓冲区使用交换文件"
-#~ msgid "cannot open "
-#~ msgstr "不能打开"
+#: ../../../runtime/optwin.vim:1009
+msgid "number of characters typed to cause a swap file update"
+msgstr "导致交换文件更新的字符数"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: 不能打开窗口!\n"
+#: ../../../runtime/optwin.vim:1011
+msgid "time in msec after which the swap file will be updated"
+msgstr "更新交换文件前所需的毫秒数"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "需要 Amigados 版本 2.04 以上\n"
+# do not translate to avoid writing Chinese in files
+#: ../../../runtime/optwin.vim:1015
+msgid "command line editing"
+msgstr ""
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "需要 %s 版本 %<PRId64>\n"
+#: ../../../runtime/optwin.vim:1016
+msgid "how many command lines are remembered"
+msgstr "记住的命令行数"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "不能打开 NIL:\n"
+#: ../../../runtime/optwin.vim:1018
+msgid "key that triggers command-line expansion"
+msgstr "触发命令行扩展的键"
-#~ msgid "Cannot create "
-#~ msgstr "不能创建 "
+#: ../../../runtime/optwin.vim:1020
+msgid "like 'wildchar' but can also be used in a mapping"
+msgstr "类似 'wildchar',但也可以在映射中使用"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim 返回值: %d\n"
+#: ../../../runtime/optwin.vim:1022
+msgid "specifies how command line completion works"
+msgstr "指定命令行如何补全"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "不能切换主控台(console)模式 !?\n"
+#: ../../../runtime/optwin.vim:1025
+msgid "empty or \"tagfile\" to list file name of matching tags"
+msgstr "空或 \"tagfile\" 来列出匹配标签的文件名"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: 不是主控台(console)??\n"
+#: ../../../runtime/optwin.vim:1028
+msgid "list of file name extensions that have a lower priority"
+msgstr "优先级低的文件扩展名列表"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: 不能用 -f 选项执行 shell"
+#: ../../../runtime/optwin.vim:1031
+msgid "list of file name extensions added when searching for a file"
+msgstr "搜索文件时添加的文件扩展名列表"
-#~ msgid "Cannot execute "
-#~ msgstr "不能执行 "
+#: ../../../runtime/optwin.vim:1036
+msgid "list of patterns to ignore files for file name completion"
+msgstr "文件名补全所忽略文件的模式列表"
-#~ msgid "shell "
-#~ msgstr "shell "
+#: ../../../runtime/optwin.vim:1039
+msgid "ignore case when using file names"
+msgstr "使用文件名时忽略大小写"
-#~ msgid " returned\n"
-#~ msgstr " 已返回\n"
+#: ../../../runtime/optwin.vim:1041
+msgid "ignore case when completing file names"
+msgstr "补全文件名时忽略大小写"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE 太小"
+#: ../../../runtime/optwin.vim:1044
+msgid "command-line completion shows a list of matches"
+msgstr "命令行补全时显示匹配列表"
-#~ msgid "I/O ERROR"
-#~ msgstr "I/O 错误"
+#: ../../../runtime/optwin.vim:1047
+msgid "key used to open the command-line window"
+msgstr "用于打开命令行窗口的键"
-#~ msgid "Message"
-#~ msgstr "消息"
+#: ../../../runtime/optwin.vim:1049
+msgid "height of the command-line window"
+msgstr "命令行窗口的高度"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' 不是 80, 不能执行外部命令"
+#: ../../../runtime/optwin.vim:1053
+msgid "executing external commands"
+msgstr "执行外部命令"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: 选择打印机失败"
+#: ../../../runtime/optwin.vim:1054
+msgid "name of the shell program used for external commands"
+msgstr "用于外部命令的 shell 程序的名称"
-#~ msgid "to %s on %s"
-#~ msgstr "从 %s 到 %s"
+#: ../../../runtime/optwin.vim:1056
+msgid "character(s) to enclose a shell command in"
+msgstr "用于包围 shell 命令的字符"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: 未知的打印机字体: %s"
+#: ../../../runtime/optwin.vim:1058
+msgid "like 'shellquote' but include the redirection"
+msgstr "类似 'shellquote',但包含重定向"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: 打印错误: %s"
+#: ../../../runtime/optwin.vim:1060
+msgid "characters to escape when 'shellxquote' is ("
+msgstr "'shellxquote' 为 ( 时需要转义的字符"
-#~ msgid "Printing '%s'"
-#~ msgstr "打印 '%s'"
+#: ../../../runtime/optwin.vim:1062
+msgid "argument for 'shell' to execute a command"
+msgstr "'shell' 执行命令的参数"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: 字符集 \"%s\" 不能对应字体\"%s\""
+#: ../../../runtime/optwin.vim:1064
+msgid "used to redirect command output to a file"
+msgstr "用于将命令输出重定向到文件"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: 不正确的字符 '%c' 出现在字体名称 \"%s\" 内"
+#: ../../../runtime/optwin.vim:1066
+msgid "use a temp file for shell commands instead of using a pipe"
+msgstr "对 shell 命令使用临时文件而不是管道"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: 双重信号,退出中\n"
+#: ../../../runtime/optwin.vim:1068
+msgid "program used for \"=\" command"
+msgstr "用于 \"=\" 命令的程序"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: 拦截到致命信号(deadly signal) %s\n"
+#: ../../../runtime/optwin.vim:1071
+msgid "program used to format lines with \"gq\" command"
+msgstr "用 \"gq\" 命令格式化代码时使用的程序"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: 拦截到致命信号(deadly signal)\n"
+#: ../../../runtime/optwin.vim:1073
+msgid "program used for the \"K\" command"
+msgstr "用于 \"K\" 命令的程序"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "打开 X display 用时 %<PRId64> 秒"
+#: ../../../runtime/optwin.vim:1075
+msgid "warn when using a shell command and a buffer has changes"
+msgstr "当使用 shell 命令并且缓冲区有修改时发出警告"
+
+#: ../../../runtime/optwin.vim:1080
+msgid "running make and jumping to errors (quickfix)"
+msgstr "运行 make 并跳到错误(快速修复)"
+
+#: ../../../runtime/optwin.vim:1081
+msgid "name of the file that contains error messages"
+msgstr "包含错误消息的文件的名称"
+
+#: ../../../runtime/optwin.vim:1083
+msgid "list of formats for error messages"
+msgstr "错误消息的格式列表"
+
+#: ../../../runtime/optwin.vim:1086
+msgid "program used for the \":make\" command"
+msgstr "用于 \":make\" 命令的程序"
+
+#: ../../../runtime/optwin.vim:1089
+msgid "string used to put the output of \":make\" in the error file"
+msgstr "用于将 \":make\" 的输出放在错误文件中的字符串"
+
+#: ../../../runtime/optwin.vim:1091
+msgid "name of the errorfile for the 'makeprg' command"
+msgstr "'makeprg' 命令的错误文件的名称"
+
+#: ../../../runtime/optwin.vim:1093
+msgid "program used for the \":grep\" command"
+msgstr "用于 \":grep\" 命令的程序"
+
+#: ../../../runtime/optwin.vim:1096
+msgid "list of formats for output of 'grepprg'"
+msgstr "'grepprg' 的输出格式列表"
+
+#: ../../../runtime/optwin.vim:1098
+msgid "encoding of the \":make\" and \":grep\" output"
+msgstr "\":make\" 和 \":grep\" 输出的编码"
+
+#: ../../../runtime/optwin.vim:1105
+msgid "system specific"
+msgstr "系统特定"
+
+#: ../../../runtime/optwin.vim:1106
+msgid "use forward slashes in file names; for Unix-like shells"
+msgstr "在文件名中使用正斜杠;用于类 Unix shell"
+
+#: ../../../runtime/optwin.vim:1108
+msgid "specifies slash/backslash used for completion"
+msgstr "指定补全时使用的斜杠/反斜杠"
+
+#: ../../../runtime/optwin.vim:1113
+msgid "language specific"
+msgstr "语言特定"
+
+#: ../../../runtime/optwin.vim:1114
+msgid "specifies the characters in a file name"
+msgstr "指定文件名中的字符"
+
+#: ../../../runtime/optwin.vim:1116
+msgid "specifies the characters in an identifier"
+msgstr "指定标识符中的字符"
+
+#: ../../../runtime/optwin.vim:1118
+msgid "specifies the characters in a keyword"
+msgstr "指定关键字中的字符"
+
+#: ../../../runtime/optwin.vim:1121
+msgid "specifies printable characters"
+msgstr "指定可打印字符"
+
+#: ../../../runtime/optwin.vim:1124
+msgid "specifies escape characters in a string"
+msgstr "指定字符串中的转义字符"
+
+#: ../../../runtime/optwin.vim:1129
+msgid "display the buffer right-to-left"
+msgstr "从右到左显示缓冲区"
+
+#: ../../../runtime/optwin.vim:1132
+msgid "when to edit the command-line right-to-left"
+msgstr "何时从右到左编辑命令行"
+
+#: ../../../runtime/optwin.vim:1135
+msgid "insert characters backwards"
+msgstr "倒序插入字符"
+
+#: ../../../runtime/optwin.vim:1137
+msgid "allow CTRL-_ in Insert and Command-line mode to toggle 'revins'"
+msgstr "在插入和命令行模式下允许 CTRL-_ 切换 'revins'"
+
+#: ../../../runtime/optwin.vim:1139
+msgid "the ASCII code for the first letter of the Hebrew alphabet"
+msgstr "希伯来字母表第一个字母的 ASCII 码"
+
+#: ../../../runtime/optwin.vim:1141
+msgid "use Hebrew keyboard mapping"
+msgstr "使用希伯来语键盘映射"
+
+#: ../../../runtime/optwin.vim:1143
+msgid "use phonetic Hebrew keyboard mapping"
+msgstr "使用希伯来语的语音键盘映射"
+
+#: ../../../runtime/optwin.vim:1147
+msgid "prepare for editing Arabic text"
+msgstr "准备编辑阿拉伯语文本"
+
+#: ../../../runtime/optwin.vim:1150
+msgid "perform shaping of Arabic characters"
+msgstr "阿拉伯语的字形重整"
+
+#: ../../../runtime/optwin.vim:1152
+msgid "terminal will perform bidi handling"
+msgstr "终端支持双向文本"
+
+#: ../../../runtime/optwin.vim:1156
+msgid "name of a keyboard mapping"
+msgstr "键盘映射名称"
+
+#: ../../../runtime/optwin.vim:1160
+msgid "list of characters that are translated in Normal mode"
+msgstr "在普通模式下转换的字符列表"
+
+#: ../../../runtime/optwin.vim:1162
+msgid "apply 'langmap' to mapped characters"
+msgstr "对映射的字符应用 'langmap'"
+
+#: ../../../runtime/optwin.vim:1166
+msgid "when set never use IM; overrules following IM options"
+msgstr "设置时总不使用输入法;覆盖以下输入法选项"
+
+#: ../../../runtime/optwin.vim:1169
+msgid "in Insert mode: 1: use :lmap; 2: use IM; 0: neither"
+msgstr "插入模式:1:使用 :lamp;2:使用输入法;0:都不用"
+
+#: ../../../runtime/optwin.vim:1172
+msgid "entering a search pattern: 1: use :lmap; 2: use IM; 0: neither"
+msgstr "输入搜索模式时:1:使用 :lamp;2:使用输入法;0:都不用"
+
+#: ../../../runtime/optwin.vim:1176
+msgid "when set always use IM when starting to edit a command line"
+msgstr "如果设置,开始编辑命令行时总是使用输入法"
+
+#: ../../../runtime/optwin.vim:1178
+msgid "function to obtain IME status"
+msgstr "获取输入法状态的函数"
+
+#: ../../../runtime/optwin.vim:1180
+msgid "function to enable/disable IME"
+msgstr "启用/禁用输入法的函数"
+
+#: ../../../runtime/optwin.vim:1185
+msgid "multi-byte characters"
+msgstr "多字节字符"
+
+#: ../../../runtime/optwin.vim:1186
+msgid "character encoding used in Nvim: \"utf-8\""
+msgstr "Nvim 中使用的字符编码:\"utf-8\""
+
+#: ../../../runtime/optwin.vim:1188
+msgid "character encoding for the current file"
+msgstr "当前文件的字符编码"
+
+#: ../../../runtime/optwin.vim:1191
+msgid "automatically detected character encodings"
+msgstr "自动检测字符编码"
+
+#: ../../../runtime/optwin.vim:1193
+msgid "expression used for character encoding conversion"
+msgstr "用于字符编码转换的表达式"
+
+#: ../../../runtime/optwin.vim:1195
+msgid "delete combining (composing) characters on their own"
+msgstr "删除组合字符本身"
+
+#: ../../../runtime/optwin.vim:1197
+msgid "maximum number of combining (composing) characters displayed"
+msgstr "显示的最大字符组合数"
+
+#: ../../../runtime/optwin.vim:1200
+msgid "key that activates the X input method"
+msgstr "激活 X 输入方法的键"
+
+#: ../../../runtime/optwin.vim:1203
+msgid "width of ambiguous width characters"
+msgstr "宽度有歧义字符的宽度"
+
+#: ../../../runtime/optwin.vim:1205
+msgid "emoji characters are full width"
+msgstr "表情字符视作全宽"
+
+#: ../../../runtime/optwin.vim:1209
+msgid "various"
+msgstr "杂项"
+
+#: ../../../runtime/optwin.vim:1210
+msgid ""
+"when to use virtual editing: \"block\", \"insert\", \"all\"\n"
+"and/or \"onemore\""
+msgstr "何时使用虚拟编辑:\"block\", \"insert\", \"all\" 和/或 \"onemore\""
+
+#: ../../../runtime/optwin.vim:1212
+msgid "list of autocommand events which are to be ignored"
+msgstr "要忽略的自动命令事件列表"
+
+#: ../../../runtime/optwin.vim:1214
+msgid "load plugin scripts when starting up"
+msgstr "启动时加载插件脚本"
+
+#: ../../../runtime/optwin.vim:1216
+msgid "enable reading .vimrc/.exrc/.gvimrc in the current directory"
+msgstr "启用读取在当前目录下的 .vimrc/.exrc/.gvimrc"
+
+#: ../../../runtime/optwin.vim:1218
+msgid "safer working with script files in the current directory"
+msgstr "在当前目录下使用脚本文件时更安全"
+
+#: ../../../runtime/optwin.vim:1220
+msgid "use the 'g' flag for \":substitute\""
+msgstr "打开 \":substitute\" 的 'g' 标志"
+
+#: ../../../runtime/optwin.vim:1223
+msgid "allow reading/writing devices"
+msgstr "允许读写设备"
+
+#: ../../../runtime/optwin.vim:1227
+msgid "maximum depth of function calls"
+msgstr "函数调用的最大深度"
+
+#: ../../../runtime/optwin.vim:1231
+msgid "list of words that specifies what to put in a session file"
+msgstr "指定放入会话文件的内容的单词列表"
+
+#: ../../../runtime/optwin.vim:1233
+msgid "list of words that specifies what to save for :mkview"
+msgstr "指定 :mkview 保存的内容的单词列表"
+
+#: ../../../runtime/optwin.vim:1235
+msgid "directory where to store files with :mkview"
+msgstr ":mkview 存放文件的目录"
+
+#: ../../../runtime/optwin.vim:1239
+msgid "list that specifies what to write in the ShaDa file"
+msgstr "指定在 ShaDa 文件中写入的内容的列表"
+
+#: ../../../runtime/optwin.vim:1243
+msgid "what happens with a buffer when it's no longer in a window"
+msgstr "当缓冲区不再位于窗口中时,会发生什么"
+
+#: ../../../runtime/optwin.vim:1246
+msgid "empty, \"nofile\", \"nowrite\", \"quickfix\", etc.: type of buffer"
+msgstr "空, \"nofile\", \"nowrite\", \"quickfix\" 等; 缓冲区类型"
+
+#: ../../../runtime/optwin.vim:1250
+msgid "whether the buffer shows up in the buffer list"
+msgstr "缓冲区是否显示在缓冲区列表中"
+
+#: ../../../runtime/optwin.vim:1253
+msgid "set to \"msg\" to see all error messages"
+msgstr "设置为 \"msg\" 以查看所有错误消息"
+
+#: ../../../runtime/optwin.vim:1255
+msgid "whether to show the signcolumn"
+msgstr "是否显示标号列"
+
+#: ../../../runtime/optwin.vim:1282
+msgid "name of the MzScheme dynamic library"
+msgstr "MzScheme 动态库的名字"
+
+#: ../../../runtime/optwin.vim:1284
+msgid "name of the MzScheme GC dynamic library"
+msgstr "MzScheme GC 动态库的名字"
+
+#: ../../../runtime/optwin.vim:1288
+msgid "whether to use Python 2 or 3"
+msgstr "是否使用 Python 2 和 3"
+
+#~ msgid "\t\t\t (Unimplemented)\n"
+#~ msgstr "\t\t\t (尚未实现)\n"
#~ msgid ""
#~ "\n"
-#~ "Vim: Got X error\n"
+#~ "\n"
+#~ "Arguments:\n"
#~ msgstr ""
#~ "\n"
-#~ "Vim: X 错误\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "测试 X display 失败"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "打开 X display 超时"
+#~ "\n"
+#~ "参数:\n"
#~ msgid ""
#~ "\n"
-#~ "Cannot execute shell sh\n"
+#~ " [not usable with this version of Vim]"
#~ msgstr ""
#~ "\n"
-#~ "无法执行 shell sh\n"
+#~ " [不能在该版本的 Vim 上使用]"
#~ msgid ""
#~ "\n"
-#~ "Cannot create pipes\n"
+#~ " a: Find assignments to this symbol\n"
+#~ " c: Find functions calling this function\n"
+#~ " d: Find functions called by this function\n"
+#~ " e: Find this egrep pattern\n"
+#~ " f: Find this file\n"
+#~ " g: Find this definition\n"
+#~ " i: Find files #including this file\n"
+#~ " s: Find this C symbol\n"
+#~ " t: Find this text string\n"
#~ msgstr ""
#~ "\n"
-#~ "无法建立管道\n"
+#~ " a: 搜索对此符号的赋值\n"
+#~ " c: 搜索调用此函数的函数\n"
+#~ " d: 搜索此函数调用的函数\n"
+#~ " e: 搜索此 egrep 模式\n"
+#~ " f: 搜索此文件\n"
+#~ " g: 搜索此定义\n"
+#~ " i: 搜索包含此文件的文件\n"
+#~ " s: 搜索此 C 符号\n"
+#~ " t: 搜索此文本字符串\n"
#~ msgid ""
#~ "\n"
-#~ "Cannot fork\n"
+#~ " # line"
#~ msgstr ""
#~ "\n"
-#~ "无法 fork\n"
+#~ " # 行 "
#~ msgid ""
#~ "\n"
-#~ "Command terminated\n"
+#~ " or:"
#~ msgstr ""
#~ "\n"
-#~ "命令已结束\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP 丢失了到 ICE 的连接"
+#~ " 或:"
-#~ msgid "Opening the X display failed"
-#~ msgstr "打开 X display 失败"
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+#~ msgid ""
+#~ "\n"
+#~ "# %s History (newest to oldest):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# %s 历史记录 (从新到旧):\n"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP 处理 save-yourself 请求"
+#~ msgid ""
+#~ "\n"
+#~ "# Buffer list:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# 缓冲区列表:\n"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP 打开连接"
+#~ msgid ""
+#~ "\n"
+#~ "# File marks:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# 文件标记:\n"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE 连接监视失败"
+#~ msgid ""
+#~ "\n"
+#~ "# History of marks within files (newest to oldest):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# 文件内的标记历史记录 (从新到旧):\n"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection 调用失败: %s"
+#~ msgid ""
+#~ "\n"
+#~ "# Jumplist (newest first):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# 跳转列表 (从新到旧):\n"
-#~ msgid "At line"
-#~ msgstr "在行号 "
+#, c-format
+#~ msgid ""
+#~ "\n"
+#~ "# Last %sSearch Pattern:\n"
+#~ "~"
+#~ msgstr ""
+#~ "\n"
+#~ "# 最后 %s搜索模式:\n"
+#~ "~"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "无法加载 vim32.dll!"
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid ""
+#~ "\n"
+#~ "# Last Substitute String:\n"
+#~ "$"
+#~ msgstr ""
+#~ "\n"
+#~ "# 最近的替换字符串:\n"
+#~ "$"
-#~ msgid "VIM Error"
-#~ msgstr "VIM 错误"
+#~ msgid ""
+#~ "\n"
+#~ "# Registers:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# 寄存器:\n"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "无法修正到 DLL 的函数指针!"
+#~ msgid ""
+#~ "\n"
+#~ "# global variables:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# 全局变量:\n"
-#~ msgid "shell returned %d"
-#~ msgstr "Shell 返回 %d"
+#~ msgid ""
+#~ "\n"
+#~ "--- Registers ---"
+#~ msgstr ""
+#~ "\n"
+#~ "--- 寄存器 ---"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: 拦截到 %s 事件\n"
+#~ msgid ""
+#~ "\n"
+#~ "--- Terminal codes ---"
+#~ msgstr ""
+#~ "\n"
+#~ "--- 终端编码 ---"
-#~ msgid "close"
-#~ msgstr "关闭"
+#~ msgid ""
+#~ "\n"
+#~ "--- Terminal keys ---"
+#~ msgstr ""
+#~ "\n"
+#~ "--- 终端按键 ---"
-#~ msgid "logoff"
-#~ msgstr "注消"
+#~ msgid ""
+#~ "\n"
+#~ "16-bit MS-DOS version"
+#~ msgstr ""
+#~ "\n"
+#~ "16 位 MS-DOS 版本"
-#~ msgid "shutdown"
-#~ msgstr "关机"
+#~ msgid ""
+#~ "\n"
+#~ "32-bit MS-DOS version"
+#~ msgstr ""
+#~ "\n"
+#~ "32 位 MS-DOS 版本"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: 找不到命令"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (Athena version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "gvim (Athena 版本) 可识别的参数:\n"
#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
+#~ "\n"
+#~ "Arguments recognised by gvim (GTK+ version):\n"
#~ msgstr ""
-#~ "在你的 $PATH 中找不到 VIMRUN.EXE。\n"
-#~ "外部命令执行完毕后将不会暂停。\n"
-#~ "进一步说明请见 :help win32-vimrun"
+#~ "\n"
+#~ "gvim (GTK+ 版本) 可识别的参数:\n"
-#~ msgid "Vim Warning"
-#~ msgstr "Vim 警告"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (Motif version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "gvim (Motif 版本) 可识别的参数:\n"
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "不支持 %s 中的转换"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (RISC OS version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "gvim (RISC OS 版本) 可识别的参数:\n"
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: 使用了不正确的参数"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "gvim (neXtaw 版本) 可识别的参数:\n"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Tag 文件路径被截断为 %s\n"
+#~ msgid ""
+#~ "\n"
+#~ "Big version "
+#~ msgstr ""
+#~ "\n"
+#~ "大型版本 "
-#~ msgid "new shell started\n"
-#~ msgstr "启动新 shell\n"
+#~ msgid ""
+#~ "\n"
+#~ "Cannot create pipes\n"
+#~ msgstr ""
+#~ "\n"
+#~ "无法建立管道\n"
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "无法撤销;仍然继续"
+#~ msgid ""
+#~ "\n"
+#~ "Cannot execute shell "
+#~ msgstr ""
+#~ "\n"
+#~ "无法执行 shell"
-#~ msgid "number changes time"
-#~ msgstr " 编号 改变 时间"
+#~ msgid ""
+#~ "\n"
+#~ "Cannot execute shell sh\n"
+#~ msgstr ""
+#~ "\n"
+#~ "无法执行 shell sh\n"
#~ msgid ""
#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
+#~ "Cannot fork\n"
#~ msgstr ""
#~ "\n"
-#~ "MS-Windows 16/32 位图形界面版本"
+#~ "无法 fork\n"
#~ msgid ""
#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
+#~ "Command terminated\n"
#~ msgstr ""
#~ "\n"
-#~ "MS-Windows 32 位图形界面版本"
+#~ "命令已结束\n"
-#~ msgid " in Win32s mode"
-#~ msgstr " Win32s 模式"
+#, fuzzy
+#~ msgid ""
+#~ "\n"
+#~ "Extra patches: "
+#~ msgstr "外部符合:\n"
-#~ msgid " with OLE support"
-#~ msgstr " 带 OLE 支持"
+#~ msgid ""
+#~ "\n"
+#~ "Huge version "
+#~ msgstr ""
+#~ "\n"
+#~ "巨型版本 "
#~ msgid ""
#~ "\n"
-#~ "MS-Windows 32-bit console version"
+#~ "Included patches: "
#~ msgstr ""
#~ "\n"
-#~ "MS-Windows 32 位控制台版本"
+#~ "包含补丁: "
#~ msgid ""
#~ "\n"
@@ -7634,17 +9550,24 @@ msgstr "E446: 光标处没有文件名"
#~ msgid ""
#~ "\n"
-#~ "32-bit MS-DOS version"
+#~ "MS-Windows 16/32-bit GUI version"
#~ msgstr ""
#~ "\n"
-#~ "32 位 MS-DOS 版本"
+#~ "MS-Windows 16/32 位图形界面版本"
#~ msgid ""
#~ "\n"
-#~ "16-bit MS-DOS version"
+#~ "MS-Windows 32-bit GUI version"
#~ msgstr ""
#~ "\n"
-#~ "16 位 MS-DOS 版本"
+#~ "MS-Windows 32 位图形界面版本"
+
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit console version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32 位控制台版本"
#~ msgid ""
#~ "\n"
@@ -7669,6 +9592,13 @@ msgstr "E446: 光标处没有文件名"
#~ msgid ""
#~ "\n"
+#~ "Normal version "
+#~ msgstr ""
+#~ "\n"
+#~ "正常版本 "
+
+#~ msgid ""
+#~ "\n"
#~ "RISC OS version"
#~ msgstr ""
#~ "\n"
@@ -7676,73 +9606,463 @@ msgstr "E446: 光标处没有文件名"
#~ msgid ""
#~ "\n"
-#~ "Big version "
+#~ "Small version "
#~ msgstr ""
#~ "\n"
-#~ "大型版本 "
+#~ "小型版本 "
#~ msgid ""
#~ "\n"
-#~ "Normal version "
+#~ "Tiny version "
#~ msgstr ""
#~ "\n"
-#~ "正常版本 "
+#~ "微型版本 "
#~ msgid ""
#~ "\n"
-#~ "Small version "
+#~ "Vim: Got X error\n"
#~ msgstr ""
#~ "\n"
-#~ "小型版本 "
+#~ "Vim: X 错误\n"
#~ msgid ""
#~ "\n"
-#~ "Tiny version "
+#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
+#~ "%<PRIu64>\n"
#~ msgstr ""
#~ "\n"
-#~ "微型版本 "
+#~ "[字节] 总共 alloc-free %<PRIu64>-%<PRIu64>,使用中 %<PRIu64>,高峰使用 "
+#~ "%<PRIu64>\n"
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "带 GTK2-GNOME 图形界面。"
+#, fuzzy
+#~ msgid " for Vim defaults "
+#~ msgstr " # pid 数据库名称 prepend path\n"
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "带 GTK-GNOME 图形界面。"
+#~ msgid " user exrc file: \""
+#~ msgstr " 用户 exrc 文件: \""
-#~ msgid "with GTK2 GUI."
-#~ msgstr "带 GTK2 图形界面。"
+#~ msgid " user vimrc file: \""
+#~ msgstr " 用户 vimrc 文件: \""
-#~ msgid "with GTK GUI."
-#~ msgstr "带 GTK 图形界面。"
+#~ msgid " system menu file: \""
+#~ msgstr " 系统菜单文件: \""
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "带 X11-Motif 图形界面。"
+#~ msgid " user gvimrc file: \""
+#~ msgstr " 用户 gvimrc 文件: \""
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "带 X11-neXtaw 图形界面。"
+#~ msgid " 2nd user exrc file: \""
+#~ msgstr " 第二用户 exrc 文件: \""
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "带 X11-Athena 图形界面。"
+#~ msgid " DEBUG BUILD"
+#~ msgstr " 调试版本"
-#~ msgid "with Photon GUI."
-#~ msgstr "带 Photon 图形界面。"
+#~ msgid " Features included (+) or not (-):\n"
+#~ msgstr " 可使用(+)与不可使用(-)的功能:\n"
-#~ msgid "with GUI."
-#~ msgstr "带图形界面。"
+#, fuzzy
+#~ msgid " Quit, or continue with caution.\n"
+#~ msgstr " 退出,或小心地继续。\n"
-#~ msgid "with Carbon GUI."
-#~ msgstr "带 Carbon 图形界面。"
+#~ msgid " system gvimrc file: \""
+#~ msgstr " 系统 gvimrc 文件: \""
-#~ msgid "with Cocoa GUI."
-#~ msgstr "带 Cocoa 图形界面。"
+#~ msgid " # pid database name prepend path\n"
+#~ msgstr " # pid 数据库名 prepend path\n"
-#~ msgid "with (classic) GUI."
-#~ msgstr "带(传统)图形界面。"
+#~ msgid " (NOT FOUND)"
+#~ msgstr " (找不到)"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " 系统 gvimrc 文件: \""
+#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+#~ msgstr " (RET/BS: 向下/向上一行, 空格/b: 一页, d/u: 半页, q: 退出)"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " 用户 gvimrc 文件: \""
+#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+#~ msgstr " (RET: 向下一行, 空白键: 一页, d: 半页, q: 退出)"
+
+#~ msgid " (lang)"
+#~ msgstr " (语言)"
+
+#~ msgid " 2nd user vimrc file: \""
+#~ msgstr " 第二用户 vimrc 文件: \""
+
+#~ msgid " 3rd user vimrc file: \""
+#~ msgstr " 第三用户 vimrc 文件: \""
+
+#~ msgid " BLOCK"
+#~ msgstr " 块"
+
+#~ msgid " LINE"
+#~ msgstr " 行"
+
+#~ msgid " in Win32s mode"
+#~ msgstr " Win32s 模式"
+
+#~ msgid " on 1 line"
+#~ msgstr "共 1 行"
+
+#~ msgid " returned\n"
+#~ msgstr " 已返回\n"
+
+#~ msgid " vim [arguments] "
+#~ msgstr " vim [参数] "
+
+#~ msgid " with OLE support"
+#~ msgstr " 带 OLE 支持"
+
+#~ msgid "\"\n"
+#~ msgstr "\"\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy, c-format
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# 这个 viminfo 文件是由 Vim %s 生成的。\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# 'encoding' 在此文件建立时的值\n"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid ""
+#~ "# You may edit it if you're careful!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "# 如果要自行修改请特别小心!\n"
+#~ "\n"
+
+#, fuzzy, c-format
+#~ msgid "%-5s: %s%*s (Usage: %s)"
+#~ msgstr "%-5s: %-30s (用法: %s)"
+
+#~ msgid "%2d %-5ld %-34s <none>\n"
+#~ msgstr "%2d %-5ld %-34s <无>\n"
+
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr "%<%f%h%m%=页 %N"
+
+#, c-format
+#~ msgid "%<PRId64> characters"
+#~ msgstr "%<PRId64> 个字符"
+
+#, c-format
+#~ msgid "%<PRId64> fewer lines"
+#~ msgstr "少了 %<PRId64> 行"
+
+#, c-format
+#~ msgid "%<PRId64> lines %sed 1 time"
+#~ msgstr "%<PRId64> 行 %s 了 1 次"
+
+#, c-format
+#~ msgid "%<PRId64> lines moved"
+#~ msgstr "移动了 %<PRId64> 行"
+
+#, c-format
+#~ msgid "%<PRId64> more lines"
+#~ msgstr "多了 %<PRId64> 行"
+
+#, c-format
+#~ msgid "%d files to edit\n"
+#~ msgstr "还有 %d 个文件等待编辑\n"
+
+#~ msgid "%d of %d edited"
+#~ msgstr "%d 中 %d 已编辑"
+
+# bad to translate
+#, c-format
+#~ msgid "%sviminfo: %s in line: "
+#~ msgstr "%sviminfo: %s 位于行: "
+
+#~ msgid "&Cancel"
+#~ msgstr "取消(&C)"
+
+#~ msgid "&Dismiss"
+#~ msgstr "取消(&D)"
+
+#~ msgid "&Filter"
+#~ msgstr "过滤(&F)"
+
+#~ msgid "&Help"
+#~ msgstr "帮助(&H)"
+
+#~ msgid "&OK"
+#~ msgstr "确定(&O)"
+
+#~ msgid ""
+#~ "&OK\n"
+#~ "&Cancel"
+#~ msgstr ""
+#~ "确定(&O)\n"
+#~ "取消(&C)"
+
+#~ msgid ""
+#~ "&OK\n"
+#~ "&Load File"
+#~ msgstr ""
+#~ "确定(&O)\n"
+#~ "加载文件(&L)"
+
+#~ msgid "&Replace"
+#~ msgstr "替换(&R)"
+
+#~ msgid "&Undo"
+#~ msgstr "撤销(&U)"
+
+#~ msgid "' not known. Available builtin terminals are:"
+#~ msgstr "' 未知。可用的内建终端有:"
+
+#, c-format
+#~ msgid "(NFA) COULD NOT OPEN %s !"
+#~ msgstr "(NFA) 不能打开 %s !"
+
+#~ msgid "+\t\t\tStart at end of file"
+#~ msgstr "+\t\t\t启动后跳到文件末尾"
+
+#~ msgid "+<lnum>\t\tStart at line <lnum>"
+#~ msgstr "+<lnum>\t\t启动后跳到第 <lnum> 行"
+
+#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+#~ msgstr "+reverse\t\t不使用反显 (也可用 +rv)"
+
+#~ msgid "--columns <number>\tInitial width of window in columns"
+#~ msgstr "--columns <number>\t窗口初始宽度"
+
+#~ msgid "--help\t\tShow Gnome arguments"
+#~ msgstr "--help\t\t显示 Gnome 相关参数"
+
+#~ msgid "--literal\t\tDon't expand wildcards"
+#~ msgstr "--literal\t\t不扩展通配符"
+
+#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+#~ msgstr "--remote <files>\t如有可能,在 Vim 服务器上编辑文件 <files>"
+
+#~ msgid ""
+#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+#~ msgstr "--remote-expr <expr>\t在 Vim 服务器上求 <expr> 的值并打印结果"
+
+#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+#~ msgstr "--remote-send <keys>\t送出 <keys> 到 Vim 服务器并退出"
+
+#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
+#~ msgstr "--remote-silent <files> 同上,找不到服务器时不抱怨"
+
+#~ msgid "--remote-tab <files> As --remote but open tab page for each file"
+#~ msgstr "--remote-tab <files> 同 --remote 但对每个文件打开一个标签页"
+
+#~ msgid ""
+#~ "--remote-wait <files> As --remote but wait for files to have been edited"
+#~ msgstr "--remote-wait <files> 同 --remote 但会等待文件完成编辑"
+
+#~ msgid ""
+#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
+#~ msgstr "--remote-wait-silent <files> 同上,找不到服务器时不抱怨"
+
+#~ msgid "--role <role>\tSet a unique role to identify the main window"
+#~ msgstr "--role <role>\t设置用于区分主窗口的窗口角色名"
+
+#~ msgid "--rows <number>\tInitial height of window in rows"
+#~ msgstr "--rows <number>\t窗口初始高度"
+
+#~ msgid "--serverlist\t\tList available Vim server names and exit"
+#~ msgstr "--serverlist\t\t列出可用的 Vim 服务器名称并退出"
+
+#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
+#~ msgstr "--servername <name>\t发送到或成为 Vim 服务器 <name>"
+
+#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+#~ msgstr "--socketid <xid>\t在另一个 GTK 部件中打开 Vim"
+
+#~ msgid "-A\t\t\tstart in Arabic mode"
+#~ msgstr "-A\t\t\t以 Arabic 模式启动"
+
+#~ msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+#~ msgstr "-C\t\t\t兼容传统的 Vi: 'compatible'"
+
+#~ msgid "-D\t\t\tDebugging mode"
+#~ msgstr "-D\t\t\t调试模式"
+
+#~ msgid "-F\t\t\tStart in Farsi mode"
+#~ msgstr "-F\t\t\t以 Farsi 模式启动"
+
+#~ msgid "-H\t\t\tStart in Hebrew mode"
+#~ msgstr "-H\t\t\t以 Hebrew 模式启动"
+
+#~ msgid "-L\t\t\tSame as -r"
+#~ msgstr "-L\t\t\t同 -r"
+
+#~ msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+#~ msgstr "-N\t\t\t不完全兼容传统的 Vi: 'nocompatible'"
+
+#~ msgid "-O[N]\t\tLike -o but split vertically"
+#~ msgstr "-O[N]\t\t同 -o 但垂直分割"
+
+#~ msgid "-P <parent title>\tOpen Vim inside parent application"
+#~ msgstr "-P <parent title>\t在父应用程序中打开 Vim"
+
+#~ msgid "-R\t\t\tReadonly mode (like \"view\")"
+#~ msgstr "-R\t\t\t只读模式 (同 \"view\")"
+
+#~ msgid "-T <terminal>\tSet terminal type to <terminal>"
+#~ msgstr "-T <terminal>\t设定终端类型为 <terminal>"
+
+#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+#~ msgstr "-U <gvimrc>\t\t使用 <gvimrc> 替代任何 .gvimrc"
+
+#~ msgid "-V[N]\t\tVerbose level"
+#~ msgstr "-V[N]\t\tVerbose 等级"
+
+#~ msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+#~ msgstr "-V[N][fname]\t\t详细 [level N] [log messages to fname]"
+
+#~ msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+#~ msgstr "-W <scriptout>\t将所有输入的命令写入到文件 <scriptout>"
+
+#~ msgid "-X\t\t\tDo not connect to X server"
+#~ msgstr "-X\t\t\t不连接到 X Server"
+
+#~ msgid "-b\t\t\tBinary mode"
+#~ msgstr "-b\t\t\t二进制模式"
+
+#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
+#~ msgstr "-background <color>\t使用 <color> 作为背景色 (也可用 -bg)"
+
+#~ msgid "-boldfont <font>\tUse <font> for bold text"
+#~ msgstr "-boldfont <font>\t使用 <font> 作为粗体字体"
+
+#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+#~ msgstr "-borderwidth <width>\t设定边框宽度为 <width> (也可用 -bw)"
+
+#~ msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+#~ msgstr "-d\t\t\tDiff 模式 (同 \"vimdiff\")"
+
+#~ msgid "-dev <device>\t\tUse <device> for I/O"
+#~ msgstr "-dev <device>\t\t使用 <device> 进行输入输出"
+
+#~ msgid "-display <display>\tConnect vim to this particular X-server"
+#~ msgstr "-display <display>\t将 vim 与指定的 X-server 连接"
+
+#~ msgid "-display <display>\tRun vim on <display>"
+#~ msgstr "-display <display>\t在 <display> 上运行 vim"
+
+#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
+#~ msgstr "-display <display>\t在 <display> 上运行 vim (也可用 --display)"
+
+#~ msgid "-e\t\t\tEx mode (like \"ex\")"
+#~ msgstr "-e\t\t\tEx 模式 (同 \"ex\")"
+
+#~ msgid "-f\t\t\tDon't use newcli to open window"
+#~ msgstr "-f\t\t\t不使用 newcli 来打开窗口"
+
+#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+#~ msgstr "-f 或 --nofork\t前台: 启动图形界面时不 fork"
+
+#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+#~ msgstr "-font <font>\t使用 <font> 作为一般字体 (也可用 -fn)"
+
+#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+#~ msgstr "-foreground <color>\t使用 <color> 作为一般文字颜色 (也可用 -fg)"
+
+#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+#~ msgstr "-g\t\t\t使用图形界面 (同 \"gvim\")"
+
+#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+#~ msgstr "-geometry <geom>\t使用 <geom> 作为初始位置 (也可用 -geom)"
+
+#~ msgid "-h or --help\tPrint Help (this message) and exit"
+#~ msgstr "-h 或 --help\t打印帮助(本信息)并退出"
+
+#~ msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+#~ msgstr "-i <viminfo>\t\t使用 <viminfo> 取代 .viminfo"
+
+#~ msgid "-iconic\t\tStart vim iconified"
+#~ msgstr "-iconic\t\t启动后最小化"
+
+#~ msgid "-italicfont <font>\tUse <font> for italic text"
+#~ msgstr "-italicfont <font>\t使用 <font> 作为斜体字体"
+
+#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+#~ msgstr "-menuheight <height>\t设定菜单栏高度为 <height> (也可用 -mh)"
+
+#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
+#~ msgstr "-name <name>\t\t读取 Resource 时把 vim 视为 <name>"
+
+#~ msgid "-r\t\t\tList swap files and exit"
+#~ msgstr "-r\t\t\t列出交换文件并退出"
+
+#~ msgid "-r (with file name)\tRecover crashed session"
+#~ msgstr "-r (跟文件名)\t\t恢复崩溃的会话"
+
+#~ msgid "-register\t\tRegister this gvim for OLE"
+#~ msgstr "-register\t\t注册此 gvim 到 OLE"
+
+#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
+#~ msgstr "-reverse\t\t使用反显 (也可用 -rv)"
+
+#~ msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+#~ msgstr "-s\t\t\t安静(批处理)模式 (只能与 \"ex\" 一起使用)"
+
+#~ msgid ""
+#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+#~ msgstr "-scrollbarwidth <width> 设定滚动条宽度为 <width> (也可用 -sw)"
+
+#~ msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+#~ msgstr "-u <vimrc>\t\t使用 <vimrc> 替代任何 .vimrc"
+
+#~ msgid "-unregister\t\tUnregister gvim for OLE"
+#~ msgstr "-unregister\t\t取消 OLE 中的 gvim 注册"
+
+#~ msgid "-v\t\t\tVi mode (like \"vi\")"
+#~ msgstr "-v\t\t\tVi 模式 (同 \"vi\")"
+
+#~ msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+#~ msgstr "-w <scriptout>\t将所有输入的命令追加到文件 <scriptout>"
+
+#~ msgid "-x\t\t\tEdit encrypted files"
+#~ msgstr "-x\t\t\t编辑加密的文件"
+
+#~ msgid "-xrm <resource>\tSet the specified resource"
+#~ msgstr "-xrm <resource>\t设定指定的资源"
+
+#~ msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+#~ msgstr "-y\t\t\t容易模式 (同 \"evim\",无模式)"
+
+#~ msgid "1 buffer deleted"
+#~ msgstr "删除了 1 个缓冲区"
+
+#~ msgid "1 buffer unloaded"
+#~ msgstr "释放了 1 个缓冲区"
+
+#~ msgid "1 buffer wiped out"
+#~ msgstr "清除了 1 个缓冲区"
+
+#, c-format
+#~ msgid "1 line %sed %d times"
+#~ msgstr "1 行 %s 了 %d 次"
+
+#, c-format
+#~ msgid "1 line %sed 1 time"
+#~ msgstr "1 行 %s 了 1 次"
+
+#, c-format
+#~ msgid "1 line --%d%%--"
+#~ msgstr "1 行 --%d%%--"
+
+#~ msgid "1 line changed"
+#~ msgstr "改变了 1 行"
+
+#~ msgid "1 line indented "
+#~ msgstr "缩进了 1 行 "
+
+#~ msgid "1 line yanked"
+#~ msgstr "复制了 1 行"
+
+#~ msgid "1 match"
+#~ msgstr "1 个匹配,"
+
+#~ msgid "1 more file to edit. Quit anyway?"
+#~ msgstr "还有 1 个文件未编辑。确实要退出吗?"
+
+#~ msgid "1 substitution"
+#~ msgstr "1 次替换,"
#~ msgid "2nd user gvimrc file: \""
#~ msgstr "第二用户 gvimrc 文件: \""
@@ -7750,182 +10070,1439 @@ msgstr "E446: 光标处没有文件名"
#~ msgid "3rd user gvimrc file: \""
#~ msgstr "第三用户 gvimrc 文件: \""
-#~ msgid " system menu file: \""
-#~ msgstr " 系统菜单文件: \""
+#~ msgid ": Send expression failed.\n"
+#~ msgstr ": 发送表达式失败。\n"
+
+#~ msgid ": Send failed.\n"
+#~ msgstr ": 发送失败。\n"
+
+#~ msgid ": Send failed. Trying to execute locally\n"
+#~ msgstr ": 发送失败。尝试本地执行\n"
+
+#~ msgid "<buffer object (deleted) at %8lX>"
+#~ msgstr "<缓冲区对象(已删除): %8lX>"
+
+#~ msgid "<cannot open> "
+#~ msgstr "<无法打开>"
+
+#~ msgid "<window %d>"
+#~ msgstr "<窗口 %d>"
+
+#~ msgid "<window object (deleted) at %.8lX>"
+#~ msgstr "<窗口对象(已删除): %.8lX>"
+
+#~ msgid "<window object (unknown) at %.8lX>"
+#~ msgstr "<窗口对象(未知): %.8lX>"
+
+#~ msgid ""
+#~ "???: Sorry, this command is disabled, the MzScheme library could not be "
+#~ "loaded."
+#~ msgstr "???: 抱歉,此命令不可用,无法加载 MzScheme 库"
+
+#~ msgid "ANCHOR_BUF_SIZE too small."
+#~ msgstr "ANCHOR_BUF_SIZE 太小"
+
+#~ msgid "Add a new database"
+#~ msgstr "添加一个新的数据库"
+
+#, c-format
+#~ msgid "Added cscope database %s"
+#~ msgstr "添加了 cscope 数据库 %s"
+
+#~ msgid "Affix flags ignored when PFXPOSTPONE used in %s line %d: %s"
+#~ msgstr "%s 第 %d 行,使用 PFXPOSTPONE 时附加标志被忽略: %s"
+
+#~ msgid "All cscope databases reset"
+#~ msgstr "所有 cscope 数据库已被重置"
+
+#~ msgid "Append File"
+#~ msgstr "追加文件"
+
+#~ msgid "At line"
+#~ msgstr "在行号 "
+
+#~ msgid "Binary tag search"
+#~ msgstr "二进制查找(Binary search) 标签(Tags)"
+
+#~ msgid "Browse class"
+#~ msgstr "浏览 class"
+
+#, c-format
+#~ msgid "Calling shell to execute: \"%s\""
+#~ msgstr "调用 shell 执行: \"%s\""
+
+#~ msgid "Cancel"
+#~ msgstr "取消"
+
+#~ msgid "Cannot connect to Netbeans"
+#~ msgstr "无法连接到 Netbeans"
+
+#~ msgid "Cannot connect to Netbeans #2"
+#~ msgstr "无法连接到 Netbeans #2"
+
+#~ msgid ""
+#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+#~ "$PATH).\n"
+#~ msgstr ""
+#~ "不能连接到 SNiFF+。请检查环境变量 ($PATH 里必需可以找到 sniffemacs)\n"
+
+#~ msgid "Cannot create "
+#~ msgstr "不能创建 "
+
+#~ msgid "Cannot execute "
+#~ msgstr "不能执行 "
+
+#~ msgid "Cannot open NIL:\n"
+#~ msgstr "不能打开 NIL:\n"
+
+#~ msgid "Close tab"
+#~ msgstr "关闭标签"
+
+#~ msgid "Compilation: "
+#~ msgstr "编译方式: "
#~ msgid "Compiler: "
#~ msgstr "编译器: "
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "菜单 帮助->孤儿 查看说明 "
+#~ msgid "Conversion in %s not supported"
+#~ msgstr "不支持 %s 中的转换"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "无模式运行,输入文字即插入"
+#~ msgid "Could not fix up function pointers to the DLL!"
+#~ msgstr "无法修正到 DLL 的函数指针!"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "菜单 编辑->全局设定->开/关插入模式 "
+#~ msgid "Could not load vim32.dll!"
+#~ msgstr "无法加载 vim32.dll!"
-#, fuzzy
-#~ msgid " for two modes "
-#~ msgstr " # pid 数据库名称 prepend path\n"
+#~ msgid ""
+#~ "Could not open temporary log file for writing, displaying on stderr ... "
+#~ msgstr "无法打开临时日志文件进行写入,显示在 stderr 中..."
-#, fuzzy
-#~ msgid " for Vim defaults "
-#~ msgstr " # pid 数据库名称 prepend path\n"
+#, c-format
+#~ msgid "Cscope tag: %s"
+#~ msgstr "Cscope tag: %s"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "警告: 检测到 Windows 95/98/ME"
+#~ msgid "Diff with Vim"
+#~ msgstr "用 Vim 比较(diff)"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "输入 :help windows95<Enter> 查看相关说明 "
+#~ msgid "Direction"
+#~ msgstr "方向"
+
+#~ msgid "Directories"
+#~ msgstr "目录"
+
+#~ msgid "Directory\t*.nothing\n"
+#~ msgstr "目录\t*.nothing\n"
+
+#~ msgid "Down"
+#~ msgstr "向下"
+
+#~ msgid "E106: Unknown variable: \"%s\""
+#~ msgstr "E106: 未定义的变量: \"%s\""
+
+#~ msgid "E130: Undefined function: %s"
+#~ msgstr "E130: 函数 %s 尚未定义"
+
+#~ msgid "E136: viminfo: Too many errors, skipping rest of file"
+#~ msgstr "E136: viminfo: 错误过多,忽略文件的剩余部分"
+
+#, c-format
+#~ msgid "E138: Can't write viminfo file %s!"
+#~ msgstr "E138: 无法写入 viminfo 文件 %s!"
+
+#~ msgid "E14: Invalid address"
+#~ msgstr "E14: 无效的地址"
+
+#~ msgid "E172: Only one file name allowed"
+#~ msgstr "E172: 只允许一个文件名"
+
+#~ msgid "E173: 1 more file to edit"
+#~ msgstr "E173: 还有 1 个文件未编辑"
+
+#~ msgid "E188: Obtaining window position not implemented for this platform"
+#~ msgstr "E188: 在此平台上不能获得窗口位置"
+
+#~ msgid "E195: Cannot open viminfo file for reading"
+#~ msgstr "E195: 无法打开并读取 viminfo 文件"
+
+#~ msgid "E196: No digraphs in this version"
+#~ msgstr "E196: 此版本无复合字符(digraph)"
+
+#~ msgid "E198: cmd_pchar beyond the command length"
+#~ msgstr "E198: cmd_pchar 超过命令长度"
+
+#~ msgid "E229: Cannot start the GUI"
+#~ msgstr "E229: 无法启动图形界面"
+
+#~ msgid "E230: Cannot read from \"%s\""
+#~ msgstr "E230: 无法读取文件 \"%s\""
+
+#~ msgid "E231: 'guifontwide' invalid"
+#~ msgstr "E231: 无效的 'guifontwide'"
+
+#~ msgid "E232: Cannot create BalloonEval with both message and callback"
+#~ msgstr "E232: 不能同时使用消息和回调函数来创建 BalloonEval"
+
+#~ msgid "E233: cannot open display"
+#~ msgstr "E233: 无法打开 display"
+
+#~ msgid "E234: Unknown fontset: %s"
+#~ msgstr "E234: 未知的 Fontset: %s"
+
+#~ msgid "E237: Printer selection failed"
+#~ msgstr "E237: 选择打印机失败"
+
+#~ msgid "E238: Print error: %s"
+#~ msgstr "E238: 打印错误: %s"
+
+#~ msgid "E240: No connection to Vim server"
+#~ msgstr "E240: 没有到 Vim 服务器的连接"
+
+#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+#~ msgstr "E243: 不支持的参数: \"-%s\";请使用 OLE 版本。"
+
+#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+#~ msgstr "E244: 字符集 \"%s\" 不能对应字体\"%s\""
+
+#~ msgid "E245: Illegal char '%c' in font name \"%s\""
+#~ msgstr "E245: 不正确的字符 '%c' 出现在字体名称 \"%s\" 内"
+
+#~ msgid "E247: no registered server named \"%s\""
+#~ msgstr "E247: 没有名叫 \"%s\" 的已注册的服务器"
+
+#~ msgid "E248: Failed to send command to the destination program"
+#~ msgstr "E248: 无法发送命令到目的程序"
+
+#~ msgid "E249: couldn't read VIM instance registry property"
+#~ msgstr "E249: 不能读取 VIM 的 注册表属性"
+
+#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+#~ msgstr "E250: Fontset %s 缺少下列字符集的字体:"
+
+#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
+#~ msgstr "E251: VIM 实例注册属性有误。已删除!"
+
+#~ msgid "E252: Fontset name: %s"
+#~ msgstr "E252: Fontset 名称: %s"
+
+#~ msgid "E253: Fontset name: %s\n"
+#~ msgstr "E253: Fontset 名称: %s\n"
+
+#~ msgid "E256: Hangul automata ERROR"
+#~ msgstr "E256: Hangul automata 错误"
+
+#~ msgid "E257: cstag: tag not found"
+#~ msgstr "E257: cstag: 找不到 tag"
+
+#~ msgid "E258: Unable to send to client"
+#~ msgstr "E258: 无法发送到客户端"
+
+#, c-format
+#~ msgid "E259: no matches found for cscope query %s of %s"
+#~ msgstr "E259: cscope 查询 %s %s 没有找到匹配的结果"
+
+#~ msgid "E260: cscope connection not found"
+#~ msgstr "E260: 找不到 cscope 连接"
+
+#, c-format
+#~ msgid "E261: cscope connection %s not found"
+#~ msgstr "E261: 找不到 cscope 连接 %s"
+
+#, c-format
+#~ msgid "E262: error reading cscope connection %<PRId64>"
+#~ msgstr "E262: 读取 cscope 连接 %<PRId64> 出错"
+
+#~ msgid ""
+#~ "E263: Sorry, this command is disabled, the Python library could not be "
+#~ "loaded."
+#~ msgstr "E263: 抱歉,此命令不可用,无法加载 Python 库。"
+
+#~ msgid "E264: Python: Error initialising I/O objects"
+#~ msgstr "E264: Python: 初始化 I/O 对象出错"
+
+#~ msgid ""
+#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
+#~ "loaded."
+#~ msgstr "E266: 抱歉,此命令不可用,无法加载 Ruby 库"
+
+#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+#~ msgstr "E26: 无法使用 Hebrew: 编译时没有启用\n"
+
+#~ msgid "E273: unknown longjmp status %d"
+#~ msgstr "E273: 未知的 longjmp 状态 %d"
+
+#~ msgid "E274: Sniff: Error during read. Disconnected"
+#~ msgstr "E274: Sniff: 读取错误. 取消连接"
+
+#~ msgid "E275: Unknown SNiFF+ request: %s"
+#~ msgstr "E275: 不正确的 SNiff+ 调用: %s"
+
+#~ msgid "E276: Error connecting to SNiFF+"
+#~ msgstr "E276: 连接到 SNiFF+ 失败"
+
+#~ msgid "E277: Unable to read a server reply"
+#~ msgstr "E277: 无法读取服务器响应"
+
+#~ msgid "E278: SNiFF+ not connected"
+#~ msgstr "E278: 未连接到 SNiFF+"
+
+#~ msgid "E279: Not a SNiFF+ buffer"
+#~ msgstr "E279: 不是 SNiFF+ 的缓冲区"
+
+#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+#~ msgstr "E27: 无法使用 Farsi: 编译时没有启用\n"
+
+#~ msgid ""
+#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
+#~ "dev@vim.org"
+#~ msgstr "E280: TCL 严重错误: reflist 损坏!?请报告给 vim-dev@vim.org"
+
+#~ msgid ""
+#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
+#~ "org"
+#~ msgstr "E281: TCL 错误: 退出返回值不是整数!?请报告给 vim-dev@vim.org"
+
+#~ msgid "E285: Failed to create input context"
+#~ msgstr "E285: 无法创建输入上下文"
+
+#~ msgid "E287: Warning: Could not set destroy callback to IM"
+#~ msgstr "E287: 警告: 无法设定输入法的释放回调函数"
+
+#~ msgid "E288: input method doesn't support any style"
+#~ msgstr "E288: 输入法不支持任何风格"
+
+#~ msgid "E289: input method doesn't support my preedit type"
+#~ msgstr "E289: 输入法不支持我的预编辑类型"
+
+#~ msgid "E290: over-the-spot style requires fontset"
+#~ msgstr "E290: over-the-spot 风格需要 Fontset"
+
+#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+#~ msgstr "E291: 你的 GTK+ 比 1.2.3 旧。状态区不可用。"
+
+#~ msgid "E292: Input Method Server is not running"
+#~ msgstr "E292: 输入法服务器未运行"
+
+#~ msgid "E338: Sorry, no file browser in console mode"
+#~ msgstr "E338: 抱歉,控制台模式下没有文件浏览器"
+
+#~ msgid "E339: Pattern too long"
+#~ msgstr "E339: 模式太长"
+
+#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
+#~ msgstr "E341: 内部错误: lalloc(%<PRId64>, )"
+
+#~ msgid "E360: Cannot execute shell with -f option"
+#~ msgstr "E360: 不能用 -f 选项执行 shell"
+
+#~ msgid "E361: Crash intercepted; regexp too complex?"
+#~ msgstr "E361: 不能执行; regular expression 太复杂?"
+
+#~ msgid "E363: pattern caused out-of-stack error"
+#~ msgstr "E363: regular expression 造成堆栈用光的错误"
#~ msgid "E370: Could not load library %s"
#~ msgstr "E370: 无法加载库 %s"
+#~ msgid "E371: Command not found"
+#~ msgstr "E371: 找不到命令"
+
+#~ msgid "E396: containedin argument not accepted here"
+#~ msgstr "E396: 使用了不正确的参数"
+
+#, c-format
+#~ msgid "E422: terminal code too long: %s"
+#~ msgstr "E422: 终端编码太长: %s"
+
+#~ msgid "E430: Tag file path truncated for %s\n"
+#~ msgstr "E430: Tag 文件路径被截断为 %s\n"
+
+#, c-format
+#~ msgid "E436: No \"%s\" entry in termcap"
+#~ msgstr "E436: termcap 中没有 \"%s\" 项"
+
+#~ msgid "E437: terminal capability \"cm\" required"
+#~ msgstr "E437: 终端需要能力 \"cm\""
+
+#~ msgid "E448: Could not load library function %s"
+#~ msgstr "E448: 无法加载库函数 %s"
+
+#~ msgid "E449: Invalid expression received"
+#~ msgstr "E449: 收到无效的表达式"
+
+#~ msgid "E460: The resource fork would be lost (add ! to override)"
+#~ msgstr "E460: Resource fork 会丢失 (请加 ! 强制执行)"
+
+#, c-format
+#~ msgid "E469: invalid cscopequickfix flag %c for %c"
+#~ msgstr "E469: cscopequickfix 标志 %c 对 %c 无效"
+
+#~ msgid "E505: "
+#~ msgstr "E505: "
+
+#~ msgid "E506: Can't write to backup file (add ! to override)"
+#~ msgstr "E506: 无法写入备份文件 (请加 ! 强制执行)"
+
+#~ msgid "E507: Close error for backup file (add ! to override)"
+#~ msgstr "E507: 关闭备份文件出错 (请加 ! 强制执行)"
+
+#~ msgid "E508: Can't read file for backup (add ! to override)"
+#~ msgstr "E508: 无法读取文件以供备份 (请加 ! 强制执行)"
+
+#~ msgid "E50: Too many \\z("
+#~ msgstr "E50: 太多 \\z("
+
+#, fuzzy, c-format
#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr "抱歉,此命令不可用: 无法加载 Perl 库。"
+#~ "E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty "
+#~ "to override)"
+#~ msgstr "E513: 写入错误,转换失败 (请将 'fenc' 置空以强制执行)"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "用多个 Vim 编辑(&M)"
+#, c-format
+#~ msgid "E51: Too many %s("
+#~ msgstr "E51: 太多 %s("
-#~ msgid "Edit with single &Vim"
-#~ msgstr "用单个 Vim 编辑(&V)"
+#~ msgid "E522: Not found in termcap"
+#~ msgstr "E522: Termcap 里面找不到"
-#~ msgid "Diff with Vim"
-#~ msgstr "用 Vim 比较(diff)"
+#~ msgid "E52: Unmatched \\z("
+#~ msgstr "E52: 不匹配的 \\z("
+
+#~ msgid "E530: Cannot change term in GUI"
+#~ msgstr "E530: 在图形界面中不能改变终端"
+
+#~ msgid "E531: Use \":gui\" to start the GUI"
+#~ msgstr "E531: 请用 \":gui\" 启动图形界面"
+
+#~ msgid "E533: can't select wide font"
+#~ msgstr "E533: 无法选择宽字体"
+
+#~ msgid "E538: No mouse support"
+#~ msgstr "E538: 不支持鼠标"
+
+#~ msgid "E541: too many items"
+#~ msgstr "E541: 项目过多"
+
+#~ msgid "E543: Not a valid codepage"
+#~ msgstr "E543: 无效的代码页"
+
+#~ msgid "E547: Illegal mouseshape"
+#~ msgstr "E547: 无效的鼠标形状"
+
+#~ msgid "E557: Cannot open termcap file"
+#~ msgstr "E557: 无法打开 termcap 文件"
+
+#~ msgid "E558: Terminal entry not found in terminfo"
+#~ msgstr "E558: 在 terminfo 中找不到终端项"
+
+#~ msgid "E559: Terminal entry not found in termcap"
+#~ msgstr "E559: 在 termcap 中找不到终端项"
+
+#, c-format
+#~ msgid "E560: Usage: cs[cope] %s"
+#~ msgstr "E560: 用法: cs[cope] %s"
+
+#~ msgid "E561: unknown cscope search type"
+#~ msgstr "E561: 未知的 cscope 查找类型"
+
+#~ msgid "E562: Usage: cstag <ident>"
+#~ msgstr "E562: 用法: cstag <ident>"
+
+#~ msgid "E563: stat error"
+#~ msgstr "E563: stat 错误"
+
+#, c-format
+#~ msgid "E563: stat(%s) error: %d"
+#~ msgstr "E563: stat(%s) 错误: %d"
+
+#, c-format
+#~ msgid "E564: %s is not a directory or a valid cscope database"
+#~ msgstr "E564: %s 不是目录或有效的 cscope 数据库"
+
+#~ msgid "E566: Could not create cscope pipes"
+#~ msgstr "E566: 无法创建 cscope 管道"
+
+#~ msgid "E567: no cscope connections"
+#~ msgstr "E567: 没有 cscope 连接"
+
+#~ msgid "E568: duplicate cscope database not added"
+#~ msgstr "E568: 重复的 cscope 数据库未被加入"
+
+#~ msgid "E569: maximum number of cscope connections reached"
+#~ msgstr "E569: 已达到 cscope 的最大连接数"
+
+#~ msgid "E570: fatal error in cs_manage_matches"
+#~ msgstr "E570: cs_manage_matches 严重错误"
+
+#~ msgid ""
+#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
+#~ "loaded."
+#~ msgstr "E571: 抱歉,此命令不可用,无法加载 Tcl 库"
+
+#~ msgid "E572: exit code %d"
+#~ msgstr "E572: 退出返回值 %d"
+
+#~ msgid "E573: Invalid server id used: %s"
+#~ msgstr "E573: 使用了无效的服务器 id: %s"
+
+#, c-format
+#~ msgid "E574: Unknown register type %d"
+#~ msgstr "E574: 未知的寄存器类型 %d"
+
+#~ msgid "E596: Invalid font(s)"
+#~ msgstr "E596: 无效的字体"
+
+#~ msgid "E597: can't select fontset"
+#~ msgstr "E597: 无法选择 Fontset"
+
+#~ msgid "E599: Value of 'imactivatekey' is invalid"
+#~ msgstr "E599: 'imactivatekey' 的值无效"
+
+#, c-format
+#~ msgid "E59: invalid character after %s@"
+#~ msgstr "E59: %s@ 后面有无效的字符"
+
+#, c-format
+#~ msgid "E609: Cscope error: %s"
+#~ msgstr "E609: Cscope 错误: %s"
+
+#, c-format
+#~ msgid "E60: Too many complex %s{...}s"
+#~ msgstr "E60: 太多复杂的 %s{...}s"
+
+#~ msgid "E613: Unknown printer font: %s"
+#~ msgstr "E613: 未知的打印机字体: %s"
+
+#~ msgid "E614: vim_SelFile: can't return to current directory"
+#~ msgstr "E614: vim_SelFile: 无法返回当前目录"
+
+#~ msgid "E615: vim_SelFile: can't get current directory"
+#~ msgstr "E615: vim_SelFile: 无法获取当前目录"
+
+#~ msgid "E616: vim_SelFile: can't get font %s"
+#~ msgstr "E616: vim_SelFile: 无法获取字体 %s"
+
+#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+#~ msgstr "E617: 在 GTK+ 2 图形界面中不能更改"
+
+#, c-format
+#~ msgid "E61: Nested %s*"
+#~ msgstr "E61: 嵌套的 %s*"
+
+#~ msgid "E622: Could not fork for cscope"
+#~ msgstr "E622: 无法对 cscope 进行 fork"
+
+#~ msgid "E625: cannot open cscope database: %s"
+#~ msgstr "E625: 无法打开 cscope 数据库: %s"
+
+#~ msgid "E626: cannot get cscope database information"
+#~ msgstr "E626: 无法获取 cscope 数据库信息"
+
+#, c-format
+#~ msgid "E62: Nested %s%c"
+#~ msgstr "E62: 嵌套的 %s%c"
+
+#~ msgid "E63: invalid use of \\_"
+#~ msgstr "E63: 不正确地使用 \\_"
+
+#, c-format
+#~ msgid "E64: %s%c follows nothing"
+#~ msgstr "E64: %s%c 前面无内容"
+
+#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
+#~ msgstr "E658: 缓冲区 %<PRId64> 丢失 NetBeans 连接"
+
+#~ msgid "E65: Illegal back reference"
+#~ msgstr "E65: 无效的回引"
+
+#~ msgid "E665: Cannot start GUI, no valid font found"
+#~ msgstr "E665: 无法启动图形界面,找不到有效的字体"
+
+#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+#~ msgstr "E668: NetBeans 连接信息文件中错误的访问模式: \"%s\""
+
+#~ msgid "E672: Unable to open window inside MDI application"
+#~ msgstr "E672: 无法在 MDI 应用程序中打开窗口"
+
+#, c-format
+#~ msgid "E678: Invalid character after %s%%[dxouU]"
+#~ msgstr "E678: %s%%[dxouU] 后面有无效的字符"
+
+#~ msgid "E679: recursive loop loading syncolor.vim"
+#~ msgstr "E679: 加载 syncolor.vim 时出现嵌套循环"
+
+#~ msgid "E68: Invalid character after \\z"
+#~ msgstr "E68: \\z 后面有无效的字符"
+
+#~ msgid "E693: Can only compare Funcref with Funcref"
+#~ msgstr "E693: 只能比较 Funcref 和 Funcref"
+
+#, c-format
+#~ msgid "E706: Variable type mismatch for: %s"
+#~ msgstr "E706: 变量类型不匹配: %s"
+
+#~ msgid "E724: variable nested too deep for displaying"
+#~ msgstr "E724: 变量嵌套过深无法显示"
+
+#~ msgid "E729: using Funcref as a String"
+#~ msgstr "E729: 将函数当做字符串使用"
+
+#~ msgid "E744: NetBeans does not allow changes in read-only files"
+#~ msgstr "E744: NetBeans 不允许改变只读文件"
+
+#~ msgid ""
+#~ "E747: Cannot change directory, buffer is modified (add ! to override)"
+#~ msgstr "E747: 不能改变目录,缓冲区已修改 (请加 ! 强制执行)"
+
+#~ msgid "E761: Format error in affix file FOL, LOW or UPP"
+#~ msgstr "E761: 附加文件 FOL、LOW 或 UPP 中格式错误"
+
+#~ msgid "E762: Character in FOL, LOW or UPP is out of range"
+#~ msgstr "E762: FOL、LOW 或 UPP 中字符超出范围"
+
+#~ msgid "E775: Eval feature not available"
+#~ msgstr "E775: 求值功能不可用"
+
+#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+#~ msgstr "E800: 无法使用 Arabic: 编译时没有启用\n"
+
+#~ msgid "E839: Completion function changed window"
+#~ msgstr "E839: 补全函数更改了窗口"
+
+#~ msgid "E865: (NFA) Regexp end encountered prematurely"
+#~ msgstr "E865: (NFA) 过早地遇到了正则表达式的结尾"
+
+#, c-format
+#~ msgid "E867: (NFA) Unknown operator '\\%%%c'"
+#~ msgstr "E867: (NFA) 未知的操作符 '\\%%%c'"
+
+#, c-format
+#~ msgid "E867: (NFA) Unknown operator '\\z%c'"
+#~ msgstr "E867: (NFA) 未知的操作符 '\\z%c'"
+
+#, c-format
+#~ msgid "E869: (NFA) Unknown operator '\\@%c'"
+#~ msgstr "E869: (NFA) 未知的操作符 '\\@%c'"
+
+#~ msgid "E870: (NFA regexp) Error reading repetition limits"
+#~ msgstr "E870: (NFA regexp) 读取重复限制时出错"
+
+#~ msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+#~ msgstr "E871: (NFA regexp) 不能多个跟多个!"
+
+#~ msgid "E872: (NFA regexp) Too many '('"
+#~ msgstr "E872: (NFA regexp) 太多 '('"
+
+#~ msgid "E873: (NFA regexp) proper termination error"
+#~ msgstr "E873: (NFA regexp) 未适当终止"
+
+#~ msgid "E874: (NFA) Could not pop the stack !"
+#~ msgstr "E874: (NFA) 无法出栈!"
+
+#~ msgid ""
+#~ "E875: (NFA regexp) (While converting from postfix to NFA), too many "
+#~ "states left on stack"
+#~ msgstr "E875: (NFA regexp) (从后缀转换到 NFA 时),栈上遗留了太多状态"
+
+#~ msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+#~ msgstr "E876: (NFA regexp) 没有足够的空间存储整个NFA "
+
+#, c-format
+#~ msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
+#~ msgstr "E877: (NFA regexp) 不可用的字符类: %<PRId64>"
+
+#, fuzzy
+#~ msgid "E879: (NFA regexp) Too many \\z("
+#~ msgstr "E50: 太多 \\z("
+
+#~ msgid "ERROR: "
+#~ msgstr "错误: "
+
+#~ msgid "Edit File"
+#~ msgstr "编辑文件"
+
+#~ msgid "Edit File in new window"
+#~ msgstr "在新窗口编辑文件"
#~ msgid "Edit with &Vim"
#~ msgstr "用 Vim 编辑(&V)"
+#~ msgid "Edit with &multiple Vims"
+#~ msgstr "用多个 Vim 编辑(&M)"
+
#~ msgid "Edit with existing Vim - "
#~ msgstr "用当前的 Vim 编辑 - "
+#~ msgid "Edit with single &Vim"
+#~ msgstr "用单个 Vim 编辑(&V)"
+
#~ msgid "Edits the selected file(s) with Vim"
#~ msgstr "用 Vim 编辑选中的文件"
+#~ msgid "Encoding:"
+#~ msgstr "编码:"
+
+#~ msgid "Enter encryption key: "
+#~ msgstr "输入密码: "
+
+#~ msgid "Enter nr of choice (<CR> to abort): "
+#~ msgstr "输入 nr 或选择 (<CR> 退出): "
+
+#~ msgid "Enter same key again: "
+#~ msgstr "请再输入一次: "
+
#~ msgid "Error creating process: Check if gvim is in your path!"
#~ msgstr "创建进程失败: 请检查 gvim 是否在路径中!"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll 错误"
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Expression"
+#~ msgstr "表达式"
+
+#~ msgid "External submatches:\n"
+#~ msgstr "外部符合:\n"
+
+#~ msgid "Files"
+#~ msgstr "文件"
+
+#~ msgid "Filter"
+#~ msgstr "过滤器"
+
+#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
+#~ msgstr "查找和替换字符串 (使用 '\\\\' 来查找 '\\')"
+
+#~ msgid "Find &Next"
+#~ msgstr "查找下一个(&N)"
+
+#~ msgid "Find Next"
+#~ msgstr "查找下一个"
+
+#~ msgid "Find string (use '\\\\' to find a '\\')"
+#~ msgstr "查找字符串 (使用 '\\\\' 来查找 '\\')"
+
+#~ msgid "Find symbol"
+#~ msgstr "查找 symbol"
+
+#~ msgid "Find what:"
+#~ msgstr "查找内容:"
+
+#~ msgid "Font '%s' is not fixed-width"
+#~ msgstr "'%s' 不是固定宽度的字体"
+
+#~ msgid "Font Selection"
+#~ msgstr "选择字体"
+
+#~ msgid "Font%<PRId64> width is not twice that of font0\n"
+#~ msgstr "字体%<PRId64>的宽度不是字体0的两倍\n"
+
+#~ msgid "Font0 width: %<PRId64>\n"
+#~ msgstr "字体0的宽度:%<PRId64>\n"
+
+#~ msgid "Font0: %s\n"
+#~ msgstr "字体0: %s\n"
+
+#~ msgid ""
+#~ "Font1 width: %<PRId64>\n"
+#~ "\n"
+#~ msgstr ""
+#~ "字体1的宽度: %<PRId64>\n"
+#~ "\n"
+
+#~ msgid "Font1: %s\n"
+#~ msgstr "字体1: %s\n"
+
+#~ msgid "Font:"
+#~ msgstr "字体:"
+
+#~ msgid "Generate docu for"
+#~ msgstr "产生文件: "
+
+#~ msgid "Hit ENTER to continue"
+#~ msgstr "请按 ENTER 继续"
+
+#~ msgid "I/O ERROR"
+#~ msgstr "I/O 错误"
+
+#~ msgid "Ignoring long line in tags file"
+#~ msgstr "忽略较长的行在 tags 文件中"
+
+#~ msgid "Illegal register name"
+#~ msgstr "无效的寄存器名"
+
+#~ msgid "Illegal starting char"
+#~ msgstr "无效的启动字符"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Input Line"
+#~ msgstr "输入行"
+
+#~ msgid "Input _Methods"
+#~ msgstr "输入法(_M)"
+
+#~ msgid "Invalid argument for"
+#~ msgstr "无效的参数"
+
+#~ msgid "Invalid font specification"
+#~ msgstr "指定了无效的字体"
+
+#~ msgid "Keys don't match!"
+#~ msgstr "两次密码不匹配!"
+
+#~ msgid "Kill a connection"
+#~ msgstr "结束一个连接"
+
+#~ msgid "Linear tag search"
+#~ msgstr "线性查找标签 (Tags)"
+
+#~ msgid "Linking: "
+#~ msgstr "链接方式: "
+
+#~ msgid "Match case"
+#~ msgstr "匹配大小写"
+
+#~ msgid "Match whole word only"
+#~ msgstr "匹配完整的词"
+
+#~ msgid "Message"
+#~ msgstr "消息"
+
+#~ msgid "Missing '>'"
+#~ msgstr "缺少 '>'"
+
+#, c-format
+#~ msgid "Missing FOL/LOW/UPP line in %s"
+#~ msgstr "%s 中缺少 FOL/LOW/UPP 行"
+
+#~ msgid "Modified by "
+#~ msgstr "修改者 "
+
+#~ msgid "Name:"
+#~ msgstr "名称:"
+
+#~ msgid "Need %s version %<PRId64>\n"
+#~ msgstr "需要 %s 版本 %<PRId64>\n"
+
+#~ msgid "Need Amigados version 2.04 or later\n"
+#~ msgstr "需要 Amigados 版本 2.04 以上\n"
+
+#~ msgid "NetBeans disallows writes of unmodified buffers"
+#~ msgstr "NetBeans 不允许未修改的缓冲区写入"
+
+#~ msgid "New tab"
+#~ msgstr "新建标签"
+
+#~ msgid "No display: Send expression failed.\n"
+#~ msgstr "没有 display: 发送表达式失败。\n"
+
+#~ msgid "No match at cursor, finding next"
+#~ msgstr "在光标处没有匹配,查找下一个"
+
+#~ msgid "No undo possible; continue anyway"
+#~ msgstr "无法撤销;仍然继续"
+
+#~ msgid "Not Used"
+#~ msgstr "未使用"
+
+#~ msgid "Nvim: Reading from stdin...\n"
+#~ msgstr "Vim: 从标准输入读取...\n"
+
+#~ msgid "OK"
+#~ msgstr "确定"
+
+#~ msgid "Open File dialog"
+#~ msgstr "打开文件对话框"
+
+#~ msgid "Open Tab..."
+#~ msgstr "打开标签..."
+
+#~ msgid "Open tab..."
+#~ msgstr "打开标签..."
+
+#~ msgid "Opening the X display failed"
+#~ msgstr "打开 X display 失败"
+
+#~ msgid "Opening the X display timed out"
+#~ msgstr "打开 X display 超时"
+
+#~ msgid "Opening the X display took %<PRId64> msec"
+#~ msgstr "打开 X display 用时 %<PRId64> 秒"
+
+#~ msgid "Partial writes disallowed for NetBeans buffers"
+#~ msgstr "NetBeans 不允许缓冲区部分写入"
#~ msgid "Path length too long!"
#~ msgstr "路径太长!"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: 未知的 Fontset: %s"
+#~ msgid "Pathname:"
+#~ msgstr "路径:"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: 未知的字体: %s"
+#~ msgid "Query for a pattern"
+#~ msgstr "查询一个模式"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: 字体 \"%s\" 不是等宽字体"
+#~ msgid "Reading from stdin..."
+#~ msgstr "从标准输入读取..."
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: 无法加载库函数 %s"
+#~ msgid "Reinit all connections"
+#~ msgstr "重置所有连接"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: 无法使用 Hebrew: 编译时没有启用\n"
+#~ msgid "Replace"
+#~ msgstr "替换"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: 无法使用 Farsi: 编译时没有启用\n"
+#~ msgid "Replace &All"
+#~ msgstr "全部替换(&A)"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: 无法使用 Arabic: 编译时没有启用\n"
+#~ msgid "Replace All"
+#~ msgstr "全部替换"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: 没有名叫 \"%s\" 的已注册的服务器"
+#~ msgid "Replace with:"
+#~ msgstr "替换为:"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: 无法打开 display"
+#~ msgid "Retrieve"
+#~ msgstr "恢复"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: 收到无效的表达式"
+#~ msgid "Retrieve from all projects"
+#~ msgstr "恢复: 从所有项目"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans 不允许改变只读文件"
+#~ msgid "Retrieve from file"
+#~ msgstr "恢复: 从文件"
-#~ msgid "Affix flags ignored when PFXPOSTPONE used in %s line %d: %s"
-#~ msgstr "%s 第 %d 行,使用 PFXPOSTPONE 时附加标志被忽略: %s"
+#~ msgid "Retrieve from project"
+#~ msgstr "恢复: 从对象"
-#~ msgid "[No file]"
-#~ msgstr "[未命名]"
+#~ msgid "Run Macro"
+#~ msgstr "执行宏"
+
+#~ msgid "Running in Vi compatible mode"
+#~ msgstr "运行于 Vi 兼容模式"
+
+#~ msgid "Running modeless, typed text is inserted"
+#~ msgstr "无模式运行,输入文字即插入"
+
+#~ msgid "SNiFF+ is currently "
+#~ msgstr "SNiFF+ 目前"
+
+#~ msgid "Save As"
+#~ msgstr "另存为"
+
+#~ msgid "Save File dialog"
+#~ msgstr "保存文件对话框"
+
+#~ msgid "Save Redirection"
+#~ msgstr "保存重定向"
+
+#~ msgid "Save Session"
+#~ msgstr "保存会话"
+
+#~ msgid "Save Setup"
+#~ msgstr "保存设定"
+
+#~ msgid "Save View"
+#~ msgstr "保存视图"
+
+#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+#~ msgstr "滚动条部件: 无法获取滑块图像的几何大小"
+
+# do not translate to avoid writing Chinese in files
+#, fuzzy
+#~ msgid "Search String"
+#~ msgstr "查找字符串"
+
+#~ msgid "Select Directory dialog"
+#~ msgstr "选择目录对话框"
+
+#~ msgid "Show base class of"
+#~ msgstr "显示 base class of:"
+
+#~ msgid "Show class in hierarchy"
+#~ msgstr "显示层次关系的类"
+
+#~ msgid "Show class in restricted hierarchy"
+#~ msgstr "显示 restricted 层次关系的 class"
+
+#~ msgid "Show connections"
+#~ msgstr "显示连接"
+
+#~ msgid "Show docu of"
+#~ msgstr "显示文件: "
+
+#~ msgid "Show overridden member function"
+#~ msgstr "显示被覆盖的成员函数"
+
+#~ msgid "Show source of"
+#~ msgstr "显示源代码: "
+
+#~ msgid "Show this message"
+#~ msgstr "显示此信息"
+
+#~ msgid "Size:"
+#~ msgstr "尺寸:"
+
+#~ msgid "Sniff: Error during write. Disconnected"
+#~ msgstr "Sniff: 写入错误。结束连接"
+
+#~ msgid ""
+#~ "Sorry, this command is disabled: the Perl library could not be loaded."
+#~ msgstr "抱歉,此命令不可用: 无法加载 Perl 库。"
+
+#~ msgid "Source Vim script"
+#~ msgstr "执行 Vim 脚本"
+
+#~ msgid "Style:"
+#~ msgstr "风格:"
+
+#, fuzzy
+#~ msgid "Substitute "
+#~ msgstr "1 次替换,"
+
+#~ msgid "Swap file already exists!"
+#~ msgstr "交换文件已存在!"
+
+#~ msgid "Tear off this menu"
+#~ msgstr "撕下此菜单"
+
+#~ msgid "Testing the X display failed"
+#~ msgstr "测试 X display 失败"
+
+#~ msgid "Thanks for flying Vim"
+#~ msgstr "感谢您选择 Vim"
+
+#~ msgid "This Vim was not compiled with the diff feature."
+#~ msgstr "此 Vim 编译时没有加入 diff 功能"
+
+#~ msgid "This cscope command does not support splitting the window.\n"
+#~ msgstr "这个 cscope 命令不支持分割窗口。\n"
+
+#~ msgid "Toggle implementation/definition"
+#~ msgstr "切换实现/定义"
+
+#, fuzzy
+#~ msgid "Unable to get option value"
+#~ msgstr "选项参数后的内容无效"
+
+#~ msgid "Unable to register a command server name"
+#~ msgstr "无法注册命令服务器名"
+
+#~ msgid "Up"
+#~ msgstr "向上"
+
+#~ msgid "Used CUT_BUFFER0 instead of empty selection"
+#~ msgstr "使用 CUT_BUFFER0 来取代空选择"
+
+#~ msgid "VIM - Search and Replace..."
+#~ msgstr "VIM - 查找和替换..."
+
+#~ msgid "VIM - Search..."
+#~ msgstr "VIM - 查找..."
+
+#~ msgid "VIM - Vi IMproved"
+#~ msgstr "VIM - Vi IMproved"
+
+#~ msgid "VIM Error"
+#~ msgstr "VIM 错误"
+
+#~ msgid "VIM: Can't open window!\n"
+#~ msgstr "VIM: 不能打开窗口!\n"
+
+#~ msgid ""
+#~ "VIMRUN.EXE not found in your $PATH.\n"
+#~ "External commands will not pause after completion.\n"
+#~ "See :help win32-vimrun for more information."
+#~ msgstr ""
+#~ "在你的 $PATH 中找不到 VIMRUN.EXE。\n"
+#~ "外部命令执行完毕后将不会暂停。\n"
+#~ "进一步说明请见 :help win32-vimrun"
+
+#~ msgid "Vim - Font Selector"
+#~ msgstr "Vim - 字体选择器"
+
+#~ msgid ""
+#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+#~ msgstr "Vim E458: 无法分配颜色表项,某些颜色可能不正确"
+
+#~ msgid "Vim Warning"
+#~ msgstr "Vim 警告"
+
+#~ msgid "Vim dialog"
+#~ msgstr "Vim 对话框"
+
+#~ msgid "Vim dialog..."
+#~ msgstr "Vim 对话框..."
+
+#~ msgid "Vim error"
+#~ msgstr "Vim 错误"
+
+#~ msgid "Vim error: ~a"
+#~ msgstr "Vim 错误: ~a"
+
+#~ msgid "Vim exiting with %d\n"
+#~ msgstr "Vim 返回值: %d\n"
+
+#~ msgid "Vim: Caught %s event\n"
+#~ msgstr "Vim: 拦截到 %s 事件\n"
+
+#~ msgid "Vim: Caught deadly signal\n"
+#~ msgstr "Vim: 拦截到致命信号(deadly signal)\n"
+
+#~ msgid "Vim: Caught deadly signal %s\n"
+#~ msgstr "Vim: 拦截到致命信号(deadly signal) %s\n"
+
+#~ msgid "Vim: Double signal, exiting\n"
+#~ msgstr "Vim: 双重信号,退出中\n"
+
+#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+#~ msgstr "Vim: 错误: 无法从 NetBeans 中启动 gvim\n"
+
+#~ msgid "Vim: Finished.\n"
+#~ msgstr "Vim: 结束。\n"
+
+#~ msgid "Vim: Main window unexpectedly destroyed\n"
+#~ msgstr "Vim: 主窗口被意外地摧毁\n"
+
+#~ msgid "Vim: Received \"die\" request from session manager\n"
+#~ msgstr "Vim: 从会话管理器收到 \"die\" 请求\n"
+
+#~ msgid "Vim: Warning: Input is not from a terminal\n"
+#~ msgstr "Vim: 警告: 输入不是来自终端(键盘)\n"
+
+#~ msgid "Vim: Warning: Output is not to a terminal\n"
+#~ msgstr "Vim: 警告: 输出不是到终端(屏幕)\n"
+
+#~ msgid "Vim: preserving files...\n"
+#~ msgstr "Vim: 正在保留文件……\n"
+
+#~ msgid "WARNING: Windows 95/98/ME detected"
+#~ msgstr "警告: 检测到 Windows 95/98/ME"
+
+#~ msgid "Warning: terminal cannot highlight"
+#~ msgstr "警告: 你的终端不能显示高亮"
+
+#~ msgid "Window position: X %d, Y %d"
+#~ msgstr "窗口位置: X %d, Y %d"
+
+#~ msgid "XSMP ICE connection watch failed"
+#~ msgstr "XSMP ICE 连接监视失败"
+
+#~ msgid "XSMP handling save-yourself request"
+#~ msgstr "XSMP 处理 save-yourself 请求"
+
+#~ msgid "XSMP lost ICE connection"
+#~ msgstr "XSMP 丢失了到 ICE 的连接"
+
+#~ msgid "XSMP opening connection"
+#~ msgstr "XSMP 打开连接"
+
+#~ msgid "Xref has a"
+#~ msgstr "Xref 有"
+
+#~ msgid "Xref referred by"
+#~ msgstr "Xref 被谁参考:"
+
+#~ msgid "Xref refers to"
+#~ msgstr "Xref 参考到"
+
+#~ msgid "Xref used by"
+#~ msgstr "Xref 被谁使用:"
+
+#~ msgid "Zero count"
+#~ msgstr "计数为零"
#~ msgid "[Error List]"
#~ msgstr "[错误列表]"
-#~ msgid "E106: Unknown variable: \"%s\""
-#~ msgstr "E106: 未定义的变量: \"%s\""
+#~ msgid "[NL found]"
+#~ msgstr "[找到 NL]"
-#~ msgid "function "
-#~ msgstr "函数 "
+#~ msgid "[New file]"
+#~ msgstr "[新文件]"
-#~ msgid "E130: Undefined function: %s"
-#~ msgstr "E130: 函数 %s 尚未定义"
+#~ msgid "[No file]"
+#~ msgstr "[未命名]"
-#~ msgid "Run Macro"
-#~ msgstr "执行宏"
+#~ msgid ""
+#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
+#~ "\n"
+#~ msgstr ""
+#~ "[调用] 总共 re/malloc(): %<PRIu64>,总共 free()': %<PRIu64>\n"
+#~ "\n"
-#~ msgid "E242: Color name not recognized: %s"
-#~ msgstr "E242: %s 为不能识别的颜色名称"
+#~ msgid "[crypted]"
+#~ msgstr "[已加密]"
-#~ msgid "error reading cscope connection %d"
-#~ msgstr "读取 cscope 连接 %d 时错误"
+#~ msgid "[fifo/socket]"
+#~ msgstr "[fifo/socket]"
-#~ msgid "E260: cscope connection not found"
-#~ msgstr "E260: 找不到 cscope 连接"
+#~ msgid "[string too long]"
+#~ msgstr "[字符串太长]"
-#~ msgid "cscope connection closed"
-#~ msgstr "cscope 连接已关闭"
+#~ msgid "attempt to refer to deleted buffer"
+#~ msgstr "试图引用已被删除的缓冲区"
+
+#~ msgid "attempt to refer to deleted window"
+#~ msgstr "试图引用已被删除的窗口"
+
+#~ msgid "block of 1 line yanked"
+#~ msgstr "复制了 1 行的块"
+
+#~ msgid "buffer is invalid"
+#~ msgstr "缓冲区无效"
+
+#~ msgid "by Bram Moolenaar et al."
+#~ msgstr "维护人 Bram Moolenaar 等"
+
+#~ msgid "can't delete OutputObject attributes"
+#~ msgstr "不能删除 OutputObject 属性"
+
+#~ msgid "cannot change console mode ?!\n"
+#~ msgstr "不能切换主控台(console)模式 !?\n"
+
+#~ msgid "cannot create buffer/window command: object is being deleted"
+#~ msgstr "无法创建缓冲区/窗口命令: 对象将被删除"
+
+#~ msgid "cannot delete line"
+#~ msgstr "无法删除行"
+
+#~ msgid "cannot insert line"
+#~ msgstr "无法插入行"
+
+#~ msgid "cannot insert/append line"
+#~ msgstr "无法插入/追加行"
+
+#~ msgid "cannot open "
+#~ msgstr "不能打开"
+
+#~ msgid ""
+#~ "cannot register callback command: buffer/window is already being deleted"
+#~ msgstr "无法注册回调命令: 缓冲区/窗口已被删除"
+
+#~ msgid "cannot register callback command: buffer/window reference not found"
+#~ msgstr "无法注册回调命令: 找不到缓冲区/窗口引用"
+
+#~ msgid "cannot replace line"
+#~ msgstr "无法替换行"
+
+#~ msgid "cannot set line(s)"
+#~ msgstr "无法设定行"
+
+#~ msgid "cannot yank; delete anyway"
+#~ msgstr "无法复制;改为删除"
+
+#~ msgid "close"
+#~ msgstr "关闭"
+
+#~ msgid "connected"
+#~ msgstr "连接中"
#~ msgid "couldn't malloc\n"
#~ msgstr "不能使用 malloc\n"
-#~ msgid "%2d %-5ld %-34s <none>\n"
-#~ msgstr "%2d %-5ld %-34s <无>\n"
+#~ msgid "couldn't open buffer"
+#~ msgstr "无法打开缓冲区"
-#~ msgid "E249: couldn't read VIM instance registry property"
-#~ msgstr "E249: 不能读取 VIM 的 注册表属性"
+#~ msgid "cs_create_connection exec failed"
+#~ msgstr "cs_create_connection 执行失败"
-#~ msgid "\"\n"
-#~ msgstr "\"\n"
+#, fuzzy
+#~ msgid "cs_create_connection setpgid failed"
+#~ msgstr "cs_create_connection 执行失败"
-#~ msgid "--help\t\tShow Gnome arguments"
-#~ msgstr "--help\t\t显示 Gnome 相关参数"
+#~ msgid "cs_create_connection: fdopen for fr_fp failed"
+#~ msgstr "cs_create_connection: fdopen fr_fp 失败"
-#~ msgid "[string too long]"
-#~ msgstr "[字符串太长]"
+#~ msgid "cs_create_connection: fdopen for to_fp failed"
+#~ msgstr "cs_create_connection: fdopen to_fp 失败"
-#~ msgid "Hit ENTER to continue"
-#~ msgstr "请按 ENTER 继续"
+#~ msgid "cscope commands:\n"
+#~ msgstr "cscope 命令:\n"
-#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
-#~ msgstr " (RET/BS: 向下/向上一行, 空格/b: 一页, d/u: 半页, q: 退出)"
+#, c-format
+#~ msgid "cscope connection %s closed"
+#~ msgstr "cscope 连接 %s 已关闭"
-#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
-#~ msgstr " (RET: 向下一行, 空白键: 一页, d: 半页, q: 退出)"
+#~ msgid "cursor position outside buffer"
+#~ msgstr "光标位置在缓冲区外"
-#~ msgid "E361: Crash intercepted; regexp too complex?"
-#~ msgstr "E361: 不能执行; regular expression 太复杂?"
+#~ msgid "defaulting to '"
+#~ msgstr "默认值为: '"
-#~ msgid "E363: pattern caused out-of-stack error"
-#~ msgstr "E363: regular expression 造成堆栈用光的错误"
+#~ msgid "error reading cscope connection %d"
+#~ msgstr "读取 cscope 连接 %d 时错误"
-#~ msgid " BLOCK"
-#~ msgstr " 块"
+#~ msgid "filename / context / line\n"
+#~ msgstr "文件名 / 上下文 / 行\n"
-#~ msgid " LINE"
-#~ msgstr " 行"
+#~ msgid "freeing %<PRId64> lines"
+#~ msgstr "释放了 %<PRId64> 行"
-#~ msgid "Enter nr of choice (<CR> to abort): "
-#~ msgstr "输入 nr 或选择 (<CR> 退出): "
+#~ msgid "gvimext.dll error"
+#~ msgstr "gvimext.dll 错误"
-#~ msgid "Linear tag search"
-#~ msgstr "线性查找标签 (Tags)"
+#~ msgid "hidden option"
+#~ msgstr "隐藏的选项"
-#~ msgid "Binary tag search"
-#~ msgstr "二进制查找(Binary search) 标签(Tags)"
+#~ msgid "internal error: unknown option type"
+#~ msgstr "内部错误:未知的选项类型"
+
+#~ msgid "invalid attribute"
+#~ msgstr "无效的属性"
+
+#~ msgid "invalid buffer number"
+#~ msgstr "无效的缓冲区号"
+
+#~ msgid "invalid expression"
+#~ msgstr "无效的表达式"
+
+#~ msgid "invalid mark name"
+#~ msgstr "无效的标记名称"
+
+#~ msgid "keyboard interrupt"
+#~ msgstr "键盘中断"
+
+#~ msgid "linenr out of range"
+#~ msgstr "行号超出范围"
+
+#~ msgid "logoff"
+#~ msgstr "注消"
+
+#~ msgid "mark not set"
+#~ msgstr "没有设定标记"
+
+#~ msgid "mch_get_shellsize: not a console??\n"
+#~ msgstr "mch_get_shellsize: 不是主控台(console)??\n"
+
+#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
+#~ msgstr "菜单 编辑->全局设定->开/关插入模式 "
+
+#~ msgid "menu Help->Orphans for information "
+#~ msgstr "菜单 帮助->孤儿 查看说明 "
+
+#~ msgid "new shell started\n"
+#~ msgstr "启动新 shell\n"
+
+#~ msgid "no cscope connections\n"
+#~ msgstr "没有 cscope 连接\n"
+
+#~ msgid "no specific match"
+#~ msgstr "找不到匹配的项"
+
+#~ msgid "no such buffer"
+#~ msgstr "无此缓冲区"
+
+#~ msgid "no such window"
+#~ msgstr "无此窗口"
+
+#~ msgid "not "
+#~ msgstr "未"
+
+#~ msgid "not allowed in the Vim sandbox"
+#~ msgstr "不允许在 sandbox 中使用"
+
+#~ msgid "not implemented yet"
+#~ msgstr "尚未实现"
+
+#~ msgid "number changes time"
+#~ msgstr " 编号 改变 时间"
+
+#~ msgid "read from Netbeans socket"
+#~ msgstr "从 Netbeans 套接字读取"
+
+#~ msgid "readonly attribute"
+#~ msgstr "只读属性"
+
+#~ msgid "row %d column %d"
+#~ msgstr "第 %d 行 第 %d 列"
+
+#~ msgid "shell "
+#~ msgstr "shell "
+
+#~ msgid "shell returned %d"
+#~ msgstr "Shell 返回 %d"
+
+#~ msgid "shutdown"
+#~ msgstr "关机"
+
+#~ msgid "softspace must be an integer"
+#~ msgstr "softspace 必须是整数"
+
+#~ msgid "string cannot contain newlines"
+#~ msgstr "字符串不能包含换行(NL)"
+
+#~ msgid "to %s on %s"
+#~ msgstr "从 %s 到 %s"
+
+#~ msgid "type :help cp-default<Enter> for info on this"
+#~ msgstr "输入 :help cp-default<Enter> 查看相关说明 "
+
+#~ msgid "type :help windows95<Enter> for info on this"
+#~ msgstr "输入 :help windows95<Enter> 查看相关说明 "
+
+#~ msgid "type :help<Enter> or <F1> for on-line help"
+#~ msgstr "输入 :help<Enter> 或 <F1> 查看在线帮助 "
+
+#~ msgid "type :set nocp<Enter> for Vim defaults"
+#~ msgstr "输入 :set nocp<Enter> 恢复默认的 Vim "
+
+#~ msgid "unknown flag: "
+#~ msgstr "未知的标志: "
+
+#~ msgid "unknown option"
+#~ msgstr "未知的选项"
+
+#~ msgid "unknown vimOption"
+#~ msgstr "未知的 vim 选项"
+
+#~ msgid "version "
+#~ msgstr "版本 "
+
+#~ msgid "vim error"
+#~ msgstr "vim 错误"
+
+#~ msgid "window index is out of range"
+#~ msgstr "窗口索引超出范围"
+
+#~ msgid "window is invalid"
+#~ msgstr "窗口无效"
+
+#~ msgid "with (classic) GUI."
+#~ msgstr "带(传统)图形界面。"
#~ msgid "with BeOS GUI."
#~ msgstr "使用 BeOS 图形界面。"
+
+#~ msgid "with Carbon GUI."
+#~ msgstr "带 Carbon 图形界面。"
+
+#~ msgid "with Cocoa GUI."
+#~ msgstr "带 Cocoa 图形界面。"
+
+#~ msgid "with GTK GUI."
+#~ msgstr "带 GTK 图形界面。"
+
+#~ msgid "with GTK-GNOME GUI."
+#~ msgstr "带 GTK-GNOME 图形界面。"
+
+#~ msgid "with GTK2 GUI."
+#~ msgstr "带 GTK2 图形界面。"
+
+#~ msgid "with GTK2-GNOME GUI."
+#~ msgstr "带 GTK2-GNOME 图形界面。"
+
+#~ msgid "with GUI."
+#~ msgstr "带图形界面。"
+
+#~ msgid "with Photon GUI."
+#~ msgstr "带 Photon 图形界面。"
+
+#~ msgid "with X11-Athena GUI."
+#~ msgstr "带 X11-Athena 图形界面。"
+
+#~ msgid "with X11-Motif GUI."
+#~ msgstr "带 X11-Motif 图形界面。"
+
+#~ msgid "with X11-neXtaw GUI."
+#~ msgstr "带 X11-neXtaw 图形界面。"
+
+#~ msgid "without GUI."
+#~ msgstr "无图形界面。"
+
+#~ msgid "writelines() requires list of strings"
+#~ msgstr "writelines() 需要字符串列表作参数"
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index d54deaf983..f3a55696aa 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.c
@@ -742,7 +742,7 @@ static void script_dump_profile(FILE *fd)
// Keep going till the end of file, so that trailing
// continuation lines are listed.
for (int i = 0;; i++) {
- if (vim_fgets((char_u *)IObuff, IOSIZE, sfd)) {
+ if (vim_fgets(IObuff, IOSIZE, sfd)) {
break;
}
// When a line has been truncated, append NL, taking care
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index d7590f6f57..ef168d1d45 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -1338,9 +1338,9 @@ static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
return QF_OK;
}
-/// Parse the match for '%+' format pattern. The whole matching line is included
-/// in the error string. Return the matched line in "fields->errmsg".
-static void qf_parse_fmt_plus(const char *linebuf, size_t linelen, qffields_T *fields)
+/// Copy a non-error line into the error string. Return the matched line in
+/// "fields->errmsg".
+static int copy_nonerror_line(const char *linebuf, size_t linelen, qffields_T *fields)
FUNC_ATTR_NONNULL_ALL
{
if (linelen >= fields->errmsglen) {
@@ -1348,7 +1348,10 @@ static void qf_parse_fmt_plus(const char *linebuf, size_t linelen, qffields_T *f
fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
fields->errmsglen = linelen + 1;
}
+ // copy whole line to error message
STRLCPY(fields->errmsg, linebuf, linelen + 1);
+
+ return QF_OK;
}
/// Parse the match for error message ('%m') pattern in regmatch.
@@ -1495,7 +1498,7 @@ static int qf_parse_match(char *linebuf, size_t linelen, efm_T *fmt_ptr, regmatc
status = qf_parse_fmt_f(regmatch, midx, fields, idx);
} else if (i == FMT_PATTERN_M) {
if (fmt_ptr->flags == '+' && !qf_multiscan) { // %+
- qf_parse_fmt_plus(linebuf, linelen, fields);
+ status = copy_nonerror_line(linebuf, linelen, fields);
} else if (midx > 0) { // %m
status = qf_parse_fmt_m(regmatch, midx, fields);
}
@@ -1603,15 +1606,8 @@ static int qf_parse_line_nomatch(char *linebuf, size_t linelen, qffields_T *fiel
fields->namebuf[0] = NUL; // no match found, remove file name
fields->lnum = 0; // don't jump to this line
fields->valid = false;
- if (linelen >= fields->errmsglen) {
- // linelen + null terminator
- fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
- fields->errmsglen = linelen + 1;
- }
- // copy whole line to error message
- STRLCPY(fields->errmsg, linebuf, linelen + 1);
- return QF_OK;
+ return copy_nonerror_line(linebuf, linelen, fields);
}
/// Parse multi-line error format prefixes (%C and %Z)
@@ -2788,7 +2784,7 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char qf_viscol, char
// Move the cursor to the first line in the buffer
pos_T save_cursor = curwin->w_cursor;
curwin->w_cursor.lnum = 0;
- if (!do_search(NULL, '/', '/', (char_u *)qf_pattern, (long)1, SEARCH_KEEP, NULL)) {
+ if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL)) {
curwin->w_cursor = save_cursor;
}
}
@@ -4308,10 +4304,17 @@ void ex_make(exarg_T *eap)
incr_quickfix_busy();
- int res = qf_init(wp, fname, (eap->cmdidx != CMD_make
- && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
- (eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd),
- qf_cmdtitle(*eap->cmdlinep), enc);
+ char *errorformat = p_efm;
+ bool newlist = true;
+
+ if (eap->cmdidx != CMD_make && eap->cmdidx != CMD_lmake) {
+ errorformat = p_gefm;
+ }
+ if (eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd) {
+ newlist = false;
+ }
+
+ int res = qf_init(wp, fname, errorformat, newlist, qf_cmdtitle(*eap->cmdlinep), enc);
qf_info_T *qi = &ql_info;
if (wp != NULL) {
@@ -6708,7 +6711,7 @@ static bool mark_quickfix_ctx(qf_info_T *qi, int copyID)
typval_T *ctx = qi->qf_lists[i].qf_ctx;
if (ctx != NULL && ctx->v_type != VAR_NUMBER
&& ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) {
- abort = abort || set_ref_in_item(ctx, copyID, NULL, NULL);
+ abort = set_ref_in_item(ctx, copyID, NULL, NULL);
}
Callback *cb = &qi->qf_lists[i].qf_qftf_cb;
@@ -6990,7 +6993,7 @@ static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch)
}
linenr_T lnum = 1;
- while (!vim_fgets((char_u *)IObuff, IOSIZE, fd) && !got_int) {
+ while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
char *line = (char *)IObuff;
if (vim_regexec(p_regmatch, line, (colnr_T)0)) {
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 1aa78a3cba..95557a3469 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -2241,6 +2241,25 @@ list_T *reg_submatch_list(int no)
return list;
}
+/// Initialize the values used for matching against multiple lines
+///
+/// @param win window in which to search or NULL
+/// @param buf buffer in which to search
+/// @param lnum nr of line to start looking for match
+static void init_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum)
+{
+ rex.reg_match = NULL;
+ rex.reg_mmatch = rmp;
+ rex.reg_buf = buf;
+ rex.reg_win = win;
+ rex.reg_firstlnum = lnum;
+ rex.reg_maxline = rex.reg_buf->b_ml.ml_line_count - lnum;
+ rex.reg_line_lbr = false;
+ rex.reg_ic = rmp->rmm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = rmp->rmm_maxcol;
+}
+
// XXX Do not allow headers generator to catch definitions from regexp_nfa.c
#ifndef DO_NOT_DEFINE_EMPTY_ATTRIBUTES
# include "nvim/regexp_bt.c"
diff --git a/src/nvim/regexp_bt.c b/src/nvim/regexp_bt.c
index 2ac96997fc..2337dbb51c 100644
--- a/src/nvim/regexp_bt.c
+++ b/src/nvim/regexp_bt.c
@@ -5164,17 +5164,7 @@ static int bt_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, bool line_l
static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col,
proftime_T *tm, int *timed_out)
{
- rex.reg_match = NULL;
- rex.reg_mmatch = rmp;
- rex.reg_buf = buf;
- rex.reg_win = win;
- rex.reg_firstlnum = lnum;
- rex.reg_maxline = rex.reg_buf->b_ml.ml_line_count - lnum;
- rex.reg_line_lbr = false;
- rex.reg_ic = rmp->rmm_ic;
- rex.reg_icombine = false;
- rex.reg_maxcol = rmp->rmm_maxcol;
-
+ init_regexec_multi(rmp, win, buf, lnum);
return bt_regexec_both(NULL, col, tm, timed_out);
}
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index c4102c40ec..ed3a0f38a4 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -7601,16 +7601,6 @@ static int nfa_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col, bool line_
static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col,
proftime_T *tm, int *timed_out)
{
- rex.reg_match = NULL;
- rex.reg_mmatch = rmp;
- rex.reg_buf = buf;
- rex.reg_win = win;
- rex.reg_firstlnum = lnum;
- rex.reg_maxline = rex.reg_buf->b_ml.ml_line_count - lnum;
- rex.reg_line_lbr = false;
- rex.reg_ic = rmp->rmm_ic;
- rex.reg_icombine = false;
- rex.reg_maxcol = rmp->rmm_maxcol;
-
+ init_regexec_multi(rmp, win, buf, lnum);
return nfa_regexec_both(NULL, col, tm, timed_out);
}
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index e1a2483438..8fafe4b6b9 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -1930,7 +1930,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
cookie.fp = fopen_noinh_readbin(fname_exp);
if (cookie.fp == NULL && check_other) {
- // Try again, replacing file name ".vimrc" by "_vimrc" or vice versa,
+ // Try again, replacing file name ".nvimrc" by "_nvimrc" or vice versa,
// and ".exrc" by "_exrc" or vice versa.
p = path_tail(fname_exp);
if ((*p == '.' || *p == '_')
@@ -2043,7 +2043,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
} else {
// Read the first line so we can check for a UTF-8 BOM.
firstline = (uint8_t *)getsourceline(0, (void *)&cookie, 0, true);
- if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
+ if (firstline != NULL && strlen((char *)firstline) >= 3 && firstline[0] == 0xef
&& firstline[1] == 0xbb && firstline[2] == 0xbf) {
// Found BOM; setup conversion, skip over BOM and recode the line.
convert_setup(&cookie.conv, "utf-8", p_enc);
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 378306b8d7..cb31da3e87 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -156,7 +156,7 @@ int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatc
rc_did_emsg = true;
return FAIL;
}
- pat = spats[i].pat;
+ pat = (char_u *)spats[i].pat;
magic = spats[i].magic;
no_smartcase = spats[i].no_scs;
} else if (options & SEARCH_HIS) { // put new pattern in history
@@ -205,9 +205,9 @@ char_u *get_search_pat(void)
void save_re_pat(int idx, char *pat, int magic)
{
- if (spats[idx].pat != (char_u *)pat) {
+ if (spats[idx].pat != pat) {
free_spat(&spats[idx]);
- spats[idx].pat = (char_u *)xstrdup(pat);
+ spats[idx].pat = xstrdup(pat);
spats[idx].magic = magic;
spats[idx].no_scs = no_smartcase;
spats[idx].timestamp = os_time();
@@ -230,11 +230,11 @@ void save_search_patterns(void)
if (save_level++ == 0) {
saved_spats[0] = spats[0];
if (spats[0].pat != NULL) {
- saved_spats[0].pat = (char_u *)xstrdup((char *)spats[0].pat);
+ saved_spats[0].pat = xstrdup(spats[0].pat);
}
saved_spats[1] = spats[1];
if (spats[1].pat != NULL) {
- saved_spats[1].pat = (char_u *)xstrdup((char *)spats[1].pat);
+ saved_spats[1].pat = xstrdup(spats[1].pat);
}
saved_spats_last_idx = last_idx;
saved_spats_no_hlsearch = no_hlsearch;
@@ -301,7 +301,7 @@ void save_last_search_pattern(void)
saved_last_search_spat = spats[RE_SEARCH];
if (spats[RE_SEARCH].pat != NULL) {
- saved_last_search_spat.pat = (char_u *)xstrdup((char *)spats[RE_SEARCH].pat);
+ saved_last_search_spat.pat = xstrdup(spats[RE_SEARCH].pat);
}
saved_last_idx = last_idx;
saved_no_hlsearch = no_hlsearch;
@@ -344,7 +344,7 @@ static void restore_incsearch_state(void)
char_u *last_search_pattern(void)
{
- return spats[RE_SEARCH].pat;
+ return (char_u *)spats[RE_SEARCH].pat;
}
/// Return true when case should be ignored for search pattern "pat".
@@ -440,7 +440,7 @@ void set_csearch_until(int t_cmd)
char_u *last_search_pat(void)
{
- return spats[last_idx].pat;
+ return (char_u *)spats[last_idx].pat;
}
// Reset search direction to forward. For "gd" and "gD" commands.
@@ -459,7 +459,7 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
if (*s == NUL) {
spats[idx].pat = NULL;
} else {
- spats[idx].pat = (char_u *)xstrdup((char *)s);
+ spats[idx].pat = xstrdup((char *)s);
}
spats[idx].timestamp = os_time();
spats[idx].additional_data = NULL;
@@ -479,7 +479,7 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
if (spats[idx].pat == NULL) {
saved_spats[idx].pat = NULL;
} else {
- saved_spats[idx].pat = (char_u *)xstrdup((char *)spats[idx].pat);
+ saved_spats[idx].pat = xstrdup(spats[idx].pat);
}
saved_spats_last_idx = last_idx;
}
@@ -532,7 +532,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
int found;
linenr_T lnum; // no init to shut up Apollo cc
regmmatch_T regmatch;
- char_u *ptr;
+ char *ptr;
colnr_T matchcol;
lpos_T endpos;
lpos_T matchpos;
@@ -576,11 +576,11 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
&& pos->lnum <= buf->b_ml.ml_line_count
&& pos->col < MAXCOL - 2) {
// Watch out for the "col" being MAXCOL - 2, used in a closed fold.
- ptr = (char_u *)ml_get_buf(buf, pos->lnum, false);
- if ((int)STRLEN(ptr) <= pos->col) {
+ ptr = ml_get_buf(buf, pos->lnum, false);
+ if ((int)strlen(ptr) <= pos->col) {
start_char_len = 1;
} else {
- start_char_len = utfc_ptr2len((char *)ptr + pos->col);
+ start_char_len = utfc_ptr2len(ptr + pos->col);
}
} else {
start_char_len = 1;
@@ -645,9 +645,9 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
submatch = first_submatch(&regmatch);
// "lnum" may be past end of buffer for "\n\zs".
if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) {
- ptr = (char_u *)"";
+ ptr = "";
} else {
- ptr = (char_u *)ml_get_buf(buf, lnum + matchpos.lnum, false);
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
}
// Forward search in the first line: match should be after
@@ -686,7 +686,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
if (matchcol == matchpos.col && ptr[matchcol] != NUL) {
- matchcol += utfc_ptr2len((char *)ptr + matchcol);
+ matchcol += utfc_ptr2len(ptr + matchcol);
}
if (matchcol == 0 && (options & SEARCH_START)) {
@@ -716,7 +716,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
// Need to get the line pointer again, a multi-line search may
// have made it invalid.
- ptr = (char_u *)ml_get_buf(buf, lnum, false);
+ ptr = ml_get_buf(buf, lnum, false);
}
if (!match_ok) {
continue;
@@ -769,7 +769,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
// for empty match: advance one char
if (matchcol == matchpos.col
&& ptr[matchcol] != NUL) {
- matchcol += utfc_ptr2len((char *)ptr + matchcol);
+ matchcol += utfc_ptr2len(ptr + matchcol);
}
} else {
// Stop when the match is in a next line.
@@ -778,7 +778,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
matchcol = matchpos.col;
if (ptr[matchcol] != NUL) {
- matchcol += utfc_ptr2len((char *)ptr + matchcol);
+ matchcol += utfc_ptr2len(ptr + matchcol);
}
}
if (ptr[matchcol] == NUL
@@ -798,7 +798,7 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
}
// Need to get the line pointer again, a
// multi-line search may have made it invalid.
- ptr = (char_u *)ml_get_buf(buf, lnum + matchpos.lnum, false);
+ ptr = ml_get_buf(buf, lnum + matchpos.lnum, false);
}
// If there is only a match after the cursor, skip
@@ -826,8 +826,8 @@ int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir,
} else {
pos->col--;
if (pos->lnum <= buf->b_ml.ml_line_count) {
- ptr = (char_u *)ml_get_buf(buf, pos->lnum, false);
- pos->col -= utf_head_off((char *)ptr, (char *)ptr + pos->col);
+ ptr = ml_get_buf(buf, pos->lnum, false);
+ pos->col -= utf_head_off(ptr, ptr + pos->col);
}
}
if (end_pos != NULL) {
@@ -1000,19 +1000,19 @@ static int first_submatch(regmmatch_T *rp)
/// @param sia optional arguments or NULL
///
/// @return 0 for failure, 1 for found, 2 for found and line offset added.
-int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, int options,
+int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, long count, int options,
searchit_arg_T *sia)
{
pos_T pos; // position of the last match
- char_u *searchstr;
+ char *searchstr;
struct soffset old_off;
int retval; // Return value
- char_u *p;
+ char *p;
long c;
- char_u *dircp;
+ char *dircp;
char *strcopy = NULL;
char_u *ps;
- char_u *msgbuf = NULL;
+ char *msgbuf = NULL;
size_t len;
bool has_offset = false;
@@ -1078,7 +1078,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
}
} else {
// make search_regcomp() use spats[RE_SEARCH].pat
- searchstr = (char_u *)"";
+ searchstr = "";
}
}
@@ -1086,12 +1086,12 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
// Find end of regular expression.
// If there is a matching '/' or '?', toss it.
ps = (char_u *)strcopy;
- p = (char_u *)skip_regexp_ex((char *)pat, search_delim, p_magic, &strcopy, NULL);
+ p = skip_regexp_ex(pat, search_delim, p_magic, &strcopy, NULL);
if (strcopy != (char *)ps) {
// made a copy of "pat" to change "\?" to "?"
- searchcmdlen += (int)(STRLEN(pat) - strlen(strcopy));
- pat = (char_u *)strcopy;
- searchstr = (char_u *)strcopy;
+ searchcmdlen += (int)(strlen(pat) - strlen(strcopy));
+ pat = strcopy;
+ searchstr = strcopy;
}
if (*p == search_delim) {
dircp = p; // remember where we put the NUL
@@ -1116,7 +1116,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
if (ascii_isdigit(*p) || *p == '+' || *p == '-') { // got an offset
// 'nr' or '+nr' or '-nr'
if (ascii_isdigit(*p) || ascii_isdigit(*(p + 1))) {
- spats[0].off.off = atol((char *)p);
+ spats[0].off.off = atol(p);
} else if (*p == '-') { // single '-'
spats[0].off.off = -1;
} else { // single '+'
@@ -1136,8 +1136,8 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
if ((options & SEARCH_ECHO) && messaging() && !msg_silent
&& (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) {
- char_u *trunc;
- char_u off_buf[40];
+ char *trunc;
+ char off_buf[40];
size_t off_len = 0;
// Compute msg_row early.
@@ -1147,7 +1147,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
if (!cmd_silent
&& (spats[0].off.line || spats[0].off.end || spats[0].off.off)) {
p = off_buf; // -V507
- *p++ = (char_u)dirc;
+ *p++ = (char)dirc;
if (spats[0].off.end) {
*p++ = 'e';
} else if (!spats[0].off.line) {
@@ -1158,10 +1158,10 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
}
*p = NUL;
if (spats[0].off.off != 0 || spats[0].off.line) {
- snprintf((char *)p, sizeof(off_buf) - 1 - (size_t)(p - off_buf),
+ snprintf(p, sizeof(off_buf) - 1 - (size_t)(p - off_buf),
"%" PRId64, spats[0].off.off);
}
- off_len = STRLEN(off_buf);
+ off_len = strlen(off_buf);
}
if (*searchstr == NUL) {
@@ -1184,12 +1184,12 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
// Use up to 'showcmd' column.
len = (size_t)((Rows - msg_row - 1) * Columns + sc_col - 1);
}
- if (len < STRLEN(p) + off_len + SEARCH_STAT_BUF_LEN + 3) {
- len = STRLEN(p) + off_len + SEARCH_STAT_BUF_LEN + 3;
+ if (len < strlen(p) + off_len + SEARCH_STAT_BUF_LEN + 3) {
+ len = strlen(p) + off_len + SEARCH_STAT_BUF_LEN + 3;
}
} else {
// Reserve enough space for the search pattern + offset.
- len = STRLEN(p) + off_len + 3;
+ len = strlen(p) + off_len + 3;
}
xfree(msgbuf);
@@ -1200,19 +1200,19 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
// do not fill the msgbuf buffer, if cmd_silent is set, leave it
// empty for the search_stat feature.
if (!cmd_silent) {
- msgbuf[0] = (char_u)dirc;
- if (utf_iscomposing(utf_ptr2char((char *)p))) {
+ msgbuf[0] = (char)dirc;
+ if (utf_iscomposing(utf_ptr2char(p))) {
// Use a space to draw the composing char on.
msgbuf[1] = ' ';
- memmove(msgbuf + 2, p, STRLEN(p));
+ memmove(msgbuf + 2, p, strlen(p));
} else {
- memmove(msgbuf + 1, p, STRLEN(p));
+ memmove(msgbuf + 1, p, strlen(p));
}
if (off_len > 0) {
- memmove(msgbuf + STRLEN(p) + 1, off_buf, off_len);
+ memmove(msgbuf + strlen(p) + 1, off_buf, off_len);
}
- trunc = (char_u *)msg_strtrunc((char *)msgbuf, true);
+ trunc = msg_strtrunc(msgbuf, true);
if (trunc != NULL) {
xfree(msgbuf);
msgbuf = trunc;
@@ -1223,14 +1223,14 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
// it would be blanked out again very soon. Show it on the
// left, but do reverse the text.
if (curwin->w_p_rl && *curwin->w_p_rlc == 's') {
- char_u *r = (char_u *)reverse_text(trunc != NULL ? (char *)trunc : (char *)msgbuf);
+ char *r = reverse_text(trunc != NULL ? trunc : msgbuf);
xfree(msgbuf);
msgbuf = r;
// move reversed text to beginning of buffer
while (*r == ' ') {
r++;
}
- size_t pat_len = (size_t)(msgbuf + STRLEN(msgbuf) - r);
+ size_t pat_len = (size_t)(msgbuf + strlen(msgbuf) - r);
memmove(msgbuf, r, pat_len);
// overwrite old text
if ((size_t)(r - msgbuf) >= pat_len) {
@@ -1239,7 +1239,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
memset(msgbuf + pat_len, ' ', (size_t)(r - msgbuf));
}
}
- msg_outtrans((char *)msgbuf);
+ msg_outtrans(msgbuf);
msg_clr_eos();
msg_check();
@@ -1279,7 +1279,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
}
c = searchit(curwin, curbuf, &pos, NULL, dirc == '/' ? FORWARD : BACKWARD,
- searchstr, count,
+ (char_u *)searchstr, count,
(spats[0].off.end * SEARCH_END
+ (options
& (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS + SEARCH_MSG
@@ -1288,7 +1288,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
RE_LAST, sia);
if (dircp != NULL) {
- *dircp = (char_u)search_delim; // restore second '/' or '?' for normal_cmd()
+ *dircp = (char)search_delim; // restore second '/' or '?' for normal_cmd()
}
if (!shortmess(SHM_SEARCH)
@@ -1375,7 +1375,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count,
break;
}
- dirc = *++pat;
+ dirc = (uint8_t)(*++pat);
search_delim = dirc;
if (dirc != '?' && dirc != '/') {
retval = 0;
@@ -1480,7 +1480,7 @@ int searchc(cmdarg_T *cap, int t_cmd)
int dir = cap->arg; // true for searching forward
long count = cap->count1; // repeat count
int col;
- char_u *p;
+ char *p;
int len;
bool stop = true;
@@ -1526,14 +1526,14 @@ int searchc(cmdarg_T *cap, int t_cmd)
cap->oap->inclusive = true;
}
- p = (char_u *)get_cursor_line_ptr();
+ p = get_cursor_line_ptr();
col = curwin->w_cursor.col;
- len = (int)STRLEN(p);
+ len = (int)strlen(p);
while (count--) {
for (;;) {
if (dir > 0) {
- col += utfc_ptr2len((char *)p + col);
+ col += utfc_ptr2len(p + col);
if (col >= len) {
return FAIL;
}
@@ -1541,7 +1541,7 @@ int searchc(cmdarg_T *cap, int t_cmd)
if (col == 0) {
return FAIL;
}
- col -= utf_head_off((char *)p, (char *)p + col - 1) + 1;
+ col -= utf_head_off(p, p + col - 1) + 1;
}
if (lastc_bytelen == 1) {
if (p[col] == c && stop) {
@@ -1562,7 +1562,7 @@ int searchc(cmdarg_T *cap, int t_cmd)
col += lastc_bytelen - 1;
} else {
// To previous char, which may be multi-byte.
- col -= utf_head_off((char *)p, (char *)p + col);
+ col -= utf_head_off(p, p + col);
}
}
curwin->w_cursor.col = col;
@@ -1699,7 +1699,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
bool backwards = false; // init for gcc
bool raw_string = false; // search for raw string
bool inquote = false; // true when inside quotes
- char_u *ptr;
+ char *ptr;
int hash_dir = 0; // Direction searched for # things
int comment_dir = 0; // Direction searched for comments
int traveled = 0; // how far we've searched so far
@@ -1712,7 +1712,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
pos = curwin->w_cursor;
pos.coladd = 0;
- char_u *linep = (char_u *)ml_get(pos.lnum); // pointer to current line
+ char *linep = ml_get(pos.lnum); // pointer to current line
// vi compatible matching
bool cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
@@ -1759,9 +1759,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
// Only check for special things when 'cpo' doesn't have '%'.
if (!cpo_match) {
// Are we before or at #if, #else etc.?
- ptr = (char_u *)skipwhite((char *)linep);
+ ptr = skipwhite(linep);
if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep)) {
- ptr = (char_u *)skipwhite((char *)ptr + 1);
+ ptr = skipwhite(ptr + 1);
if (STRNCMP(ptr, "if", 2) == 0
|| STRNCMP(ptr, "endif", 5) == 0
|| STRNCMP(ptr, "el", 2) == 0) {
@@ -1798,7 +1798,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
pos.col--;
}
for (;;) {
- initc = utf_ptr2char((char *)linep + pos.col);
+ initc = utf_ptr2char(linep + pos.col);
if (initc == NUL) {
break;
}
@@ -1807,11 +1807,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (findc) {
break;
}
- pos.col += utfc_ptr2len((char *)linep + pos.col);
+ pos.col += utfc_ptr2len(linep + pos.col);
}
if (!findc) {
// no brace in the line, maybe use " #if" then
- if (!cpo_match && *skipwhite((char *)linep) == '#') {
+ if (!cpo_match && *skipwhite(linep) == '#') {
hash_dir = 1;
} else {
return NULL;
@@ -1821,7 +1821,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
// Set "match_escaped" if there are an odd number of
// backslashes.
- for (col = pos.col; check_prevcol(linep, col, '\\', &col);) {
+ for (col = pos.col; check_prevcol((char_u *)linep, col, '\\', &col);) {
bslcnt++;
}
match_escaped = (bslcnt & 1);
@@ -1834,7 +1834,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
oap->motion_type = kMTLineWise; // Linewise for this case only
}
if (initc != '#') {
- ptr = (char_u *)skipwhite(skipwhite((char *)linep) + 1);
+ ptr = skipwhite(skipwhite(linep) + 1);
if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0) {
hash_dir = 1;
} else if (STRNCMP(ptr, "endif", 5) == 0) {
@@ -1853,14 +1853,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
}
pos.lnum += hash_dir;
- linep = (char_u *)ml_get(pos.lnum);
+ linep = ml_get(pos.lnum);
line_breakcheck(); // check for CTRL-C typed
- ptr = (char_u *)skipwhite((char *)linep);
+ ptr = skipwhite(linep);
if (*ptr != '#') {
continue;
}
pos.col = (colnr_T)(ptr - linep);
- ptr = (char_u *)skipwhite((char *)ptr + 1);
+ ptr = skipwhite(ptr + 1);
if (hash_dir > 0) {
if (STRNCMP(ptr, "if", 2) == 0) {
count++;
@@ -1907,7 +1907,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
// backward search: Check if this line contains a single-line comment
if ((backwards && comment_dir) || lisp) {
- comment_col = check_linecomment((char *)linep);
+ comment_col = check_linecomment(linep);
}
if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) {
lispcomm = true; // find match inside this comment
@@ -1931,14 +1931,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
}
- linep = (char_u *)ml_get(pos.lnum);
- pos.col = (colnr_T)STRLEN(linep); // pos.col on trailing NUL
+ linep = ml_get(pos.lnum);
+ pos.col = (colnr_T)strlen(linep); // pos.col on trailing NUL
do_quotes = -1;
line_breakcheck();
// Check if this line contains a single-line comment
if (comment_dir || lisp) {
- comment_col = check_linecomment((char *)linep);
+ comment_col = check_linecomment(linep);
}
// skip comment
if (lisp && comment_col != MAXCOL) {
@@ -1946,7 +1946,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
} else {
pos.col--;
- pos.col -= utf_head_off((char *)linep, (char *)linep + pos.col);
+ pos.col -= utf_head_off(linep, linep + pos.col);
}
} else { // forward search
if (linep[pos.col] == NUL
@@ -1966,15 +1966,15 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
}
- linep = (char_u *)ml_get(pos.lnum);
+ linep = ml_get(pos.lnum);
pos.col = 0;
do_quotes = -1;
line_breakcheck();
if (lisp) { // find comment pos in new line
- comment_col = check_linecomment((char *)linep);
+ comment_col = check_linecomment(linep);
}
} else {
- pos.col += utfc_ptr2len((char *)linep + pos.col);
+ pos.col += utfc_ptr2len(linep + pos.col);
}
}
@@ -2003,18 +2003,18 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
} else if (raw_string) {
if (linep[pos.col - 1] == 'R'
&& linep[pos.col] == '"'
- && vim_strchr((char *)linep + pos.col + 1, '(') != NULL) {
+ && vim_strchr(linep + pos.col + 1, '(') != NULL) {
// Possible start of raw string. Now that we have the
// delimiter we can check if it ends before where we
// started searching, or before the previously found
// raw string start.
- if (!find_rawstring_end((char *)linep, &pos,
+ if (!find_rawstring_end(linep, &pos,
count > 0 ? &match_pos : &curwin->w_cursor)) {
count++;
match_pos = pos;
match_pos.col--;
}
- linep = (char_u *)ml_get(pos.lnum); // may have been released
+ linep = ml_get(pos.lnum); // may have been released
}
} else if (linep[pos.col - 1] == '/'
&& linep[pos.col] == '*'
@@ -2078,8 +2078,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
if (pos.lnum > 1) {
- ptr = (char_u *)ml_get(pos.lnum - 1);
- if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\') {
+ ptr = ml_get(pos.lnum - 1);
+ if (*ptr && *(ptr + strlen(ptr) - 1) == '\\') {
do_quotes = 1;
if (start_in_quotes == kNone) {
inquote = at_start;
@@ -2092,7 +2092,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
// ml_get() only keeps one line, need to get linep again
- linep = (char_u *)ml_get(pos.lnum);
+ linep = ml_get(pos.lnum);
}
}
}
@@ -2109,7 +2109,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
// we do not know which part to ignore. Therefore we only set
// inquote if the number of quotes in a line is even, unless this
// line or the previous one ends in a '\'. Complicated, isn't it?
- const int c = utf_ptr2char((char *)linep + pos.col);
+ const int c = utf_ptr2char(linep + pos.col);
switch (c) {
case NUL:
// at end of line without trailing backslash, reset inquote
@@ -2174,8 +2174,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (curbuf->b_p_lisp
&& vim_strchr("(){}[]", c) != NULL
&& pos.col > 1
- && check_prevcol(linep, pos.col, '\\', NULL)
- && check_prevcol(linep, pos.col - 1, '#', NULL)) {
+ && check_prevcol((char_u *)linep, pos.col, '\\', NULL)
+ && check_prevcol((char_u *)linep, pos.col - 1, '#', NULL)) {
break;
}
@@ -2186,7 +2186,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
int col, bslcnt = 0;
if (!cpo_bsl) {
- for (col = pos.col; check_prevcol(linep, col, '\\', &col);) {
+ for (col = pos.col; check_prevcol((char_u *)linep, col, '\\', &col);) {
bslcnt++;
}
}
@@ -2389,7 +2389,7 @@ int current_search(long count, bool forward)
}
// Is the pattern is zero-width?, this time, don't care about the direction
- int zero_width = is_zero_width(spats[last_idx].pat, true, &curwin->w_cursor,
+ int zero_width = is_zero_width((char_u *)spats[last_idx].pat, true, &curwin->w_cursor,
FORWARD);
if (zero_width == -1) {
return FAIL; // pattern not found
@@ -2423,7 +2423,7 @@ int current_search(long count, bool forward)
result = searchit(curwin, curbuf, &pos, &end_pos,
(dir ? FORWARD : BACKWARD),
- spats[last_idx].pat, i ? count : 1,
+ (char_u *)spats[last_idx].pat, i ? count : 1,
SEARCH_KEEP | flags, RE_SEARCH, NULL);
p_ws = old_p_ws;
@@ -2507,7 +2507,7 @@ static int is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direct
int flag = 0;
if (pattern == NULL) {
- pattern = spats[last_idx].pat;
+ pattern = (char_u *)spats[last_idx].pat;
}
if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH,
@@ -2562,10 +2562,10 @@ int linewhite(linenr_T lnum)
return *p == NUL;
}
-// Add the search count "[3/19]" to "msgbuf".
-// See update_search_stat() for other arguments.
+/// Add the search count "[3/19]" to "msgbuf".
+/// See update_search_stat() for other arguments.
static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg,
- char_u *msgbuf, bool recompute, int maxcount, long timeout)
+ char *msgbuf, bool recompute, int maxcount, long timeout)
{
searchstat_T stat;
@@ -2610,7 +2610,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
len += 2;
}
- memmove(msgbuf + STRLEN(msgbuf) - len, t, len);
+ memmove(msgbuf + strlen(msgbuf) - len, t, len);
if (dirc == '?' && stat.cur == maxcount + 1) {
stat.cur = -1;
}
@@ -2618,7 +2618,7 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool sh
// keep the message even after redraw, but don't put in history
msg_hist_off = true;
msg_ext_set_kind("search_count");
- give_warning((char *)msgbuf, false);
+ give_warning(msgbuf, false);
msg_hist_off = false;
}
}
@@ -2642,7 +2642,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
static int incomplete = 0;
static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
static int chgtick = 0;
- static char_u *lastpat = NULL;
+ static char *lastpat = NULL;
static buf_T *lbuf = NULL;
proftime_T start;
@@ -2666,8 +2666,8 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
// XXX: above comment should be "no MB_STRCMP function" ?
if (!(chgtick == buf_get_changedtick(curbuf)
&& lastpat != NULL // suppress clang/NULL passed as nonnull parameter
- && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0
- && STRLEN(lastpat) == STRLEN(spats[last_idx].pat)
+ && STRNICMP(lastpat, spats[last_idx].pat, strlen(lastpat)) == 0
+ && strlen(lastpat) == strlen(spats[last_idx].pat)
&& equalpos(lastpos, *cursor_pos)
&& lbuf == curbuf)
|| wraparound || cur < 0 || (maxcount > 0 && cur > maxcount)
@@ -2717,7 +2717,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
}
if (done_search) {
xfree(lastpat);
- lastpat = (char_u *)xstrdup((char *)spats[last_idx].pat);
+ lastpat = xstrdup(spats[last_idx].pat);
chgtick = (int)buf_get_changedtick(curbuf);
lbuf = curbuf;
lastpos = p;
@@ -2827,7 +2827,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
goto the_end;
}
xfree(spats[last_idx].pat);
- spats[last_idx].pat = (char_u *)xstrdup((char *)pattern);
+ spats[last_idx].pat = xstrdup((char *)pattern);
}
if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) {
goto the_end; // the previous pattern was never defined
@@ -3433,9 +3433,9 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
int old_files;
int already_searched;
char_u *file_line;
- char_u *line;
- char_u *p;
- char_u save_char;
+ char *line;
+ char *p;
+ char save_char;
bool define_matched;
regmatch_T regmatch;
regmatch_T incl_regmatch;
@@ -3444,8 +3444,8 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
bool did_show = false;
bool found = false;
int i;
- char_u *already = NULL;
- char_u *startp = NULL;
+ char *already = NULL;
+ char *startp = NULL;
win_T *curwin_save = NULL;
const int l_g_do_tagpreview = g_do_tagpreview;
@@ -3499,11 +3499,11 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
if (lnum > end_lnum) { // do at least one line
lnum = end_lnum;
}
- line = get_line_and_copy(lnum, file_line);
+ line = (char *)get_line_and_copy(lnum, file_line);
for (;;) {
if (incl_regmatch.regprog != NULL
- && vim_regexec(&incl_regmatch, (char *)line, (colnr_T)0)) {
+ && vim_regexec(&incl_regmatch, line, (colnr_T)0)) {
char_u *p_fname = (curr_fname == (char_u *)curbuf->b_fname)
? (char_u *)curbuf->b_ffname : curr_fname;
@@ -3584,20 +3584,20 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
if (inc_opt != NULL
&& strstr(inc_opt, "\\zs") != NULL) {
// pattern contains \zs, use the match
- p = (char_u *)incl_regmatch.startp[0];
+ p = incl_regmatch.startp[0];
i = (int)(incl_regmatch.endp[0]
- incl_regmatch.startp[0]);
} else {
// find the file name after the end of the match
- for (p = (char_u *)incl_regmatch.endp[0];
- *p && !vim_isfilec(*p); p++) {}
- for (i = 0; vim_isfilec(p[i]); i++) {}
+ for (p = incl_regmatch.endp[0];
+ *p && !vim_isfilec((uint8_t)(*p)); p++) {}
+ for (i = 0; vim_isfilec((uint8_t)p[i]); i++) {}
}
if (i == 0) {
// Nothing found, use the rest of the line.
- p = (char_u *)incl_regmatch.endp[0];
- i = (int)STRLEN(p);
+ p = incl_regmatch.endp[0];
+ i = (int)strlen(p);
} else if (p > line) {
// Avoid checking before the start of the line, can
// happen if \zs appears in the regexp.
@@ -3611,7 +3611,7 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
}
save_char = p[i];
p[i] = NUL;
- msg_outtrans_attr((char *)p, HL_ATTR(HLF_D));
+ msg_outtrans_attr(p, HL_ATTR(HLF_D));
p[i] = save_char;
}
@@ -3678,12 +3678,12 @@ void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bo
search_line:
define_matched = false;
if (def_regmatch.regprog != NULL
- && vim_regexec(&def_regmatch, (char *)line, (colnr_T)0)) {
+ && vim_regexec(&def_regmatch, line, (colnr_T)0)) {
// Pattern must be first identifier after 'define', so skip
// to that position before checking for match of pattern. Also
// don't let it match beyond the end of this identifier.
- p = (char_u *)def_regmatch.endp[0];
- while (*p && !vim_iswordc(*p)) {
+ p = def_regmatch.endp[0];
+ while (*p && !vim_iswordc((uint8_t)(*p))) {
p++;
}
define_matched = true;
@@ -3694,27 +3694,27 @@ search_line:
if (def_regmatch.regprog == NULL || define_matched) {
if (define_matched || compl_status_sol()) {
// compare the first "len" chars from "ptr"
- startp = (char_u *)skipwhite((char *)p);
+ startp = skipwhite(p);
if (p_ic) {
- matched = !mb_strnicmp((char *)startp, (char *)ptr, len);
+ matched = !mb_strnicmp(startp, (char *)ptr, len);
} else {
matched = !STRNCMP(startp, ptr, len);
}
if (matched && define_matched && whole
- && vim_iswordc(startp[len])) {
+ && vim_iswordc((uint8_t)startp[len])) {
matched = false;
}
} else if (regmatch.regprog != NULL
- && vim_regexec(&regmatch, (char *)line, (colnr_T)(p - line))) {
+ && vim_regexec(&regmatch, line, (colnr_T)(p - line))) {
matched = true;
- startp = (char_u *)regmatch.startp[0];
+ startp = regmatch.startp[0];
// Check if the line is not a comment line (unless we are
// looking for a define). A line starting with "# define"
// is not considered to be a comment line.
if (skip_comments) {
if ((*line != '#'
|| STRNCMP(skipwhite((char *)line + 1), "define", 6) != 0)
- && get_leader_len((char *)line, NULL, false, true)) {
+ && get_leader_len(line, NULL, false, true)) {
matched = false;
}
@@ -3722,7 +3722,7 @@ search_line:
// Skips lines like "int backwards; / * normal index
// * /" when looking for "normal".
// Note: Doesn't skip "/ *" in comments.
- p = (char_u *)skipwhite((char *)line);
+ p = skipwhite(line);
if (matched
|| (p[0] == '/' && p[1] == '*') || p[0] == '*') {
for (p = line; *p && p < startp; p++) {
@@ -3754,15 +3754,15 @@ search_line:
break;
}
found = true;
- char_u *aux = p = startp;
+ char *aux = p = startp;
if (compl_status_adding()) {
p += ins_compl_len();
- if (vim_iswordp(p)) {
+ if (vim_iswordp((char_u *)p)) {
goto exit_matched;
}
- p = find_word_start(p);
+ p = (char *)find_word_start((char_u *)p);
}
- p = find_word_end(p);
+ p = (char *)find_word_end((char_u *)p);
i = (int)(p - aux);
if (compl_status_adding() && i == ins_compl_len()) {
@@ -3776,8 +3776,8 @@ search_line:
if (lnum >= end_lnum) {
goto exit_matched;
}
- line = get_line_and_copy(++lnum, file_line);
- } else if (vim_fgets(line = file_line,
+ line = (char *)get_line_and_copy(++lnum, file_line);
+ } else if (vim_fgets(line = (char *)file_line,
LSIZE, files[depth].fp)) {
goto exit_matched;
}
@@ -3785,9 +3785,9 @@ search_line:
// we read a line, set "already" to check this "line" later
// if depth >= 0 we'll increase files[depth].lnum far
// below -- Acevedo
- already = aux = p = (char_u *)skipwhite((char *)line);
- p = find_word_start(p);
- p = find_word_end(p);
+ already = aux = p = skipwhite(line);
+ p = (char *)find_word_start((char_u *)p);
+ p = (char *)find_word_end((char_u *)p);
if (p > aux) {
if (*aux != ')' && IObuff[i - 1] != TAB) {
if (IObuff[i - 1] != ' ') {
@@ -3810,14 +3810,14 @@ search_line:
cont_s_ipos = true;
}
IObuff[i] = NUL;
- aux = (char_u *)IObuff;
+ aux = IObuff;
if (i == ins_compl_len()) {
goto exit_matched;
}
}
- const int add_r = ins_compl_add_infercase(aux, i, p_ic,
+ const int add_r = ins_compl_add_infercase((char_u *)aux, i, p_ic,
curr_fname == (char_u *)curbuf->b_fname
? NULL : curr_fname,
dir, cont_s_ipos);
@@ -3924,7 +3924,7 @@ exit_matched:
&& action == ACTION_EXPAND
&& !compl_status_sol()
&& *startp != NUL
- && *(p = startp + utfc_ptr2len((char *)startp)) != NUL) {
+ && *(p = startp + utfc_ptr2len(startp)) != NUL) {
goto search_line;
}
}
@@ -3940,7 +3940,7 @@ exit_matched:
// end-of-file, close the file and continue in the file that included
// it.
while (depth >= 0 && !already
- && vim_fgets(line = file_line, LSIZE, files[depth].fp)) {
+ && vim_fgets(line = (char *)file_line, LSIZE, files[depth].fp)) {
fclose(files[depth].fp);
old_files--;
files[old_files].name = files[depth].name;
@@ -3955,7 +3955,7 @@ exit_matched:
if (depth >= 0) { // we could read the line
files[depth].lnum++;
// Remove any CR and LF from the line.
- i = (int)STRLEN(line);
+ i = (int)strlen(line);
if (i > 0 && line[i - 1] == '\n') {
line[--i] = NUL;
}
@@ -3966,7 +3966,7 @@ exit_matched:
if (++lnum > end_lnum) {
break;
}
- line = get_line_and_copy(lnum, file_line);
+ line = (char *)get_line_and_copy(lnum, file_line);
}
already = NULL;
}
@@ -4011,11 +4011,11 @@ fpip_end:
vim_regfree(def_regmatch.regprog);
}
-static void show_pat_in_path(char_u *line, int type, bool did_show, int action, FILE *fp,
+static void show_pat_in_path(char *line, int type, bool did_show, int action, FILE *fp,
linenr_T *lnum, long count)
FUNC_ATTR_NONNULL_ARG(1, 6)
{
- char_u *p;
+ char *p;
if (did_show) {
msg_putchar('\n'); // cursor below last one
@@ -4026,7 +4026,7 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action,
return;
}
for (;;) {
- p = line + STRLEN(line) - 1;
+ p = line + strlen(line) - 1;
if (fp != NULL) {
// We used fgets(), so get rid of newline at end
if (p >= line && *p == '\n') {
@@ -4045,7 +4045,7 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action,
msg_puts_attr((const char *)IObuff, HL_ATTR(HLF_N));
msg_puts(" ");
}
- msg_prt_line((char *)line, false);
+ msg_prt_line(line, false);
// Definition continues until line that doesn't end with '\'
if (got_int || type != FIND_DEFINE || p < line || *p != '\\') {
@@ -4061,7 +4061,7 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action,
if (++*lnum > curbuf->b_ml.ml_line_count) {
break;
}
- line = (char_u *)ml_get(*lnum);
+ line = ml_get(*lnum);
}
msg_putchar('\n');
}
diff --git a/src/nvim/search.h b/src/nvim/search.h
index cd8431c916..092098d5fd 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -73,7 +73,7 @@ typedef struct soffset {
/// Structure containing last search pattern and its attributes.
typedef struct spat {
- char_u *pat; ///< The pattern (in allocated memory) or NULL.
+ char *pat; ///< The pattern (in allocated memory) or NULL.
bool magic; ///< Magicness of the pattern.
bool no_scs; ///< No smartcase for this pattern.
Timestamp timestamp; ///< Time of the last change.
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 42f5e3456d..0f81217b4a 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1217,7 +1217,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
.end = cur_entry.data.search_pattern.place_cursor_at_end,
.off = cur_entry.data.search_pattern.offset,
},
- .pat = (char_u *)cur_entry.data.search_pattern.pat,
+ .pat = cur_entry.data.search_pattern.pat,
.additional_data = cur_entry.data.search_pattern.additional_data,
.timestamp = cur_entry.timestamp,
};
@@ -2379,7 +2379,7 @@ static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
.is_substitute_pattern = is_substitute_pattern,
.highlighted = ((is_substitute_pattern ^ search_last_used)
&& search_highlighted),
- .pat = (char *)pat.pat,
+ .pat = pat.pat,
.additional_data = pat.additional_data,
.search_backward = (!is_substitute_pattern && pat.off.dir == '?'),
}
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 8ee28fea34..e6d2eac7c3 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -2590,7 +2590,7 @@ void ex_spellrepall(exarg_T *eap)
sub_nlines = 0;
curwin->w_cursor.lnum = 0;
while (!got_int) {
- if (do_search(NULL, '/', '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
+ if (do_search(NULL, '/', '/', (char *)frompat, 1L, SEARCH_KEEP, NULL) == 0
|| u_save_cursor() == FAIL) {
break;
}
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index 395051453a..1b338ef4bf 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -2086,7 +2086,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
hash_init(&aff->af_comp);
// Read all the lines in the file one by one.
- while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
+ while (!vim_fgets((char *)rline, MAXLINELEN, fd) && !got_int) {
line_breakcheck();
lnum++;
@@ -3146,14 +3146,14 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
spin->si_msg_count = 999999;
// Read and ignore the first line: word count.
- if (vim_fgets(line, MAXLINELEN, fd) || !ascii_isdigit(*skipwhite((char *)line))) {
+ if (vim_fgets((char *)line, MAXLINELEN, fd) || !ascii_isdigit(*skipwhite((char *)line))) {
semsg(_("E760: No word count in %s"), fname);
}
// Read all the lines in the file one by one.
// The words are converted to 'encoding' here, before being added to
// the hashtable.
- while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) {
+ while (!vim_fgets((char *)line, MAXLINELEN, fd) && !got_int) {
line_breakcheck();
lnum++;
if (line[0] == '#' || line[0] == '/') {
@@ -3696,7 +3696,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
spell_message(spin, (char *)IObuff);
// Read all the lines in the file one by one.
- while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
+ while (!vim_fgets((char *)rline, MAXLINELEN, fd) && !got_int) {
line_breakcheck();
lnum++;
@@ -5598,7 +5598,7 @@ void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo
// since its flags sort before the one with WF_BANNED.
fd = os_fopen(fname, "r");
if (fd != NULL) {
- while (!vim_fgets(line, MAXWLEN * 2, fd)) {
+ while (!vim_fgets((char *)line, MAXWLEN * 2, fd)) {
fpos = fpos_next;
fpos_next = ftell(fd);
if (fpos_next < 0) {
diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c
index 355233fc5b..cc5c61b855 100644
--- a/src/nvim/spellsuggest.c
+++ b/src/nvim/spellsuggest.c
@@ -641,7 +641,7 @@ void spell_suggest(int count)
}
// Replace the word.
- p = xmalloc(STRLEN(line) - (size_t)stp->st_orglen + (size_t)stp->st_wordlen + 1);
+ p = xmalloc(strlen(line) - (size_t)stp->st_orglen + (size_t)stp->st_wordlen + 1);
c = (int)(sug.su_badptr - (char_u *)line);
memmove(p, line, (size_t)c);
STRCPY(p + c, stp->st_word);
@@ -880,7 +880,7 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname)
}
// Read it line by line.
- while (!vim_fgets(line, MAXWLEN * 2, fd) && !got_int) {
+ while (!vim_fgets((char *)line, MAXWLEN * 2, fd) && !got_int) {
line_breakcheck();
p = (char_u *)vim_strchr((char *)line, '/');
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 35b9d71ea3..7e4677e502 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -110,6 +110,80 @@ static char *mt_names[MT_COUNT/2] =
#define NOTAGFILE 99 // return value for jumpto_tag
static char *nofile_fname = NULL; // fname for NOTAGFILE error
+/// Return values used when reading lines from a tags file.
+typedef enum {
+ TAGS_READ_SUCCESS = 1,
+ TAGS_READ_EOF,
+ TAGS_READ_IGNORE,
+} tags_read_status_T;
+
+/// States used during a tags search
+typedef enum {
+ TS_START, ///< at start of file
+ TS_LINEAR, ///< linear searching forward, till EOF
+ TS_BINARY, ///< binary searching
+ TS_SKIP_BACK, ///< skipping backwards
+ TS_STEP_FORWARD, ///< stepping forwards
+} tagsearch_state_T;
+
+/// Binary search file offsets in a tags file
+typedef struct {
+ off_T low_offset; ///< offset for first char of first line that
+ ///< could match
+ off_T high_offset; ///< offset of char after last line that could
+ ///< match
+ off_T curr_offset; ///< Current file offset in search range
+ off_T curr_offset_used; ///< curr_offset used when skipping back
+ off_T match_offset; ///< Where the binary search found a tag
+ int low_char; ///< first char at low_offset
+ int high_char; ///< first char at high_offset
+} tagsearch_info_T;
+
+/// Return values used when matching tags against a pattern.
+typedef enum {
+ TAG_MATCH_SUCCESS = 1,
+ TAG_MATCH_FAIL,
+ TAG_MATCH_STOP,
+ TAG_MATCH_NEXT,
+} tagmatch_status_T;
+
+/// Arguments used for matching tags read from a tags file against a pattern.
+typedef struct {
+ int matchoff; ///< tag match offset
+ bool match_re; ///< true if the tag matches a regexp
+ bool match_no_ic; ///< true if the tag matches with case
+ bool has_re; ///< regular expression used
+ bool sortic; ///< tags file sorted ignoring case (foldcase)
+ bool sort_error; ///< tags file not sorted
+} findtags_match_args_T;
+
+/// State information used during a tag search
+typedef struct {
+ tagsearch_state_T state; ///< tag search state
+ bool stop_searching; ///< stop when match found or error
+ pat_T *orgpat; ///< holds unconverted pattern info
+ char *lbuf; ///< line buffer
+ int lbuf_size; ///< length of lbuf
+ char *tag_fname; ///< name of the tag file
+ FILE *fp; ///< current tags file pointer
+ int flags; ///< flags used for tag search
+ int tag_file_sorted; ///< !_TAG_FILE_SORTED value
+ bool get_searchpat; ///< used for 'showfulltag'
+ bool help_only; ///< only search for help tags
+ bool did_open; ///< did open a tag file
+ int mincount; ///< MAXCOL: find all matches
+ ///< other: minimal number of matches
+ bool linear; ///< do a linear search
+ vimconv_T vimconv;
+ char help_lang[3]; ///< lang of current tags file
+ int help_pri; ///< help language priority
+ char *help_lang_find; ///< lang to be found
+ bool is_txt; ///< flag of file extension
+ int match_count; ///< number of matches found
+ garray_T ga_match[MT_COUNT]; ///< stores matches in sequence
+ hashtab_T ht_match[MT_COUNT]; ///< stores matches by key
+} findtags_state_T;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tag.c.generated.h"
#endif
@@ -1355,6 +1429,873 @@ static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int fl
return result;
}
+/// Initialize the state used by find_tags()
+static void findtags_state_init(findtags_state_T *st, char *pat, int flags, int mincount)
+{
+ st->tag_fname = xmalloc(MAXPATHL + 1);
+ st->fp = NULL;
+ st->orgpat = xmalloc(sizeof(pat_T));
+ st->orgpat->pat = (char_u *)pat;
+ st->orgpat->len = (int)strlen(pat);
+ st->orgpat->regmatch.regprog = NULL;
+ st->flags = flags;
+ st->tag_file_sorted = NUL;
+ st->help_lang_find = NULL;
+ st->is_txt = false;
+ st->did_open = false;
+ st->help_only = (flags & TAG_HELP);
+ st->get_searchpat = false;
+ st->help_lang[0] = NUL;
+ st->help_pri = 0;
+ st->mincount = mincount;
+ st->lbuf_size = LSIZE;
+ st->lbuf = xmalloc((size_t)st->lbuf_size);
+ st->match_count = 0;
+ st->stop_searching = false;
+
+ for (int mtt = 0; mtt < MT_COUNT; mtt++) {
+ ga_init(&st->ga_match[mtt], sizeof(char *), 100);
+ hash_init(&st->ht_match[mtt]);
+ }
+}
+
+/// Free the state used by find_tags()
+static void findtags_state_free(findtags_state_T *st)
+{
+ xfree(st->tag_fname);
+ xfree(st->lbuf);
+ vim_regfree(st->orgpat->regmatch.regprog);
+ xfree(st->orgpat);
+}
+
+/// Initialize the language and priority used for searching tags in a Vim help
+/// file.
+/// Returns true to process the help file for tags and false to skip the file.
+static bool findtags_in_help_init(findtags_state_T *st)
+{
+ int i;
+
+ // Keep "en" as the language if the file extension is ".txt"
+ if (st->is_txt) {
+ STRCPY(st->help_lang, "en");
+ } else {
+ // Prefer help tags according to 'helplang'. Put the two-letter
+ // language name in help_lang[].
+ i = (int)STRLEN(st->tag_fname);
+ if (i > 3 && st->tag_fname[i - 3] == '-') {
+ STRLCPY(st->help_lang, st->tag_fname + i - 2, 3);
+ } else {
+ STRCPY(st->help_lang, "en");
+ }
+ }
+ // When searching for a specific language skip tags files for other
+ // languages.
+ if (st->help_lang_find != NULL
+ && STRICMP(st->help_lang, st->help_lang_find) != 0) {
+ return false;
+ }
+
+ // For CTRL-] in a help file prefer a match with the same language.
+ if ((st->flags & TAG_KEEP_LANG)
+ && st->help_lang_find == NULL
+ && curbuf->b_fname != NULL
+ && (i = (int)strlen(curbuf->b_fname)) > 4
+ && curbuf->b_fname[i - 1] == 'x'
+ && curbuf->b_fname[i - 4] == '.'
+ && STRNICMP(curbuf->b_fname + i - 3, st->help_lang, 2) == 0) {
+ st->help_pri = 0;
+ } else {
+ st->help_pri = 1;
+ char *s;
+ for (s = p_hlg; *s != NUL; s++) {
+ if (STRNICMP(s, st->help_lang, 2) == 0) {
+ break;
+ }
+ st->help_pri++;
+ if ((s = vim_strchr(s, ',')) == NULL) {
+ break;
+ }
+ }
+ if (s == NULL || *s == NUL) {
+ // Language not in 'helplang': use last, prefer English, unless
+ // found already.
+ st->help_pri++;
+ if (STRICMP(st->help_lang, "en") != 0) {
+ st->help_pri++;
+ }
+ }
+ }
+
+ return true;
+}
+
+/// Use the function set in 'tagfunc' (if configured and enabled) to get the
+/// tags.
+/// Return OK if at least 1 tag has been successfully found, NOTDONE if the
+/// 'tagfunc' is not used or the 'tagfunc' returns v:null and FAIL otherwise.
+static int findtags_apply_tfu(findtags_state_T *st, char *pat, char *buf_ffname)
+{
+ const bool use_tfu = ((st->flags & TAG_NO_TAGFUNC) == 0);
+
+ if (!use_tfu || tfu_in_use || *curbuf->b_p_tfu == NUL) {
+ return NOTDONE;
+ }
+
+ tfu_in_use = true;
+ int retval = find_tagfunc_tags((char_u *)pat, st->ga_match, &st->match_count,
+ st->flags, (char_u *)buf_ffname);
+ tfu_in_use = false;
+
+ return retval;
+}
+
+/// Read the next line from a tags file.
+/// Returns TAGS_READ_SUCCESS if a tags line is successfully read and should be
+/// processed.
+/// Returns TAGS_READ_EOF if the end of file is reached.
+/// Returns TAGS_READ_IGNORE if the current line should be ignored (used when
+/// reached end of a emacs included tags file)
+static tags_read_status_T findtags_get_next_line(findtags_state_T *st, tagsearch_info_T *sinfo_p)
+{
+ int eof;
+ off_T offset;
+
+ // For binary search: compute the next offset to use.
+ if (st->state == TS_BINARY) {
+ offset = sinfo_p->low_offset + ((sinfo_p->high_offset - sinfo_p->low_offset) / 2);
+ if (offset == sinfo_p->curr_offset) {
+ return TAGS_READ_EOF; // End the binary search without a match.
+ } else {
+ sinfo_p->curr_offset = offset;
+ }
+ } else if (st->state == TS_SKIP_BACK) {
+ // Skipping back (after a match during binary search).
+ sinfo_p->curr_offset -= st->lbuf_size * 2;
+ if (sinfo_p->curr_offset < 0) {
+ sinfo_p->curr_offset = 0;
+ rewind(st->fp);
+ st->state = TS_STEP_FORWARD;
+ }
+ }
+
+ // When jumping around in the file, first read a line to find the
+ // start of the next line.
+ if (st->state == TS_BINARY || st->state == TS_SKIP_BACK) {
+ // Adjust the search file offset to the correct position
+ sinfo_p->curr_offset_used = sinfo_p->curr_offset;
+ vim_ignored = vim_fseek(st->fp, sinfo_p->curr_offset, SEEK_SET);
+ eof = vim_fgets(st->lbuf, st->lbuf_size, st->fp);
+ if (!eof && sinfo_p->curr_offset != 0) {
+ sinfo_p->curr_offset = vim_ftell(st->fp);
+ if (sinfo_p->curr_offset == sinfo_p->high_offset) {
+ // oops, gone a bit too far; try from low offset
+ vim_ignored = vim_fseek(st->fp, sinfo_p->low_offset, SEEK_SET);
+ sinfo_p->curr_offset = sinfo_p->low_offset;
+ }
+ eof = vim_fgets(st->lbuf, st->lbuf_size, st->fp);
+ }
+ // skip empty and blank lines
+ while (!eof && vim_isblankline(st->lbuf)) {
+ sinfo_p->curr_offset = vim_ftell(st->fp);
+ eof = vim_fgets(st->lbuf, st->lbuf_size, st->fp);
+ }
+ if (eof) {
+ // Hit end of file. Skip backwards.
+ st->state = TS_SKIP_BACK;
+ sinfo_p->match_offset = vim_ftell(st->fp);
+ sinfo_p->curr_offset = sinfo_p->curr_offset_used;
+ return TAGS_READ_IGNORE;
+ }
+ } else {
+ // Not jumping around in the file: Read the next line.
+
+ // skip empty and blank lines
+ do {
+ eof = vim_fgets(st->lbuf, st->lbuf_size, st->fp);
+ } while (!eof && vim_isblankline(st->lbuf));
+
+ if (eof) {
+ return TAGS_READ_EOF;
+ }
+ }
+
+ return TAGS_READ_SUCCESS;
+}
+
+/// Parse a tags file header line in "st->lbuf".
+/// Returns true if the current line in st->lbuf is not a tags header line and
+/// should be parsed as a regular tag line. Returns false if the line is a
+/// header line and the next header line should be read.
+static bool findtags_hdr_parse(findtags_state_T *st)
+{
+ // Header lines in a tags file start with "!_TAG_"
+ if (strncmp(st->lbuf, "!_TAG_", 6) != 0) {
+ // Non-header item before the header, e.g. "!" itself.
+ return true;
+ }
+
+ // Process the header line.
+ if (strncmp(st->lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) {
+ st->tag_file_sorted = (uint8_t)st->lbuf[18];
+ }
+ if (strncmp(st->lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) {
+ // Prepare to convert every line from the specified encoding to
+ // 'encoding'.
+ char *p;
+ for (p = st->lbuf + 20; *p > ' ' && *p < 127; p++) {}
+ *p = NUL;
+ convert_setup(&st->vimconv, st->lbuf + 20, p_enc);
+ }
+
+ // Read the next line. Unrecognized flags are ignored.
+ return false;
+}
+
+/// Handler to initialize the state when starting to process a new tags file.
+/// Called in the TS_START state when finding tags from a tags file.
+/// Returns true if the line read from the tags file should be parsed and
+/// false if the line should be ignored.
+static bool findtags_start_state_handler(findtags_state_T *st, bool *sortic,
+ tagsearch_info_T *sinfo_p)
+{
+ const bool noic = (st->flags & TAG_NOIC);
+
+ // The header ends when the line sorts below "!_TAG_". When case is
+ // folded lower case letters sort before "_".
+ if (strncmp(st->lbuf, "!_TAG_", 6) <= 0
+ || (st->lbuf[0] == '!' && ASCII_ISLOWER(st->lbuf[1]))) {
+ return findtags_hdr_parse(st);
+ }
+
+ // Headers ends.
+
+ // When there is no tag head, or ignoring case, need to do a
+ // linear search.
+ // When no "!_TAG_" is found, default to binary search. If
+ // the tag file isn't sorted, the second loop will find it.
+ // When "!_TAG_FILE_SORTED" found: start binary search if
+ // flag set.
+ if (st->linear) {
+ st->state = TS_LINEAR;
+ } else if (st->tag_file_sorted == NUL) {
+ st->state = TS_BINARY;
+ } else if (st->tag_file_sorted == '1') {
+ st->state = TS_BINARY;
+ } else if (st->tag_file_sorted == '2') {
+ st->state = TS_BINARY;
+ *sortic = true;
+ st->orgpat->regmatch.rm_ic = (p_ic || !noic);
+ } else {
+ st->state = TS_LINEAR;
+ }
+
+ if (st->state == TS_BINARY && st->orgpat->regmatch.rm_ic && !*sortic) {
+ // Binary search won't work for ignoring case, use linear
+ // search.
+ st->linear = true;
+ st->state = TS_LINEAR;
+ }
+
+ // When starting a binary search, get the size of the file and
+ // compute the first offset.
+ if (st->state == TS_BINARY) {
+ if (vim_fseek(st->fp, 0, SEEK_END) != 0) {
+ // can't seek, don't use binary search
+ st->state = TS_LINEAR;
+ } else {
+ // Get the tag file size.
+ // Don't use lseek(), it doesn't work
+ // properly on MacOS Catalina.
+ const off_T filesize = vim_ftell(st->fp);
+ vim_ignored = vim_fseek(st->fp, 0, SEEK_SET);
+
+ // Calculate the first read offset in the file. Start
+ // the search in the middle of the file.
+ sinfo_p->low_offset = 0;
+ sinfo_p->low_char = 0;
+ sinfo_p->high_offset = filesize;
+ sinfo_p->curr_offset = 0;
+ sinfo_p->high_char = 0xff;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+/// Parse a tag line read from a tags file.
+/// Also compares the tag name in "tagpp->tagname" with a search pattern in
+/// "st->orgpat->head" as a quick check if the tag may match.
+/// Returns:
+/// - TAG_MATCH_SUCCESS if the tag may match
+/// - TAG_MATCH_FAIL if the tag doesn't match
+/// - TAG_MATCH_NEXT to look for the next matching tag (used in a binary search)
+/// - TAG_MATCH_STOP if all the tags are processed without a match.
+/// Uses the values in "margs" for doing the comparison.
+static tagmatch_status_T findtags_parse_line(findtags_state_T *st, tagptrs_T *tagpp,
+ findtags_match_args_T *margs,
+ tagsearch_info_T *sinfo_p)
+{
+ int status;
+ int i;
+ int cmplen;
+ int tagcmp;
+
+ // Figure out where the different strings are in this line.
+ // For "normal" tags: Do a quick check if the tag matches.
+ // This speeds up tag searching a lot!
+ if (st->orgpat->headlen) {
+ CLEAR_FIELD(*tagpp);
+ tagpp->tagname = st->lbuf;
+ tagpp->tagname_end = (char_u *)vim_strchr(st->lbuf, TAB);
+ if (tagpp->tagname_end == NULL) {
+ // Corrupted tag line.
+ return TAG_MATCH_FAIL;
+ }
+
+ // Skip this line if the length of the tag is different and
+ // there is no regexp, or the tag is too short.
+ cmplen = (int)(tagpp->tagname_end - (char_u *)tagpp->tagname);
+ if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
+ cmplen = (int)p_tl;
+ }
+ if ((st->flags & TAG_REGEXP) && st->orgpat->headlen < cmplen) {
+ cmplen = st->orgpat->headlen;
+ } else if (st->state == TS_LINEAR && st->orgpat->headlen != cmplen) {
+ return TAG_MATCH_NEXT;
+ }
+
+ if (st->state == TS_BINARY) {
+ // Simplistic check for unsorted tags file.
+ i = (int)tagpp->tagname[0];
+ if (margs->sortic) {
+ i = TOUPPER_ASC(tagpp->tagname[0]);
+ }
+ if (i < sinfo_p->low_char || i > sinfo_p->high_char) {
+ margs->sort_error = true;
+ }
+
+ // Compare the current tag with the searched tag.
+ if (margs->sortic) {
+ tagcmp = tag_strnicmp((char_u *)tagpp->tagname, st->orgpat->head,
+ (size_t)cmplen);
+ } else {
+ tagcmp = STRNCMP(tagpp->tagname, st->orgpat->head, cmplen);
+ }
+
+ // A match with a shorter tag means to search forward.
+ // A match with a longer tag means to search backward.
+ if (tagcmp == 0) {
+ if (cmplen < st->orgpat->headlen) {
+ tagcmp = -1;
+ } else if (cmplen > st->orgpat->headlen) {
+ tagcmp = 1;
+ }
+ }
+
+ if (tagcmp == 0) {
+ // We've located the tag, now skip back and search
+ // forward until the first matching tag is found.
+ st->state = TS_SKIP_BACK;
+ sinfo_p->match_offset = sinfo_p->curr_offset;
+ return TAG_MATCH_NEXT;
+ }
+ if (tagcmp < 0) {
+ sinfo_p->curr_offset = vim_ftell(st->fp);
+ if (sinfo_p->curr_offset < sinfo_p->high_offset) {
+ sinfo_p->low_offset = sinfo_p->curr_offset;
+ if (margs->sortic) {
+ sinfo_p->low_char = TOUPPER_ASC(tagpp->tagname[0]);
+ } else {
+ sinfo_p->low_char = (uint8_t)tagpp->tagname[0];
+ }
+ return TAG_MATCH_NEXT;
+ }
+ }
+ if (tagcmp > 0 && sinfo_p->curr_offset != sinfo_p->high_offset) {
+ sinfo_p->high_offset = sinfo_p->curr_offset;
+ if (margs->sortic) {
+ sinfo_p->high_char = TOUPPER_ASC(tagpp->tagname[0]);
+ } else {
+ sinfo_p->high_char = (uint8_t)tagpp->tagname[0];
+ }
+ return TAG_MATCH_NEXT;
+ }
+
+ // No match yet and are at the end of the binary search.
+ return TAG_MATCH_STOP;
+ } else if (st->state == TS_SKIP_BACK) {
+ assert(cmplen >= 0);
+ if (mb_strnicmp(tagpp->tagname, (char *)st->orgpat->head, (size_t)cmplen) != 0) {
+ st->state = TS_STEP_FORWARD;
+ } else {
+ // Have to skip back more. Restore the curr_offset
+ // used, otherwise we get stuck at a long line.
+ sinfo_p->curr_offset = sinfo_p->curr_offset_used;
+ }
+ return TAG_MATCH_NEXT;
+ } else if (st->state == TS_STEP_FORWARD) {
+ assert(cmplen >= 0);
+ if (mb_strnicmp(tagpp->tagname, (char *)st->orgpat->head, (size_t)cmplen) != 0) {
+ if ((off_T)vim_ftell(st->fp) > sinfo_p->match_offset) {
+ return TAG_MATCH_STOP; // past last match
+ } else {
+ return TAG_MATCH_NEXT; // before first match
+ }
+ }
+ } else {
+ // skip this match if it can't match
+ assert(cmplen >= 0);
+ if (mb_strnicmp(tagpp->tagname, (char *)st->orgpat->head, (size_t)cmplen) != 0) {
+ return TAG_MATCH_NEXT;
+ }
+ }
+
+ // Can be a matching tag, isolate the file name and command.
+ tagpp->fname = tagpp->tagname_end + 1;
+ tagpp->fname_end = (char_u *)vim_strchr((char *)tagpp->fname, TAB);
+ if (tagpp->fname_end == NULL) {
+ status = FAIL;
+ } else {
+ tagpp->command = tagpp->fname_end + 1;
+ status = OK;
+ }
+ } else {
+ status = parse_tag_line((char_u *)st->lbuf, tagpp);
+ }
+
+ if (status == FAIL) {
+ return TAG_MATCH_FAIL;
+ }
+
+ return TAG_MATCH_SUCCESS;
+}
+
+/// Initialize the structure used for tag matching.
+static void findtags_matchargs_init(findtags_match_args_T *margs, int flags)
+{
+ margs->matchoff = 0; // match offset
+ margs->match_re = false; // match with regexp
+ margs->match_no_ic = false; // matches with case
+ margs->has_re = (flags & TAG_REGEXP); // regexp used
+ margs->sortic = false; // tag file sorted in nocase
+ margs->sort_error = false; // tags file not sorted
+}
+
+/// Compares the tag name in "tagpp->tagname" with a search pattern in
+/// "st->orgpat->pat".
+/// Returns true if the tag matches, false if the tag doesn't match.
+/// Uses the values in "margs" for doing the comparison.
+static bool findtags_match_tag(findtags_state_T *st, tagptrs_T *tagpp, findtags_match_args_T *margs)
+{
+ bool match = false;
+
+ // First try matching with the pattern literally (also when it is
+ // a regexp).
+ int cmplen = (int)(tagpp->tagname_end - (char_u *)tagpp->tagname);
+ if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
+ cmplen = (int)p_tl;
+ }
+ // if tag length does not match, don't try comparing
+ if (st->orgpat->len != cmplen) {
+ match = false;
+ } else {
+ if (st->orgpat->regmatch.rm_ic) {
+ assert(cmplen >= 0);
+ match = mb_strnicmp(tagpp->tagname, (char *)st->orgpat->pat, (size_t)cmplen) == 0;
+ if (match) {
+ margs->match_no_ic = STRNCMP(tagpp->tagname, st->orgpat->pat, cmplen) == 0;
+ }
+ } else {
+ match = STRNCMP(tagpp->tagname, st->orgpat->pat, cmplen) == 0;
+ }
+ }
+
+ // Has a regexp: Also find tags matching regexp.
+ margs->match_re = false;
+ if (!match && st->orgpat->regmatch.regprog != NULL) {
+ int cc = *tagpp->tagname_end;
+ *tagpp->tagname_end = NUL;
+ match = vim_regexec(&st->orgpat->regmatch, tagpp->tagname, (colnr_T)0);
+ if (match) {
+ margs->matchoff = (int)(st->orgpat->regmatch.startp[0] - tagpp->tagname);
+ if (st->orgpat->regmatch.rm_ic) {
+ st->orgpat->regmatch.rm_ic = false;
+ margs->match_no_ic = vim_regexec(&st->orgpat->regmatch,
+ tagpp->tagname, (colnr_T)0);
+ st->orgpat->regmatch.rm_ic = true;
+ }
+ }
+ *tagpp->tagname_end = (char_u)cc;
+ margs->match_re = true;
+ }
+
+ return match;
+}
+
+/// Convert the encoding of a line read from a tags file in "st->lbuf".
+/// Converting the pattern from 'enc' to the tags file encoding doesn't work,
+/// because characters are not recognized. The converted line is saved in
+/// st->lbuf.
+static void findtags_string_convert(findtags_state_T *st)
+{
+ char *conv_line = string_convert(&st->vimconv, st->lbuf, NULL);
+ if (conv_line == NULL) {
+ return;
+ }
+
+ // Copy or swap lbuf and conv_line.
+ int len = (int)strlen(conv_line) + 1;
+ if (len > st->lbuf_size) {
+ xfree(st->lbuf);
+ st->lbuf = conv_line;
+ st->lbuf_size = len;
+ } else {
+ STRCPY(st->lbuf, conv_line);
+ xfree(conv_line);
+ }
+}
+
+/// Add a matching tag found in a tags file to st->ht_match and st->ga_match.
+static void findtags_add_match(findtags_state_T *st, tagptrs_T *tagpp, findtags_match_args_T *margs,
+ char *buf_ffname, hash_T *hash)
+{
+ const bool name_only = (st->flags & TAG_NAMES);
+ int mtt;
+ size_t len = 0;
+ bool is_current; // file name matches
+ bool is_static; // current tag line is static
+ char *mfp;
+ char *p;
+ char_u *s;
+
+ // Decide in which array to store this match.
+ is_current = test_for_current((char *)tagpp->fname, (char *)tagpp->fname_end,
+ st->tag_fname, buf_ffname);
+ is_static = test_for_static(tagpp);
+
+ // Decide in which of the sixteen tables to store this match.
+ if (is_static) {
+ if (is_current) {
+ mtt = MT_ST_CUR;
+ } else {
+ mtt = MT_ST_OTH;
+ }
+ } else {
+ if (is_current) {
+ mtt = MT_GL_CUR;
+ } else {
+ mtt = MT_GL_OTH;
+ }
+ }
+ if (st->orgpat->regmatch.rm_ic && !margs->match_no_ic) {
+ mtt += MT_IC_OFF;
+ }
+ if (margs->match_re) {
+ mtt += MT_RE_OFF;
+ }
+
+ // Add the found match in ht_match[mtt] and ga_match[mtt].
+ // Store the info we need later, which depends on the kind of
+ // tags we are dealing with.
+ if (st->help_only) {
+#define ML_EXTRA 3
+ // Append the help-heuristic number after the tagname, for
+ // sorting it later. The heuristic is ignored for
+ // detecting duplicates.
+ // The format is {tagname}@{lang}NUL{heuristic}NUL
+ *tagpp->tagname_end = NUL;
+ len = (size_t)(tagpp->tagname_end - (char_u *)tagpp->tagname);
+ mfp = xmalloc(sizeof(char) + len + 10 + ML_EXTRA + 1);
+
+ p = mfp;
+ STRCPY(p, tagpp->tagname);
+ p[len] = '@';
+ STRCPY(p + len + 1, st->help_lang);
+ snprintf(p + len + 1 + ML_EXTRA, strlen(p) + len + 1 + ML_EXTRA, "%06d",
+ help_heuristic(tagpp->tagname,
+ margs->match_re ? margs->matchoff : 0,
+ !margs->match_no_ic) + st->help_pri);
+
+ *tagpp->tagname_end = TAB;
+ } else if (name_only) {
+ if (st->get_searchpat) {
+ char_u *temp_end = tagpp->command;
+
+ if (*temp_end == '/') {
+ while (*temp_end && *temp_end != '\r'
+ && *temp_end != '\n'
+ && *temp_end != '$') {
+ temp_end++;
+ }
+ }
+
+ if (tagpp->command + 2 < temp_end) {
+ len = (size_t)(temp_end - tagpp->command - 2);
+ mfp = xmalloc(len + 2);
+ STRLCPY(mfp, tagpp->command + 2, len + 1);
+ } else {
+ mfp = NULL;
+ }
+ st->get_searchpat = false;
+ } else {
+ len = (size_t)((char *)tagpp->tagname_end - tagpp->tagname);
+ mfp = xmalloc(sizeof(char) + len + 1);
+ STRLCPY(mfp, tagpp->tagname, len + 1);
+
+ // if wanted, re-read line to get long form too
+ if (State & MODE_INSERT) {
+ st->get_searchpat = p_sft;
+ }
+ }
+ } else {
+ size_t tag_fname_len = strlen(st->tag_fname);
+ // Save the tag in a buffer.
+ // Use 0x02 to separate fields (Can't use NUL, because the
+ // hash key is terminated by NUL).
+ // Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
+ // other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
+ // without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
+ // Here <mtt> is the "mtt" value plus 1 to avoid NUL.
+ len = tag_fname_len + strlen(st->lbuf) + 3;
+ mfp = xmalloc(sizeof(char) + len + 1);
+ p = mfp;
+ p[0] = (char)(mtt + 1);
+ STRCPY(p + 1, st->tag_fname);
+#ifdef BACKSLASH_IN_FILENAME
+ // Ignore differences in slashes, avoid adding
+ // both path/file and path\file.
+ slash_adjust(p + 1);
+#endif
+ p[tag_fname_len + 1] = TAG_SEP;
+ s = (char_u *)p + 1 + tag_fname_len + 1;
+ STRCPY(s, st->lbuf);
+ }
+
+ if (mfp != NULL) {
+ hashitem_T *hi;
+
+ // Don't add identical matches.
+ // "mfp" is used as a hash key, there is a NUL byte to end
+ // the part that matters for comparing, more bytes may
+ // follow after it. E.g. help tags store the priority
+ // after the NUL.
+ *hash = hash_hash((char_u *)mfp);
+ hi = hash_lookup(&st->ht_match[mtt], (const char *)mfp, strlen(mfp), *hash);
+ if (HASHITEM_EMPTY(hi)) {
+ hash_add_item(&st->ht_match[mtt], hi, (char_u *)mfp, *hash);
+ GA_APPEND(char *, &st->ga_match[mtt], mfp);
+ st->match_count++;
+ } else {
+ // duplicate tag, drop it
+ xfree(mfp);
+ }
+ }
+}
+
+/// Read and get all the tags from file st->tag_fname.
+/// Sets "st->stop_searching" to true to stop searching for additional tags.
+static void findtags_get_all_tags(findtags_state_T *st, findtags_match_args_T *margs,
+ char *buf_ffname)
+{
+ tagptrs_T tagp;
+ tagsearch_info_T search_info;
+ int retval;
+ hash_T hash = 0;
+
+ // This is only to avoid a compiler warning for using search_info
+ // uninitialised.
+ CLEAR_FIELD(search_info);
+
+ // Read and parse the lines in the file one by one
+ for (;;) {
+ // check for CTRL-C typed, more often when jumping around
+ if (st->state == TS_BINARY || st->state == TS_SKIP_BACK) {
+ line_breakcheck();
+ } else {
+ fast_breakcheck();
+ }
+ if ((st->flags & TAG_INS_COMP)) { // Double brackets for gcc
+ ins_compl_check_keys(30, false);
+ }
+ if (got_int || ins_compl_interrupted()) {
+ st->stop_searching = true;
+ break;
+ }
+ // When mincount is TAG_MANY, stop when enough matches have been
+ // found (for completion).
+ if (st->mincount == TAG_MANY && st->match_count >= TAG_MANY) {
+ st->stop_searching = true;
+ break;
+ }
+ if (st->get_searchpat) {
+ goto line_read_in;
+ }
+
+ retval = (int)findtags_get_next_line(st, &search_info);
+ if (retval == TAGS_READ_IGNORE) {
+ continue;
+ }
+ if (retval == TAGS_READ_EOF) {
+ break;
+ }
+
+line_read_in:
+
+ if (st->vimconv.vc_type != CONV_NONE) {
+ findtags_string_convert(st);
+ }
+
+ // When still at the start of the file, check for Emacs tags file
+ // format, and for "not sorted" flag.
+ if (st->state == TS_START) {
+ if (!findtags_start_state_handler(st, &margs->sortic, &search_info)) {
+ continue;
+ }
+ }
+
+ // When the line is too long the NUL will not be in the
+ // last-but-one byte (see vim_fgets()).
+ // Has been reported for Mozilla JS with extremely long names.
+ // In that case we need to increase lbuf_size.
+ if (st->lbuf[st->lbuf_size - 2] != NUL) {
+ st->lbuf_size *= 2;
+ xfree(st->lbuf);
+ st->lbuf = xmalloc((size_t)st->lbuf_size);
+
+ if (st->state == TS_STEP_FORWARD || st->state == TS_LINEAR) {
+ // Seek to the same position to read the same line again
+ vim_ignored = vim_fseek(st->fp, search_info.curr_offset, SEEK_SET);
+ }
+ // this will try the same thing again, make sure the offset is
+ // different
+ search_info.curr_offset = 0;
+ continue;
+ }
+
+ retval = (int)findtags_parse_line(st, &tagp, margs, &search_info);
+ if (retval == TAG_MATCH_NEXT) {
+ continue;
+ }
+ if (retval == TAG_MATCH_STOP) {
+ break;
+ }
+ if (retval == TAG_MATCH_FAIL) {
+ semsg(_("E431: Format error in tags file \"%s\""), st->tag_fname);
+ semsg(_("Before byte %" PRId64), (int64_t)vim_ftell(st->fp));
+ st->stop_searching = true;
+ return;
+ }
+
+ // If a match is found, add it to ht_match[] and ga_match[].
+ if (findtags_match_tag(st, &tagp, margs)) {
+ findtags_add_match(st, &tagp, margs, buf_ffname, &hash);
+ }
+ } // forever
+}
+
+/// Search for tags matching "st->orgpat.pat" in the "st->tag_fname" tags file.
+/// Information needed to search for the tags is in the "st" state structure.
+/// The matching tags are returned in "st". If an error is encountered, then
+/// "st->stop_searching" is set to true.
+static void findtags_in_file(findtags_state_T *st, int flags, char *buf_ffname)
+{
+ findtags_match_args_T margs;
+
+ st->vimconv.vc_type = CONV_NONE;
+ st->tag_file_sorted = NUL;
+ st->fp = NULL;
+ findtags_matchargs_init(&margs, st->flags);
+
+ // A file that doesn't exist is silently ignored. Only when not a
+ // single file is found, an error message is given (further on).
+ if (curbuf->b_help) {
+ if (!findtags_in_help_init(st)) {
+ return;
+ }
+ }
+
+ st->fp = os_fopen(st->tag_fname, "r");
+ if (st->fp == NULL) {
+ return;
+ }
+
+ if (p_verbose >= 5) {
+ verbose_enter();
+ smsg(_("Searching tags file %s"), st->tag_fname);
+ verbose_leave();
+ }
+ st->did_open = true; // remember that we found at least one file
+
+ st->state = TS_START; // we're at the start of the file
+
+ // Read and parse the lines in the file one by one
+ findtags_get_all_tags(st, &margs, buf_ffname);
+
+ if (st->fp != NULL) {
+ fclose(st->fp);
+ st->fp = NULL;
+ }
+ if (st->vimconv.vc_type != CONV_NONE) {
+ convert_setup(&st->vimconv, NULL, NULL);
+ }
+
+ if (margs.sort_error) {
+ semsg(_("E432: Tags file not sorted: %s"), st->tag_fname);
+ }
+
+ // Stop searching if sufficient tags have been found.
+ if (st->match_count >= st->mincount) {
+ st->stop_searching = true;
+ }
+}
+
+/// Copy the tags found by find_tags() to "matchesp".
+/// Returns the number of matches copied.
+static int findtags_copy_matches(findtags_state_T *st, char ***matchesp)
+{
+ const bool name_only = (st->flags & TAG_NAMES);
+ char **matches;
+ int mtt;
+ int i;
+ char *mfp;
+ char *p;
+
+ if (st->match_count > 0) {
+ matches = xmalloc((size_t)st->match_count * sizeof(char *));
+ } else {
+ matches = NULL;
+ }
+ st->match_count = 0;
+ for (mtt = 0; mtt < MT_COUNT; mtt++) {
+ for (i = 0; i < st->ga_match[mtt].ga_len; i++) {
+ mfp = ((char **)(st->ga_match[mtt].ga_data))[i];
+ if (matches == NULL) {
+ xfree(mfp);
+ } else {
+ if (!name_only) {
+ // Change mtt back to zero-based.
+ *mfp = (char)(*mfp - 1);
+
+ // change the TAG_SEP back to NUL
+ for (p = mfp + 1; *p != NUL; p++) {
+ if (*p == TAG_SEP) {
+ *p = NUL;
+ }
+ }
+ }
+ matches[st->match_count++] = mfp;
+ }
+ }
+
+ ga_clear(&st->ga_match[mtt]);
+ hash_clear(&st->ht_match[mtt]);
+ }
+
+ *matchesp = matches;
+ return st->match_count;
+}
+
/// find_tags() - search for tags in tags files
///
/// Return FAIL if search completely failed (*num_matches will be 0, *matchesp
@@ -1383,87 +2324,28 @@ static int find_tagfunc_tags(char_u *pat, garray_T *ga, int *match_count, int fl
/// @param pat pattern to search for
/// @param num_matches return: number of matches found
/// @param matchesp return: array of matches found
-/// @param mincount MAXCOL: find all matches other: minimal number of matches */
+/// @param mincount MAXCOL: find all matches
+/// other: minimal number of matches
/// @param buf_ffname name of buffer for priority
int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int mincount,
char *buf_ffname)
{
- FILE *fp;
- char *lbuf; // line buffer
- int lbuf_size = LSIZE; // length of lbuf
- char *tag_fname; // name of tag file
+ findtags_state_T st;
tagname_T tn; // info for get_tagfname()
int first_file; // trying first tag file
- tagptrs_T tagp;
- bool did_open = false; // did open a tag file
- bool stop_searching = false; // stop when match found or error
int retval = FAIL; // return value
- int is_static; // current tag line is static
- int is_current; // file name matches
- bool eof = false; // found end-of-file
- char *p;
- char_u *s;
- int i;
- int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value
- struct tag_search_info { // Binary search file offsets
- off_T low_offset; // offset for first char of first line that
- // could match
- off_T high_offset; // offset of char after last line that could
- // match
- off_T curr_offset; // Current file offset in search range
- off_T curr_offset_used; // curr_offset used when skipping back
- off_T match_offset; // Where the binary search found a tag
- int low_char; // first char at low_offset
- int high_char; // first char at high_offset
- } search_info;
- int tagcmp;
- off_T offset;
int round;
- enum {
- TS_START, // at start of file
- TS_LINEAR, // linear searching forward, till EOF
- TS_BINARY, // binary searching
- TS_SKIP_BACK, // skipping backwards
- TS_STEP_FORWARD, // stepping forwards
- } state; // Current search state
- int cmplen;
- int match; // matches
- int match_no_ic = 0; // matches with rm_ic == false
- int match_re; // match with regexp
- int matchoff = 0;
int save_emsg_off;
- char *mfp;
- garray_T ga_match[MT_COUNT]; // stores matches in sequence
- hashtab_T ht_match[MT_COUNT]; // stores matches by key
- hash_T hash = 0;
- int match_count = 0; // number of matches found
- char **matches;
- int mtt;
int help_save;
- int help_pri = 0;
- char_u *help_lang_find = NULL; // lang to be found
- char_u help_lang[3]; // lang of current tags file
+ int i;
char *saved_pat = NULL; // copy of pat[]
- bool is_txt = false;
-
- pat_T orgpat; // holds unconverted pattern info
- vimconv_T vimconv;
- int findall = (mincount == MAXCOL || mincount == TAG_MANY);
- // find all matching tags
- bool sort_error = false; // tags file not sorted
- int linear; // do a linear search
- bool sortic = false; // tag file sorted in nocase
- bool line_error = false; // syntax error
+ int findall = (mincount == MAXCOL || mincount == TAG_MANY); // find all matching tags
int has_re = (flags & TAG_REGEXP); // regexp used
- int help_only = (flags & TAG_HELP);
- int name_only = (flags & TAG_NAMES);
int noic = (flags & TAG_NOIC);
- int get_it_again = false;
int verbose = (flags & TAG_VERBOSE);
- int use_tfu = ((flags & TAG_NO_TAGFUNC) == 0);
int save_p_ic = p_ic;
// Change the value of 'ignorecase' according to 'tagcase' for the
@@ -1488,60 +2370,53 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
}
help_save = curbuf->b_help;
- orgpat.pat = (char_u *)pat;
- orgpat.regmatch.regprog = NULL;
- vimconv.vc_type = CONV_NONE;
- // Allocate memory for the buffers that are used
- lbuf = xmalloc((size_t)lbuf_size);
- tag_fname = xmalloc(MAXPATHL + 1);
- for (mtt = 0; mtt < MT_COUNT; mtt++) {
- ga_init(&ga_match[mtt], sizeof(char *), 100);
- hash_init(&ht_match[mtt]);
- }
+ findtags_state_init(&st, pat, flags, mincount);
// Initialize a few variables
- if (help_only) { // want tags from help file
+ if (st.help_only) { // want tags from help file
curbuf->b_help = true; // will be restored later
}
- orgpat.len = (int)strlen(pat);
if (curbuf->b_help) {
// When "@ab" is specified use only the "ab" language, otherwise
// search all languages.
- if (orgpat.len > 3 && pat[orgpat.len - 3] == '@'
- && ASCII_ISALPHA(pat[orgpat.len - 2])
- && ASCII_ISALPHA(pat[orgpat.len - 1])) {
- saved_pat = xstrnsave(pat, (size_t)orgpat.len - 3);
- help_lang_find = (char_u *)&pat[orgpat.len - 2];
- orgpat.pat = (char_u *)saved_pat;
- orgpat.len -= 3;
+ if (st.orgpat->len > 3 && pat[st.orgpat->len - 3] == '@'
+ && ASCII_ISALPHA(pat[st.orgpat->len - 2])
+ && ASCII_ISALPHA(pat[st.orgpat->len - 1])) {
+ saved_pat = xstrnsave(pat, (size_t)st.orgpat->len - 3);
+ st.help_lang_find = &pat[st.orgpat->len - 2];
+ st.orgpat->pat = (char_u *)saved_pat;
+ st.orgpat->len -= 3;
}
}
- if (p_tl != 0 && orgpat.len > p_tl) { // adjust for 'taglength'
- orgpat.len = (int)p_tl;
+ if (p_tl != 0 && st.orgpat->len > p_tl) { // adjust for 'taglength'
+ st.orgpat->len = (int)p_tl;
}
save_emsg_off = emsg_off;
emsg_off = true; // don't want error for invalid RE here
- prepare_pats(&orgpat, has_re);
+ prepare_pats(st.orgpat, has_re);
emsg_off = save_emsg_off;
- if (has_re && orgpat.regmatch.regprog == NULL) {
+ if (has_re && st.orgpat->regmatch.regprog == NULL) {
goto findtag_end;
}
- // This is only to avoid a compiler warning for using search_info
- // uninitialised.
- CLEAR_FIELD(search_info);
+ retval = findtags_apply_tfu(&st, pat, buf_ffname);
+ if (retval != NOTDONE) {
+ goto findtag_end;
+ }
- if (*curbuf->b_p_tfu != NUL && use_tfu && !tfu_in_use) {
- tfu_in_use = true;
- retval = find_tagfunc_tags((char_u *)pat, &ga_match[0], &match_count, flags,
- (char_u *)buf_ffname);
- tfu_in_use = false;
- if (retval != NOTDONE) {
- goto findtag_end;
- }
+ // re-initialize the default return value
+ retval = FAIL;
+
+ // Set a flag if the file extension is .txt
+ if ((flags & TAG_KEEP_LANG)
+ && st.help_lang_find == NULL
+ && curbuf->b_fname != NULL
+ && (i = (int)strlen(curbuf->b_fname)) > 4
+ && STRICMP(curbuf->b_fname + i - 4, ".txt") == 0) {
+ st.is_txt = true;
}
// When finding a specified number of matches, first try with matching
@@ -1552,630 +2427,18 @@ int find_tags(char *pat, int *num_matches, char ***matchesp, int flags, int minc
// tags files twice.
// When the tag file is case-fold sorted, it is either one or the other.
// Only ignore case when TAG_NOIC not used or 'ignorecase' set.
-
- // Set a flag if the file extension is .txt
- if ((flags & TAG_KEEP_LANG)
- && help_lang_find == NULL
- && curbuf->b_fname != NULL
- && (i = (int)strlen(curbuf->b_fname)) > 4
- && STRICMP(curbuf->b_fname + i - 4, ".txt") == 0) {
- is_txt = true;
- }
- orgpat.regmatch.rm_ic = ((p_ic || !noic)
- && (findall || orgpat.headlen == 0 || !p_tbs));
+ st.orgpat->regmatch.rm_ic = ((p_ic || !noic)
+ && (findall || st.orgpat->headlen == 0 || !p_tbs));
for (round = 1; round <= 2; round++) {
- linear = (orgpat.headlen == 0 || !p_tbs || round == 2);
+ st.linear = (st.orgpat->headlen == 0 || !p_tbs || round == 2);
// Try tag file names from tags option one by one.
for (first_file = true;
- get_tagfname(&tn, first_file, tag_fname) == OK;
+ get_tagfname(&tn, first_file, st.tag_fname) == OK;
first_file = false) {
- // A file that doesn't exist is silently ignored. Only when not a
- // single file is found, an error message is given (further on).
- if (curbuf->b_help) {
- // Keep en if the file extension is .txt
- if (is_txt) {
- STRCPY(help_lang, "en");
- } else {
- // Prefer help tags according to 'helplang'. Put the
- // two-letter language name in help_lang[].
- i = (int)STRLEN(tag_fname);
- if (i > 3 && tag_fname[i - 3] == '-') {
- STRCPY(help_lang, tag_fname + i - 2);
- } else {
- STRCPY(help_lang, "en");
- }
- }
-
- // When searching for a specific language skip tags files
- // for other languages.
- if (help_lang_find != NULL
- && STRICMP(help_lang, help_lang_find) != 0) {
- continue;
- }
-
- // For CTRL-] in a help file prefer a match with the same
- // language.
- if ((flags & TAG_KEEP_LANG)
- && help_lang_find == NULL
- && curbuf->b_fname != NULL
- && (i = (int)strlen(curbuf->b_fname)) > 4
- && curbuf->b_fname[i - 1] == 'x'
- && curbuf->b_fname[i - 4] == '.'
- && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) {
- help_pri = 0;
- } else {
- help_pri = 1;
- for (s = p_hlg; *s != NUL; s++) {
- if (STRNICMP(s, help_lang, 2) == 0) {
- break;
- }
- help_pri++;
- if ((s = (char_u *)vim_strchr((char *)s, ',')) == NULL) {
- break;
- }
- }
- if (s == NULL || *s == NUL) {
- // Language not in 'helplang': use last, prefer English,
- // unless found already.
- help_pri++;
- if (STRICMP(help_lang, "en") != 0) {
- help_pri++;
- }
- }
- }
- }
-
- if ((fp = os_fopen(tag_fname, "r")) == NULL) {
- continue;
- }
-
- if (p_verbose >= 5) {
- verbose_enter();
- smsg(_("Searching tags file %s"), tag_fname);
- verbose_leave();
- }
-
- did_open = true; // remember that we found at least one file
-
- state = TS_START; // we're at the start of the file
-
- // Read and parse the lines in the file one by one
- for (;;) {
- // check for CTRL-C typed, more often when jumping around
- if (state == TS_BINARY || state == TS_SKIP_BACK) {
- line_breakcheck();
- } else {
- fast_breakcheck();
- }
- if ((flags & TAG_INS_COMP)) { // Double brackets for gcc
- ins_compl_check_keys(30, false);
- }
- if (got_int || ins_compl_interrupted()) {
- stop_searching = true;
- break;
- }
- // When mincount is TAG_MANY, stop when enough matches have been
- // found (for completion).
- if (mincount == TAG_MANY && match_count >= TAG_MANY) {
- stop_searching = true;
- retval = OK;
- break;
- }
- if (get_it_again) {
- goto line_read_in;
- }
- // For binary search: compute the next offset to use.
- if (state == TS_BINARY) {
- offset = search_info.low_offset + ((search_info.high_offset
- - search_info.low_offset) / 2);
- if (offset == search_info.curr_offset) {
- break; // End the binary search without a match.
- }
- search_info.curr_offset = offset;
- } else if (state == TS_SKIP_BACK) {
- // Skipping back (after a match during binary search).
- search_info.curr_offset -= lbuf_size * 2;
- if (search_info.curr_offset < 0) {
- search_info.curr_offset = 0;
- rewind(fp);
- state = TS_STEP_FORWARD;
- }
- }
-
- // When jumping around in the file, first read a line to find the
- // start of the next line.
- if (state == TS_BINARY || state == TS_SKIP_BACK) {
- // Adjust the search file offset to the correct position
- search_info.curr_offset_used = search_info.curr_offset;
- vim_fseek(fp, search_info.curr_offset, SEEK_SET);
- eof = vim_fgets((char_u *)lbuf, lbuf_size, fp);
- if (!eof && search_info.curr_offset != 0) {
- // The explicit cast is to work around a bug in gcc 3.4.2
- // (repeated below).
- search_info.curr_offset = vim_ftell(fp);
- if (search_info.curr_offset == search_info.high_offset) {
- // oops, gone a bit too far; try from low offset
- vim_fseek(fp, search_info.low_offset, SEEK_SET);
- search_info.curr_offset = search_info.low_offset;
- }
- eof = vim_fgets((char_u *)lbuf, lbuf_size, fp);
- }
- // skip empty and blank lines
- while (!eof && vim_isblankline(lbuf)) {
- search_info.curr_offset = vim_ftell(fp);
- eof = vim_fgets((char_u *)lbuf, lbuf_size, fp);
- }
- if (eof) {
- // Hit end of file. Skip backwards.
- state = TS_SKIP_BACK;
- search_info.match_offset = vim_ftell(fp);
- search_info.curr_offset = search_info.curr_offset_used;
- continue;
- }
- } else {
- // Not jumping around in the file: Read the next line.
-
- // skip empty and blank lines
- do {
- eof = vim_fgets((char_u *)lbuf, lbuf_size, fp);
- } while (!eof && vim_isblankline(lbuf));
-
- if (eof) {
- break; // end of file
- }
- }
-line_read_in:
-
- if (vimconv.vc_type != CONV_NONE) {
- char *conv_line;
- int len;
-
- // Convert every line. Converting the pattern from 'enc' to
- // the tags file encoding doesn't work, because characters are
- // not recognized.
- conv_line = string_convert(&vimconv, lbuf, NULL);
- if (conv_line != NULL) {
- // Copy or swap lbuf and conv_line.
- len = (int)strlen(conv_line) + 1;
- if (len > lbuf_size) {
- xfree(lbuf);
- lbuf = conv_line;
- lbuf_size = len;
- } else {
- STRCPY(lbuf, conv_line);
- xfree(conv_line);
- }
- }
- }
-
- // When still at the start of the file, check for Emacs tags file
- // format, and for "not sorted" flag.
- if (state == TS_START) {
- // The header ends when the line sorts below "!_TAG_". When
- // case is folded lower case letters sort before "_".
- if (STRNCMP(lbuf, "!_TAG_", 6) <= 0
- || (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) {
- if (STRNCMP(lbuf, "!_TAG_", 6) != 0) {
- // Non-header item before the header, e.g. "!" itself.
- goto parse_line;
- }
-
- // Read header line.
- if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) {
- tag_file_sorted = (uint8_t)lbuf[18];
- }
- if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) {
- // Prepare to convert every line from the specified
- // encoding to 'encoding'.
- for (p = lbuf + 20; *p > ' ' && *p < 127; p++) {}
- *p = NUL;
- convert_setup(&vimconv, lbuf + 20, p_enc);
- }
-
- // Read the next line. Unrecognized flags are ignored.
- continue;
- }
-
- // Headers ends.
-
- // When there is no tag head, or ignoring case, need to do a
- // linear search.
- // When no "!_TAG_" is found, default to binary search. If
- // the tag file isn't sorted, the second loop will find it.
- // When "!_TAG_FILE_SORTED" found: start binary search if
- // flag set.
- if (linear) {
- state = TS_LINEAR;
- } else if (tag_file_sorted == NUL) {
- state = TS_BINARY;
- } else if (tag_file_sorted == '1') {
- state = TS_BINARY;
- } else if (tag_file_sorted == '2') {
- state = TS_BINARY;
- sortic = true;
- orgpat.regmatch.rm_ic = (p_ic || !noic);
- } else {
- state = TS_LINEAR;
- }
-
- if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) {
- // Binary search won't work for ignoring case, use linear
- // search.
- linear = true;
- state = TS_LINEAR;
- }
-
- // When starting a binary search, get the size of the file and
- // compute the first offset.
- if (state == TS_BINARY) {
- if (vim_fseek(fp, 0, SEEK_END) != 0) {
- // can't seek, don't use binary search
- state = TS_LINEAR;
- } else {
- // Get the tag file size.
- // Don't use lseek(), it doesn't work
- // properly on MacOS Catalina.
- const off_T filesize = vim_ftell(fp);
- vim_fseek(fp, 0, SEEK_SET);
-
- // Calculate the first read offset in the file. Start
- // the search in the middle of the file.
- search_info.low_offset = 0;
- search_info.low_char = 0;
- search_info.high_offset = filesize;
- search_info.curr_offset = 0;
- search_info.high_char = 0xff;
- }
- continue;
- }
- }
-
-parse_line:
- // When the line is too long the NUL will not be in the
- // last-but-one byte (see vim_fgets()).
- // Has been reported for Mozilla JS with extremely long names.
- // In that case we need to increase lbuf_size.
- if (lbuf[lbuf_size - 2] != NUL) {
- lbuf_size *= 2;
- xfree(lbuf);
- lbuf = xmalloc((size_t)lbuf_size);
- // this will try the same thing again, make sure the offset is
- // different
- search_info.curr_offset = 0;
- continue;
- }
-
- // Figure out where the different strings are in this line.
- // For "normal" tags: Do a quick check if the tag matches.
- // This speeds up tag searching a lot!
- if (orgpat.headlen) {
- CLEAR_FIELD(tagp);
- tagp.tagname = lbuf;
- tagp.tagname_end = (char_u *)vim_strchr(lbuf, TAB);
- if (tagp.tagname_end == NULL) {
- // Corrupted tag line.
- line_error = true;
- break;
- }
-
- // Skip this line if the length of the tag is different and
- // there is no regexp, or the tag is too short.
- cmplen = (int)(tagp.tagname_end - (char_u *)tagp.tagname);
- if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
- cmplen = (int)p_tl;
- }
- if (has_re && orgpat.headlen < cmplen) {
- cmplen = orgpat.headlen;
- } else if (state == TS_LINEAR && orgpat.headlen != cmplen) {
- continue;
- }
-
- if (state == TS_BINARY) {
- // Simplistic check for unsorted tags file.
- i = (int)tagp.tagname[0];
- if (sortic) {
- i = TOUPPER_ASC(tagp.tagname[0]);
- }
- if (i < search_info.low_char || i > search_info.high_char) {
- sort_error = true;
- }
-
- // Compare the current tag with the searched tag.
- if (sortic) {
- tagcmp = tag_strnicmp((char_u *)tagp.tagname, orgpat.head,
- (size_t)cmplen);
- } else {
- tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
- }
-
- // A match with a shorter tag means to search forward.
- // A match with a longer tag means to search backward.
- if (tagcmp == 0) {
- if (cmplen < orgpat.headlen) {
- tagcmp = -1;
- } else if (cmplen > orgpat.headlen) {
- tagcmp = 1;
- }
- }
-
- if (tagcmp == 0) {
- // We've located the tag, now skip back and search
- // forward until the first matching tag is found.
- state = TS_SKIP_BACK;
- search_info.match_offset = search_info.curr_offset;
- continue;
- }
- if (tagcmp < 0) {
- search_info.curr_offset = vim_ftell(fp);
- if (search_info.curr_offset < search_info.high_offset) {
- search_info.low_offset = search_info.curr_offset;
- if (sortic) {
- search_info.low_char =
- TOUPPER_ASC(tagp.tagname[0]);
- } else {
- search_info.low_char = (uint8_t)tagp.tagname[0];
- }
- continue;
- }
- }
- if (tagcmp > 0
- && search_info.curr_offset != search_info.high_offset) {
- search_info.high_offset = search_info.curr_offset;
- if (sortic) {
- search_info.high_char =
- TOUPPER_ASC(tagp.tagname[0]);
- } else {
- search_info.high_char = (uint8_t)tagp.tagname[0];
- }
- continue;
- }
-
- // No match yet and are at the end of the binary search.
- break;
- } else if (state == TS_SKIP_BACK) {
- assert(cmplen >= 0);
- if (mb_strnicmp(tagp.tagname, (char *)orgpat.head, (size_t)cmplen) != 0) {
- state = TS_STEP_FORWARD;
- } else {
- // Have to skip back more. Restore the curr_offset
- // used, otherwise we get stuck at a long line.
- search_info.curr_offset = search_info.curr_offset_used;
- }
- continue;
- } else if (state == TS_STEP_FORWARD) {
- assert(cmplen >= 0);
- if (mb_strnicmp(tagp.tagname, (char *)orgpat.head, (size_t)cmplen) != 0) {
- if ((off_T)vim_ftell(fp) > search_info.match_offset) {
- break; // past last match
- } else {
- continue; // before first match
- }
- }
- } else {
- // skip this match if it can't match
- assert(cmplen >= 0);
- }
- if (mb_strnicmp(tagp.tagname, (char *)orgpat.head, (size_t)cmplen) != 0) {
- continue;
- }
-
- // Can be a matching tag, isolate the file name and command.
- tagp.fname = tagp.tagname_end + 1;
- tagp.fname_end = (char_u *)vim_strchr((char *)tagp.fname, TAB);
- tagp.command = tagp.fname_end + 1;
- if (tagp.fname_end == NULL) {
- i = FAIL;
- } else {
- i = OK;
- }
- } else {
- i = parse_tag_line((char_u *)lbuf, &tagp);
- }
- if (i == FAIL) {
- line_error = true;
- break;
- }
-
- // First try matching with the pattern literally (also when it is
- // a regexp).
- cmplen = (int)(tagp.tagname_end - (char_u *)tagp.tagname);
- if (p_tl != 0 && cmplen > p_tl) { // adjust for 'taglength'
- cmplen = (int)p_tl;
- }
- // if tag length does not match, don't try comparing
- if (orgpat.len != cmplen) {
- match = false;
- } else {
- if (orgpat.regmatch.rm_ic) {
- assert(cmplen >= 0);
- match = mb_strnicmp(tagp.tagname, (char *)orgpat.pat, (size_t)cmplen) == 0;
- if (match) {
- match_no_ic = (STRNCMP(tagp.tagname, orgpat.pat,
- cmplen) == 0);
- }
- } else {
- match = (STRNCMP(tagp.tagname, orgpat.pat, cmplen) == 0);
- }
- }
-
- // Has a regexp: Also find tags matching regexp.
- match_re = false;
- if (!match && orgpat.regmatch.regprog != NULL) {
- int cc;
-
- cc = *tagp.tagname_end;
- *tagp.tagname_end = NUL;
- match = vim_regexec(&orgpat.regmatch, tagp.tagname, (colnr_T)0);
- if (match) {
- matchoff = (int)(orgpat.regmatch.startp[0] - tagp.tagname);
- if (orgpat.regmatch.rm_ic) {
- orgpat.regmatch.rm_ic = false;
- match_no_ic = vim_regexec(&orgpat.regmatch, tagp.tagname, (colnr_T)0);
- orgpat.regmatch.rm_ic = true;
- }
- }
- *tagp.tagname_end = (char_u)cc;
- match_re = true;
- }
-
- // If a match is found, add it to ht_match[] and ga_match[].
- if (match) {
- size_t len = 0;
-
- // Decide in which array to store this match.
- is_current = test_for_current((char *)tagp.fname, (char *)tagp.fname_end,
- tag_fname,
- buf_ffname);
- is_static = test_for_static(&tagp);
-
- // Decide in which of the sixteen tables to store this match.
- if (is_static) {
- if (is_current) {
- mtt = MT_ST_CUR;
- } else {
- mtt = MT_ST_OTH;
- }
- } else {
- if (is_current) {
- mtt = MT_GL_CUR;
- } else {
- mtt = MT_GL_OTH;
- }
- }
- if (orgpat.regmatch.rm_ic && !match_no_ic) {
- mtt += MT_IC_OFF;
- }
- if (match_re) {
- mtt += MT_RE_OFF;
- }
-
- // Add the found match in ht_match[mtt] and ga_match[mtt].
- // Store the info we need later, which depends on the kind of
- // tags we are dealing with.
- if (help_only) {
-#define ML_EXTRA 3
- // Append the help-heuristic number after the tagname, for
- // sorting it later. The heuristic is ignored for
- // detecting duplicates.
- // The format is {tagname}@{lang}NUL{heuristic}NUL
- *tagp.tagname_end = NUL;
- len = (size_t)(tagp.tagname_end - (char_u *)tagp.tagname);
- mfp = xmalloc(sizeof(char) + len + 10 + ML_EXTRA + 1);
-
- p = mfp;
- STRCPY(p, tagp.tagname);
- p[len] = '@';
- STRCPY(p + len + 1, help_lang);
- snprintf(p + len + 1 + ML_EXTRA, strlen(p) + len + 1 + ML_EXTRA, "%06d",
- help_heuristic(tagp.tagname,
- match_re ? matchoff : 0, !match_no_ic)
- + help_pri);
-
- *tagp.tagname_end = TAB;
- } else if (name_only) {
- if (get_it_again) {
- char_u *temp_end = tagp.command;
-
- if (*temp_end == '/') {
- while (*temp_end && *temp_end != '\r'
- && *temp_end != '\n'
- && *temp_end != '$') {
- temp_end++;
- }
- }
-
- if (tagp.command + 2 < temp_end) {
- len = (size_t)(temp_end - tagp.command - 2);
- mfp = xmalloc(len + 2);
- STRLCPY(mfp, tagp.command + 2, len + 1);
- } else {
- mfp = NULL;
- }
- get_it_again = false;
- } else {
- len = (size_t)(tagp.tagname_end - (char_u *)tagp.tagname);
- mfp = xmalloc(sizeof(char) + len + 1);
- STRLCPY(mfp, tagp.tagname, len + 1);
-
- // if wanted, re-read line to get long form too
- if (State & MODE_INSERT) {
- get_it_again = p_sft;
- }
- }
- } else {
- size_t tag_fname_len = strlen(tag_fname);
- // Save the tag in a buffer.
- // Use 0x02 to separate fields (Can't use NUL, because the
- // hash key is terminated by NUL).
- // Emacs tag: <mtt><tag_fname><0x02><ebuf><0x02><lbuf><NUL>
- // other tag: <mtt><tag_fname><0x02><0x02><lbuf><NUL>
- // without Emacs tags: <mtt><tag_fname><0x02><lbuf><NUL>
- // Here <mtt> is the "mtt" value plus 1 to avoid NUL.
- len = tag_fname_len + strlen(lbuf) + 3;
- mfp = xmalloc(sizeof(char) + len + 1);
- p = mfp;
- p[0] = (char)(mtt + 1);
- STRCPY(p + 1, tag_fname);
-#ifdef BACKSLASH_IN_FILENAME
- // Ignore differences in slashes, avoid adding
- // both path/file and path\file.
- slash_adjust(p + 1);
-#endif
- p[tag_fname_len + 1] = TAG_SEP;
- s = (char_u *)p + 1 + tag_fname_len + 1;
- STRCPY(s, lbuf);
- }
-
- if (mfp != NULL) {
- hashitem_T *hi;
-
- // Don't add identical matches.
- // "mfp" is used as a hash key, there is a NUL byte to end
- // the part that matters for comparing, more bytes may
- // follow after it. E.g. help tags store the priority
- // after the NUL.
- hash = hash_hash((char_u *)mfp);
- hi = hash_lookup(&ht_match[mtt], (const char *)mfp,
- strlen(mfp), hash);
- if (HASHITEM_EMPTY(hi)) {
- hash_add_item(&ht_match[mtt], hi, (char_u *)mfp, hash);
- ga_grow(&ga_match[mtt], 1);
- ((char **)(ga_match[mtt].ga_data))[ga_match[mtt].ga_len++] = mfp;
- match_count++;
- } else {
- // duplicate tag, drop it
- xfree(mfp);
- }
- }
- }
- } // forever
-
- if (line_error) {
- semsg(_("E431: Format error in tags file \"%s\""), tag_fname);
- semsg(_("Before byte %" PRId64), (int64_t)vim_ftell(fp));
- stop_searching = true;
- line_error = false;
- }
-
- fclose(fp);
- if (vimconv.vc_type != CONV_NONE) {
- convert_setup(&vimconv, NULL, NULL);
- }
-
- tag_file_sorted = NUL;
- if (sort_error) {
- semsg(_("E432: Tags file not sorted: %s"), tag_fname);
- sort_error = false;
- }
-
- // Stop searching if sufficient tags have been found.
- if (match_count >= mincount) {
+ findtags_in_file(&st, flags, buf_ffname);
+ if (st.stop_searching) {
retval = OK;
- stop_searching = true;
- }
-
- if (stop_searching) {
break;
}
} // end of for-each-file loop
@@ -2184,63 +2447,32 @@ parse_line:
// stop searching when already did a linear search, or when TAG_NOIC
// used, and 'ignorecase' not set or already did case-ignore search
- if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) {
+ if (st.stop_searching || st.linear || (!p_ic && noic)
+ || st.orgpat->regmatch.rm_ic) {
break;
}
- orgpat.regmatch.rm_ic = true; // try another time while ignoring case
+
+ // try another time while ignoring case
+ st.orgpat->regmatch.rm_ic = true;
}
- if (!stop_searching) {
- if (!did_open && verbose) { // never opened any tags file
+ if (!st.stop_searching) {
+ if (!st.did_open && verbose) { // never opened any tags file
emsg(_("E433: No tags file"));
}
retval = OK; // It's OK even when no tag found
}
findtag_end:
- xfree(lbuf);
- vim_regfree(orgpat.regmatch.regprog);
- xfree(tag_fname);
+ findtags_state_free(&st);
// Move the matches from the ga_match[] arrays into one list of
// matches. When retval == FAIL, free the matches.
if (retval == FAIL) {
- match_count = 0;
- }
-
- if (match_count > 0) {
- matches = xmalloc((size_t)match_count * sizeof(char *));
- } else {
- matches = NULL;
- }
- match_count = 0;
- for (mtt = 0; mtt < MT_COUNT; mtt++) {
- for (i = 0; i < ga_match[mtt].ga_len; i++) {
- mfp = ((char **)(ga_match[mtt].ga_data))[i];
- if (matches == NULL) {
- xfree(mfp);
- } else {
- if (!name_only) {
- // Change mtt back to zero-based.
- *mfp = (char)(*mfp - 1);
-
- // change the TAG_SEP back to NUL
- for (p = mfp + 1; *p != NUL; p++) {
- if (*p == TAG_SEP) {
- *p = NUL;
- }
- }
- }
- matches[match_count++] = mfp;
- }
- }
-
- ga_clear(&ga_match[mtt]);
- hash_clear(&ht_match[mtt]);
+ st.match_count = 0;
}
- *matchesp = matches;
- *num_matches = match_count;
+ *num_matches = findtags_copy_matches(&st, matchesp);
curbuf->b_help = help_save;
xfree(saved_pat);
@@ -2762,7 +2994,7 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
// start search before first line
curwin->w_cursor.lnum = 0;
}
- if (do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
+ if (do_search(NULL, pbuf[0], pbuf[0], (char *)pbuf + 1, (long)1,
search_options, NULL)) {
retval = OK;
} else {
@@ -2771,7 +3003,7 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
// try again, ignore case now
p_ic = true;
- if (!do_search(NULL, pbuf[0], pbuf[0], pbuf + 1, (long)1,
+ if (!do_search(NULL, pbuf[0], pbuf[0], (char *)pbuf + 1, (long)1,
search_options, NULL)) {
// Failed to find pattern, take a guess: "^func ("
found = 2;
@@ -2779,11 +3011,11 @@ static int jumpto_tag(const char_u *lbuf_arg, int forceit, int keep_help)
cc = *tagp.tagname_end;
*tagp.tagname_end = NUL;
snprintf((char *)pbuf, LSIZE, "^%s\\s\\*(", tagp.tagname);
- if (!do_search(NULL, '/', '/', pbuf, (long)1, search_options, NULL)) {
+ if (!do_search(NULL, '/', '/', (char *)pbuf, (long)1, search_options, NULL)) {
// Guess again: "^char * \<func ("
snprintf((char *)pbuf, LSIZE, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
tagp.tagname);
- if (!do_search(NULL, '/', '/', pbuf, (long)1,
+ if (!do_search(NULL, '/', '/', (char *)pbuf, (long)1,
search_options, NULL)) {
found = 0;
}
diff --git a/src/nvim/testdir/check.vim b/src/nvim/testdir/check.vim
index 8a1080a2f3..61d3a99a67 100644
--- a/src/nvim/testdir/check.vim
+++ b/src/nvim/testdir/check.vim
@@ -90,6 +90,14 @@ func CheckUnix()
endif
endfunc
+" Command to check for running on Linux
+command CheckLinux call CheckLinux()
+func CheckLinux()
+ if !has('linux')
+ throw 'Skipped: only works on Linux'
+ endif
+endfunc
+
" Command to check that making screendumps is supported.
" Caller must source screendump.vim
command CheckScreendump call CheckScreendump()
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index ce23141c7a..a1b04a4601 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -174,7 +174,12 @@ func RunTheTest(test)
if a:test =~ 'Test_nocatch_'
" Function handles errors itself. This avoids skipping commands after the
" error.
+ let g:skipped_reason = ''
exe 'call ' . a:test
+ if g:skipped_reason != ''
+ call add(s:messages, ' Skipped')
+ call add(s:skipped, 'SKIPPED ' . a:test . ': ' . g:skipped_reason)
+ endif
else
try
let s:test = a:test
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
index f4c32599f1..2945b4a03a 100644
--- a/src/nvim/testdir/test_autocmd.vim
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -4,6 +4,7 @@ source shared.vim
source check.vim
source term_util.vim
source screendump.vim
+source load.vim
func s:cleanup_buffers() abort
for bnr in range(1, bufnr('$'))
@@ -20,8 +21,35 @@ func Test_vim_did_enter()
" becomes one.
endfunc
+" Test for the CursorHold autocmd
+func Test_CursorHold_autocmd()
+ CheckRunVimInTerminal
+ call writefile(['one', 'two', 'three'], 'Xfile')
+ let before =<< trim END
+ set updatetime=10
+ au CursorHold * call writefile([line('.')], 'Xoutput', 'a')
+ END
+ call writefile(before, 'Xinit')
+ let buf = RunVimInTerminal('-S Xinit Xfile', {})
+ call term_sendkeys(buf, "G")
+ call term_wait(buf, 20)
+ call term_sendkeys(buf, "gg")
+ call term_wait(buf)
+ call WaitForAssert({-> assert_equal(['1'], readfile('Xoutput')[-1:-1])})
+ call term_sendkeys(buf, "j")
+ call term_wait(buf)
+ call WaitForAssert({-> assert_equal(['1', '2'], readfile('Xoutput')[-2:-1])})
+ call term_sendkeys(buf, "j")
+ call term_wait(buf)
+ call WaitForAssert({-> assert_equal(['1', '2', '3'], readfile('Xoutput')[-3:-1])})
+ call StopVimInTerminal(buf)
+
+ call delete('Xinit')
+ call delete('Xoutput')
+ call delete('Xfile')
+endfunc
+
if has('timers')
- source load.vim
func ExitInsertMode(id)
call feedkeys("\<Esc>")
@@ -267,6 +295,61 @@ func Test_win_tab_autocmd()
unlet g:record
endfunc
+func Test_WinResized()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set scrolloff=0
+ call setline(1, ['111', '222'])
+ vnew
+ call setline(1, ['aaa', 'bbb'])
+ new
+ call setline(1, ['foo', 'bar'])
+
+ let g:resized = 0
+ au WinResized * let g:resized += 1
+
+ func WriteResizedEvent()
+ call writefile([json_encode(v:event)], 'XresizeEvent')
+ endfunc
+ au WinResized * call WriteResizedEvent()
+ END
+ call writefile(lines, 'Xtest_winresized', 'D')
+ let buf = RunVimInTerminal('-S Xtest_winresized', {'rows': 10})
+
+ " redraw now to avoid a redraw after the :echo command
+ call term_sendkeys(buf, ":redraw!\<CR>")
+ call TermWait(buf)
+
+ call term_sendkeys(buf, ":echo g:resized\<CR>")
+ call WaitForAssert({-> assert_match('^0$', term_getline(buf, 10))}, 1000)
+
+ " increase window height, two windows will be reported
+ call term_sendkeys(buf, "\<C-W>+")
+ call TermWait(buf)
+ call term_sendkeys(buf, ":echo g:resized\<CR>")
+ call WaitForAssert({-> assert_match('^1$', term_getline(buf, 10))}, 1000)
+
+ let event = readfile('XresizeEvent')[0]->json_decode()
+ call assert_equal({
+ \ 'windows': [1002, 1001],
+ \ }, event)
+
+ " increase window width, three windows will be reported
+ call term_sendkeys(buf, "\<C-W>>")
+ call TermWait(buf)
+ call term_sendkeys(buf, ":echo g:resized\<CR>")
+ call WaitForAssert({-> assert_match('^2$', term_getline(buf, 10))}, 1000)
+
+ let event = readfile('XresizeEvent')[0]->json_decode()
+ call assert_equal({
+ \ 'windows': [1002, 1001, 1000],
+ \ }, event)
+
+ call delete('XresizeEvent')
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_WinScrolled()
CheckRunVimInTerminal
@@ -277,13 +360,17 @@ func Test_WinScrolled()
endfor
let win_id = win_getid()
let g:matched = v:false
+ func WriteScrollEvent()
+ call writefile([json_encode(v:event)], 'XscrollEvent')
+ endfunc
execute 'au WinScrolled' win_id 'let g:matched = v:true'
let g:scrolled = 0
au WinScrolled * let g:scrolled += 1
au WinScrolled * let g:amatch = str2nr(expand('<amatch>'))
au WinScrolled * let g:afile = str2nr(expand('<afile>'))
+ au WinScrolled * call WriteScrollEvent()
END
- call writefile(lines, 'Xtest_winscrolled')
+ call writefile(lines, 'Xtest_winscrolled', 'D')
let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6})
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
@@ -293,15 +380,33 @@ func Test_WinScrolled()
call term_sendkeys(buf, "zlzh:echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000)
+ let event = readfile('XscrollEvent')[0]->json_decode()
+ call assert_equal({
+ \ 'all': {'leftcol': 1, 'topline': 0, 'width': 0, 'height': 0, 'skipcol': 0},
+ \ '1000': {'leftcol': -1, 'topline': 0, 'width': 0, 'height': 0, 'skipcol': 0}
+ \ }, event)
+
" Scroll up/down in Normal mode.
call term_sendkeys(buf, "\<c-e>\<c-y>:echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^4 ', term_getline(buf, 6))}, 1000)
+ let event = readfile('XscrollEvent')[0]->json_decode()
+ call assert_equal({
+ \ 'all': {'leftcol': 0, 'topline': 1, 'width': 0, 'height': 0, 'skipcol': 0},
+ \ '1000': {'leftcol': 0, 'topline': -1, 'width': 0, 'height': 0, 'skipcol': 0}
+ \ }, event)
+
" Scroll up/down in Insert mode.
call term_sendkeys(buf, "Mi\<c-x>\<c-e>\<Esc>i\<c-x>\<c-y>\<Esc>")
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^6 ', term_getline(buf, 6))}, 1000)
+ let event = readfile('XscrollEvent')[0]->json_decode()
+ call assert_equal({
+ \ 'all': {'leftcol': 0, 'topline': 1, 'width': 0, 'height': 0, 'skipcol': 0},
+ \ '1000': {'leftcol': 0, 'topline': -1, 'width': 0, 'height': 0, 'skipcol': 0}
+ \ }, event)
+
" Scroll the window horizontally to focus the last letter of the third line
" containing only six characters. Moving to the previous and shorter lines
" should trigger another autocommand as Vim has to make them visible.
@@ -309,6 +414,12 @@ func Test_WinScrolled()
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^8 ', term_getline(buf, 6))}, 1000)
+ let event = readfile('XscrollEvent')[0]->json_decode()
+ call assert_equal({
+ \ 'all': {'leftcol': 5, 'topline': 0, 'width': 0, 'height': 0, 'skipcol': 0},
+ \ '1000': {'leftcol': -5, 'topline': 0, 'width': 0, 'height': 0, 'skipcol': 0}
+ \ }, event)
+
" Ensure the command was triggered for the specified window ID.
call term_sendkeys(buf, ":echo g:matched\<CR>")
call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000)
@@ -317,8 +428,38 @@ func Test_WinScrolled()
call term_sendkeys(buf, ":echo g:amatch == win_id && g:afile == win_id\<CR>")
call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000)
+ call delete('XscrollEvent')
+ call StopVimInTerminal(buf)
+endfunc
+
+func Test_WinScrolled_mouse()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set nowrap scrolloff=0
+ set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard=
+ call setline(1, ['foo']->repeat(32))
+ split
+ let g:scrolled = 0
+ au WinScrolled * let g:scrolled += 1
+ END
+ call writefile(lines, 'Xtest_winscrolled_mouse', 'D')
+ let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10})
+
+ " With the upper split focused, send a scroll-down event to the unfocused one.
+ call test_setmouse(7, 1)
+ call term_sendkeys(buf, "\<ScrollWheelDown>")
+ call TermWait(buf)
+ call term_sendkeys(buf, ":echo g:scrolled\<CR>")
+ call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000)
+
+ " Again, but this time while we're in insert mode.
+ call term_sendkeys(buf, "i\<ScrollWheelDown>\<Esc>")
+ call TermWait(buf)
+ call term_sendkeys(buf, ":echo g:scrolled\<CR>")
+ call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000)
+
call StopVimInTerminal(buf)
- call delete('Xtest_winscrolled')
endfunc
func Test_WinScrolled_close_curwin()
@@ -331,7 +472,7 @@ func Test_WinScrolled_close_curwin()
au WinScrolled * close
au VimLeave * call writefile(['123456'], 'Xtestout')
END
- call writefile(lines, 'Xtest_winscrolled_close_curwin')
+ call writefile(lines, 'Xtest_winscrolled_close_curwin', 'D')
let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6})
" This was using freed memory
@@ -339,12 +480,64 @@ func Test_WinScrolled_close_curwin()
call TermWait(buf)
call StopVimInTerminal(buf)
+ " check the startup script finished to the end
call assert_equal(['123456'], readfile('Xtestout'))
-
- call delete('Xtest_winscrolled_close_curwin')
call delete('Xtestout')
endfunc
+func Test_WinScrolled_once_only()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set cmdheight=2
+ call setline(1, ['aaa', 'bbb'])
+ let trigger_count = 0
+ func ShowInfo(id)
+ echo g:trigger_count g:winid winlayout()
+ endfunc
+
+ vsplit
+ split
+ " use a timer to show the info after a redraw
+ au WinScrolled * let trigger_count += 1 | let winid = expand('<amatch>') | call timer_start(100, 'ShowInfo')
+ wincmd j
+ wincmd l
+ END
+ call writefile(lines, 'Xtest_winscrolled_once', 'D')
+ let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2})
+
+ call term_sendkeys(buf, "\<C-E>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
+" Check that WinScrolled is not triggered immediately when defined and there
+" are split windows.
+func Test_WinScrolled_not_when_defined()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ call setline(1, ['aaa', 'bbb'])
+ echo 'nothing happened'
+ func ShowTriggered(id)
+ echo 'triggered'
+ endfunc
+ END
+ call writefile(lines, 'Xtest_winscrolled_not', 'D')
+ let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2})
+ call term_sendkeys(buf, ":split\<CR>")
+ call TermWait(buf)
+ " use a timer to show the message after redrawing
+ call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {})
+
+ call term_sendkeys(buf, "\<C-E>")
+ call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_WinScrolled_long_wrapped()
CheckRunVimInTerminal
@@ -357,7 +550,7 @@ func Test_WinScrolled_long_wrapped()
call setline(1, repeat('foo', height * width))
call cursor(1, height * width)
END
- call writefile(lines, 'Xtest_winscrolled_long_wrapped')
+ call writefile(lines, 'Xtest_winscrolled_long_wrapped', 'D')
let buf = RunVimInTerminal('-S Xtest_winscrolled_long_wrapped', {'rows': 6})
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
@@ -374,8 +567,6 @@ func Test_WinScrolled_long_wrapped()
call term_sendkeys(buf, '$')
call term_sendkeys(buf, ":echo g:scrolled\<CR>")
call WaitForAssert({-> assert_match('^3 ', term_getline(buf, 6))}, 1000)
-
- call delete('Xtest_winscrolled_long_wrapped')
endfunc
func Test_WinClosed()
@@ -2760,6 +2951,7 @@ func Test_SpellFileMissing_bwipe()
call assert_fails('set spell spelllang=0', 'E937:')
au! SpellFileMissing
+ set nospell spelllang=en
bwipe
endfunc
diff --git a/src/nvim/testdir/test_buffer.vim b/src/nvim/testdir/test_buffer.vim
index 3300278802..549aa691c8 100644
--- a/src/nvim/testdir/test_buffer.vim
+++ b/src/nvim/testdir/test_buffer.vim
@@ -67,15 +67,6 @@ func Test_bunload_with_offset()
call assert_fails('1,4bunload', 'E16:')
call assert_fails(',100bunload', 'E16:')
- " Use a try-catch for this test. When assert_fails() is used for this
- " test, the command fails with E515: instead of E90:
- let caught_E90 = 0
- try
- $bunload
- catch /E90:/
- let caught_E90 = 1
- endtry
- call assert_equal(1, caught_E90)
call assert_fails('$bunload', 'E90:')
endfunc
diff --git a/src/nvim/testdir/test_bufline.vim b/src/nvim/testdir/test_bufline.vim
index fae6b1dab7..d4dee38620 100644
--- a/src/nvim/testdir/test_bufline.vim
+++ b/src/nvim/testdir/test_bufline.vim
@@ -5,12 +5,15 @@ source screendump.vim
source check.vim
func Test_setbufline_getbufline()
+ " similar to Test_set_get_bufline()
new
let b = bufnr('%')
hide
call assert_equal(0, setbufline(b, 1, ['foo', 'bar']))
call assert_equal(['foo'], getbufline(b, 1))
+ call assert_equal('foo', getbufoneline(b, 1))
call assert_equal(['bar'], getbufline(b, '$'))
+ call assert_equal('bar', getbufoneline(b, '$'))
call assert_equal(['foo', 'bar'], getbufline(b, 1, 2))
exe "bd!" b
call assert_equal([], getbufline(b, 1, 2))
@@ -34,10 +37,21 @@ func Test_setbufline_getbufline()
call assert_equal(0, setbufline(b, 4, ['d', 'e']))
call assert_equal(['c'], b->getbufline(3))
+ call assert_equal('c', b->getbufoneline(3))
call assert_equal(['d'], getbufline(b, 4))
+ call assert_equal('d', getbufoneline(b, 4))
call assert_equal(['e'], getbufline(b, 5))
+ call assert_equal('e', getbufoneline(b, 5))
call assert_equal([], getbufline(b, 6))
call assert_equal([], getbufline(b, 2, 1))
+
+ if has('job')
+ call setbufline(b, 2, [function('eval'), #{key: 123}, test_null_job()])
+ call assert_equal(["function('eval')",
+ \ "{'key': 123}",
+ \ "no process"],
+ \ getbufline(b, 2, 4))
+ endif
exe "bwipe! " . b
endfunc
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 2921c8b41a..b9da4ca7bb 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -1850,6 +1850,11 @@ func Test_cmdline_expr()
call assert_equal("\"e \<C-\>\<C-Y>", @:)
endfunc
+" This was making the insert position negative
+func Test_cmdline_expr_register()
+ exe "sil! norm! ?\<C-\>e0\<C-R>0\<Esc>?\<C-\>e0\<CR>"
+endfunc
+
" Test for 'imcmdline' and 'imsearch'
" This test doesn't actually test the input method functionality.
func Test_cmdline_inputmethod()
diff --git a/src/nvim/testdir/test_cpoptions.vim b/src/nvim/testdir/test_cpoptions.vim
index ef51d955f1..b9307ab30b 100644
--- a/src/nvim/testdir/test_cpoptions.vim
+++ b/src/nvim/testdir/test_cpoptions.vim
@@ -8,19 +8,19 @@ source view_util.vim
" file name.
func Test_cpo_a()
let save_cpo = &cpo
- call writefile(['one'], 'Xfile')
+ call writefile(['one'], 'XfileCpoA')
" Wipe out all the buffers, so that the alternate file is empty
edit Xfoo | %bw
set cpo-=a
new
- read Xfile
+ read XfileCpoA
call assert_equal('', @#)
%d
set cpo+=a
- read Xfile
- call assert_equal('Xfile', @#)
+ read XfileCpoA
+ call assert_equal('XfileCpoA', @#)
close!
- call delete('Xfile')
+ call delete('XfileCpoA')
let &cpo = save_cpo
endfunc
@@ -99,31 +99,31 @@ endfunc
" Test for the 'C' flag in 'cpo' (line continuation)
func Test_cpo_C()
let save_cpo = &cpo
- call writefile(['let l = [', '\ 1,', '\ 2]'], 'Xfile')
+ call writefile(['let l = [', '\ 1,', '\ 2]'], 'XfileCpoC')
set cpo-=C
- source Xfile
+ source XfileCpoC
call assert_equal([1, 2], g:l)
set cpo+=C
- call assert_fails('source Xfile', ['E697:', 'E10:'])
- call delete('Xfile')
+ call assert_fails('source XfileCpoC', ['E697:', 'E10:'])
+ call delete('XfileCpoC')
let &cpo = save_cpo
endfunc
" Test for the 'd' flag in 'cpo' (tags relative to the current file)
func Test_cpo_d()
let save_cpo = &cpo
- call mkdir('Xdir')
+ call mkdir('XdirCpoD')
call writefile(["one\tXfile1\t/^one$/"], 'tags')
- call writefile(["two\tXfile2\t/^two$/"], 'Xdir/tags')
+ call writefile(["two\tXfile2\t/^two$/"], 'XdirCpoD/tags')
set tags=./tags
set cpo-=d
- edit Xdir/Xfile
+ edit XdirCpoD/Xfile
call assert_equal('two', taglist('.*')[0].name)
set cpo+=d
call assert_equal('one', taglist('.*')[0].name)
%bw!
call delete('tags')
- call delete('Xdir', 'rf')
+ call delete('XdirCpoD', 'rf')
set tags&
let &cpo = save_cpo
endfunc
@@ -204,14 +204,14 @@ func Test_cpo_F()
let save_cpo = &cpo
new
set cpo-=F
- write Xfile
+ write XfileCpoF
call assert_equal('', @%)
- call delete('Xfile')
+ call delete('XfileCpoF')
set cpo+=F
- write Xfile
- call assert_equal('Xfile', @%)
+ write XfileCpoF
+ call assert_equal('XfileCpoF', @%)
close!
- call delete('Xfile')
+ call delete('XfileCpoF')
let &cpo = save_cpo
endfunc
@@ -415,16 +415,16 @@ endfunc
" Test for the 'O' flag in 'cpo' (overwriting an existing file)
func Test_cpo_O()
let save_cpo = &cpo
- new Xfile
+ new XfileCpoO
call setline(1, 'one')
- call writefile(['two'], 'Xfile')
+ call writefile(['two'], 'XfileCpoO')
set cpo-=O
call assert_fails('write', 'E13:')
set cpo+=O
write
- call assert_equal(['one'], readfile('Xfile'))
+ call assert_equal(['one'], readfile('XfileCpoO'))
close!
- call delete('Xfile')
+ call delete('XfileCpoO')
let &cpo = save_cpo
endfunc
@@ -434,18 +434,18 @@ endfunc
" name)
func Test_cpo_P()
let save_cpo = &cpo
- call writefile([], 'Xfile')
+ call writefile([], 'XfileCpoP')
new
call setline(1, 'one')
set cpo+=F
set cpo-=P
- write >> Xfile
+ write >> XfileCpoP
call assert_equal('', @%)
set cpo+=P
- write >> Xfile
- call assert_equal('Xfile', @%)
+ write >> XfileCpoP
+ call assert_equal('XfileCpoP', @%)
close!
- call delete('Xfile')
+ call delete('XfileCpoP')
let &cpo = save_cpo
endfunc
@@ -638,8 +638,8 @@ endfunc
" Test for the 'Z' flag in 'cpo' (write! resets 'readonly')
func Test_cpo_Z()
let save_cpo = &cpo
- call writefile([], 'Xfile')
- new Xfile
+ call writefile([], 'XfileCpoZ')
+ new XfileCpoZ
setlocal readonly
set cpo-=Z
write!
@@ -649,7 +649,7 @@ func Test_cpo_Z()
write!
call assert_equal(1, &readonly)
close!
- call delete('Xfile')
+ call delete('XfileCpoZ')
let &cpo = save_cpo
endfunc
@@ -728,8 +728,8 @@ endfunc
" flag)
func Test_cpo_plus()
let save_cpo = &cpo
- call writefile([], 'Xfile')
- new Xfile
+ call writefile([], 'XfileCpoPlus')
+ new XfileCpoPlus
call setline(1, 'foo')
write X1
call assert_equal(1, &modified)
@@ -737,7 +737,7 @@ func Test_cpo_plus()
write X2
call assert_equal(0, &modified)
close!
- call delete('Xfile')
+ call delete('XfileCpoPlus')
call delete('X1')
call delete('X2')
let &cpo = save_cpo
@@ -843,17 +843,17 @@ endfunc
" loaded and ':preserve' is used.
func Test_cpo_ampersand()
throw 'Skipped: Nvim does not support cpoptions flag "&"'
- call writefile(['one'], 'Xfile')
+ call writefile(['one'], 'XfileCpoAmp')
let after =<< trim [CODE]
set cpo+=&
preserve
qall
[CODE]
- if RunVim([], after, 'Xfile')
- call assert_equal(1, filereadable('.Xfile.swp'))
- call delete('.Xfile.swp')
+ if RunVim([], after, 'XfileCpoAmp')
+ call assert_equal(1, filereadable('.XfileCpoAmp.swp'))
+ call delete('.XfileCpoAmp.swp')
endif
- call delete('Xfile')
+ call delete('XfileCpoAmp')
endfunc
" Test for the '\' flag in 'cpo' (backslash in a [] range in a search pattern)
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index 0de5310735..d83cd505a6 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -243,6 +243,36 @@ func Test_diffput_two()
bwipe! b
endfunc
+" Test for :diffget/:diffput with a range that is inside a diff chunk
+func Test_diffget_diffput_range()
+ call setline(1, range(1, 10))
+ new
+ call setline(1, range(11, 20))
+ windo diffthis
+ 3,5diffget
+ call assert_equal(['13', '14', '15'], getline(3, 5))
+ call setline(1, range(1, 10))
+ 4,8diffput
+ wincmd p
+ call assert_equal(['13', '4', '5', '6', '7', '8', '19'], getline(3, 9))
+ %bw!
+endfunc
+
+" Test for :diffget/:diffput with an empty buffer and a non-empty buffer
+func Test_diffget_diffput_empty_buffer()
+ %d _
+ new
+ call setline(1, 'one')
+ windo diffthis
+ diffget
+ call assert_equal(['one'], getline(1, '$'))
+ %d _
+ diffput
+ wincmd p
+ call assert_equal([''], getline(1, '$'))
+ %bw!
+endfunc
+
" :diffput and :diffget completes names of buffers which
" are in diff mode and which are different then current buffer.
" No completion when the current window is not in diff mode.
@@ -645,7 +675,11 @@ func Test_diffexpr()
call assert_equal(normattr, screenattr(1, 1))
call assert_equal(normattr, screenattr(2, 1))
call assert_notequal(normattr, screenattr(3, 1))
+ diffoff!
+ " Try using an non-existing function for 'diffexpr'.
+ set diffexpr=NewDiffFunc()
+ call assert_fails('windo diffthis', ['E117:', 'E97:'])
diffoff!
%bwipe!
set diffexpr& diffopt&
@@ -1316,6 +1350,89 @@ func Test_diff_filler_cursorcolumn()
call delete('Xtest_diff_cuc')
endfunc
+" Test for adding/removing lines inside diff chunks, between diff chunks
+" and before diff chunks
+func Test_diff_modify_chunks()
+ enew!
+ let w2_id = win_getid()
+ call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
+ new
+ let w1_id = win_getid()
+ call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i'])
+ windo diffthis
+
+ " remove a line between two diff chunks and create a new diff chunk
+ call win_gotoid(w2_id)
+ 5d
+ call win_gotoid(w1_id)
+ call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd')
+
+ " add a line between two diff chunks
+ call win_gotoid(w2_id)
+ normal! 4Goe
+ call win_gotoid(w1_id)
+ call diff_hlID(4, 1)->synIDattr('name')->assert_equal('')
+ call diff_hlID(5, 1)->synIDattr('name')->assert_equal('')
+
+ " remove all the lines in a diff chunk.
+ call win_gotoid(w2_id)
+ 7,8d
+ call win_gotoid(w1_id)
+ let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd',
+ \ 'DiffAdd', ''], hl)
+
+ " remove lines from one diff chunk to just before the next diff chunk
+ call win_gotoid(w2_id)
+ call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
+ 2,6d
+ call win_gotoid(w1_id)
+ let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd',
+ \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
+
+ " remove lines just before the top of a diff chunk
+ call win_gotoid(w2_id)
+ call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
+ 5,6d
+ call win_gotoid(w1_id)
+ let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText',
+ \ 'DiffAdd', 'DiffAdd', ''], hl)
+
+ " remove line after the end of a diff chunk
+ call win_gotoid(w2_id)
+ call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
+ 4d
+ call win_gotoid(w1_id)
+ let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText',
+ \ 'DiffText', ''], hl)
+
+ " remove lines starting from the end of one diff chunk and ending inside
+ " another diff chunk
+ call win_gotoid(w2_id)
+ call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
+ 4,7d
+ call win_gotoid(w1_id)
+ let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd',
+ \ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
+
+ " removing the only remaining diff chunk should make the files equal
+ call win_gotoid(w2_id)
+ call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i'])
+ 8d
+ let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl)
+ call win_gotoid(w2_id)
+ 4d
+ call win_gotoid(w1_id)
+ let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
+ call assert_equal(['', '', '', '', '', '', '', '', ''], hl)
+
+ %bw!
+endfunc
func Test_diff_binary()
CheckScreendump
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
index dc850515b0..89e597f401 100644
--- a/src/nvim/testdir/test_edit.vim
+++ b/src/nvim/testdir/test_edit.vim
@@ -1863,11 +1863,9 @@ func Test_edit_insertmode_ex_edit()
call writefile(lines, 'Xtest_edit_insertmode_ex_edit')
let buf = RunVimInTerminal('-S Xtest_edit_insertmode_ex_edit', #{rows: 6})
- call TermWait(buf, 50)
- call assert_match('^-- INSERT --\s*$', term_getline(buf, 6))
+ call WaitForAssert({-> assert_match('^-- INSERT --\s*$', term_getline(buf, 6))})
call term_sendkeys(buf, "\<C-B>\<C-L>")
- call TermWait(buf, 50)
- call assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))
+ call WaitForAssert({-> assert_notmatch('^-- INSERT --\s*$', term_getline(buf, 6))})
" clean up
call StopVimInTerminal(buf)
@@ -1875,15 +1873,16 @@ func Test_edit_insertmode_ex_edit()
endfunc
" Pressing escape in 'insertmode' should beep
-func Test_edit_insertmode_esc_beeps()
- throw "Skipped: Nvim does not support 'insertmode'"
+" FIXME: Execute this later, when using valgrind it makes the next test
+" Test_edit_insertmode_ex_edit() fail.
+func Test_z_edit_insertmode_esc_beeps()
new
- set insertmode
- call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
+ " set insertmode
+ " call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
set insertmode&
- " unsupported CTRL-G command should beep in insert mode.
+ " unsupported "CTRL-G l" command should beep in insert mode.
call assert_beeps("normal i\<C-G>l")
- close!
+ bwipe!
endfunc
" Test for 'hkmap' and 'hkmapp'
diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim
index 42b1f8ca48..44bed890f5 100644
--- a/src/nvim/testdir/test_excmd.vim
+++ b/src/nvim/testdir/test_excmd.vim
@@ -78,6 +78,14 @@ func Test_file_cmd()
call assert_fails('3file', 'E474:')
call assert_fails('0,0file', 'E474:')
call assert_fails('0file abc', 'E474:')
+ if !has('win32')
+ " Change the name of the buffer to the same name
+ new Xfile1
+ file Xfile1
+ call assert_equal('Xfile1', @%)
+ call assert_equal('Xfile1', @#)
+ bw!
+ endif
endfunc
" Test for the :drop command
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 69508cb19e..1d9465dd94 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -126,6 +126,7 @@ let s:filename_checks = {
\ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'],
\ 'cook': ['file.cook'],
\ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'],
+ \ 'cqlang': ['file.cql'],
\ 'crm': ['file.crm'],
\ 'crontab': ['crontab', 'crontab.file', '/etc/cron.d/file', 'any/etc/cron.d/file'],
\ 'cs': ['file.cs', 'file.csx'],
@@ -349,6 +350,7 @@ let s:filename_checks = {
\ 'maxima': ['file.demo', 'file.dmt', 'file.dm1', 'file.dm2', 'file.dm3',
\ 'file.wxm', 'maxima-init.mac'],
\ 'mel': ['file.mel'],
+ \ 'mermaid': ['file.mmd', 'file.mmdc', 'file.mermaid'],
\ 'meson': ['meson.build', 'meson_options.txt'],
\ 'messages': ['/log/auth', '/log/cron', '/log/daemon', '/log/debug', '/log/kern', '/log/lpr', '/log/mail', '/log/messages', '/log/news/news', '/log/syslog', '/log/user',
\ '/log/auth.log', '/log/cron.log', '/log/daemon.log', '/log/debug.log', '/log/kern.log', '/log/lpr.log', '/log/mail.log', '/log/messages.log', '/log/news/news.log', '/log/syslog.log', '/log/user.log',
diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim
index 5a96548893..e6b6341fce 100644
--- a/src/nvim/testdir/test_getvar.vim
+++ b/src/nvim/testdir/test_getvar.vim
@@ -133,11 +133,20 @@ func Test_get_lambda()
call assert_equal([], get(l:L, 'args'))
endfunc
+func s:FooBar()
+endfunc
+
" get({func}, {what} [, {default}])
func Test_get_func()
let l:F = function('tr')
call assert_equal('tr', get(l:F, 'name'))
call assert_equal(l:F, get(l:F, 'func'))
+
+ let Fb_func = function('s:FooBar')
+ call assert_match('<SNR>\d\+_FooBar', get(Fb_func, 'name'))
+ let Fb_ref = funcref('s:FooBar')
+ call assert_match('<SNR>\d\+_FooBar', get(Fb_ref, 'name'))
+
call assert_equal({'func has': 'no dict'}, get(l:F, 'dict', {'func has': 'no dict'}))
call assert_equal(0, get(l:F, 'dict'))
call assert_equal([], get(l:F, 'args'))
diff --git a/src/nvim/testdir/test_lambda.vim b/src/nvim/testdir/test_lambda.vim
index ce15243993..025eb016a8 100644
--- a/src/nvim/testdir/test_lambda.vim
+++ b/src/nvim/testdir/test_lambda.vim
@@ -62,7 +62,7 @@ endfunc
function Test_lambda_fails()
call assert_equal(3, {a, b -> a + b}(1, 2))
call assert_fails('echo {a, a -> a + a}(1, 2)', 'E853:')
- call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E15:')
+ call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E451:')
echo assert_fails('echo 10->{a -> a + 2}', 'E107:')
endfunc
diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim
index 5d9be99444..600b6132a9 100644
--- a/src/nvim/testdir/test_match.vim
+++ b/src/nvim/testdir/test_match.vim
@@ -363,4 +363,80 @@ func Test_matchadd_other_window()
call delete('XscriptMatchCommon')
endfunc
+func Test_match_in_linebreak()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set breakindent linebreak breakat+=]
+ call printf('%s]%s', repeat('x', 50), repeat('x', 70))->setline(1)
+ call matchaddpos('ErrorMsg', [[1, 51]])
+ END
+ call writefile(lines, 'XscriptMatchLinebreak')
+ let buf = RunVimInTerminal('-S XscriptMatchLinebreak', #{rows: 10})
+ call TermWait(buf)
+ call VerifyScreenDump(buf, 'Test_match_linebreak', {})
+
+ call StopVimInTerminal(buf)
+ call delete('XscriptMatchLinebreak')
+endfunc
+
+func Test_match_with_incsearch()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set incsearch
+ call setline(1, range(20))
+ call matchaddpos('ErrorMsg', [3])
+ END
+ call writefile(lines, 'XmatchWithIncsearch')
+ let buf = RunVimInTerminal('-S XmatchWithIncsearch', #{rows: 6})
+ call TermWait(buf)
+ call VerifyScreenDump(buf, 'Test_match_with_incsearch_1', {})
+
+ call term_sendkeys(buf, ":s/0")
+ call VerifyScreenDump(buf, 'Test_match_with_incsearch_2', {})
+
+ call term_sendkeys(buf, "\<CR>")
+ call StopVimInTerminal(buf)
+ call delete('XmatchWithIncsearch')
+endfunc
+
+" Test for deleting matches outside of the screen redraw top/bottom lines
+" This should cause a redraw of those lines.
+func Test_matchdelete_redraw()
+ new
+ call setline(1, range(1, 500))
+ call cursor(250, 1)
+ let m1 = matchaddpos('Search', [[250]])
+ let m2 = matchaddpos('Search', [[10], [450]])
+ redraw!
+ let m3 = matchaddpos('Search', [[240], [260]])
+ call matchdelete(m2)
+ let m = getmatches()
+ call assert_equal(2, len(m))
+ call assert_equal([250], m[0].pos1)
+ redraw!
+ call matchdelete(m1)
+ call assert_equal(1, len(getmatches()))
+ bw!
+endfunc
+
+func Test_match_tab_with_linebreak()
+ CheckRunVimInTerminal
+
+ let lines =<< trim END
+ set linebreak
+ call setline(1, "\tix")
+ call matchadd('ErrorMsg', '\t')
+ END
+ call writefile(lines, 'XscriptMatchTabLinebreak')
+ let buf = RunVimInTerminal('-S XscriptMatchTabLinebreak', #{rows: 10})
+ call TermWait(buf)
+ call VerifyScreenDump(buf, 'Test_match_tab_linebreak', {})
+
+ call StopVimInTerminal(buf)
+ call delete('XscriptMatchTabLinebreak')
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim
index 057f4a1bea..ca3b736429 100644
--- a/src/nvim/testdir/test_method.vim
+++ b/src/nvim/testdir/test_method.vim
@@ -153,6 +153,22 @@ endfunc
func Test_method_not_supported()
call assert_fails('eval 123->changenr()', 'E276:')
+ call assert_fails('echo "abc"->invalidfunc()', 'E117:')
+ " Test for too many or too few arguments to a method
+ call assert_fails('let n="abc"->len(2)', 'E118:')
+ call assert_fails('let n=10->setwinvar()', 'E119:')
endfunc
-" vim: shiftwidth=2 sts=2 expandtab
+" Test for passing optional arguments to methods
+func Test_method_args()
+ let v:errors = []
+ let n = 10->assert_inrange(1, 5, "Test_assert_inrange")
+ if v:errors[0] !~ 'Test_assert_inrange'
+ call assert_report(v:errors[0])
+ else
+ " Test passed
+ let v:errors = []
+ endif
+endfunc
+
+" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
index e5756bd505..83709420bf 100644
--- a/src/nvim/testdir/test_normal.vim
+++ b/src/nvim/testdir/test_normal.vim
@@ -3001,24 +3001,6 @@ func Test_normal47_visual_buf_wipe()
set nomodified
endfunc
-func Test_normal47_autocmd()
- " disabled, does not seem to be possible currently
- throw "Skipped: not possible to test cursorhold autocmd while waiting for input in normal_cmd"
- new
- call append(0, repeat('-',20))
- au CursorHold * call feedkeys('2l', '')
- 1
- set updatetime=20
- " should delete 12 chars (d12l)
- call feedkeys('d1', '!')
- call assert_equal('--------', getline(1))
-
- " clean up
- au! CursorHold
- set updatetime=4000
- bw!
-endfunc
-
func Test_normal48_wincmd()
new
exe "norm! \<c-w>c"
diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim
index 9b8a776c95..b8f6c5240c 100644
--- a/src/nvim/testdir/test_prompt_buffer.vim
+++ b/src/nvim/testdir/test_prompt_buffer.vim
@@ -180,6 +180,8 @@ func Test_prompt_buffer_edit()
call assert_beeps('normal! S')
call assert_beeps("normal! \<C-A>")
call assert_beeps("normal! \<C-X>")
+ call assert_beeps("normal! dp")
+ call assert_beeps("normal! do")
" pressing CTRL-W in the prompt buffer should trigger the window commands
call assert_equal(1, winnr())
exe "normal A\<C-W>\<C-W>"
diff --git a/src/nvim/testdir/test_recover.vim b/src/nvim/testdir/test_recover.vim
index fc073cacd2..92e22687af 100644
--- a/src/nvim/testdir/test_recover.vim
+++ b/src/nvim/testdir/test_recover.vim
@@ -1,5 +1,7 @@
" Test :recover
+source check.vim
+
func Test_recover_root_dir()
" This used to access invalid memory.
split Xtest
@@ -23,6 +25,21 @@ func Test_recover_root_dir()
set dir&
endfunc
+" Make a copy of the current swap file to "Xswap".
+" Return the name of the swap file.
+func CopySwapfile()
+ preserve
+ " get the name of the swap file
+ let swname = split(execute("swapname"))[0]
+ let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '')
+ " make a copy of the swap file in Xswap
+ set binary
+ exe 'sp ' . swname
+ w! Xswap
+ set nobinary
+ return swname
+endfunc
+
" Inserts 10000 lines with text to fill the swap file with two levels of pointer
" blocks. Then recovers from the swap file and checks all text is restored.
"
@@ -40,15 +57,9 @@ func Test_swap_file()
let i += 1
endwhile
$delete
- preserve
- " get the name of the swap file
- let swname = split(execute("swapname"))[0]
- let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '')
- " make a copy of the swap file in Xswap
- set binary
- exe 'sp ' . swname
- w! Xswap
- set nobinary
+
+ let swname = CopySwapfile()
+
new
only!
bwipe! Xtest
@@ -69,3 +80,388 @@ func Test_swap_file()
set undolevels&
enew! | only
endfunc
+
+func Test_nocatch_process_still_running()
+ let g:skipped_reason = 'test_override() is N/A'
+ return
+ " sysinfo.uptime probably only works on Linux
+ if !has('linux')
+ let g:skipped_reason = 'only works on Linux'
+ return
+ endif
+ " the GUI dialog can't be handled
+ if has('gui_running')
+ let g:skipped_reason = 'only works in the terminal'
+ return
+ endif
+
+ " don't intercept existing swap file here
+ au! SwapExists
+
+ " Edit a file and grab its swapfile.
+ edit Xswaptest
+ call setline(1, ['a', 'b', 'c'])
+ let swname = CopySwapfile()
+
+ " Forget we edited this file
+ new
+ only!
+ bwipe! Xswaptest
+
+ call rename('Xswap', swname)
+ call feedkeys('e', 'tL')
+ redir => editOutput
+ edit Xswaptest
+ redir END
+ call assert_match('E325: ATTENTION', editOutput)
+ call assert_match('file name: .*Xswaptest', editOutput)
+ call assert_match('process ID: \d* (STILL RUNNING)', editOutput)
+
+ " Forget we edited this file
+ new
+ only!
+ bwipe! Xswaptest
+
+ " pretend we rebooted
+ call test_override("uptime", 0)
+ sleep 1
+
+ call feedkeys('e', 'tL')
+ redir => editOutput
+ edit Xswaptest
+ redir END
+ call assert_match('E325: ATTENTION', editOutput)
+ call assert_notmatch('(STILL RUNNING)', editOutput)
+
+ call test_override("ALL", 0)
+ call delete(swname)
+endfunc
+
+" Test for :recover with multiple swap files
+func Test_recover_multiple_swap_files()
+ CheckUnix
+ new Xfile1
+ call setline(1, ['a', 'b', 'c'])
+ preserve
+ let b = readblob(swapname(''))
+ call writefile(b, '.Xfile1.swm')
+ call writefile(b, '.Xfile1.swn')
+ call writefile(b, '.Xfile1.swo')
+ %bw!
+ call feedkeys(":recover Xfile1\<CR>3\<CR>q", 'xt')
+ call assert_equal(['a', 'b', 'c'], getline(1, '$'))
+ " try using out-of-range number to select a swap file
+ bw!
+ call feedkeys(":recover Xfile1\<CR>4\<CR>q", 'xt')
+ call assert_equal('Xfile1', @%)
+ call assert_equal([''], getline(1, '$'))
+ bw!
+ call feedkeys(":recover Xfile1\<CR>0\<CR>q", 'xt')
+ call assert_equal('Xfile1', @%)
+ call assert_equal([''], getline(1, '$'))
+ bw!
+
+ call delete('.Xfile1.swm')
+ call delete('.Xfile1.swn')
+ call delete('.Xfile1.swo')
+endfunc
+
+" Test for :recover using an empty swap file
+func Test_recover_empty_swap_file()
+ CheckUnix
+ call writefile([], '.Xfile1.swp')
+ let msg = execute('recover Xfile1')
+ call assert_match('Unable to read block 0 from .Xfile1.swp', msg)
+ call assert_equal('Xfile1', @%)
+ bw!
+
+ " make sure there are no old swap files laying around
+ for f in glob('.sw?', 0, 1)
+ call delete(f)
+ endfor
+
+ " :recover from an empty buffer
+ call assert_fails('recover', 'E305:')
+ call delete('.Xfile1.swp')
+endfunc
+
+" Test for :recover using a corrupted swap file
+" Refer to the comments in the memline.c file for the swap file headers
+" definition.
+func Test_recover_corrupted_swap_file()
+ CheckUnix
+
+ " recover using a partial swap file
+ call writefile(0z1234, '.Xfile1.swp')
+ call assert_fails('recover Xfile1', 'E295:')
+ bw!
+
+ " recover using invalid content in the swap file
+ call writefile([repeat('1', 2*1024)], '.Xfile1.swp')
+ call assert_fails('recover Xfile1', 'E307:')
+ call delete('.Xfile1.swp')
+
+ " :recover using a swap file with a corrupted header
+ edit Xfile1
+ preserve
+ let sn = swapname('')
+ let b = readblob(sn)
+ let save_b = copy(b)
+ bw!
+
+ " Not all fields are written in a system-independent manner. Detect whether
+ " the test is running on a little or big-endian system, so the correct
+ " corruption values can be set.
+ " The B0_MAGIC_LONG field may be 32-bit or 64-bit, depending on the system,
+ " even though the value stored is only 32-bits. Therefore, need to check
+ " both the high and low 32-bits to compute these values.
+ let little_endian = (b[1008:1011] == 0z33323130) || (b[1012:1015] == 0z33323130)
+ let system_64bit = little_endian ? (b[1012:1015] == 0z00000000) : (b[1008:1011] == 0z00000000)
+
+ " clear the B0_MAGIC_LONG field
+ if system_64bit
+ let b[1008:1015] = 0z00000000.00000000
+ else
+ let b[1008:1011] = 0z00000000
+ endif
+ call writefile(b, sn)
+ let msg = execute('recover Xfile1')
+ call assert_match('the file has been damaged', msg)
+ call assert_equal('Xfile1', @%)
+ call assert_equal([''], getline(1, '$'))
+ bw!
+
+ " reduce the page size
+ let b = copy(save_b)
+ let b[12:15] = 0z00010000
+ call writefile(b, sn)
+ let msg = execute('recover Xfile1')
+ call assert_match('page size is smaller than minimum value', msg)
+ call assert_equal('Xfile1', @%)
+ call assert_equal([''], getline(1, '$'))
+ bw!
+
+ " clear the pointer ID
+ let b = copy(save_b)
+ let b[4096:4097] = 0z0000
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E310:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal([''], getline(1, '$'))
+ bw!
+
+ " set the number of pointers in a pointer block to zero
+ let b = copy(save_b)
+ let b[4098:4099] = 0z0000
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['???EMPTY BLOCK'], getline(1, '$'))
+ bw!
+
+ " set the block number in a pointer entry to a negative number
+ let b = copy(save_b)
+ if system_64bit
+ let b[4104:4111] = little_endian ? 0z00000000.00000080 : 0z80000000.00000000
+ else
+ let b[4104:4107] = little_endian ? 0z00000080 : 0z80000000
+ endif
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['???LINES MISSING'], getline(1, '$'))
+ bw!
+
+ " clear the data block ID
+ let b = copy(save_b)
+ let b[8192:8193] = 0z0000
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['???BLOCK MISSING'], getline(1, '$'))
+ bw!
+
+ " set the number of lines in the data block to zero
+ let b = copy(save_b)
+ if system_64bit
+ let b[8208:8215] = 0z00000000.00000000
+ else
+ let b[8208:8211] = 0z00000000
+ endif
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['??? from here until ???END lines may have been inserted/deleted',
+ \ '???END'], getline(1, '$'))
+ bw!
+
+ " use an invalid text start for the lines in a data block
+ let b = copy(save_b)
+ if system_64bit
+ let b[8216:8219] = 0z00000000
+ else
+ let b[8212:8215] = 0z00000000
+ endif
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['???'], getline(1, '$'))
+ bw!
+
+ " use an incorrect text end (db_txt_end) for the data block
+ let b = copy(save_b)
+ let b[8204:8207] = little_endian ? 0z80000000 : 0z00000080
+ call writefile(b, sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['??? from here until ???END lines may be messed up', '',
+ \ '???END'], getline(1, '$'))
+ bw!
+
+ " remove the data block
+ let b = copy(save_b)
+ call writefile(b[:8191], sn)
+ call assert_fails('recover Xfile1', 'E312:')
+ call assert_equal('Xfile1', @%)
+ call assert_equal(['???MANY LINES MISSING'], getline(1, '$'))
+
+ bw!
+ call delete(sn)
+endfunc
+
+" Test for :recover using an encrypted swap file
+func Test_recover_encrypted_swap_file()
+ CheckFeature cryptv
+ CheckUnix
+
+ " Recover an encrypted file from the swap file without the original file
+ new Xfile1
+ call feedkeys(":X\<CR>vim\<CR>vim\<CR>", 'xt')
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+ preserve
+ let b = readblob('.Xfile1.swp')
+ call writefile(b, '.Xfile1.swm')
+ bw!
+ call feedkeys(":recover Xfile1\<CR>vim\<CR>\<CR>", 'xt')
+ call assert_equal(['aaa', 'bbb', 'ccc'], getline(1, '$'))
+ bw!
+ call delete('.Xfile1.swm')
+
+ " Recover an encrypted file from the swap file with the original file
+ new Xfile1
+ call feedkeys(":X\<CR>vim\<CR>vim\<CR>", 'xt')
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+ update
+ call setline(1, ['111', '222', '333'])
+ preserve
+ let b = readblob('.Xfile1.swp')
+ call writefile(b, '.Xfile1.swm')
+ bw!
+ call feedkeys(":recover Xfile1\<CR>vim\<CR>\<CR>", 'xt')
+ call assert_equal(['111', '222', '333'], getline(1, '$'))
+ call assert_true(&modified)
+ bw!
+ call delete('.Xfile1.swm')
+ call delete('Xfile1')
+endfunc
+
+" Test for :recover using a unreadable swap file
+func Test_recover_unreadble_swap_file()
+ CheckUnix
+ CheckNotRoot
+ new Xfile1
+ let b = readblob('.Xfile1.swp')
+ call writefile(b, '.Xfile1.swm')
+ bw!
+ call setfperm('.Xfile1.swm', '-w-------')
+ call assert_fails('recover Xfile1', 'E306:')
+ call delete('.Xfile1.swm')
+endfunc
+
+" Test for using :recover when the original file and the swap file have the
+" same contents.
+func Test_recover_unmodified_file()
+ CheckUnix
+ call writefile(['aaa', 'bbb', 'ccc'], 'Xfile1')
+ edit Xfile1
+ preserve
+ let b = readblob('.Xfile1.swp')
+ %bw!
+ call writefile(b, '.Xfile1.swz')
+ let msg = execute('recover Xfile1')
+ call assert_equal(['aaa', 'bbb', 'ccc'], getline(1, '$'))
+ call assert_false(&modified)
+ call assert_match('Buffer contents equals file contents', msg)
+ bw!
+ call delete('Xfile1')
+ call delete('.Xfile1.swz')
+endfunc
+
+" Test for recovering a file when editing a symbolically linked file
+func Test_recover_symbolic_link()
+ CheckUnix
+ call writefile(['aaa', 'bbb', 'ccc'], 'Xfile1')
+ silent !ln -s Xfile1 Xfile2
+ edit Xfile2
+ call assert_equal('.Xfile1.swp', fnamemodify(swapname(''), ':t'))
+ preserve
+ let b = readblob('.Xfile1.swp')
+ %bw!
+ call writefile([], 'Xfile1')
+ call writefile(b, '.Xfile1.swp')
+ silent! recover Xfile2
+ call assert_equal(['aaa', 'bbb', 'ccc'], getline(1, '$'))
+ call assert_true(&modified)
+ update
+ %bw!
+ call assert_equal(['aaa', 'bbb', 'ccc'], readfile('Xfile1'))
+ call delete('Xfile1')
+ call delete('Xfile2')
+ call delete('.Xfile1.swp')
+endfunc
+
+" Test for recovering a file when an autocmd moves the cursor to an invalid
+" line. This used to result in an internal error (E315) which is fixed
+" by 8.2.2966.
+func Test_recover_invalid_cursor_pos()
+ call writefile([], 'Xfile1')
+ edit Xfile1
+ preserve
+ let b = readblob('.Xfile1.swp')
+ bw!
+ augroup Test
+ au!
+ au BufReadPost Xfile1 normal! 3G
+ augroup END
+ call writefile(range(1, 3), 'Xfile1')
+ call writefile(b, '.Xfile1.swp')
+ try
+ recover Xfile1
+ catch /E308:/
+ " this test is for the :E315 internal error.
+ " ignore the 'E308: Original file may have been changed' error
+ endtry
+ redraw!
+ augroup Test
+ au!
+ augroup END
+ augroup! Test
+ call delete('Xfile1')
+ call delete('.Xfile1.swp')
+endfunc
+
+" Test for recovering a buffer without a name
+func Test_noname_buffer()
+ new
+ call setline(1, ['one', 'two'])
+ preserve
+ let sn = swapname('')
+ let b = readblob(sn)
+ bw!
+ call writefile(b, sn)
+ exe "recover " .. sn
+ call assert_equal(['one', 'two'], getline(1, '$'))
+ call delete(sn)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
index f9f7c5b492..42467c5508 100644
--- a/src/nvim/testdir/test_startup.vim
+++ b/src/nvim/testdir/test_startup.vim
@@ -1024,6 +1024,7 @@ endfunc
" Test for using the 'exrc' option
func Test_exrc()
+ throw 'Skipped: Nvim requires user input for the exrc option'
let after =<< trim [CODE]
call assert_equal(1, &exrc)
call assert_equal(1, &secure)
diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim
index 34d1d585ce..cf46b4c5bd 100644
--- a/src/nvim/testdir/test_swap.vim
+++ b/src/nvim/testdir/test_swap.vim
@@ -203,8 +203,8 @@ func Test_swapfile_delete()
" This test won't work as root because root can successfully run kill(1, 0)
if !IsRoot()
" Write the swapfile with a modified PID, now it will be automatically
- " deleted. Process one should never be Vim.
- let swapfile_bytes[24:27] = 0z01000000
+ " deleted. Process 0x3fffffff most likely does not exist.
+ let swapfile_bytes[24:27] = 0zffffff3f
call writefile(swapfile_bytes, swapfile_name)
let s:swapname = ''
split XswapfileText
@@ -421,6 +421,161 @@ func Test_swap_symlink()
call delete('Xswapdir', 'rf')
endfunc
+func s:get_unused_pid(base)
+ if has('job')
+ " Execute 'echo' as a temporary job, and return its pid as an unused pid.
+ if has('win32')
+ let cmd = 'cmd /c echo'
+ else
+ let cmd = 'echo'
+ endif
+ let j = job_start(cmd)
+ while job_status(j) ==# 'run'
+ sleep 10m
+ endwhile
+ if job_status(j) ==# 'dead'
+ return job_info(j).process
+ endif
+ endif
+ " Must add four for MS-Windows to see it as a different one.
+ return a:base + 4
+endfunc
+
+func s:blob_to_pid(b)
+ return a:b[3] * 16777216 + a:b[2] * 65536 + a:b[1] * 256 + a:b[0]
+endfunc
+
+func s:pid_to_blob(i)
+ let b = 0z
+ let b[0] = and(a:i, 0xff)
+ let b[1] = and(a:i / 256, 0xff)
+ let b[2] = and(a:i / 65536, 0xff)
+ let b[3] = and(a:i / 16777216, 0xff)
+ return b
+endfunc
+
+func Test_swap_auto_delete()
+ " Create a valid swapfile by editing a file with a special extension.
+ split Xtest.scr
+ call setline(1, ['one', 'two', 'three'])
+ write " file is written, not modified
+ write " write again to make sure the swapfile is created
+ " read the swapfile as a Blob
+ let swapfile_name = swapname('%')
+ let swapfile_bytes = readfile(swapfile_name, 'B')
+
+ " Forget about the file, recreate the swap file, then edit it again. The
+ " swap file should be automatically deleted.
+ bwipe!
+ " Change the process ID to avoid the "still running" warning.
+ let swapfile_bytes[24:27] = s:pid_to_blob(s:get_unused_pid(
+ \ s:blob_to_pid(swapfile_bytes[24:27])))
+ call writefile(swapfile_bytes, swapfile_name)
+ edit Xtest.scr
+ " will end up using the same swap file after deleting the existing one
+ call assert_equal(swapfile_name, swapname('%'))
+ bwipe!
+
+ " create the swap file again, but change the host name so that it won't be
+ " deleted
+ autocmd! SwapExists
+ augroup test_swap_recover_ext
+ autocmd!
+ autocmd SwapExists * let v:swapchoice = 'e'
+ augroup END
+
+ " change the host name
+ let swapfile_bytes[28 + 40] = swapfile_bytes[28 + 40] + 2
+ call writefile(swapfile_bytes, swapfile_name)
+ edit Xtest.scr
+ call assert_equal(1, filereadable(swapfile_name))
+ " will use another same swap file name
+ call assert_notequal(swapfile_name, swapname('%'))
+ bwipe!
+
+ call delete('Xtest.scr')
+ call delete(swapfile_name)
+ augroup test_swap_recover_ext
+ autocmd!
+ augroup END
+ augroup! test_swap_recover_ext
+endfunc
+
+" Test for renaming a buffer when the swap file is deleted out-of-band
+func Test_missing_swap_file()
+ CheckUnix
+ new Xfile2
+ call delete(swapname(''))
+ call assert_fails('file Xfile3', 'E301:')
+ call assert_equal('Xfile3', bufname())
+ call assert_true(bufexists('Xfile2'))
+ call assert_true(bufexists('Xfile3'))
+ %bw!
+endfunc
+
+" Test for :preserve command
+func Test_preserve()
+ new Xfile4
+ setlocal noswapfile
+ call assert_fails('preserve', 'E313:')
+ bw!
+endfunc
+
+" Test for the v:swapchoice variable
+func Test_swapchoice()
+ call writefile(['aaa', 'bbb'], 'Xfile5')
+ edit Xfile5
+ preserve
+ let swapfname = swapname('')
+ let b = readblob(swapfname)
+ bw!
+ call writefile(b, swapfname)
+
+ autocmd! SwapExists
+
+ " Test for v:swapchoice = 'o' (readonly)
+ augroup test_swapchoice
+ autocmd!
+ autocmd SwapExists * let v:swapchoice = 'o'
+ augroup END
+ edit Xfile5
+ call assert_true(&readonly)
+ call assert_equal(['aaa', 'bbb'], getline(1, '$'))
+ %bw!
+ call assert_true(filereadable(swapfname))
+
+ " Test for v:swapchoice = 'a' (abort)
+ augroup test_swapchoice
+ autocmd!
+ autocmd SwapExists * let v:swapchoice = 'a'
+ augroup END
+ try
+ edit Xfile5
+ catch /^Vim:Interrupt$/
+ endtry
+ call assert_equal('', @%)
+ call assert_true(bufexists('Xfile5'))
+ %bw!
+ call assert_true(filereadable(swapfname))
+
+ " Test for v:swapchoice = 'd' (delete)
+ augroup test_swapchoice
+ autocmd!
+ autocmd SwapExists * let v:swapchoice = 'd'
+ augroup END
+ edit Xfile5
+ call assert_equal('Xfile5', @%)
+ %bw!
+ call assert_false(filereadable(swapfname))
+
+ call delete('Xfile5')
+ call delete(swapfname)
+ augroup test_swapchoice
+ autocmd!
+ augroup END
+ augroup! test_swapchoice
+endfunc
+
func Test_no_swap_file()
call assert_equal("\nNo swap file", execute('swapname'))
endfunc
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
index bfc61e7b48..be60a3535c 100644
--- a/src/nvim/testdir/test_tagjump.vim
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -231,15 +231,13 @@ func Test_tag_symbolic()
endfunc
" Tests for tag search with !_TAG_FILE_ENCODING.
-" Depends on the test83-tags2 and test83-tags3 files.
func Test_tag_file_encoding()
- throw 'skipped: Nvim removed test83-tags2, test83-tags3'
if has('vms')
- return
+ throw 'Skipped: does not work on VMS'
endif
if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
- return
+ throw 'Skipped: iconv does not work'
endif
let save_enc = &encoding
@@ -264,18 +262,31 @@ func Test_tag_file_encoding()
" case2:
new
- set tags=test83-tags2
+ let content = ['!_TAG_FILE_ENCODING cp932 //',
+ \ "\x82`\x82a\x82b Xtags2.txt /\x82`\x82a\x82b"]
+ call writefile(content, 'Xtags')
+ set tags=Xtags
tag /.BC
call assert_equal('Xtags2.txt', expand('%:t'))
call assert_equal('ABC', getline('.'))
+ call delete('Xtags')
close
" case3:
new
- set tags=test83-tags3
+ let contents = [
+ \ "!_TAG_FILE_SORTED 1 //",
+ \ "!_TAG_FILE_ENCODING cp932 //"]
+ for i in range(1, 100)
+ call add(contents, 'abc' .. i
+ \ .. " Xtags3.txt /\x82`\x82a\x82b")
+ endfor
+ call writefile(contents, 'Xtags')
+ set tags=Xtags
tag abc50
call assert_equal('Xtags3.txt', expand('%:t'))
call assert_equal('ABC', getline('.'))
+ call delete('Xtags')
close
set tags&
@@ -327,6 +338,7 @@ func Test_tagjump_etags()
\ ], 'Xtags2')
tag main
call assert_equal(2, line('.'))
+ call assert_fails('tag bar', 'E426:')
" corrupted tag line
call writefile([
@@ -352,6 +364,27 @@ func Test_tagjump_etags()
\ ], 'Xtags')
call assert_fails('tag foo', 'E431:')
+ " end of file after a CTRL-L line
+ call writefile([
+ \ "\x0c",
+ \ "Xmain.c,64",
+ \ "void foo() {}\x7ffoo\x011,0",
+ \ "\x0c",
+ \ ], 'Xtags')
+ call assert_fails('tag main', 'E426:')
+
+ " error in an included tags file
+ call writefile([
+ \ "\x0c",
+ \ "Xtags2,include"
+ \ ], 'Xtags')
+ call writefile([
+ \ "\x0c",
+ \ "Xmain.c,64",
+ \ "void foo() {}",
+ \ ], 'Xtags2')
+ call assert_fails('tag foo', 'E431:')
+
call delete('Xtags')
call delete('Xtags2')
call delete('Xmain.c')
@@ -772,11 +805,11 @@ endfunc
" Test for an unsorted tags file
func Test_tag_sort()
- call writefile([
+ let l = [
\ "first\tXfoo\t1",
\ "ten\tXfoo\t3",
- \ "six\tXfoo\t2"],
- \ 'Xtags')
+ \ "six\tXfoo\t2"]
+ call writefile(l, 'Xtags')
set tags=Xtags
let code =<< trim [CODE]
int first() {}
@@ -787,7 +820,14 @@ func Test_tag_sort()
call assert_fails('tag first', 'E432:')
+ " When multiple tag files are not sorted, then message should be displayed
+ " multiple times
+ call writefile(l, 'Xtags2')
+ set tags=Xtags,Xtags2
+ call assert_fails('tag first', ['E432:', 'E432:'])
+
call delete('Xtags')
+ call delete('Xtags2')
call delete('Xfoo')
set tags&
%bwipe
@@ -1448,6 +1488,16 @@ func Test_tagfile_errors()
endtry
call assert_equal(v:true, caught_431)
+ " tag name and file name are not separated by a tab
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "foo Xfile 1"], 'Xtags')
+ call assert_fails('tag foo', 'E431:')
+
+ " file name and search pattern are not separated by a tab
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "foo\tXfile 1;"], 'Xtags')
+ call assert_fails('tag foo', 'E431:')
+
call delete('Xtags')
call delete('Xfile')
set tags&
@@ -1480,4 +1530,86 @@ func Test_stag_close_window_on_error()
set tags&
endfunc
+" Test for 'tagbsearch' (binary search)
+func Test_tagbsearch()
+ " If a tags file header says the tags are sorted, but the tags are actually
+ " unsorted, then binary search should fail and linear search should work.
+ call writefile([
+ \ "!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/",
+ \ "third\tXfoo\t3",
+ \ "second\tXfoo\t2",
+ \ "first\tXfoo\t1"],
+ \ 'Xtags')
+ set tags=Xtags
+ let code =<< trim [CODE]
+ int first() {}
+ int second() {}
+ int third() {}
+ [CODE]
+ call writefile(code, 'Xfoo')
+
+ enew
+ set tagbsearch
+ call assert_fails('tag first', 'E426:')
+ call assert_equal('', bufname())
+ call assert_fails('tag second', 'E426:')
+ call assert_equal('', bufname())
+ tag third
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(3, line('.'))
+ %bw!
+
+ set notagbsearch
+ tag first
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(1, line('.'))
+ enew
+ tag second
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(2, line('.'))
+ enew
+ tag third
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(3, line('.'))
+ %bw!
+
+ " If a tags file header says the tags are unsorted, but the tags are
+ " actually sorted, then binary search should work.
+ call writefile([
+ \ "!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/",
+ \ "first\tXfoo\t1",
+ \ "second\tXfoo\t2",
+ \ "third\tXfoo\t3"],
+ \ 'Xtags')
+
+ set tagbsearch
+ tag first
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(1, line('.'))
+ enew
+ tag second
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(2, line('.'))
+ enew
+ tag third
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(3, line('.'))
+ %bw!
+
+ " Binary search fails on EOF
+ call writefile([
+ \ "!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/",
+ \ "bar\tXfoo\t1",
+ \ "foo\tXfoo\t2"],
+ \ 'Xtags')
+ call assert_fails('tag bbb', 'E426:')
+
+ call delete('Xtags')
+ call delete('Xfoo')
+ set tags& tagbsearch&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
index 658485582c..0387ef2bd8 100644
--- a/src/nvim/testdir/test_taglist.vim
+++ b/src/nvim/testdir/test_taglist.vim
@@ -36,6 +36,12 @@ func Test_taglist()
call assert_equal('d', cmd[0]['kind'])
call assert_equal('call cursor(3, 4)', cmd[0]['cmd'])
+ " Use characters with value > 127 in the tag extra field.
+ call writefile([
+ \ "vFoo\tXfoo\t4" .. ';"' .. "\ttypename:int\ta£££\tv",
+ \ ], 'Xtags')
+ call assert_equal('v', taglist('vFoo')[0].kind)
+
call assert_fails("let l=taglist([])", 'E730:')
call delete('Xtags')
@@ -221,6 +227,11 @@ func Test_format_error()
endtry
call assert_true(caught_exception)
+ " no field after the filename for a tag
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "foo\tXfile"], 'Xtags')
+ call assert_fails("echo taglist('foo')", 'E431:')
+
set tags&
call delete('Xtags')
endfunc
@@ -241,4 +252,30 @@ func Test_tag_complete_wildoptions()
set tags&
endfunc
+func Test_tag_complete_with_overlong_line()
+ let tagslines =<< trim END
+ !_TAG_FILE_FORMAT 2 //
+ !_TAG_FILE_SORTED 1 //
+ !_TAG_FILE_ENCODING utf-8 //
+ inboundGSV a 1;" r
+ inboundGovernor a 2;" kind:⊢ type:forall (muxMode :: MuxMode) socket peerAddr versionNumber m a b. (MonadAsync m, MonadCatch m, MonadEvaluate m, MonadThrow m, MonadThrow (STM m), MonadTime m, MonadTimer m, MonadMask m, Ord peerAddr, HasResponder muxMode ~ True) => Tracer m (RemoteTransitionTrace peerAddr) -> Tracer m (InboundGovernorTrace peerAddr) -> ServerControlChannel muxMode peerAddr ByteString m a b -> DiffTime -> MuxConnectionManager muxMode socket peerAddr versionNumber ByteString m a b -> StrictTVar m InboundGovernorObservableState -> m Void
+ inboundGovernorCounters a 3;" kind:⊢ type:InboundGovernorState muxMode peerAddr m a b -> InboundGovernorCounters
+ END
+ call writefile(tagslines, 'Xtags')
+ set tags=Xtags
+
+ " try with binary search
+ set tagbsearch
+ call feedkeys(":tag inbou\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"tag inboundGSV inboundGovernor inboundGovernorCounters', @:)
+ " try with linear search
+ set notagbsearch
+ call feedkeys(":tag inbou\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal('"tag inboundGSV inboundGovernor inboundGovernorCounters', @:)
+ set tagbsearch&
+
+ call delete('Xtags')
+ set tags&
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 54ab9a0471..aacf30712a 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3868,6 +3868,27 @@ void close_others(int message, int forceit)
}
}
+/// Store the relevant window pointers for tab page "tp". To be used before
+/// use_tabpage().
+void unuse_tabpage(tabpage_T *tp)
+{
+ tp->tp_topframe = topframe;
+ tp->tp_firstwin = firstwin;
+ tp->tp_lastwin = lastwin;
+ tp->tp_curwin = curwin;
+}
+
+/// Set the relevant pointers to use tab page "tp". May want to call
+/// unuse_tabpage() first.
+void use_tabpage(tabpage_T *tp)
+{
+ curtab = tp;
+ topframe = curtab->tp_topframe;
+ firstwin = curtab->tp_firstwin;
+ lastwin = curtab->tp_lastwin;
+ curwin = curtab->tp_curwin;
+}
+
// Allocate the first window and put an empty buffer in it.
// Only called from main().
void win_alloc_first(void)
@@ -3878,11 +3899,8 @@ void win_alloc_first(void)
}
first_tabpage = alloc_tabpage();
- first_tabpage->tp_topframe = topframe;
curtab = first_tabpage;
- curtab->tp_firstwin = firstwin;
- curtab->tp_lastwin = lastwin;
- curtab->tp_curwin = curwin;
+ unuse_tabpage(first_tabpage);
}
// Init `aucmd_win`. This can only be done after the first window
@@ -4253,10 +4271,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a
win_T *next_prevwin = tp->tp_prevwin;
tabpage_T *old_curtab = curtab;
- curtab = tp;
- firstwin = tp->tp_firstwin;
- lastwin = tp->tp_lastwin;
- topframe = tp->tp_topframe;
+ use_tabpage(tp);
if (old_curtab != curtab) {
tabpage_check_windows(old_curtab);
@@ -5263,37 +5278,265 @@ void win_new_screen_cols(void)
win_reconfig_floats(); // The size of floats might change
}
-/// Trigger WinScrolled for "curwin" if needed.
-void may_trigger_winscrolled(void)
+/// Make a snapshot of all the window scroll positions and sizes of the current
+/// tab page.
+void snapshot_windows_scroll_size(void)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ wp->w_last_topline = wp->w_topline;
+ wp->w_last_leftcol = wp->w_leftcol;
+ wp->w_last_skipcol = wp->w_skipcol;
+ wp->w_last_width = wp->w_width;
+ wp->w_last_height = wp->w_height;
+ }
+}
+
+static bool did_initial_scroll_size_snapshot = false;
+
+void may_make_initial_scroll_size_snapshot(void)
+{
+ if (!did_initial_scroll_size_snapshot) {
+ did_initial_scroll_size_snapshot = true;
+ snapshot_windows_scroll_size();
+ }
+}
+
+/// Create a dictionary with information about size and scroll changes in a
+/// window.
+/// Returns the dictionary with refcount set to one.
+/// Returns NULL on internal error.
+static dict_T *make_win_info_dict(int width, int height, int topline, int leftcol, int skipcol)
+{
+ dict_T *const d = tv_dict_alloc();
+ d->dv_refcount = 1;
+
+ // not actually looping, for breaking out on error
+ while (1) {
+ typval_T tv = {
+ .v_lock = VAR_UNLOCKED,
+ .v_type = VAR_NUMBER,
+ };
+
+ tv.vval.v_number = width;
+ if (tv_dict_add_tv(d, S_LEN("width"), &tv) == FAIL) {
+ break;
+ }
+ tv.vval.v_number = height;
+ if (tv_dict_add_tv(d, S_LEN("height"), &tv) == FAIL) {
+ break;
+ }
+ tv.vval.v_number = topline;
+ if (tv_dict_add_tv(d, S_LEN("topline"), &tv) == FAIL) {
+ break;
+ }
+ tv.vval.v_number = leftcol;
+ if (tv_dict_add_tv(d, S_LEN("leftcol"), &tv) == FAIL) {
+ break;
+ }
+ tv.vval.v_number = skipcol;
+ if (tv_dict_add_tv(d, S_LEN("skipcol"), &tv) == FAIL) {
+ break;
+ }
+ return d;
+ }
+ tv_dict_unref(d);
+ return NULL;
+}
+
+/// Return values of check_window_scroll_resize():
+enum {
+ CWSR_SCROLLED = 1, ///< at least one window scrolled
+ CWSR_RESIZED = 2, ///< at least one window size changed
+};
+
+/// This function is used for three purposes:
+/// 1. Goes over all windows in the current tab page and returns:
+/// 0 no scrolling and no size changes found
+/// CWSR_SCROLLED at least one window scrolled
+/// CWSR_RESIZED at least one window changed size
+/// CWSR_SCROLLED + CWSR_RESIZED both
+/// "size_count" is set to the nr of windows with size changes.
+/// "first_scroll_win" is set to the first window with any relevant changes.
+/// "first_size_win" is set to the first window with size changes.
+///
+/// 2. When the first three arguments are NULL and "winlist" is not NULL,
+/// "winlist" is set to the list of window IDs with size changes.
+///
+/// 3. When the first three arguments are NULL and "v_event" is not NULL,
+/// information about changed windows is added to "v_event".
+static int check_window_scroll_resize(int *size_count, win_T **first_scroll_win,
+ win_T **first_size_win, list_T *winlist, dict_T *v_event)
+{
+ int result = 0;
+ // int listidx = 0;
+ int tot_width = 0;
+ int tot_height = 0;
+ int tot_topline = 0;
+ int tot_leftcol = 0;
+ int tot_skipcol = 0;
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ const bool size_changed = wp->w_last_width != wp->w_width
+ || wp->w_last_height != wp->w_height;
+ if (size_changed) {
+ result |= CWSR_RESIZED;
+ if (winlist != NULL) {
+ // Add this window to the list of changed windows.
+ typval_T tv = {
+ .v_lock = VAR_UNLOCKED,
+ .v_type = VAR_NUMBER,
+ .vval.v_number = wp->handle,
+ };
+ // tv_list_set_item(winlist, listidx++, &tv);
+ tv_list_append_owned_tv(winlist, tv);
+ } else if (size_count != NULL) {
+ assert(first_size_win != NULL && first_scroll_win != NULL);
+ (*size_count)++;
+ if (*first_size_win == NULL) {
+ *first_size_win = wp;
+ }
+ // For WinScrolled the first window with a size change is used
+ // even when it didn't scroll.
+ if (*first_scroll_win == NULL) {
+ *first_scroll_win = wp;
+ }
+ }
+ }
+
+ const bool scroll_changed = wp->w_last_topline != wp->w_topline
+ || wp->w_last_leftcol != wp->w_leftcol
+ || wp->w_last_skipcol != wp->w_skipcol;
+ if (scroll_changed) {
+ result |= CWSR_SCROLLED;
+ if (first_scroll_win != NULL && *first_scroll_win == NULL) {
+ *first_scroll_win = wp;
+ }
+ }
+
+ if ((size_changed || scroll_changed) && v_event != NULL) {
+ // Add info about this window to the v:event dictionary.
+ int width = wp->w_width - wp->w_last_width;
+ int height = wp->w_height - wp->w_last_height;
+ int topline = wp->w_topline - wp->w_last_topline;
+ int leftcol = wp->w_leftcol - wp->w_last_leftcol;
+ int skipcol = wp->w_skipcol - wp->w_last_skipcol;
+ dict_T *d = make_win_info_dict(width, height,
+ topline, leftcol, skipcol);
+ if (d == NULL) {
+ break;
+ }
+ char winid[NUMBUFLEN];
+ int key_len = vim_snprintf(winid, sizeof(winid), "%d", wp->handle);
+ if (tv_dict_add_dict(v_event, winid, (size_t)key_len, d) == FAIL) {
+ tv_dict_unref(d);
+ break;
+ }
+ d->dv_refcount--;
+
+ tot_width += abs(width);
+ tot_height += abs(height);
+ tot_topline += abs(topline);
+ tot_leftcol += abs(leftcol);
+ tot_skipcol += abs(skipcol);
+ }
+ }
+
+ if (v_event != NULL) {
+ dict_T *alldict = make_win_info_dict(tot_width, tot_height,
+ tot_topline, tot_leftcol, tot_skipcol);
+ if (alldict != NULL) {
+ if (tv_dict_add_dict(v_event, S_LEN("all"), alldict) == FAIL) {
+ tv_dict_unref(alldict);
+ } else {
+ alldict->dv_refcount--;
+ }
+ }
+ }
+
+ return result;
+}
+
+/// Trigger WinScrolled and/or WinResized if any window in the current tab page
+/// scrolled or changed size.
+void may_trigger_win_scrolled_resized(void)
{
static bool recursive = false;
+ const bool do_resize = has_event(EVENT_WINRESIZED);
+ const bool do_scroll = has_event(EVENT_WINSCROLLED);
- if (recursive || !has_event(EVENT_WINSCROLLED)) {
+ if (recursive
+ || !(do_scroll || do_resize)
+ || !did_initial_scroll_size_snapshot) {
return;
}
- win_T *wp = curwin;
- if (wp->w_last_topline != wp->w_topline
- || wp->w_last_leftcol != wp->w_leftcol
- || wp->w_last_skipcol != wp->w_skipcol
- || wp->w_last_width != wp->w_width
- || wp->w_last_height != wp->w_height) {
- char winid[NUMBUFLEN];
- vim_snprintf(winid, sizeof(winid), "%d", wp->handle);
+ int size_count = 0;
+ win_T *first_scroll_win = NULL, *first_size_win = NULL;
+ int cwsr = check_window_scroll_resize(&size_count,
+ &first_scroll_win, &first_size_win,
+ NULL, NULL);
+ int trigger_resize = do_resize && size_count > 0;
+ int trigger_scroll = do_scroll && cwsr != 0;
+ if (!trigger_resize && !trigger_scroll) {
+ return; // no relevant changes
+ }
+
+ list_T *windows_list = NULL;
+ if (trigger_resize) {
+ // Create the list for v:event.windows before making the snapshot.
+ // windows_list = tv_list_alloc_with_items(size_count);
+ windows_list = tv_list_alloc(size_count);
+ (void)check_window_scroll_resize(NULL, NULL, NULL, windows_list, NULL);
+ }
+
+ dict_T *scroll_dict = NULL;
+ if (trigger_scroll) {
+ // Create the dict with entries for v:event before making the snapshot.
+ scroll_dict = tv_dict_alloc();
+ scroll_dict->dv_refcount = 1;
+ (void)check_window_scroll_resize(NULL, NULL, NULL, NULL, scroll_dict);
+ }
+
+ // WinScrolled/WinResized are triggered only once, even when multiple
+ // windows scrolled or changed size. Store the current values before
+ // triggering the event, if a scroll or resize happens as a side effect
+ // then WinScrolled/WinResized is triggered for that later.
+ snapshot_windows_scroll_size();
+
+ recursive = true;
+
+ // If both are to be triggered do WinResized first.
+ if (trigger_resize) {
+ save_v_event_T save_v_event;
+ dict_T *v_event = get_v_event(&save_v_event);
- recursive = true;
- apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, wp->w_buffer);
- recursive = false;
+ if (tv_dict_add_list(v_event, S_LEN("windows"), windows_list) == OK) {
+ tv_dict_set_keys_readonly(v_event);
- // an autocmd may close the window, "wp" may be invalid now
- if (win_valid_any_tab(wp)) {
- wp->w_last_topline = wp->w_topline;
- wp->w_last_leftcol = wp->w_leftcol;
- wp->w_last_skipcol = wp->w_skipcol;
- wp->w_last_width = wp->w_width;
- wp->w_last_height = wp->w_height;
+ char winid[NUMBUFLEN];
+ vim_snprintf(winid, sizeof(winid), "%d", first_size_win->handle);
+ apply_autocmds(EVENT_WINRESIZED, winid, winid, false, first_size_win->w_buffer);
}
+ restore_v_event(v_event, &save_v_event);
+ }
+
+ if (trigger_scroll) {
+ save_v_event_T save_v_event;
+ dict_T *v_event = get_v_event(&save_v_event);
+
+ // Move the entries from scroll_dict to v_event.
+ tv_dict_extend(v_event, scroll_dict, "move");
+ tv_dict_set_keys_readonly(v_event);
+ tv_dict_unref(scroll_dict);
+
+ char winid[NUMBUFLEN];
+ vim_snprintf(winid, sizeof(winid), "%d", first_scroll_win->handle);
+ apply_autocmds(EVENT_WINSCROLLED, winid, winid, false, first_scroll_win->w_buffer);
+
+ restore_v_event(v_event, &save_v_event);
}
+
+ recursive = false;
}
// Save the size of all windows in "gap".
diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua
index 0fbf58a8e7..3af1791e43 100644
--- a/test/functional/api/proc_spec.lua
+++ b/test/functional/api/proc_spec.lua
@@ -3,12 +3,12 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local funcs = helpers.funcs
-local iswin = helpers.iswin
local neq = helpers.neq
local nvim_argv = helpers.nvim_argv
local request = helpers.request
local retry = helpers.retry
local NIL = helpers.NIL
+local is_os = helpers.is_os
describe('API', function()
before_each(clear)
@@ -62,7 +62,7 @@ describe('API', function()
it('returns process info', function()
local pid = funcs.getpid()
local pinfo = request('nvim_get_proc', pid)
- eq((iswin() and 'nvim.exe' or 'nvim'), pinfo.name)
+ eq((is_os('win') and 'nvim.exe' or 'nvim'), pinfo.name)
eq(pid, pinfo.pid)
eq('number', type(pinfo.ppid))
neq(pid, pinfo.ppid)
diff --git a/test/functional/api/server_notifications_spec.lua b/test/functional/api/server_notifications_spec.lua
index 77a80ac7f3..833d54396b 100644
--- a/test/functional/api/server_notifications_spec.lua
+++ b/test/functional/api/server_notifications_spec.lua
@@ -5,7 +5,7 @@ local eq, clear, eval, command, nvim, next_msg =
local meths = helpers.meths
local exec_lua = helpers.exec_lua
local retry = helpers.retry
-local isCI = helpers.isCI
+local is_ci = helpers.is_ci
local assert_alive = helpers.assert_alive
local skip = helpers.skip
@@ -79,7 +79,7 @@ describe('notify', function()
end)
it('cancels stale events on channel close', function()
- skip(isCI(), 'hangs on CI #14083 #15251')
+ skip(is_ci(), 'hangs on CI #14083 #15251')
local catchan = eval("jobstart(['cat'], {'rpc': v:true})")
local catpath = eval('exepath("cat")')
eq({id=catchan, argv={catpath}, stream='job', mode='rpc', client = {}}, exec_lua ([[
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 045de94de2..ceff390dc5 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -250,7 +250,7 @@ describe('server -> client', function()
pcall(funcs.jobstop, jobid)
end)
- if helpers.skip(helpers.iswin()) then return end
+ if helpers.skip(helpers.is_os('win')) then return end
it('rpc and text stderr can be combined', function()
local status, rv = pcall(funcs.rpcrequest, jobid, 'poll')
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 9df73c8d69..3e1aab28ce 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -12,7 +12,6 @@ local exec = helpers.exec
local eval = helpers.eval
local expect = helpers.expect
local funcs = helpers.funcs
-local iswin = helpers.iswin
local meths = helpers.meths
local matches = helpers.matches
local pesc = helpers.pesc
@@ -400,7 +399,7 @@ describe('API', function()
end)
it('returns shell |:!| output', function()
- local win_lf = iswin() and '\r' or ''
+ local win_lf = is_os('win') and '\r' or ''
eq(':!echo foo\r\n\nfoo'..win_lf..'\n', nvim('command_output', [[!echo foo]]))
end)
@@ -2125,7 +2124,7 @@ describe('API', function()
pty='?',
}
local event = meths.get_var("opened_event")
- if not iswin() then
+ if not is_os('win') then
info.pty = event.info.pty
neq(nil, string.match(info.pty, "^/dev/"))
end
@@ -2141,7 +2140,7 @@ describe('API', function()
stream = 'job',
id = 4,
argv = (
- iswin() and {
+ is_os('win') and {
eval('&shell'),
'/s',
'/c',
@@ -2163,7 +2162,7 @@ describe('API', function()
-- :terminal with args + stopped process.
eq(1, eval('jobstop(&channel)'))
eval('jobwait([&channel], 1000)') -- Wait.
- expected2.pty = (iswin() and '?' or '') -- pty stream was closed.
+ expected2.pty = (is_os('win') and '?' or '') -- pty stream was closed.
eq(expected2, eval('nvim_get_chan_info(&channel)'))
end)
end)
@@ -2724,7 +2723,7 @@ describe('API', function()
eq({}, meths.get_runtime_file("foobarlang/", true))
end)
it('can handle bad patterns', function()
- skip(iswin())
+ skip(is_os('win'))
eq("Vim:E220: Missing }.", pcall_err(meths.get_runtime_file, "{", false))
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index 7c65cf9c37..48431ccfc7 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -229,6 +229,46 @@ describe('API/win', function()
|
]])
end)
+
+ it('updates cursorcolumn in non-current window', function()
+ local screen = Screen.new(60, 8)
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [2] = {background = Screen.colors.Grey90}, -- CursorColumn
+ [3] = {bold = true, reverse = true}, -- StatusLine
+ [4] = {reverse = true}, -- StatusLineNC
+ })
+ screen:attach()
+ command('set cursorcolumn')
+ insert([[
+ aaa
+ bbb
+ ccc
+ ddd]])
+ local oldwin = curwin()
+ command('vsplit')
+ screen:expect([[
+ aa{2:a} │aa{2:a} |
+ bb{2:b} │bb{2:b} |
+ cc{2:c} │cc{2:c} |
+ dd^d │ddd |
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {3:[No Name] [+] }{4:[No Name] [+] }|
+ |
+ ]])
+ window('set_cursor', oldwin, {2, 0})
+ screen:expect([[
+ aa{2:a} │{2:a}aa |
+ bb{2:b} │bbb |
+ cc{2:c} │{2:c}cc |
+ dd^d │{2:d}dd |
+ {1:~ }│{1:~ }|
+ {1:~ }│{1:~ }|
+ {3:[No Name] [+] }{4:[No Name] [+] }|
+ |
+ ]])
+ end)
end)
describe('{get,set}_height', function()
diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua
index 45dc06b39b..828cffa460 100644
--- a/test/functional/autocmd/dirchanged_spec.lua
+++ b/test/functional/autocmd/dirchanged_spec.lua
@@ -1,12 +1,12 @@
local lfs = require('lfs')
-local h = require('test.functional.helpers')(after_each)
+local helpers = require('test.functional.helpers')(after_each)
-local clear = h.clear
-local command = h.command
-local eq = h.eq
-local eval = h.eval
-local request = h.request
-local iswin = h.iswin
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local eval = helpers.eval
+local request = helpers.request
+local is_os = helpers.is_os
describe('autocmd DirChanged and DirChangedPre', function()
local curdir = string.gsub(lfs.currentdir(), '\\', '/')
@@ -21,8 +21,8 @@ describe('autocmd DirChanged and DirChangedPre', function()
curdir .. '\\XTEST-FUNCTIONAL-AUTOCMD-DIRCHANGED.DIR3',
}
- setup(function() for _, dir in pairs(dirs) do h.mkdir(dir) end end)
- teardown(function() for _, dir in pairs(dirs) do h.rmdir(dir) end end)
+ setup(function() for _, dir in pairs(dirs) do helpers.mkdir(dir) end end)
+ teardown(function() for _, dir in pairs(dirs) do helpers.rmdir(dir) end end)
before_each(function()
clear()
@@ -159,7 +159,7 @@ describe('autocmd DirChanged and DirChangedPre', function()
eq(1, eval('g:cdprecount'))
eq(1, eval('g:cdcount'))
- if iswin() then
+ if is_os('win') then
command('lcd '..win_dirs[1])
eq({}, eval('g:evpre'))
eq({}, eval('g:ev'))
@@ -182,7 +182,7 @@ describe('autocmd DirChanged and DirChangedPre', function()
eq(2, eval('g:cdprecount'))
eq(2, eval('g:cdcount'))
- if iswin() then
+ if is_os('win') then
command('tcd '..win_dirs[2])
eq({}, eval('g:evpre'))
eq({}, eval('g:ev'))
@@ -204,7 +204,7 @@ describe('autocmd DirChanged and DirChangedPre', function()
eq(3, eval('g:cdprecount'))
eq(3, eval('g:cdcount'))
- if iswin() then
+ if is_os('win') then
command('cd '..win_dirs[3])
eq({}, eval('g:evpre'))
eq({}, eval('g:ev'))
@@ -229,7 +229,7 @@ describe('autocmd DirChanged and DirChangedPre', function()
eq(4, eval('g:cdprecount'))
eq(4, eval('g:cdcount'))
- if iswin() then
+ if is_os('win') then
command('split '..win_dirs[1]..'/baz')
eq({}, eval('g:evpre'))
eq({}, eval('g:ev'))
@@ -278,7 +278,7 @@ describe('autocmd DirChanged and DirChangedPre', function()
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
- if iswin() then
+ if is_os('win') then
command('tabnew') -- tab 3
eq(9, eval('g:cdprecount')) -- same CWD, no DirChangedPre event
eq(9, eval('g:cdcount')) -- same CWD, no DirChanged event
diff --git a/test/functional/autocmd/focus_spec.lua b/test/functional/autocmd/focus_spec.lua
index b5fc6b7600..024dccbe8e 100644
--- a/test/functional/autocmd/focus_spec.lua
+++ b/test/functional/autocmd/focus_spec.lua
@@ -6,7 +6,7 @@ local nvim_prog = helpers.nvim_prog
local feed_command = helpers.feed_command
local feed_data = thelpers.feed_data
-if helpers.skip(helpers.iswin()) then return end
+if helpers.skip(helpers.is_os('win')) then return end
describe('autoread TUI FocusGained/FocusLost', function()
local f1 = 'xtest-foo'
diff --git a/test/functional/autocmd/signal_spec.lua b/test/functional/autocmd/signal_spec.lua
index bbe1c186b2..738064090a 100644
--- a/test/functional/autocmd/signal_spec.lua
+++ b/test/functional/autocmd/signal_spec.lua
@@ -5,10 +5,10 @@ local command = helpers.command
local eq = helpers.eq
local funcs = helpers.funcs
local next_msg = helpers.next_msg
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
-if skip(iswin(), 'Only applies to POSIX systems') then return end
+if skip(is_os('win'), 'Only applies to POSIX systems') then return end
local function posix_kill(signame, pid)
os.execute('kill -s '..signame..' -- '..pid..' >/dev/null')
diff --git a/test/functional/autocmd/termxx_spec.lua b/test/functional/autocmd/termxx_spec.lua
index 5601965bd9..4717b1fa2e 100644
--- a/test/functional/autocmd/termxx_spec.lua
+++ b/test/functional/autocmd/termxx_spec.lua
@@ -10,8 +10,8 @@ local ok = helpers.ok
local feed = helpers.feed
local pcall_err = helpers.pcall_err
local assert_alive = helpers.assert_alive
-local iswin = helpers.iswin
local skip = helpers.skip
+local is_os = helpers.is_os
describe('autocmd TermClose', function()
before_each(function()
@@ -48,7 +48,7 @@ describe('autocmd TermClose', function()
end)
it('triggers when long-running terminal job gets stopped', function()
- nvim('set_option', 'shell', iswin() and 'cmd.exe' or 'sh')
+ nvim('set_option', 'shell', is_os('win') and 'cmd.exe' or 'sh')
command('autocmd TermClose * let g:test_termclose = 23')
command('terminal')
command('call jobstop(b:terminal_job_id)')
@@ -56,7 +56,7 @@ describe('autocmd TermClose', function()
end)
it('kills job trapping SIGTERM', function()
- skip(iswin())
+ skip(is_os('win'))
nvim('set_option', 'shell', 'sh')
nvim('set_option', 'shellcmdflag', '-c')
command([[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]]
@@ -76,7 +76,7 @@ describe('autocmd TermClose', function()
end)
it('kills PTY job trapping SIGHUP and SIGTERM', function()
- skip(iswin())
+ skip(is_os('win'))
nvim('set_option', 'shell', 'sh')
nvim('set_option', 'shellcmdflag', '-c')
command([[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]]
diff --git a/test/functional/autocmd/win_scrolled_resized_spec.lua b/test/functional/autocmd/win_scrolled_resized_spec.lua
new file mode 100644
index 0000000000..bebb21bc31
--- /dev/null
+++ b/test/functional/autocmd/win_scrolled_resized_spec.lua
@@ -0,0 +1,285 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local exec = helpers.exec
+local command = helpers.command
+local feed = helpers.feed
+local meths = helpers.meths
+local assert_alive = helpers.assert_alive
+
+before_each(clear)
+
+describe('WinResized', function()
+ -- oldtest: Test_WinResized()
+ it('works', function()
+ exec([[
+ set scrolloff=0
+ call setline(1, ['111', '222'])
+ vnew
+ call setline(1, ['aaa', 'bbb'])
+ new
+ call setline(1, ['foo', 'bar'])
+
+ let g:resized = 0
+ au WinResized * let g:resized += 1
+ au WinResized * let g:v_event = deepcopy(v:event)
+ ]])
+ eq(0, eval('g:resized'))
+
+ -- increase window height, two windows will be reported
+ feed('<C-W>+')
+ eq(1, eval('g:resized'))
+ eq({windows = {1002, 1001}}, eval('g:v_event'))
+
+ -- increase window width, three windows will be reported
+ feed('<C-W>>')
+ eq(2, eval('g:resized'))
+ eq({windows = {1002, 1001, 1000}}, eval('g:v_event'))
+ end)
+end)
+
+describe('WinScrolled', function()
+ local win_id
+
+ before_each(function()
+ win_id = meths.get_current_win().id
+ command(string.format('autocmd WinScrolled %d let g:matched = v:true', win_id))
+ exec([[
+ let g:scrolled = 0
+ au WinScrolled * let g:scrolled += 1
+ au WinScrolled * let g:amatch = str2nr(expand('<amatch>'))
+ au WinScrolled * let g:afile = str2nr(expand('<afile>'))
+ au WinScrolled * let g:v_event = deepcopy(v:event)
+ ]])
+ end)
+
+ after_each(function()
+ eq(true, eval('g:matched'))
+ eq(win_id, eval('g:amatch'))
+ eq(win_id, eval('g:afile'))
+ end)
+
+ it('is triggered by scrolling vertically', function()
+ local lines = {'123', '123'}
+ meths.buf_set_lines(0, 0, -1, true, lines)
+ eq(0, eval('g:scrolled'))
+
+ feed('<C-E>')
+ eq(1, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('<C-Y>')
+ eq(2, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 0, topline = -1, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+ end)
+
+ it('is triggered by scrolling horizontally', function()
+ command('set nowrap')
+ local width = meths.win_get_width(0)
+ local line = '123' .. ('*'):rep(width * 2)
+ local lines = {line, line}
+ meths.buf_set_lines(0, 0, -1, true, lines)
+ eq(0, eval('g:scrolled'))
+
+ feed('zl')
+ eq(1, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('zh')
+ eq(2, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = -1, topline = 0, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+ end)
+
+ it('is triggered by horizontal scrolling from cursor move', function()
+ command('set nowrap')
+ local lines = {'', '', 'Foo'}
+ meths.buf_set_lines(0, 0, -1, true, lines)
+ meths.win_set_cursor(0, {3, 0})
+ eq(0, eval('g:scrolled'))
+
+ feed('zl')
+ eq(1, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('zl')
+ eq(2, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('h')
+ eq(3, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = -1, topline = 0, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('zh')
+ eq(4, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 1, topline = 0, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = -1, topline = 0, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+ end)
+
+ -- oldtest: Test_WinScrolled_long_wrapped()
+ it('is triggered by scrolling on a long wrapped line #19968', function()
+ local height = meths.win_get_height(0)
+ local width = meths.win_get_width(0)
+ meths.buf_set_lines(0, 0, -1, true, {('foo'):rep(height * width)})
+ meths.win_set_cursor(0, {1, height * width - 1})
+ eq(0, eval('g:scrolled'))
+
+ feed('gj')
+ eq(1, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 0, width = 0, height = 0, skipcol = width},
+ ['1000'] = {leftcol = 0, topline = 0, width = 0, height = 0, skipcol = width},
+ }, eval('g:v_event'))
+
+ feed('0')
+ eq(2, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 0, width = 0, height = 0, skipcol = width},
+ ['1000'] = {leftcol = 0, topline = 0, width = 0, height = 0, skipcol = -width},
+ }, eval('g:v_event'))
+
+ feed('$')
+ eq(3, eval('g:scrolled'))
+ end)
+
+ it('is triggered when the window scrolls in Insert mode', function()
+ local height = meths.win_get_height(0)
+ local lines = {}
+ for i = 1, height * 2 do
+ lines[i] = tostring(i)
+ end
+ meths.buf_set_lines(0, 0, -1, true, lines)
+
+ feed('M')
+ eq(0, eval('g:scrolled'))
+
+ feed('i<C-X><C-E><Esc>')
+ eq(1, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('i<C-X><C-Y><Esc>')
+ eq(2, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 0, topline = -1, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ feed('L')
+ eq(2, eval('g:scrolled'))
+
+ feed('A<CR><Esc>')
+ eq(3, eval('g:scrolled'))
+ eq({
+ all = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ ['1000'] = {leftcol = 0, topline = 1, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+ end)
+end)
+
+describe('WinScrolled', function()
+ -- oldtest: Test_WinScrolled_mouse()
+ it('is triggered by mouse scrolling in another window', function()
+ local screen = Screen.new(75, 10)
+ screen:attach()
+ exec([[
+ set nowrap scrolloff=0
+ set mouse=a
+ call setline(1, ['foo']->repeat(32))
+ split
+ let g:scrolled = 0
+ au WinScrolled * let g:scrolled += 1
+ ]])
+ eq(0, eval('g:scrolled'))
+
+ -- With the upper split focused, send a scroll-down event to the unfocused one.
+ meths.input_mouse('wheel', 'down', '', 0, 6, 0)
+ eq(1, eval('g:scrolled'))
+
+ -- Again, but this time while we're in insert mode.
+ feed('i')
+ meths.input_mouse('wheel', 'down', '', 0, 6, 0)
+ feed('<Esc>')
+ eq(2, eval('g:scrolled'))
+ end)
+
+ -- oldtest: Test_WinScrolled_close_curwin()
+ it('closing window does not cause use-after-free #13265', function()
+ exec([[
+ set nowrap scrolloff=0
+ call setline(1, ['aaa', 'bbb'])
+ vsplit
+ au WinScrolled * close
+ ]])
+
+ -- This was using freed memory
+ feed('<C-E>')
+ assert_alive()
+ end)
+
+ it('is triggered by mouse scrolling in unfocused floating window #18222', function()
+ local screen = Screen.new(80, 24)
+ screen:attach()
+ local buf = meths.create_buf(true, true)
+ meths.buf_set_lines(buf, 0, -1, false, {'a', 'b', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'})
+ local win = meths.open_win(buf, false, {
+ height = 5,
+ width = 10,
+ col = 0,
+ row = 1,
+ relative = 'editor',
+ style = 'minimal'
+ })
+ local winid_str = tostring(win.id)
+ exec([[
+ let g:scrolled = 0
+ autocmd WinScrolled * let g:scrolled += 1
+ autocmd WinScrolled * let g:amatch = expand('<amatch>')
+ autocmd WinScrolled * let g:v_event = deepcopy(v:event)
+ ]])
+ eq(0, eval('g:scrolled'))
+
+ meths.input_mouse('wheel', 'down', '', 0, 3, 3)
+ eq(1, eval('g:scrolled'))
+ eq(winid_str, eval('g:amatch'))
+ eq({
+ all = {leftcol = 0, topline = 3, width = 0, height = 0, skipcol = 0},
+ [winid_str] = {leftcol = 0, topline = 3, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+
+ meths.input_mouse('wheel', 'up', '', 0, 3, 3)
+ eq(2, eval('g:scrolled'))
+ eq(tostring(win.id), eval('g:amatch'))
+ eq({
+ all = {leftcol = 0, topline = 3, width = 0, height = 0, skipcol = 0},
+ [winid_str] = {leftcol = 0, topline = -3, width = 0, height = 0, skipcol = 0},
+ }, eval('g:v_event'))
+ end)
+end)
diff --git a/test/functional/autocmd/winscrolled_spec.lua b/test/functional/autocmd/winscrolled_spec.lua
deleted file mode 100644
index 12b8e7c42d..0000000000
--- a/test/functional/autocmd/winscrolled_spec.lua
+++ /dev/null
@@ -1,99 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local eq = helpers.eq
-local eval = helpers.eval
-local command = helpers.command
-local feed = helpers.feed
-local meths = helpers.meths
-local assert_alive = helpers.assert_alive
-
-before_each(clear)
-
-describe('WinScrolled', function()
- local win_id
-
- before_each(function()
- win_id = meths.get_current_win().id
- command(string.format('autocmd WinScrolled %d let g:matched = v:true', win_id))
- command('let g:scrolled = 0')
- command('autocmd WinScrolled * let g:scrolled += 1')
- command([[autocmd WinScrolled * let g:amatch = str2nr(expand('<amatch>'))]])
- command([[autocmd WinScrolled * let g:afile = str2nr(expand('<afile>'))]])
- end)
-
- after_each(function()
- eq(true, eval('g:matched'))
- eq(win_id, eval('g:amatch'))
- eq(win_id, eval('g:afile'))
- end)
-
- it('is triggered by scrolling vertically', function()
- local lines = {'123', '123'}
- meths.buf_set_lines(0, 0, -1, true, lines)
- eq(0, eval('g:scrolled'))
- feed('<C-E>')
- eq(1, eval('g:scrolled'))
- end)
-
- it('is triggered by scrolling horizontally', function()
- command('set nowrap')
- local width = meths.win_get_width(0)
- local line = '123' .. ('*'):rep(width * 2)
- local lines = {line, line}
- meths.buf_set_lines(0, 0, -1, true, lines)
- eq(0, eval('g:scrolled'))
- feed('zl')
- eq(1, eval('g:scrolled'))
- end)
-
- it('is triggered by horizontal scrolling from cursor move', function()
- command('set nowrap')
- local lines = {'', '', 'Foo'}
- meths.buf_set_lines(0, 0, -1, true, lines)
- meths.win_set_cursor(0, {3, 0})
- eq(0, eval('g:scrolled'))
- feed('zl')
- eq(1, eval('g:scrolled'))
- feed('zl')
- eq(2, eval('g:scrolled'))
- feed('h')
- eq(3, eval('g:scrolled'))
- end)
-
- it('is triggered by scrolling on a long wrapped line #19968', function()
- local height = meths.win_get_height(0)
- local width = meths.win_get_width(0)
- meths.buf_set_lines(0, 0, -1, true, {('foo'):rep(height * width)})
- meths.win_set_cursor(0, {1, height * width - 1})
- eq(0, eval('g:scrolled'))
- feed('gj')
- eq(1, eval('g:scrolled'))
- feed('0')
- eq(2, eval('g:scrolled'))
- feed('$')
- eq(3, eval('g:scrolled'))
- end)
-
- it('is triggered when the window scrolls in Insert mode', function()
- local height = meths.win_get_height(0)
- local lines = {}
- for i = 1, height * 2 do
- lines[i] = tostring(i)
- end
- meths.buf_set_lines(0, 0, -1, true, lines)
- feed('L')
- eq(0, eval('g:scrolled'))
- feed('A<CR><Esc>')
- eq(1, eval('g:scrolled'))
- end)
-end)
-
-it('closing window in WinScrolled does not cause use-after-free #13265', function()
- local lines = {'aaa', 'bbb'}
- meths.buf_set_lines(0, 0, -1, true, lines)
- command('vsplit')
- command('autocmd WinScrolled * close')
- feed('<C-E>')
- assert_alive()
-end)
diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua
index 63bd85ff43..8275575c24 100644
--- a/test/functional/core/channels_spec.lua
+++ b/test/functional/core/channels_spec.lua
@@ -1,5 +1,4 @@
local helpers = require('test.functional.helpers')(after_each)
-local uname = helpers.uname
local clear, eq, eval, next_msg, ok, source = helpers.clear, helpers.eq,
helpers.eval, helpers.next_msg, helpers.ok, helpers.source
local command, funcs, meths = helpers.command, helpers.funcs, helpers.meths
@@ -12,7 +11,6 @@ local retry = helpers.retry
local expect_twostreams = helpers.expect_twostreams
local assert_alive = helpers.assert_alive
local pcall_err = helpers.pcall_err
-local iswin = helpers.iswin
local skip = helpers.skip
describe('channels', function()
@@ -147,7 +145,7 @@ describe('channels', function()
end
it('can use stdio channel with pty', function()
- skip(iswin())
+ skip(is_os('win'))
source([[
let g:job_opts = {
\ 'on_stdout': function('OnEvent'),
@@ -180,8 +178,7 @@ describe('channels', function()
command("call chansend(id, 'incomplet\004')")
- local is_bsd = not not string.find(uname(), 'bsd')
- local bsdlike = is_bsd or is_os('mac')
+ local bsdlike = is_os('bsd') or is_os('mac')
local extra = bsdlike and "^D\008\008" or ""
expect_twoline(id, "stdout",
"incomplet"..extra, "[1, ['incomplet'], 'stdin']", true)
@@ -201,7 +198,7 @@ describe('channels', function()
it('stdio channel can use rpc and stderr simultaneously', function()
- skip(iswin())
+ skip(is_os('win'))
source([[
let g:job_opts = {
\ 'on_stderr': function('OnEvent'),
diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua
index 00b9074e29..51189b7c32 100644
--- a/test/functional/core/fileio_spec.lua
+++ b/test/functional/core/fileio_spec.lua
@@ -21,14 +21,14 @@ local read_file = helpers.read_file
local tmpname = helpers.tmpname
local trim = helpers.trim
local currentdir = helpers.funcs.getcwd
-local iswin = helpers.iswin
local assert_alive = helpers.assert_alive
local expect_exit = helpers.expect_exit
local write_file = helpers.write_file
local Screen = require('test.functional.ui.screen')
local feed_command = helpers.feed_command
-local isCI = helpers.isCI
local skip = helpers.skip
+local is_os = helpers.is_os
+local is_ci = helpers.is_ci
describe('fileio', function()
before_each(function()
@@ -90,7 +90,7 @@ describe('fileio', function()
end)
it('backup #9709', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
clear({ args={ '-i', 'Xtest_startup_shada',
'--cmd', 'set directory=Xtest_startup_swapdir' } })
@@ -110,7 +110,7 @@ describe('fileio', function()
end)
it('backup with full path #11214', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
clear()
mkdir('Xtest_backupdir')
command('set backup')
@@ -123,7 +123,7 @@ describe('fileio', function()
-- Backup filename = fullpath, separators replaced with "%".
local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1',
- iswin() and '[:/\\]' or '/', '%%') .. '~'
+ is_os('win') and '[:/\\]' or '/', '%%') .. '~'
local foo_contents = trim(read_file('Xtest_backupdir/'..backup_file_name))
local foobar_contents = trim(read_file('Xtest_startup_file1'))
@@ -132,7 +132,7 @@ describe('fileio', function()
end)
it('backup symlinked files #11349', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
clear()
local initial_content = 'foo'
@@ -154,7 +154,7 @@ describe('fileio', function()
it('backup symlinked files in first avialable backupdir #11349', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
clear()
local initial_content = 'foo'
@@ -299,7 +299,7 @@ describe('tmpdir', function()
end)
-- "…/nvim.<user>/" has wrong permissions:
- skip(iswin(), 'TODO(justinmk): need setfperm/getfperm on Windows. #8244')
+ skip(is_os('win'), 'TODO(justinmk): need setfperm/getfperm on Windows. #8244')
os.remove(testlog)
os.remove(tmproot)
mkdir(tmproot)
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 4e5c4ca351..1bae626b98 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -13,7 +13,6 @@ local retry = helpers.retry
local meths = helpers.meths
local NIL = helpers.NIL
local poke_eventloop = helpers.poke_eventloop
-local iswin = helpers.iswin
local get_pathsep = helpers.get_pathsep
local pathroot = helpers.pathroot
local exec_lua = helpers.exec_lua
@@ -24,6 +23,7 @@ local pcall_err = helpers.pcall_err
local matches = helpers.matches
local Screen = require('test.functional.ui.screen')
local skip = helpers.skip
+local is_os = helpers.is_os
describe('jobs', function()
local channel
@@ -56,7 +56,7 @@ describe('jobs', function()
it('must specify env option as a dict', function()
command("let g:job_opts.env = v:true")
local _, err = pcall(function()
- if iswin() then
+ if is_os('win') then
nvim('command', "let j = jobstart('set', g:job_opts)")
else
nvim('command', "let j = jobstart('env', g:job_opts)")
@@ -69,7 +69,7 @@ describe('jobs', function()
nvim('command', "let $VAR = 'abc'")
nvim('command', "let $TOTO = 'goodbye world'")
nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}")
- if iswin() then
+ if is_os('win') then
nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
else
nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]])
@@ -88,12 +88,12 @@ describe('jobs', function()
end)
it('append environment with pty #env', function()
- skip(iswin())
+ skip(is_os('win'))
nvim('command', "let $VAR = 'abc'")
nvim('command', "let $TOTO = 'goodbye world'")
nvim('command', "let g:job_opts.pty = v:true")
nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}")
- if iswin() then
+ if is_os('win') then
nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
else
nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]])
@@ -123,7 +123,7 @@ describe('jobs', function()
--
-- Rather than expecting a completely empty environment, ensure that $VAR
-- is *not* in the environment but $TOTO is.
- if iswin() then
+ if is_os('win') then
nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
expect_msg_seq({
{'notification', 'stdout', {0, {'hello world %VAR%', ''}}}
@@ -142,7 +142,7 @@ describe('jobs', function()
-- Since $Toto is being set in the job, it should take precedence over the
-- global $TOTO on Windows
nvim('command', "let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}")
- if iswin() then
+ if is_os('win') then
nvim('command', [[let j = jobstart('set | find /I "toto="', g:job_opts)]])
else
nvim('command', [[let j = jobstart('env | grep -i toto=', g:job_opts)]])
@@ -151,7 +151,7 @@ describe('jobs', function()
nvim('command', "let g:output = Normalize(g:job_opts.stdout)")
local actual = eval('g:output')
local expected
- if iswin() then
+ if is_os('win') then
-- Toto is normalized to TOTO so we can detect duplicates, and because
-- Windows doesn't care about case
expected = {'TOTO=def', ''}
@@ -165,7 +165,7 @@ describe('jobs', function()
it('uses &shell and &shellcmdflag if passed a string', function()
nvim('command', "let $VAR = 'abc'")
- if iswin() then
+ if is_os('win') then
nvim('command', "let j = jobstart('echo %VAR%', g:job_opts)")
else
nvim('command', "let j = jobstart('echo $VAR', g:job_opts)")
@@ -177,7 +177,7 @@ describe('jobs', function()
it('changes to given / directory', function()
nvim('command', "let g:job_opts.cwd = '/'")
- if iswin() then
+ if is_os('win') then
nvim('command', "let j = jobstart('cd', g:job_opts)")
else
nvim('command', "let j = jobstart('pwd', g:job_opts)")
@@ -192,7 +192,7 @@ describe('jobs', function()
local dir = eval("resolve(tempname())"):gsub("/", get_pathsep())
mkdir(dir)
nvim('command', "let g:job_opts.cwd = '" .. dir .. "'")
- if iswin() then
+ if is_os('win') then
nvim('command', "let j = jobstart('cd', g:job_opts)")
else
nvim('command', "let j = jobstart('pwd', g:job_opts)")
@@ -216,7 +216,7 @@ describe('jobs', function()
local dir = eval('resolve(tempname())."-bogus"')
local _, err = pcall(function()
nvim('command', "let g:job_opts.cwd = '" .. dir .. "'")
- if iswin() then
+ if is_os('win') then
nvim('command', "let j = jobstart('cd', g:job_opts)")
else
nvim('command', "let j = jobstart('pwd', g:job_opts)")
@@ -226,7 +226,7 @@ describe('jobs', function()
end)
it('error on non-executable `cwd`', function()
- skip(iswin(), 'Not applicable for Windows')
+ skip(is_os('win'), 'Not applicable for Windows')
local dir = 'Xtest_not_executable_dir'
mkdir(dir)
@@ -249,7 +249,7 @@ describe('jobs', function()
end
local executable_jobid = new_job()
- local exe = iswin() and './test/functional/fixtures' or './test/functional/fixtures/non_executable.txt'
+ local exe = is_os('win') and './test/functional/fixtures' or './test/functional/fixtures/non_executable.txt'
eq("Vim:E475: Invalid value for argument cmd: '"..exe.."' is not executable",
pcall_err(eval, "jobstart(['"..exe.."'])"))
eq("", eval("v:errmsg"))
@@ -703,7 +703,7 @@ describe('jobs', function()
describe('jobwait', function()
before_each(function()
- if iswin() then
+ if is_os('win') then
helpers.set_shell_powershell()
end
end)
@@ -787,7 +787,7 @@ describe('jobs', function()
feed_command('call rpcnotify(g:channel, "ready") | '..
'call rpcnotify(g:channel, "wait", '..
'jobwait([jobstart("'..
- (iswin() and 'Start-Sleep 10' or 'sleep 10')..
+ (is_os('win') and 'Start-Sleep 10' or 'sleep 10')..
'; exit 55")]))')
eq({'notification', 'ready', {}}, next_msg())
feed('<c-c>')
@@ -798,7 +798,7 @@ describe('jobs', function()
feed_command('call rpcnotify(g:channel, "ready") | '..
'call rpcnotify(g:channel, "wait", '..
'jobwait([jobstart("'..
- (iswin() and 'Start-Sleep 10' or 'sleep 10')..
+ (is_os('win') and 'Start-Sleep 10' or 'sleep 10')..
'; exit 55")], 10000))')
eq({'notification', 'ready', {}}, next_msg())
feed('<c-c>')
@@ -806,7 +806,7 @@ describe('jobs', function()
end)
it('can be called recursively', function()
- skip(iswin(), "TODO: Need `cat`")
+ skip(is_os('win'), "TODO: Need `cat`")
source([[
let g:opts = {}
let g:counter = 0
@@ -931,7 +931,7 @@ describe('jobs', function()
-- ..c.."', '-c', '"..c.."'])")
-- Create child with several descendants.
- if iswin() then
+ if is_os('win') then
source([[
function! s:formatprocs(pid, prefix)
let result = ''
@@ -980,13 +980,13 @@ describe('jobs', function()
endfunction
]])
end
- local sleep_cmd = (iswin()
+ local sleep_cmd = (is_os('win')
and 'ping -n 31 127.0.0.1'
or 'sleep 30')
local j = eval("jobstart('"..sleep_cmd..' | '..sleep_cmd..' | '..sleep_cmd.."')")
local ppid = funcs.jobpid(j)
local children
- if iswin() then
+ if is_os('win') then
local status, result = pcall(retry, nil, nil, function()
children = meths.get_proc_children(ppid)
-- On Windows conhost.exe may exist, and
@@ -1007,7 +1007,7 @@ describe('jobs', function()
-- Assert that nvim_get_proc() sees the children.
for _, child_pid in ipairs(children) do
local info = meths.get_proc(child_pid)
- -- eq((iswin() and 'nvim.exe' or 'nvim'), info.name)
+ -- eq((is_os('win') and 'nvim.exe' or 'nvim'), info.name)
eq(ppid, info.ppid)
end
-- Kill the root of the tree.
@@ -1028,7 +1028,7 @@ describe('jobs', function()
end)
describe('running tty-test program', function()
- if skip(iswin()) then return end
+ if skip(is_os('win')) then return end
local function next_chunk()
local rv
while true do
@@ -1125,7 +1125,7 @@ describe("pty process teardown", function()
end)
it("does not prevent/delay exit. #4798 #4900", function()
- skip(iswin())
+ skip(is_os('win'))
-- Use a nested nvim (in :term) to test without --headless.
feed_command(":terminal '"..helpers.nvim_prog
.."' -u NONE -i NONE --cmd '"..nvim_set.."' "
diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua
index 782a03bfed..53461f505a 100644
--- a/test/functional/core/main_spec.lua
+++ b/test/functional/core/main_spec.lua
@@ -9,7 +9,7 @@ local clear = helpers.clear
local funcs = helpers.funcs
local nvim_prog_abs = helpers.nvim_prog_abs
local write_file = helpers.write_file
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
describe('Command-line option', function()
@@ -51,7 +51,7 @@ describe('Command-line option', function()
eq(#('100500\n'), attrs.size)
end)
it('does not crash after reading from stdin in non-headless mode', function()
- skip(iswin())
+ skip(is_os('win'))
local screen = Screen.new(40, 8)
screen:attach()
local args = {
diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua
index 61fae7622c..a786887bbd 100644
--- a/test/functional/core/path_spec.lua
+++ b/test/functional/core/path_spec.lua
@@ -3,16 +3,16 @@ local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
local command = helpers.command
-local iswin = helpers.iswin
local insert = helpers.insert
local feed = helpers.feed
+local is_os = helpers.is_os
describe('path collapse', function()
local targetdir
local expected_path
local function join_path(...)
- local pathsep = (iswin() and '\\' or '/')
+ local pathsep = (is_os('win') and '\\' or '/')
return table.concat({...}, pathsep)
end
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 2084d365a5..bab339e253 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -20,11 +20,11 @@ local read_file = helpers.read_file
local retry = helpers.retry
local rmdir = helpers.rmdir
local sleep = helpers.sleep
-local iswin = helpers.iswin
local startswith = helpers.startswith
local write_file = helpers.write_file
local meths = helpers.meths
local alter_slashes = helpers.alter_slashes
+local is_os = helpers.is_os
local testfile = 'Xtest_startuptime'
after_each(function()
@@ -79,7 +79,7 @@ describe('startup', function()
it('in a TTY: has("ttyin")==1 has("ttyout")==1', function()
local screen = Screen.new(25, 4)
screen:attach()
- if iswin() then
+ if is_os('win') then
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
@@ -95,7 +95,7 @@ describe('startup', function()
]])
end)
it('output to pipe: has("ttyin")==1 has("ttyout")==0', function()
- if iswin() then
+ if is_os('win') then
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
@@ -111,7 +111,7 @@ describe('startup', function()
end)
end)
it('input from pipe: has("ttyin")==0 has("ttyout")==1', function()
- if iswin() then
+ if is_os('win') then
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
@@ -130,7 +130,7 @@ describe('startup', function()
it('input from pipe (implicit) #7679', function()
local screen = Screen.new(25, 4)
screen:attach()
- if iswin() then
+ if is_os('win') then
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
@@ -665,7 +665,7 @@ describe('runtime:', function()
end)
it('loads plugin/*.lua from site packages', function()
- local nvimdata = iswin() and "nvim-data" or "nvim"
+ local nvimdata = is_os('win') and "nvim-data" or "nvim"
local plugin_path = table.concat({xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb'}, pathsep)
local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep)
local plugin_after_path = table.concat({plugin_path, 'after', 'plugin'}, pathsep)
diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua
index d2135d0613..5ed71651c7 100644
--- a/test/functional/ex_cmds/cd_spec.lua
+++ b/test/functional/ex_cmds/cd_spec.lua
@@ -9,8 +9,8 @@ local clear = helpers.clear
local command = helpers.command
local exc_exec = helpers.exc_exec
local pathsep = helpers.get_pathsep()
-local iswin = helpers.iswin
local skip = helpers.skip
+local is_os = helpers.is_os
-- These directories will be created for testing
local directories = {
@@ -281,7 +281,7 @@ describe("getcwd()", function ()
end)
it("returns empty string if working directory does not exist", function()
- skip(iswin())
+ skip(is_os('win'))
command("cd "..directories.global)
command("call delete('../"..directories.global.."', 'd')")
eq("", helpers.eval("getcwd()"))
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index b7ff6a7bf7..0a0c7ca410 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -5,7 +5,6 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
local get_pathsep = helpers.get_pathsep
-local iswin = helpers.iswin
local eq = helpers.eq
local neq = helpers.neq
local funcs = helpers.funcs
@@ -15,6 +14,7 @@ local rmdir = helpers.rmdir
local sleep = helpers.sleep
local meths = helpers.meths
local skip = helpers.skip
+local is_os = helpers.is_os
local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec'
@@ -178,7 +178,7 @@ describe(':mksession', function()
command('cd ' .. cwd_dir)
command('mksession ' .. session_path)
command('%bwipeout!')
- if iswin() then
+ if is_os('win') then
sleep(100) -- Make sure all child processes have exited.
end
@@ -189,13 +189,13 @@ describe(':mksession', function()
local expected_cwd = cwd_dir .. '/' .. tab_dir
matches('^term://' .. pesc(expected_cwd) .. '//%d+:', funcs.expand('%'))
command('%bwipeout!')
- if iswin() then
+ if is_os('win') then
sleep(100) -- Make sure all child processes have exited.
end
end)
it('restores CWD for :terminal buffer at root directory #16988', function()
- skip(iswin(), 'N/A for Windows')
+ skip(is_os('win'), 'N/A for Windows')
local screen
local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua
index 10ebefd8cd..64c3464be7 100644
--- a/test/functional/ex_cmds/source_spec.lua
+++ b/test/functional/ex_cmds/source_spec.lua
@@ -14,9 +14,9 @@ local eval = helpers.eval
local exec_capture = helpers.exec_capture
local neq = helpers.neq
local matches = helpers.matches
-local iswin = helpers.iswin
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
+local is_os = helpers.is_os
describe(':source', function()
before_each(function()
@@ -44,7 +44,7 @@ describe(':source', function()
end)
it("changing 'shellslash' changes the result of expand()", function()
- if not iswin() then
+ if not is_os('win') then
pending("'shellslash' only works on Windows")
return
end
diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
index 69404039ff..8eed00c973 100644
--- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
+++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua
@@ -1,12 +1,14 @@
local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')(after_each)
local lfs = require('lfs')
+local luv = require('luv')
local eq, eval, expect, exec =
helpers.eq, helpers.eval, helpers.expect, helpers.exec
local assert_alive = helpers.assert_alive
local clear = helpers.clear
local command = helpers.command
local feed = helpers.feed
+local funcs = helpers.funcs
local nvim_prog = helpers.nvim_prog
local ok = helpers.ok
local rmdir = helpers.rmdir
@@ -100,7 +102,7 @@ describe('swapfile detection', function()
-- attempt to create a swapfile in different directory.
local init = [[
set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[//
- set swapfile fileformat=unix undolevels=-1 hidden
+ set swapfile fileformat=unix nomodified undolevels=-1 nohidden
]]
before_each(function()
nvim0 = spawn(new_argv())
@@ -263,4 +265,79 @@ describe('swapfile detection', function()
]])
nvim2:close()
end)
+
+ -- oldtest: Test_nocatch_process_still_running()
+ it('allows deleting swapfile created before boot vim-patch:8.2.2586', function()
+ local screen = Screen.new(75, 30)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg
+ [2] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
+ })
+ screen:attach()
+
+ exec(init)
+ command('set nohidden')
+
+ exec([=[
+ " Make a copy of the current swap file to "Xswap".
+ " Return the name of the swap file.
+ func CopySwapfile()
+ preserve
+ " get the name of the swap file
+ let swname = split(execute("swapname"))[0]
+ let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '')
+ " make a copy of the swap file in Xswap
+ set binary
+ exe 'sp ' . fnameescape(swname)
+ w! Xswap
+ set nobinary
+ return swname
+ endfunc
+ ]=])
+
+ -- Edit a file and grab its swapfile.
+ exec([[
+ edit Xswaptest
+ call setline(1, ['a', 'b', 'c'])
+ ]])
+ local swname = funcs.CopySwapfile()
+
+ -- Forget we edited this file
+ exec([[
+ new
+ only!
+ bwipe! Xswaptest
+ ]])
+
+ os.rename('Xswap', swname)
+
+ feed(':edit Xswaptest<CR>')
+ screen:expect({any = table.concat({
+ pesc('{2:E325: ATTENTION}'),
+ 'file name: .*Xswaptest',
+ 'process ID: %d* %(STILL RUNNING%)',
+ pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'),
+ }, '.*')})
+
+ feed('e')
+
+ -- Forget we edited this file
+ exec([[
+ new
+ only!
+ bwipe! Xswaptest
+ ]])
+
+ -- pretend that the swapfile was created before boot
+ lfs.touch(swname, os.time() - luv.uptime() - 10)
+
+ feed(':edit Xswaptest<CR>')
+ screen:expect({any = table.concat({
+ pesc('{2:E325: ATTENTION}'),
+ pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort: }^'),
+ }, '.*')})
+
+ feed('e')
+ end)
end)
diff --git a/test/functional/ex_cmds/write_spec.lua b/test/functional/ex_cmds/write_spec.lua
index e2a6b6460d..1ccd27875e 100644
--- a/test/functional/ex_cmds/write_spec.lua
+++ b/test/functional/ex_cmds/write_spec.lua
@@ -8,9 +8,9 @@ local command = helpers.command
local feed_command = helpers.feed_command
local funcs = helpers.funcs
local meths = helpers.meths
-local iswin = helpers.iswin
-local isCI = helpers.isCI
local skip = helpers.skip
+local is_os = helpers.is_os
+local is_ci = helpers.is_ci
local fname = 'Xtest-functional-ex_cmds-write'
local fname_bak = fname .. '~'
@@ -39,7 +39,7 @@ describe(':write', function()
it('&backupcopy=auto preserves symlinks', function()
command('set backupcopy=auto')
write_file('test_bkc_file.txt', 'content0')
- if iswin() then
+ if is_os('win') then
command("silent !mklink test_bkc_link.txt test_bkc_file.txt")
else
command("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
@@ -57,10 +57,10 @@ describe(':write', function()
end)
it('&backupcopy=no replaces symlink with new file', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
command('set backupcopy=no')
write_file('test_bkc_file.txt', 'content0')
- if iswin() then
+ if is_os('win') then
command("silent !mklink test_bkc_link.txt test_bkc_file.txt")
else
command("silent !ln -s test_bkc_file.txt test_bkc_link.txt")
@@ -79,7 +79,7 @@ describe(':write', function()
it("appends FIFO file", function()
-- mkfifo creates read-only .lnk files on Windows
- if iswin() or eval("executable('mkfifo')") == 0 then
+ if is_os('win') or eval("executable('mkfifo')") == 0 then
pending('missing "mkfifo" command')
end
@@ -112,7 +112,7 @@ describe(':write', function()
eq(1, eval("filereadable('test/write/p_opt.txt')"))
eq(('Vim(write):E32: No file name'), pcall_err(command, 'write ++p test_write/'))
- if not iswin() then
+ if not is_os('win') then
eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'),
pcall_err(command, 'write ++p .'))
eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'),
@@ -121,11 +121,11 @@ describe(':write', function()
end)
it('errors out correctly', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
command('let $HOME=""')
eq(funcs.fnamemodify('.', ':p:h'), funcs.fnamemodify('.', ':p:h:~'))
-- Message from check_overwrite
- if not iswin() then
+ if not is_os('win') then
eq(('Vim(write):E17: "'..funcs.fnamemodify('.', ':p:h')..'" is a directory'),
pcall_err(command, 'write .'))
end
@@ -144,7 +144,7 @@ describe(':write', function()
funcs.setfperm(fname, 'r--------')
eq('Vim(write):E505: "Xtest-functional-ex_cmds-write" is read-only (add ! to override)',
pcall_err(command, 'write'))
- if iswin() then
+ if is_os('win') then
eq(0, os.execute('del /q/f ' .. fname))
eq(0, os.execute('rd /q/s ' .. fname_bak))
else
@@ -152,7 +152,7 @@ describe(':write', function()
eq(true, os.remove(fname_bak))
end
write_file(fname_bak, 'TTYX')
- skip(iswin(), [[FIXME: exc_exec('write!') outputs 0 in Windows]])
+ skip(is_os('win'), [[FIXME: exc_exec('write!') outputs 0 in Windows]])
lfs.link(fname_bak .. ('/xxxxx'):rep(20), fname, true)
eq('Vim(write):E166: Can\'t open linked file for writing',
pcall_err(command, 'write!'))
diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua
index 7c00daf1d7..861a977ea6 100644
--- a/test/functional/ex_cmds/wviminfo_spec.lua
+++ b/test/functional/ex_cmds/wviminfo_spec.lua
@@ -3,14 +3,14 @@ local lfs = require('lfs')
local clear = helpers.clear
local command, eq, neq, write_file =
helpers.command, helpers.eq, helpers.neq, helpers.write_file
-local iswin = helpers.iswin
local read_file = helpers.read_file
+local is_os = helpers.is_os
describe(':wshada', function()
local shada_file = 'wshada_test'
before_each(function()
- clear{args={'-i', iswin() and 'nul' or '/dev/null',
+ clear{args={'-i', is_os('win') and 'nul' or '/dev/null',
-- Need 'swapfile' for these tests.
'--cmd', 'set swapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'},
args_rm={'-n', '-i', '--cmd'}}
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 1cd632f00b..ca59eb3182 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -54,7 +54,6 @@ if module.nvim_dir == module.nvim_prog then
module.nvim_dir = "."
end
-local iswin = global_helpers.iswin
local prepend_argv
if os.getenv('VALGRIND') then
@@ -557,7 +556,7 @@ function module.source(code)
end
function module.has_powershell()
- return module.eval('executable("'..(iswin() and 'powershell' or 'pwsh')..'")') == 1
+ return module.eval('executable("'..(is_os('win') and 'powershell' or 'pwsh')..'")') == 1
end
--- Sets Nvim shell to powershell.
@@ -570,9 +569,9 @@ function module.set_shell_powershell(fake)
if not fake then
assert(found)
end
- local shell = found and (iswin() and 'powershell' or 'pwsh') or module.testprg('pwsh-test')
+ local shell = found and (is_os('win') and 'powershell' or 'pwsh') or module.testprg('pwsh-test')
local set_encoding = '[Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.UTF8Encoding]::new();'
- local cmd = set_encoding..'Remove-Item -Force '..table.concat(iswin()
+ local cmd = set_encoding..'Remove-Item -Force '..table.concat(is_os('win')
and {'alias:cat', 'alias:echo', 'alias:sleep', 'alias:sort'}
or {'alias:echo'}, ',')..';'
module.exec([[
@@ -854,13 +853,13 @@ function module.exec_lua(code, ...)
end
function module.get_pathsep()
- return iswin() and '\\' or '/'
+ return is_os('win') and '\\' or '/'
end
--- Gets the filesystem root dir, namely "/" or "C:/".
function module.pathroot()
local pathsep = package.config:sub(1,1)
- return iswin() and (module.nvim_dir:sub(1,2)..pathsep) or '/'
+ return is_os('win') and (module.nvim_dir:sub(1,2)..pathsep) or '/'
end
--- Gets the full `…/build/bin/{name}` path of a test program produced by
@@ -868,7 +867,7 @@ end
---
--- @param name (string) Name of the test program.
function module.testprg(name)
- local ext = module.iswin() and '.exe' or ''
+ local ext = module.is_os('win') and '.exe' or ''
return ('%s/%s%s'):format(module.nvim_dir, name, ext)
end
@@ -895,7 +894,7 @@ function module.missing_provider(provider)
end
function module.alter_slashes(obj)
- if not iswin() then
+ if not is_os('win') then
return obj
end
if type(obj) == 'string' then
@@ -913,7 +912,7 @@ function module.alter_slashes(obj)
end
local load_factor = 1
-if global_helpers.isCI() then
+if global_helpers.is_ci() then
-- Compute load factor only once (but outside of any tests).
module.clear()
module.request('nvim_command', 'source src/nvim/testdir/load.vim')
@@ -946,14 +945,14 @@ end
-- Kill process with given pid
function module.os_kill(pid)
- return os.execute((iswin()
+ return os.execute((is_os('win')
and 'taskkill /f /t /pid '..pid..' > nul'
or 'kill -9 '..pid..' > /dev/null'))
end
-- Create folder with non existing parents
function module.mkdir_p(path)
- return os.execute((iswin()
+ return os.execute((is_os('win')
and 'mkdir '..path
or 'mkdir -p '..path))
end
diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua
index 0fa9290f3c..7ae851467f 100644
--- a/test/functional/legacy/011_autocommands_spec.lua
+++ b/test/functional/legacy/011_autocommands_spec.lua
@@ -18,11 +18,11 @@ local clear, feed_command, expect, eq, neq, dedent, write_file, feed =
helpers.clear, helpers.feed_command, helpers.expect, helpers.eq, helpers.neq,
helpers.dedent, helpers.write_file, helpers.feed
local command = helpers.command
-local iswin = helpers.iswin
local read_file = helpers.read_file
+local is_os = helpers.is_os
local function has_gzip()
- local null = iswin() and 'nul' or '/dev/null'
+ local null = is_os('win') and 'nul' or '/dev/null'
return os.execute('gzip --help >' .. null .. ' 2>&1') == 0
end
diff --git a/test/functional/legacy/025_jump_tag_hidden_spec.lua b/test/functional/legacy/025_jump_tag_hidden_spec.lua
index dd89a3680e..15bd56a601 100644
--- a/test/functional/legacy/025_jump_tag_hidden_spec.lua
+++ b/test/functional/legacy/025_jump_tag_hidden_spec.lua
@@ -23,7 +23,7 @@ describe('jump to a tag with hidden set', function()
feed_command('set hidden')
-- Create a link from test25.dir to the current directory.
- if helpers.iswin() then
+ if helpers.is_os('win') then
feed_command('!rd /q/s test25.dir')
feed_command('!mklink /j test25.dir .')
else
@@ -33,7 +33,7 @@ describe('jump to a tag with hidden set', function()
-- Create tags.text, with the current directory name inserted.
feed_command('/tags line')
- feed_command('r !' .. (helpers.iswin() and 'cd' or 'pwd'))
+ feed_command('r !' .. (helpers.is_os('win') and 'cd' or 'pwd'))
feed('d$/test<cr>')
feed('hP:.w! tags.test<cr>')
@@ -44,7 +44,7 @@ describe('jump to a tag with hidden set', function()
feed('G<C-]> x:yank a<cr>')
feed_command("call delete('tags.test')")
feed_command("call delete('Xxx')")
- if helpers.iswin() then
+ if helpers.is_os('win') then
feed_command('!rd /q test25.dir')
else
feed_command('!rm -f test25.dir')
diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua
index dd5a26ad3b..a62dc4d4c8 100644
--- a/test/functional/legacy/097_glob_path_spec.lua
+++ b/test/functional/legacy/097_glob_path_spec.lua
@@ -10,7 +10,7 @@ describe('glob() and globpath()', function()
setup(clear)
setup(function()
- if helpers.iswin() then
+ if helpers.is_os('win') then
os.execute("md sautest\\autoload")
os.execute(".>sautest\\autoload\\Test104.vim 2>nul")
os.execute(".>sautest\\autoload\\footest.vim 2>nul")
@@ -28,7 +28,7 @@ describe('glob() and globpath()', function()
-- Consistent sorting of file names
command('set nofileignorecase')
- if helpers.iswin() then
+ if helpers.is_os('win') then
command([[$put =glob('Xxx{')]])
command([[$put =glob('Xxx$')]])
@@ -72,7 +72,7 @@ describe('glob() and globpath()', function()
end)
teardown(function()
- if helpers.iswin() then
+ if helpers.is_os('win') then
os.execute('del /q/f Xxx{ Xxx$')
os.execute('rd /q /s sautest')
else
diff --git a/test/functional/legacy/delete_spec.lua b/test/functional/legacy/delete_spec.lua
index 4ba4c8d356..cefcd6c6c4 100644
--- a/test/functional/legacy/delete_spec.lua
+++ b/test/functional/legacy/delete_spec.lua
@@ -48,7 +48,7 @@ describe('Test for delete()', function()
it('symlink directory delete', function()
command("call mkdir('Xdir1')")
- if helpers.iswin() then
+ if helpers.is_os('win') then
command("silent !mklink /j Xlink Xdir1")
else
command("silent !ln -s Xdir1 Xlink")
diff --git a/test/functional/legacy/excmd_spec.lua b/test/functional/legacy/excmd_spec.lua
index ece88d26bd..eb480a6689 100644
--- a/test/functional/legacy/excmd_spec.lua
+++ b/test/functional/legacy/excmd_spec.lua
@@ -7,12 +7,12 @@ local exec_lua = helpers.exec_lua
local expect_exit = helpers.expect_exit
local feed = helpers.feed
local funcs = helpers.funcs
-local iswin = helpers.iswin
local meths = helpers.meths
local read_file = helpers.read_file
local source = helpers.source
local eq = helpers.eq
local write_file = helpers.write_file
+local is_os = helpers.is_os
local function sizeoflong()
if not exec_lua('return pcall(require, "ffi")') then
@@ -376,7 +376,7 @@ describe(':confirm command dialog', function()
{3:(Y)es, [N]o: }^ |
]])
feed('Y')
- if iswin() then
+ if is_os('win') then
screen:expect([[
foobar |
{0:~ }|
@@ -416,7 +416,7 @@ describe(':confirm command dialog', function()
{3:(Y)es, [N]o: }^ |
]])
feed('Y')
- if iswin() then
+ if is_os('win') then
screen:expect([[
foobar |
{1: }|
@@ -493,7 +493,7 @@ describe(':confirm command dialog', function()
{3:(Y)es, [N]o: }^ |
]])
feed('Y')
- if iswin() then
+ if is_os('win') then
screen:expect([[
a |
b |
diff --git a/test/functional/legacy/filechanged_spec.lua b/test/functional/legacy/filechanged_spec.lua
index 747eca1c45..cea1d6ac30 100644
--- a/test/functional/legacy/filechanged_spec.lua
+++ b/test/functional/legacy/filechanged_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, source = helpers.clear, helpers.source
local call, eq, meths = helpers.call, helpers.eq, helpers.meths
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
local function expected_empty()
@@ -17,7 +17,7 @@ describe('file changed dialog', function()
end)
it('works', function()
- skip(iswin())
+ skip(is_os('win'))
source([[
func Test_file_changed_dialog()
au! FileChangedShell
diff --git a/test/functional/legacy/match_spec.lua b/test/functional/legacy/match_spec.lua
index 271f844f9d..b6e45c396c 100644
--- a/test/functional/legacy/match_spec.lua
+++ b/test/functional/legacy/match_spec.lua
@@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local exec = helpers.exec
+local feed = helpers.feed
before_each(clear)
@@ -36,3 +37,90 @@ describe('matchaddpos()', function()
]])
end)
end)
+
+describe('match highlighting', function()
+ -- oldtest: Test_match_in_linebreak()
+ it('does not continue in linebreak vim-patch:8.2.3698', function()
+ local screen = Screen.new(75, 10)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
+ })
+ screen:attach()
+ exec([=[
+ set breakindent linebreak breakat+=]
+ call printf('%s]%s', repeat('x', 50), repeat('x', 70))->setline(1)
+ call matchaddpos('ErrorMsg', [[1, 51]])
+ ]=])
+ screen:expect([[
+ ^xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx{1:]} |
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end)
+
+ it('is shown with incsearch vim-patch:8.2.3940', function()
+ local screen = Screen.new(75, 6)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {background = Screen.colors.Yellow}, -- Search
+ [2] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
+ })
+ screen:attach()
+ exec([[
+ set incsearch
+ call setline(1, range(20))
+ call matchaddpos('ErrorMsg', [3])
+ ]])
+ screen:expect([[
+ ^0 |
+ 1 |
+ {2:2} |
+ 3 |
+ 4 |
+ |
+ ]])
+ feed(':s/0')
+ screen:expect([[
+ {1:0} |
+ 1 |
+ {2:2} |
+ 3 |
+ 4 |
+ :s/0^ |
+ ]])
+ end)
+
+ it('on a Tab vim-patch:8.2.4062', function()
+ local screen = Screen.new(75, 10)
+ screen:set_default_attr_ids({
+ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText
+ [1] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg
+ })
+ screen:attach()
+ exec([[
+ set linebreak
+ call setline(1, "\tix")
+ call matchadd('ErrorMsg', '\t')
+ ]])
+ screen:expect([[
+ {1: ^ }ix |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ end)
+end)
diff --git a/test/functional/legacy/memory_usage_spec.lua b/test/functional/legacy/memory_usage_spec.lua
index eec89aa919..8d9b28e1fc 100644
--- a/test/functional/legacy/memory_usage_spec.lua
+++ b/test/functional/legacy/memory_usage_spec.lua
@@ -3,15 +3,14 @@ local clear = helpers.clear
local eval = helpers.eval
local eq = helpers.eq
local feed_command = helpers.feed_command
-local iswin = helpers.iswin
local retry = helpers.retry
local ok = helpers.ok
local source = helpers.source
local poke_eventloop = helpers.poke_eventloop
-local uname = helpers.uname
local load_adjust = helpers.load_adjust
local write_file = helpers.write_file
-local isCI = helpers.isCI
+local is_os = helpers.is_os
+local is_ci = helpers.is_ci
local function isasan()
local version = eval('execute("version")')
@@ -22,8 +21,8 @@ clear()
if isasan() then
pending('ASAN build is difficult to estimate memory usage', function() end)
return
-elseif iswin() then
- if isCI('github') then
+elseif is_os('win') then
+ if is_ci('github') then
pending('Windows runners in Github Actions do not have a stable environment to estimate memory usage', function() end)
return
elseif eval("executable('wmic')") == 0 then
@@ -38,7 +37,7 @@ end
local monitor_memory_usage = {
memory_usage = function(self)
local handle
- if iswin() then
+ if is_os('win') then
handle = io.popen('wmic process where processid=' ..self.pid..' get WorkingSetSize')
else
handle = io.popen('ps -o rss= -p '..self.pid)
@@ -169,7 +168,7 @@ describe('memory usage', function()
-- Allow for 20% tolerance at the upper limit. That's very permissive, but
-- otherwise the test fails sometimes. On Sourcehut CI with FreeBSD we need to
-- be even much more permissive.
- local upper_multiplier = uname() == 'freebsd' and 19 or 12
+ local upper_multiplier = is_os('freebsd') and 19 or 12
local lower = before.last * 8 / 10
local upper = load_adjust((after.max + (after.last - before.last)) * upper_multiplier / 10)
check_result({before=before, after=after, last=last},
@@ -179,7 +178,7 @@ describe('memory usage', function()
end)
it('releases memory when closing windows when folds exist', function()
- if helpers.is_os('mac') then
+ if is_os('mac') then
pending('macOS memory compression causes flakiness')
end
local pid = eval('getpid()')
diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua
index 565243d5a0..b7fe39cc91 100644
--- a/test/functional/lua/diagnostic_spec.lua
+++ b/test/functional/lua/diagnostic_spec.lua
@@ -16,7 +16,7 @@ describe('vim.diagnostic', function()
exec_lua [[
require('vim.diagnostic')
- function make_diagnostic(msg, x1, y1, x2, y2, severity, source)
+ function make_diagnostic(msg, x1, y1, x2, y2, severity, source, code)
return {
lnum = x1,
col = y1,
@@ -25,23 +25,24 @@ describe('vim.diagnostic', function()
message = msg,
severity = severity,
source = source,
+ code = code,
}
end
- function make_error(msg, x1, y1, x2, y2, source)
- return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.ERROR, source)
+ function make_error(msg, x1, y1, x2, y2, source, code)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.ERROR, source, code)
end
- function make_warning(msg, x1, y1, x2, y2, source)
- return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.WARN, source)
+ function make_warning(msg, x1, y1, x2, y2, source, code)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.WARN, source, code)
end
- function make_info(msg, x1, y1, x2, y2, source)
- return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.INFO, source)
+ function make_info(msg, x1, y1, x2, y2, source, code)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.INFO, source, code)
end
- function make_hint(msg, x1, y1, x2, y2, source)
- return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.HINT, source)
+ function make_hint(msg, x1, y1, x2, y2, source, code)
+ return make_diagnostic(msg, x1, y1, x2, y2, vim.diagnostic.severity.HINT, source, code)
end
function count_diagnostics(bufnr, severity, namespace)
@@ -1160,6 +1161,44 @@ end)
eq(" some_linter: 👀 Warning", result[1][2][1])
eq(" another_linter: 🔥 Error", result[2][2][1])
end)
+
+ it('can add a suffix to virtual text', function()
+ eq(' Some error ✘', exec_lua [[
+ local diagnostics = {
+ make_error('Some error', 0, 0, 0, 0),
+ }
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics, {
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ suffix = ' ✘',
+ }
+ })
+
+ local extmarks = get_virt_text_extmarks(diagnostic_ns)
+ local virt_text = extmarks[1][4].virt_text[2][1]
+ return virt_text
+ ]])
+
+ eq(' Some error [err-code]', exec_lua [[
+ local diagnostics = {
+ make_error('Some error', 0, 0, 0, 0, nil, 'err-code'),
+ }
+
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics, {
+ underline = false,
+ virtual_text = {
+ prefix = '',
+ suffix = function(diag) return string.format(' [%s]', diag.code) end,
+ }
+ })
+
+ local extmarks = get_virt_text_extmarks(diagnostic_ns)
+ local virt_text = extmarks[1][4].virt_text[2][1]
+ return virt_text
+ ]])
+ end)
end)
describe('set()', function()
@@ -1776,10 +1815,55 @@ end)
return lines
]])
- eq(".../diagnostic.lua:0: prefix: expected 'string' or 'table' or 'function', got 42",
+ eq(".../diagnostic.lua:0: prefix: expected string|table|function, got number",
pcall_err(exec_lua, [[ vim.diagnostic.open_float({ prefix = 42 }) ]]))
end)
+ it('can add a suffix to diagnostics', function()
+ -- Default is to render the diagnostic error code
+ eq({'1. Syntax error [code-x]', '2. Some warning [code-y]'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3, nil, "code-x"),
+ make_warning("Some warning", 1, 1, 1, 3, nil, "code-y"),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ eq({'1. Syntax error', '2. Some warning'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error", 0, 1, 0, 3, nil, "code-x"),
+ make_warning("Some warning", 1, 1, 1, 3, nil, "code-y"),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer", suffix = ""})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ -- Suffix is rendered on the last line of a multiline diagnostic
+ eq({'1. Syntax error', ' More context [code-x]'}, exec_lua [[
+ local diagnostics = {
+ make_error("Syntax error\nMore context", 0, 1, 0, 3, nil, "code-x"),
+ }
+ vim.api.nvim_win_set_buf(0, diagnostic_bufnr)
+ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, diagnostics)
+ local float_bufnr, winnr = vim.diagnostic.open_float({header = false, scope = "buffer"})
+ local lines = vim.api.nvim_buf_get_lines(float_bufnr, 0, -1, false)
+ vim.api.nvim_win_close(winnr, true)
+ return lines
+ ]])
+
+ eq(".../diagnostic.lua:0: suffix: expected string|table|function, got number",
+ pcall_err(exec_lua, [[ vim.diagnostic.open_float({ suffix = 42 }) ]]))
+ end)
+
it('works with the old signature', function()
eq({'1. Syntax error'}, exec_lua [[
local diagnostics = {
diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua
index 3123ec324c..fc228e54bc 100644
--- a/test/functional/lua/fs_spec.lua
+++ b/test/functional/lua/fs_spec.lua
@@ -7,10 +7,10 @@ local mkdir_p = helpers.mkdir_p
local rmdir = helpers.rmdir
local nvim_dir = helpers.nvim_dir
local test_build_dir = helpers.test_build_dir
-local iswin = helpers.iswin
local nvim_prog = helpers.nvim_prog
+local is_os = helpers.is_os
-local nvim_prog_basename = iswin() and 'nvim.exe' or 'nvim'
+local nvim_prog_basename = is_os('win') and 'nvim.exe' or 'nvim'
before_each(clear)
@@ -102,7 +102,7 @@ describe('vim.fs', function()
eq('C:/Users/jdoe', exec_lua [[ return vim.fs.normalize('C:\\Users\\jdoe') ]])
end)
it('works with ~', function()
- if iswin() then
+ if is_os('win') then
pending([[$HOME does not exist on Windows ¯\_(ツ)_/¯]])
end
eq(os.getenv('HOME') .. '/src/foo', exec_lua [[ return vim.fs.normalize('~/src/foo') ]])
diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua
index 32c1615a45..3f107811ae 100644
--- a/test/functional/lua/overrides_spec.lua
+++ b/test/functional/lua/overrides_spec.lua
@@ -8,12 +8,12 @@ local feed = helpers.feed
local clear = helpers.clear
local funcs = helpers.funcs
local meths = helpers.meths
-local iswin = helpers.iswin
local command = helpers.command
local write_file = helpers.write_file
local exec_capture = helpers.exec_capture
local exec_lua = helpers.exec_lua
local pcall_err = helpers.pcall_err
+local is_os = helpers.is_os
local screen
@@ -135,7 +135,7 @@ describe('print', function()
print("very slow")
vim.api.nvim_command("sleep 1m") -- force deferred event processing
end
- ]], (iswin() and "timeout 1") or "sleep 0.1")
+ ]], (is_os('win') and "timeout 1") or "sleep 0.1")
eq('very slow\nvery fast', exec_capture('lua test()'))
end)
end)
diff --git a/test/functional/lua/secure_spec.lua b/test/functional/lua/secure_spec.lua
new file mode 100644
index 0000000000..a5eeee8494
--- /dev/null
+++ b/test/functional/lua/secure_spec.lua
@@ -0,0 +1,171 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+
+local eq = helpers.eq
+local clear = helpers.clear
+local command = helpers.command
+local pathsep = helpers.get_pathsep()
+local is_os = helpers.is_os
+local curbufmeths = helpers.curbufmeths
+local exec_lua = helpers.exec_lua
+local feed_command = helpers.feed_command
+local feed = helpers.feed
+local funcs = helpers.funcs
+local pcall_err = helpers.pcall_err
+
+describe('vim.secure', function()
+ describe('read()', function()
+ local xstate = 'Xstate'
+
+ setup(function()
+ helpers.mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim'))
+ end)
+
+ teardown(function()
+ helpers.rmdir(xstate)
+ end)
+
+ before_each(function()
+ helpers.write_file('Xfile', [[
+ let g:foobar = 42
+ ]])
+ clear{env={XDG_STATE_HOME=xstate}}
+ end)
+
+ after_each(function()
+ os.remove('Xfile')
+ helpers.rmdir(xstate)
+ end)
+
+ it('works', function()
+ local screen = Screen.new(80, 8)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {bold = true, reverse = true},
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [4] = {reverse = true},
+ })
+
+ local cwd = funcs.getcwd()
+
+ -- Need to use feed_command instead of exec_lua because of the confirmation prompt
+ feed_command([[lua vim.secure.read('Xfile')]])
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ :lua vim.secure.read('Xfile') |
+ {3:]] .. cwd .. pathsep .. [[Xfile is untrusted}{MATCH:%s+}|
+ {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ |
+ ]]}
+ feed('d')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ local trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust')
+ eq(string.format('! %s', cwd .. pathsep .. 'Xfile'), vim.trim(trust))
+ eq(helpers.NIL, exec_lua([[return vim.secure.read('Xfile')]]))
+
+ os.remove(funcs.stdpath('state') .. pathsep .. 'trust')
+
+ feed_command([[lua vim.secure.read('Xfile')]])
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ :lua vim.secure.read('Xfile') |
+ {3:]] .. cwd .. pathsep .. [[Xfile is untrusted}{MATCH:%s+}|
+ {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ |
+ ]]}
+ feed('a')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ local hash = funcs.sha256(helpers.read_file('Xfile'))
+ trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust')
+ eq(string.format('%s %s', hash, cwd .. pathsep .. 'Xfile'), vim.trim(trust))
+ eq(helpers.NIL, exec_lua([[vim.secure.read('Xfile')]]))
+
+ os.remove(funcs.stdpath('state') .. pathsep .. 'trust')
+
+ feed_command([[lua vim.secure.read('Xfile')]])
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ :lua vim.secure.read('Xfile') |
+ {3:]] .. cwd .. pathsep .. [[Xfile is untrusted}{MATCH:%s+}|
+ {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ |
+ ]]}
+ feed('i')
+ screen:expect{grid=[[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ -- Trust database is not updated
+ trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust')
+ eq(nil, trust)
+
+ feed_command([[lua vim.secure.read('Xfile')]])
+ screen:expect{grid=[[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ :lua vim.secure.read('Xfile') |
+ {3:]] .. cwd .. pathsep .. [[Xfile is untrusted}{MATCH:%s+}|
+ {3:[i]gnore, (v)iew, (d)eny, (a)llow: }^ |
+ ]]}
+ feed('v')
+ screen:expect{grid=[[
+ ^ let g:foobar = 42 |
+ {1:~ }|
+ {1:~ }|
+ {2:]] .. cwd .. pathsep .. [[Xfile [RO]{MATCH:%s+}|
+ |
+ {1:~ }|
+ {4:[No Name] }|
+ |
+ ]]}
+
+ -- Trust database is not updated
+ trust = helpers.read_file(funcs.stdpath('state') .. pathsep .. 'trust')
+ eq(nil, trust)
+
+ -- Cannot write file
+ pcall_err(command, 'write')
+ eq(false, curbufmeths.get_option('modifiable'))
+ end)
+ end)
+end)
diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua
index 38c7801d55..416e9e1f02 100644
--- a/test/functional/lua/uri_spec.lua
+++ b/test/functional/lua/uri_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local exec_lua = helpers.exec_lua
local eq = helpers.eq
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
local write_file = require('test.helpers').write_file
@@ -169,7 +169,7 @@ describe('URI methods', function()
describe('uri from bufnr', function()
it('Windows paths should not be treated as uris', function()
- skip(not iswin(), "Not applicable on non-Windows")
+ skip(not is_os('win'), "Not applicable on non-Windows")
local file = helpers.tmpname()
write_file(file, 'Test content')
diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua
index 74959a8e76..0b6fe9533c 100644
--- a/test/functional/options/autochdir_spec.lua
+++ b/test/functional/options/autochdir_spec.lua
@@ -16,7 +16,7 @@ describe("'autochdir'", function()
-- With 'autochdir' on, we should get the directory of tty-test.c.
clear('--cmd', 'set autochdir', targetdir..'/tty-test.c')
- eq(helpers.iswin() and expected:gsub('/', '\\') or expected, funcs.getcwd())
+ eq(helpers.is_os('win') and expected:gsub('/', '\\') or expected, funcs.getcwd())
end)
it('is not overwritten by getwinvar() call #17609',function()
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index 130ed73c34..c0d820f40e 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -12,13 +12,13 @@ local eq = helpers.eq
local ok = helpers.ok
local funcs = helpers.funcs
local insert = helpers.insert
-local iswin = helpers.iswin
local neq = helpers.neq
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
local alter_slashes = helpers.alter_slashes
local tbl_contains = helpers.tbl_contains
local expect_exit = helpers.expect_exit
+local is_os = helpers.is_os
describe('startup defaults', function()
describe(':filetype', function()
@@ -240,7 +240,7 @@ describe('startup defaults', function()
describe('$NVIM_LOG_FILE', function()
local xdgdir = 'Xtest-startup-xdg-logpath'
- local xdgstatedir = iswin() and xdgdir..'/nvim-data' or xdgdir..'/nvim'
+ local xdgstatedir = is_os('win') and xdgdir..'/nvim-data' or xdgdir..'/nvim'
after_each(function()
os.remove('Xtest-logpath')
rmdir(xdgdir)
@@ -279,7 +279,7 @@ describe('XDG defaults', function()
clear()
local rtp = eval('split(&runtimepath, ",")')
local rv = {}
- local expected = (iswin()
+ local expected = (is_os('win')
and { [[\nvim-data\site]], [[\nvim-data\site\after]], }
or { '/nvim/site', '/nvim/site/after', })
@@ -327,10 +327,10 @@ describe('XDG defaults', function()
return vimruntime, libdir
end
- local env_sep = iswin() and ';' or ':'
- local data_dir = iswin() and 'nvim-data' or 'nvim'
- local state_dir = iswin() and 'nvim-data' or 'nvim'
- local root_path = iswin() and 'C:' or ''
+ local env_sep = is_os('win') and ';' or ':'
+ local data_dir = is_os('win') and 'nvim-data' or 'nvim'
+ local state_dir = is_os('win') and 'nvim-data' or 'nvim'
+ local root_path = is_os('win') and 'C:' or ''
describe('with too long XDG variables', function()
before_each(function()
@@ -497,7 +497,7 @@ describe('XDG defaults', function()
it('are escaped properly', function()
local vimruntime, libdir = vimruntime_and_libdir()
- local path_sep = iswin() and '\\' or '/'
+ local path_sep = is_os('win') and '\\' or '/'
eq(('\\, \\, \\,' .. path_sep .. 'nvim'
.. ',\\,-\\,-\\,' .. path_sep .. 'nvim'
.. ',-\\,-\\,-' .. path_sep .. 'nvim'
@@ -549,9 +549,9 @@ end)
describe('stdpath()', function()
-- Windows appends 'nvim-data' instead of just 'nvim' to prevent collisions
-- due to XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_STATE_HOME being the same.
- local datadir = iswin() and 'nvim-data' or 'nvim'
- local statedir = iswin() and 'nvim-data' or 'nvim'
- local env_sep = iswin() and ';' or ':'
+ local datadir = is_os('win') and 'nvim-data' or 'nvim'
+ local statedir = is_os('win') and 'nvim-data' or 'nvim'
+ local env_sep = is_os('win') and ';' or ':'
it('acceptance', function()
clear() -- Do not explicitly set any env vars.
@@ -704,7 +704,7 @@ describe('stdpath()', function()
context('returns a List', function()
-- Some OS specific variables the system would have set.
local function base_env()
- if iswin() then
+ if is_os('win') then
return {
HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH
HOMEDRIVE='C:',
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 2ab1e34de4..071791e702 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -17,9 +17,9 @@ local retry = helpers.retry
local NIL = helpers.NIL
local read_file = require('test.helpers').read_file
local write_file = require('test.helpers').write_file
-local isCI = helpers.isCI
+local is_ci = helpers.is_ci
local meths = helpers.meths
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
-- Use these to get access to a coroutine so that I can run async tests and use
@@ -27,7 +27,7 @@ local skip = helpers.skip
local run, stop = helpers.run, helpers.stop
-- TODO(justinmk): hangs on Windows https://github.com/neovim/neovim/pull/11837
-if skip(iswin()) then return end
+if skip(is_os('win')) then return end
-- Fake LSP server.
local fake_lsp_code = 'test/functional/fixtures/fake-lsp-server.lua'
@@ -318,7 +318,7 @@ describe('LSP', function()
end)
it('should succeed with manual shutdown', function()
- if isCI() then
+ if is_ci() then
pending('hangs the build on CI #14028, re-enable with freeze timeout #14204')
return
elseif helpers.skip_fragile(pending) then
diff --git a/test/functional/plugin/man_spec.lua b/test/functional/plugin/man_spec.lua
index c57f43c632..c6c7d2b03d 100644
--- a/test/functional/plugin/man_spec.lua
+++ b/test/functional/plugin/man_spec.lua
@@ -8,8 +8,8 @@ local nvim_prog = helpers.nvim_prog
local matches = helpers.matches
local write_file = helpers.write_file
local tmpname = helpers.tmpname
-local isCI = helpers.isCI
local skip = helpers.skip
+local is_ci = helpers.is_ci
clear()
if funcs.executable('man') == 0 then
@@ -162,7 +162,7 @@ describe(':Man', function()
end)
it('reports non-existent man pages for absolute paths', function()
- skip(isCI('cirrus'))
+ skip(is_ci('cirrus'))
local actual_file = tmpname()
-- actual_file must be an absolute path to an existent file for us to test against it
matches('^/.+', actual_file)
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
index dda8077f05..93cf6d2b77 100644
--- a/test/functional/plugin/shada_spec.lua
+++ b/test/functional/plugin/shada_spec.lua
@@ -2140,7 +2140,7 @@ end)
describe('plugin/shada.vim', function()
local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
- local eol = helpers.iswin() and '\r\n' or '\n'
+ local eol = helpers.is_os('win') and '\r\n' or '\n'
before_each(function()
-- Note: reset() is called explicitly in each test.
os.remove(fname)
diff --git a/test/functional/preload.lua b/test/functional/preload.lua
index 74f03eaecf..43e2151f84 100644
--- a/test/functional/preload.lua
+++ b/test/functional/preload.lua
@@ -2,10 +2,10 @@
-- Busted started doing this to help provide more isolation. See issue #62
-- for more information about this.
local helpers = require('test.functional.helpers')(nil)
-local iswin = helpers.iswin
local busted = require("busted")
+local is_os = helpers.is_os
-if iswin() then
+if is_os('win') then
local ffi = require('ffi')
ffi.cdef[[
typedef int errno_t;
diff --git a/test/functional/provider/perl_spec.lua b/test/functional/provider/perl_spec.lua
index 4c5c3ece15..ce92831f4c 100644
--- a/test/functional/provider/perl_spec.lua
+++ b/test/functional/provider/perl_spec.lua
@@ -9,7 +9,7 @@ local curbufmeths = helpers.curbufmeths
local insert = helpers.insert
local expect = helpers.expect
local feed = helpers.feed
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
do
@@ -26,7 +26,7 @@ before_each(function()
end)
describe('legacy perl provider', function()
- skip(iswin())
+ skip(is_os('win'))
it('feature test', function()
eq(1, eval('has("perl")'))
@@ -70,7 +70,7 @@ describe('legacy perl provider', function()
end)
describe('perl provider', function()
- skip(iswin())
+ skip(is_os('win'))
teardown(function ()
os.remove('Xtest-perl-hello.pl')
os.remove('Xtest-perl-hello-plugin.pl')
diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua
index a5ef60d91f..fb656735dd 100644
--- a/test/functional/shada/compatibility_spec.lua
+++ b/test/functional/shada/compatibility_spec.lua
@@ -12,7 +12,7 @@ local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compati
local mock_file_path = '/a/b/'
local mock_file_path2 = '/d/e/'
-if helpers.iswin() then
+if helpers.is_os('win') then
mock_file_path = 'C:/a/'
mock_file_path2 = 'C:/d/'
end
diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua
index 2d44b0a950..da2fbbe029 100644
--- a/test/functional/shada/merging_spec.lua
+++ b/test/functional/shada/merging_spec.lua
@@ -14,7 +14,7 @@ local wshada, sdrcmd, shada_fname =
get_shada_rw('Xtest-functional-shada-merging.shada')
local mock_file_path = '/a/b/'
-if helpers.iswin() then
+if helpers.is_os('win') then
mock_file_path = 'C:/a/'
end
diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua
index 210c09e187..88a99d9b55 100644
--- a/test/functional/shada/shada_spec.lua
+++ b/test/functional/shada/shada_spec.lua
@@ -5,7 +5,7 @@ local meths, nvim_command, funcs, eq =
local write_file, spawn, set_session, nvim_prog, exc_exec =
helpers.write_file, helpers.spawn, helpers.set_session, helpers.nvim_prog,
helpers.exc_exec
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
local lfs = require('lfs')
@@ -250,7 +250,7 @@ describe('ShaDa support code', function()
end)
it('does not crash when ShaDa file directory is not writable', function()
- skip(iswin())
+ skip(is_os('win'))
funcs.mkdir(dirname, '', 0)
eq(0, funcs.filewritable(dirname))
diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua
index 457a5aa18f..cbe5e06005 100644
--- a/test/functional/terminal/altscreen_spec.lua
+++ b/test/functional/terminal/altscreen_spec.lua
@@ -6,7 +6,7 @@ local feed_data = thelpers.feed_data
local enter_altscreen = thelpers.enter_altscreen
local exit_altscreen = thelpers.exit_altscreen
-if helpers.skip(helpers.iswin()) then return end
+if helpers.skip(helpers.is_os('win')) then return end
describe(':terminal altscreen', function()
local screen
diff --git a/test/functional/terminal/api_spec.lua b/test/functional/terminal/api_spec.lua
index b5697c4c6b..38ef7c2a61 100644
--- a/test/functional/terminal/api_spec.lua
+++ b/test/functional/terminal/api_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local child_session = require('test.functional.terminal.helpers')
local ok = helpers.ok
-if helpers.skip(helpers.iswin()) then return end
+if helpers.skip(helpers.is_os('win')) then return end
describe('api', function()
local screen
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 5a75af69c0..9c8b983ff7 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -15,7 +15,7 @@ local matches = helpers.matches
local exec_lua = helpers.exec_lua
local sleep = helpers.sleep
local funcs = helpers.funcs
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
describe(':terminal buffer', function()
@@ -202,7 +202,7 @@ describe(':terminal buffer', function()
-- Save the buffer number of the terminal for later testing.
local tbuf = eval('bufnr("%")')
- local exitcmd = helpers.iswin()
+ local exitcmd = helpers.is_os('win')
and "['cmd', '/c', 'exit']"
or "['sh', '-c', 'exit']"
source([[
@@ -264,7 +264,7 @@ describe(':terminal buffer', function()
end)
it('it works with set rightleft #11438', function()
- skip(iswin())
+ skip(is_os('win'))
local columns = eval('&columns')
feed(string.rep('a', columns))
command('set rightleft')
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index fdd7b9407b..98ac03211a 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -9,7 +9,7 @@ local matches = helpers.matches
local feed_command = helpers.feed_command
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
describe(':terminal cursor', function()
@@ -90,7 +90,7 @@ describe(':terminal cursor', function()
describe('when invisible', function()
it('is not highlighted and is detached from screen cursor', function()
- skip(iswin())
+ skip(is_os('win'))
hide_cursor()
screen:expect([[
tty ready |
@@ -363,7 +363,7 @@ describe('buffer cursor position is correct in terminal without number column',
end)
describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function()
- if skip(iswin(), "Encoding problem?") then return end
+ if skip(is_os('win'), "Encoding problem?") then return end
before_each(function()
setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳')
@@ -446,7 +446,7 @@ describe('buffer cursor position is correct in terminal without number column',
end)
describe('in a line with double-cell multibyte characters and no trailing spaces,', function()
- skip(iswin(), "Encoding problem?")
+ skip(is_os('win'), "Encoding problem?")
before_each(function()
setup_ex_register('哦哦哦哦哦哦哦哦')
@@ -743,7 +743,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
end)
describe('in a line with single-cell composed multibyte characters and no trailing spaces,', function()
- if skip(iswin(), "Encoding problem?") then return end
+ if skip(is_os('win'), "Encoding problem?") then return end
before_each(function()
setup_ex_register('µ̳µ̳µ̳µ̳µ̳µ̳µ̳µ̳')
@@ -826,7 +826,7 @@ describe('buffer cursor position is correct in terminal with number column', fun
end)
describe('in a line with double-cell multibyte characters and no trailing spaces,', function()
- skip(iswin(), "Encoding problem?")
+ skip(is_os('win'), "Encoding problem?")
before_each(function()
setup_ex_register('哦哦哦哦哦哦哦哦')
diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua
index 95ee561d2b..80287bb3d0 100644
--- a/test/functional/terminal/edit_spec.lua
+++ b/test/functional/terminal/edit_spec.lua
@@ -36,7 +36,7 @@ describe(':edit term://*', function()
end)
it("runs TermOpen early enough to set buffer-local 'scrollback'", function()
- if helpers.skip(helpers.iswin()) then return end
+ if helpers.skip(helpers.is_os('win')) then return end
local columns, lines = 20, 4
local scr = get_screen(columns, lines)
local rep = 97
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 48254faa31..6b7e93a864 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -8,10 +8,10 @@ local feed_command, eval = helpers.feed_command, helpers.eval
local funcs = helpers.funcs
local retry = helpers.retry
local ok = helpers.ok
-local iswin = helpers.iswin
local command = helpers.command
-local isCI = helpers.isCI
local skip = helpers.skip
+local is_os = helpers.is_os
+local is_ci = helpers.is_ci
describe(':terminal', function()
local screen
@@ -47,8 +47,8 @@ describe(':terminal', function()
end)
it("reads output buffer on terminal reporting #4151", function()
- skip(isCI('cirrus') or iswin())
- if iswin() then
+ skip(is_ci('cirrus') or is_os('win'))
+ if is_os('win') then
feed_command([[terminal powershell -NoProfile -NoLogo -Command Write-Host -NoNewline "\"$([char]27)[6n\""; Start-Sleep -Milliseconds 500 ]])
else
feed_command([[terminal printf '\e[6n'; sleep 0.5 ]])
@@ -57,7 +57,7 @@ describe(':terminal', function()
end)
it("in normal-mode :split does not move cursor", function()
- if iswin() then
+ if is_os('win') then
feed_command([[terminal for /L \\%I in (1,0,2) do ( echo foo & ping -w 100 -n 1 127.0.0.1 > nul )]])
else
feed_command([[terminal while true; do echo foo; sleep .1; done]])
@@ -144,7 +144,7 @@ describe(':terminal (with fake shell)', function()
end
it('with no argument, acts like termopen()', function()
- skip(iswin())
+ skip(is_os('win'))
terminal_with_fake_shell()
retry(nil, 4 * screen.timeout, function()
screen:expect([[
@@ -168,7 +168,7 @@ describe(':terminal (with fake shell)', function()
end)
it("with no argument, but 'shell' has arguments, acts like termopen()", function()
- skip(iswin())
+ skip(is_os('win'))
nvim('set_option', 'shell', testprg('shell-test')..' -t jeff')
terminal_with_fake_shell()
screen:expect([[
@@ -180,7 +180,7 @@ describe(':terminal (with fake shell)', function()
end)
it('executes a given command through the shell', function()
- skip(iswin())
+ skip(is_os('win'))
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell('echo hi')
screen:expect([[
@@ -192,7 +192,7 @@ describe(':terminal (with fake shell)', function()
end)
it("executes a given command through the shell, when 'shell' has arguments", function()
- skip(iswin())
+ skip(is_os('win'))
nvim('set_option', 'shell', testprg('shell-test')..' -t jeff')
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell('echo hi')
@@ -205,7 +205,7 @@ describe(':terminal (with fake shell)', function()
end)
it('allows quotes and slashes', function()
- skip(iswin())
+ skip(is_os('win'))
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell([[echo 'hello' \ "world"]])
screen:expect([[
@@ -242,7 +242,7 @@ describe(':terminal (with fake shell)', function()
end)
it('works with :find', function()
- skip(iswin())
+ skip(is_os('win'))
terminal_with_fake_shell()
screen:expect([[
^ready $ |
@@ -253,7 +253,7 @@ describe(':terminal (with fake shell)', function()
eq('term://', string.match(eval('bufname("%")'), "^term://"))
feed([[<C-\><C-N>]])
feed_command([[find */shadacat.py]])
- if iswin() then
+ if is_os('win') then
eq('scripts\\shadacat.py', eval('bufname("%")'))
else
eq('scripts/shadacat.py', eval('bufname("%")'))
@@ -261,7 +261,7 @@ describe(':terminal (with fake shell)', function()
end)
it('works with gf', function()
- skip(iswin())
+ skip(is_os('win'))
command('set shellxquote=') -- win: avoid extra quotes
terminal_with_fake_shell([[echo "scripts/shadacat.py"]])
retry(nil, 4 * screen.timeout, function()
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index d69f3207f1..841c92387f 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -4,19 +4,31 @@
local helpers = require('test.functional.helpers')(nil)
local Screen = require('test.functional.ui.screen')
local testprg = helpers.testprg
+local exec_lua = helpers.exec_lua
local feed_command, nvim = helpers.feed_command, helpers.nvim
local function feed_data(data)
- -- A string containing NUL bytes is not converted to a Blob when
- -- calling nvim_set_var() API, so convert it using Lua instead.
- nvim('exec_lua', 'vim.g.term_data = ...', {data})
- nvim('command', 'call jobsend(b:terminal_job_id, term_data)')
+ if type(data) == 'table' then
+ data = table.concat(data, '\n')
+ end
+ exec_lua('vim.api.nvim_chan_send(vim.b.terminal_job_id, ...)', data)
end
local function feed_termcode(data)
- -- feed with the job API
- nvim('command', 'call jobsend(b:terminal_job_id, "\\x1b'..data..'")')
+ feed_data('\027' .. data)
+end
+
+local function make_lua_executor(session)
+ return function(code, ...)
+ local status, rv = session:request('nvim_exec_lua', code, {...})
+ if not status then
+ session:stop()
+ error(rv[2])
+ end
+ return rv
+ end
end
+
-- some helpers for controlling the terminal. the codes were taken from
-- infocmp xterm-256color which is less what libvterm understands
-- civis/cnorm
@@ -109,6 +121,7 @@ end
return {
feed_data = feed_data,
feed_termcode = feed_termcode,
+ make_lua_executor = make_lua_executor,
hide_cursor = hide_cursor,
show_cursor = show_cursor,
enter_altscreen = enter_altscreen,
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 3e121405d8..2ac45771d4 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -7,7 +7,7 @@ local nvim_prog_abs = helpers.nvim_prog_abs
local eq, eval = helpers.eq, helpers.eval
local funcs = helpers.funcs
local nvim_set = helpers.nvim_set
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
describe(':terminal highlight', function()
@@ -60,7 +60,7 @@ describe(':terminal highlight', function()
end)
local function pass_attrs()
- skip(iswin())
+ skip(is_os('win'))
screen:expect(sub([[
tty ready |
{NUM:text}text{10: } |
@@ -75,7 +75,7 @@ describe(':terminal highlight', function()
it('will pass the corresponding attributes', pass_attrs)
it('will pass the corresponding attributes on scrollback', function()
- skip(iswin())
+ skip(is_os('win'))
pass_attrs()
local lines = {}
for i = 1, 8 do
@@ -199,7 +199,7 @@ describe(':terminal highlight forwarding', function()
end)
it('will handle cterm and rgb attributes', function()
- skip(iswin())
+ skip(is_os('win'))
thelpers.set_fg(3)
thelpers.feed_data('text')
thelpers.feed_termcode('[38:2:255:128:0m')
@@ -251,7 +251,7 @@ describe(':terminal highlight with custom palette', function()
end)
it('will use the custom color', function()
- skip(iswin())
+ skip(is_os('win'))
thelpers.set_fg(3)
thelpers.feed_data('text')
thelpers.clear_attrs()
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index a062a77a14..899df0ac54 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -3,7 +3,7 @@ local thelpers = require('test.functional.terminal.helpers')
local clear, eq, eval = helpers.clear, helpers.eq, helpers.eval
local feed, nvim, command = helpers.feed, helpers.nvim, helpers.command
local feed_data = thelpers.feed_data
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
describe(':terminal mouse', function()
@@ -68,7 +68,7 @@ describe(':terminal mouse', function()
end)
it('does not leave terminal mode on left-release', function()
- skip(iswin())
+ skip(is_os('win'))
feed('<LeftRelease>')
eq('t', eval('mode(1)'))
end)
@@ -89,7 +89,7 @@ describe(':terminal mouse', function()
end)
it('will forward mouse press, drag and release to the program', function()
- skip(iswin())
+ skip(is_os('win'))
feed('<LeftMouse><1,2>')
screen:expect([[
line27 |
@@ -133,7 +133,7 @@ describe(':terminal mouse', function()
end)
it('will forward mouse scroll to the program', function()
- skip(iswin())
+ skip(is_os('win'))
feed('<ScrollWheelUp><0,0>')
screen:expect([[
line27 |
@@ -147,7 +147,7 @@ describe(':terminal mouse', function()
end)
it('dragging and scrolling do not interfere with each other', function()
- skip(iswin())
+ skip(is_os('win'))
feed('<LeftMouse><1,2>')
screen:expect([[
line27 |
@@ -201,7 +201,7 @@ describe(':terminal mouse', function()
end)
it('will forward mouse clicks to the program with the correct even if set nu', function()
- skip(iswin())
+ skip(is_os('win'))
command('set number')
-- When the display area such as a number is clicked, it returns to the
-- normal mode.
@@ -232,7 +232,7 @@ describe(':terminal mouse', function()
end)
describe('with a split window and other buffer', function()
- skip(iswin())
+ skip(is_os('win'))
before_each(function()
feed('<c-\\><c-n>:vsp<cr>')
screen:expect([[
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 873445f281..a4899c8219 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -3,7 +3,6 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
local feed, testprg, feed_command = helpers.feed, helpers.testprg, helpers.feed_command
-local iswin = helpers.iswin
local eval = helpers.eval
local command = helpers.command
local matches = helpers.matches
@@ -16,6 +15,7 @@ local pcall_err = helpers.pcall_err
local exec_lua = helpers.exec_lua
local assert_alive = helpers.assert_alive
local skip = helpers.skip
+local is_os = helpers.is_os
describe(':terminal scrollback', function()
local screen
@@ -140,7 +140,7 @@ describe(':terminal scrollback', function()
describe('and height decreased by 1', function()
- if skip(iswin()) then return end
+ if skip(is_os('win')) then return end
local function will_hide_top_line()
feed([[<C-\><C-N>]])
screen:try_resize(screen._width - 2, screen._height - 1)
@@ -186,7 +186,7 @@ describe(':terminal scrollback', function()
-- XXX: Can't test this reliably on Windows unless the cursor is _moved_
-- by the resize. http://docs.libuv.org/en/v1.x/signal.html
-- See also: https://github.com/rprichard/winpty/issues/110
- if skip(iswin()) then return end
+ if skip(is_os('win')) then return end
describe('and the height is decreased by 2', function()
before_each(function()
@@ -265,7 +265,7 @@ describe(':terminal scrollback', function()
-- XXX: Can't test this reliably on Windows unless the cursor is _moved_
-- by the resize. http://docs.libuv.org/en/v1.x/signal.html
-- See also: https://github.com/rprichard/winpty/issues/110
- if skip(iswin()) then return end
+ if skip(is_os('win')) then return end
local function pop_then_push()
screen:try_resize(screen._width, screen._height + 1)
screen:expect([[
@@ -347,7 +347,7 @@ end)
describe(':terminal prints more lines than the screen height and exits', function()
it('will push extra lines to scrollback', function()
- skip(iswin())
+ skip(is_os('win'))
clear()
local screen = Screen.new(30, 7)
screen:attach({rgb=false})
@@ -397,21 +397,21 @@ describe("'scrollback' option", function()
it('set to 0 behaves as 1', function()
local screen
- if iswin() then
+ if is_os('win') then
screen = thelpers.screen_setup(nil, "['cmd.exe']", 30)
else
screen = thelpers.screen_setup(nil, "['sh']", 30)
end
curbufmeths.set_option('scrollback', 0)
- feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n'))
+ feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n'))
screen:expect{any='30: line '}
retry(nil, nil, function() expect_lines(7) end)
end)
it('deletes lines (only) if necessary', function()
local screen
- if iswin() then
+ if is_os('win') then
command([[let $PROMPT='$$']])
screen = thelpers.screen_setup(nil, "['cmd.exe']", 30)
else
@@ -424,7 +424,7 @@ describe("'scrollback' option", function()
-- Wait for prompt.
screen:expect{any='%$'}
- feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n'))
+ feed_data(('%s REP 31 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n'))
screen:expect{any='30: line '}
retry(nil, nil, function() expect_lines(33, 2) end)
@@ -437,8 +437,8 @@ describe("'scrollback' option", function()
-- 'scrollback' option is synchronized with the internal sb_buffer.
command('sleep 100m')
- feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), iswin() and '\r' or '\n'))
- if iswin() then
+ feed_data(('%s REP 41 line%s'):format(testprg('shell-test'), is_os('win') and '\r' or '\n'))
+ if is_os('win') then
screen:expect{grid=[[
37: line |
38: line |
@@ -462,8 +462,8 @@ describe("'scrollback' option", function()
expect_lines(58)
-- Verify off-screen state
- matches((iswin() and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)"))
- matches((iswin() and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)"))
+ matches((is_os('win') and '^36: line[ ]*$' or '^35: line[ ]*$'), eval("getline(line('w0') - 1)"))
+ matches((is_os('win') and '^27: line[ ]*$' or '^26: line[ ]*$'), eval("getline(line('w0') - 10)"))
end)
it('deletes extra lines immediately', function()
@@ -607,7 +607,7 @@ describe("pending scrollback line handling", function()
end)
it("does not crash after nvim_buf_call #14891", function()
- skip(iswin())
+ skip(is_os('win'))
exec_lua [[
local a = vim.api
local bufnr = a.nvim_create_buf(false, true)
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index d2e409cc0f..b3d2625d78 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -5,7 +5,6 @@
-- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Bracketed-Paste-Mode
local helpers = require('test.functional.helpers')(after_each)
-local uname = helpers.uname
local thelpers = require('test.functional.terminal.helpers')
local Screen = require('test.functional.ui.screen')
local assert_alive = helpers.assert_alive
@@ -22,12 +21,15 @@ local ok = helpers.ok
local read_file = helpers.read_file
local funcs = helpers.funcs
local meths = helpers.meths
+local is_ci = helpers.is_ci
+local is_os = helpers.is_os
-if helpers.skip(helpers.iswin()) then return end
+if helpers.skip(helpers.is_os('win')) then return end
describe('TUI', function()
local screen
local child_session
+ local child_exec_lua
before_each(function()
clear()
@@ -45,6 +47,7 @@ describe('TUI', function()
{3:-- TERMINAL --} |
]])
child_session = helpers.connect(child_server)
+ child_exec_lua = thelpers.make_lua_executor(child_session)
end)
-- Wait for mode in the child Nvim (avoid "typeahead race" #10826).
@@ -819,12 +822,11 @@ describe('TUI', function()
end)
it('paste: terminal mode', function()
- if os.getenv('GITHUB_ACTIONS') ~= nil then
+ if is_ci('github') then
pending("tty-test complains about not owning the terminal -- actions/runner#241")
- return
end
- feed_data(':set statusline=^^^^^^^\n')
- feed_data(':terminal '..testprg('tty-test')..'\n')
+ child_exec_lua('vim.o.statusline="^^^^^^^"')
+ child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test'))
feed_data('i')
screen:expect{grid=[[
tty ready |
@@ -1087,7 +1089,7 @@ describe('TUI', function()
-- "bracketed paste"
feed_data('\027[200~'..expected..'\027[201~')
-- FIXME: Data race between the two feeds
- if uname() == 'freebsd' then screen:sleep(1) end
+ if is_os('freebsd') then screen:sleep(1) end
feed_data(' end')
expected = expected..' end'
screen:expect([[
@@ -1327,9 +1329,8 @@ describe('TUI', function()
end)
it('forwards :term palette colors with termguicolors', function()
- if os.getenv('GITHUB_ACTIONS') ~= nil then
+ if is_ci('github') then
pending("tty-test complains about not owning the terminal -- actions/runner#241")
- return
end
screen:set_rgb_cterm(true)
screen:set_default_attr_ids({
@@ -1340,12 +1341,9 @@ describe('TUI', function()
[5] = {{foreground = tonumber('0xff8000')}, {}},
})
- feed_data(':set statusline=^^^^^^^\n')
- feed_data(':set termguicolors\n')
- feed_data(':terminal '..testprg('tty-test')..'\n')
- -- Depending on platform the above might or might not fit in the cmdline
- -- so clear it for consistent behavior.
- feed_data(':\027')
+ child_exec_lua('vim.o.statusline="^^^^^^^"')
+ child_exec_lua('vim.o.termguicolors=true')
+ child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test'))
screen:expect{grid=[[
{1:t}ty ready |
|
@@ -1670,7 +1668,6 @@ end)
-- does not initialize the TUI.
describe("TUI 't_Co' (terminal colors)", function()
local screen
- local is_freebsd = (uname() == 'freebsd')
local function assert_term_colors(term, colorterm, maxcolors)
helpers.clear({env={TERM=term}, args={}})
@@ -1773,7 +1770,7 @@ describe("TUI 't_Co' (terminal colors)", function()
-- which is raised to 16 by COLORTERM.
it("TERM=screen no COLORTERM uses 8/256 colors", function()
- if is_freebsd then
+ if is_os('freebsd') then
assert_term_colors("screen", nil, 256)
else
assert_term_colors("screen", nil, 8)
@@ -1781,7 +1778,7 @@ describe("TUI 't_Co' (terminal colors)", function()
end)
it("TERM=screen COLORTERM=screen uses 16/256 colors", function()
- if is_freebsd then
+ if is_os('freebsd') then
assert_term_colors("screen", "screen", 256)
else
assert_term_colors("screen", "screen", 16)
@@ -1944,8 +1941,6 @@ end)
-- does not initialize the TUI.
describe("TUI 'term' option", function()
local screen
- local is_bsd = not not string.find(uname(), 'bsd')
- local is_macos = not not string.find(uname(), 'darwin')
local function assert_term(term_envvar, term_expected)
clear()
@@ -1971,11 +1966,11 @@ describe("TUI 'term' option", function()
end)
it('gets system-provided term if $TERM is valid', function()
- if uname() == "openbsd" then
+ if is_os('openbsd') then
assert_term("xterm", "xterm")
- elseif is_bsd then -- BSD lacks terminfo, builtin is always used.
+ elseif is_os('bsd') then -- BSD lacks terminfo, builtin is always used.
assert_term("xterm", "builtin_xterm")
- elseif is_macos then
+ elseif is_os('mac') then
local status, _ = pcall(assert_term, "xterm", "xterm")
if not status then
pending("macOS: unibilium could not find terminfo")
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 81cd1017db..80e9d78400 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -3,12 +3,12 @@ local thelpers = require('test.functional.terminal.helpers')
local feed_data = thelpers.feed_data
local feed, clear = helpers.feed, helpers.clear
local poke_eventloop = helpers.poke_eventloop
-local iswin = helpers.iswin
local command = helpers.command
local retry = helpers.retry
local eq = helpers.eq
local eval = helpers.eval
local skip = helpers.skip
+local is_os = helpers.is_os
describe(':terminal window', function()
local screen
@@ -19,7 +19,7 @@ describe(':terminal window', function()
end)
it('sets topline correctly #8556', function()
- skip(iswin())
+ skip(is_os('win'))
-- Test has hardcoded assumptions of dimensions.
eq(7, eval('&lines'))
feed_data('\n\n\n') -- Add blank lines.
@@ -55,7 +55,7 @@ describe(':terminal window', function()
{3:-- TERMINAL --} |
]])
- skip(iswin(), 'win: :terminal resize is unreliable #7007')
+ skip(is_os('win'), 'win: :terminal resize is unreliable #7007')
-- numberwidth=9
feed([[<C-\><C-N>]])
@@ -171,7 +171,7 @@ describe(':terminal with multigrid', function()
]])
screen:try_resize_grid(2, 20, 10)
- if iswin() then
+ if is_os('win') then
screen:expect{any="rows: 10, cols: 20"}
else
screen:expect([[
@@ -200,7 +200,7 @@ describe(':terminal with multigrid', function()
end
screen:try_resize_grid(2, 70, 3)
- if iswin() then
+ if is_os('win') then
screen:expect{any="rows: 3, cols: 70"}
else
screen:expect([[
@@ -222,7 +222,7 @@ describe(':terminal with multigrid', function()
end
screen:try_resize_grid(2, 0, 0)
- if iswin() then
+ if is_os('win') then
screen:expect{any="rows: 6, cols: 50"}
else
screen:expect([[
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index b62d173cea..1d77e1e92e 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -8,9 +8,9 @@ local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
local meths = helpers.meths
-local iswin = helpers.iswin
local sleep = helpers.sleep
local retry = helpers.retry
+local is_os = helpers.is_os
describe(':terminal', function()
local screen
@@ -96,7 +96,7 @@ describe(':terminal', function()
local w1, h1 = screen._width - 3, screen._height - 2
local w2, h2 = w1 - 6, h1 - 3
- if iswin() then
+ if is_os('win') then
-- win: SIGWINCH is unreliable, use a weaker test. #7506
retry(3, 30000, function()
screen:try_resize(w1, h1)
diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua
index c6ddf812be..f006ad4539 100644
--- a/test/functional/treesitter/parser_spec.lua
+++ b/test/functional/treesitter/parser_spec.lua
@@ -5,7 +5,7 @@ local eq = helpers.eq
local insert = helpers.insert
local exec_lua = helpers.exec_lua
local feed = helpers.feed
-local iswin = helpers.iswin
+local is_os = helpers.is_os
local skip = helpers.skip
before_each(clear)
@@ -684,7 +684,7 @@ int x = INT_MAX;
end)
it("should not inject bad languages", function()
- skip(iswin())
+ skip(is_os('win'))
exec_lua([=[
vim.treesitter.add_directive("inject-bad!", function(match, _, _, pred, metadata)
metadata.language = "{"
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 8003947078..c73c2d9f8a 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -4,10 +4,10 @@ local clear, feed = helpers.clear, helpers.feed
local source = helpers.source
local command = helpers.command
local assert_alive = helpers.assert_alive
-local uname = helpers.uname
local exec = helpers.exec
local eval = helpers.eval
local eq = helpers.eq
+local is_os = helpers.is_os
local function new_screen(opt)
local screen = Screen.new(25, 5)
@@ -717,7 +717,7 @@ describe('cmdline redraw', function()
end)
it('with <Cmd>', function()
- if string.find(uname(), 'bsd') then
+ if is_os('bsd') then
pending('FIXME #10804')
end
command('cmap a <Cmd>call sin(0)<CR>') -- no-op
diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua
index e7addd1b85..cd2b48213d 100644
--- a/test/functional/ui/embed_spec.lua
+++ b/test/functional/ui/embed_spec.lua
@@ -51,7 +51,7 @@ local function test_embed(ext_linegrid)
end)
it("doesn't erase output when setting color scheme", function()
- if 'openbsd' == helpers.uname() then
+ if helpers.is_os('openbsd') then
pending('FIXME #10804')
end
startup('--cmd', 'echoerr "foo"', '--cmd', 'color default', '--cmd', 'echoerr "bar"')
diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua
index a8b4c05747..55f873e827 100644
--- a/test/functional/ui/hlstate_spec.lua
+++ b/test/functional/ui/hlstate_spec.lua
@@ -4,10 +4,10 @@ local Screen = require('test.functional.ui.screen')
local clear, insert = helpers.clear, helpers.insert
local command = helpers.command
local meths = helpers.meths
-local iswin = helpers.iswin
local testprg = helpers.testprg
local thelpers = require('test.functional.terminal.helpers')
local skip = helpers.skip
+local is_os = helpers.is_os
describe('ext_hlstate detailed highlights', function()
local screen
@@ -183,7 +183,7 @@ describe('ext_hlstate detailed highlights', function()
end)
it("work with :terminal", function()
- skip(iswin())
+ skip(is_os('win'))
screen:set_default_attr_ids({
[1] = {{}, {{hi_name = "TermCursorNC", ui_name = "TermCursorNC", kind = "ui"}}},
@@ -212,7 +212,7 @@ describe('ext_hlstate detailed highlights', function()
thelpers.set_bold()
thelpers.feed_data('z\n')
-- TODO(bfredl): check if this distinction makes sense
- if iswin() then
+ if is_os('win') then
screen:expect([[
^tty ready |
x {5:y z} |
@@ -238,7 +238,7 @@ describe('ext_hlstate detailed highlights', function()
thelpers.feed_termcode("[A")
thelpers.feed_termcode("[2C")
- if iswin() then
+ if is_os('win') then
screen:expect([[
^tty ready |
x {6:y}{5: z} |
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 60b538eee5..f7ffe16bd6 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -9,12 +9,13 @@ local meths = helpers.meths
local async_meths = helpers.async_meths
local test_build_dir = helpers.test_build_dir
local nvim_prog = helpers.nvim_prog
-local iswin = helpers.iswin
local exec = helpers.exec
local exc_exec = helpers.exc_exec
local exec_lua = helpers.exec_lua
local poke_eventloop = helpers.poke_eventloop
local assert_alive = helpers.assert_alive
+local is_os = helpers.is_os
+local is_ci = helpers.is_ci
describe('ui/ext_messages', function()
local screen
@@ -1496,7 +1497,7 @@ describe('ui/msg_puts_printf', function()
screen = Screen.new(25, 5)
screen:attach()
- if iswin() then
+ if is_os('win') then
if os.execute('chcp 932 > NUL 2>&1') ~= 0 then
pending('missing japanese language features', function() end)
return
@@ -1507,7 +1508,7 @@ describe('ui/msg_puts_printf', function()
if (exc_exec('lang ja_JP.UTF-8') ~= 0) then
pending('Locale ja_JP.UTF-8 not supported', function() end)
return
- elseif helpers.isCI() then
+ elseif is_ci() then
-- Fails non--Windows CI. Message catalog directory issue?
pending('fails on unix CI', function() end)
return
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index b3ea0edb12..f705678bd5 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -968,6 +968,49 @@ describe('ui/mouse/input', function()
]])
end)
+ it("'sidescrolloff' applies to horizontal scrolling", function()
+ command('set nowrap')
+ command('set sidescrolloff=4')
+
+ feed("I <esc>020ib<esc>0")
+ screen:expect([[
+ testing |
+ mouse |
+ ^bbbbbbbbbbbbbbbbbbbb supp|
+ {0:~ }|
+ |
+ ]])
+
+ meths.input_mouse('wheel', 'right', '', 0, 0, 27)
+ screen:expect([[
+ g |
+ |
+ bbbb^bbbbbbbbbb support an|
+ {0:~ }|
+ |
+ ]])
+
+ -- window-local 'sidescrolloff' should override global value. #21162
+ command('setlocal sidescrolloff=2')
+ feed('0')
+ screen:expect([[
+ testing |
+ mouse |
+ ^bbbbbbbbbbbbbbbbbbbb supp|
+ {0:~ }|
+ |
+ ]])
+
+ meths.input_mouse('wheel', 'right', '', 0, 0, 27)
+ screen:expect([[
+ g |
+ |
+ bb^bbbbbbbbbbbb support an|
+ {0:~ }|
+ |
+ ]])
+ end)
+
describe('on concealed text', function()
-- Helpful for reading the test expectations:
-- :match Error /\^/
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 0825772d57..223844405e 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -6,7 +6,6 @@ local mkdir, write_file, rmdir = helpers.mkdir, helpers.write_file, helpers.rmdi
local eq = helpers.eq
local feed = helpers.feed
local feed_command = helpers.feed_command
-local iswin = helpers.iswin
local clear = helpers.clear
local command = helpers.command
local testprg = helpers.testprg
@@ -14,6 +13,7 @@ local nvim_dir = helpers.nvim_dir
local has_powershell = helpers.has_powershell
local set_shell_powershell = helpers.set_shell_powershell
local skip = helpers.skip
+local is_os = helpers.is_os
describe("shell command :!", function()
local screen
@@ -37,7 +37,7 @@ describe("shell command :!", function()
end)
it("displays output without LF/EOF. #4646 #4569 #3772", function()
- skip(iswin())
+ skip(is_os('win'))
-- NOTE: We use a child nvim (within a :term buffer)
-- to avoid triggering a UI flush.
child_session.feed_data(":!printf foo; sleep 200\n")
@@ -53,7 +53,7 @@ describe("shell command :!", function()
end)
it("throttles shell-command output greater than ~10KB", function()
- skip('openbsd' == helpers.uname(), 'FIXME #10804')
+ skip(is_os('openbsd'), 'FIXME #10804')
child_session.feed_data((":!%s REP 30001 foo\n"):format(testprg('shell-test')))
-- If we observe any line starting with a dot, then throttling occurred.
@@ -95,7 +95,7 @@ describe("shell command :!", function()
end)
it('handles control codes', function()
- skip(iswin(), 'missing printf')
+ skip(is_os('win'), 'missing printf')
local screen = Screen.new(50, 4)
screen:set_default_attr_ids {
[1] = {bold = true, reverse = true};
@@ -170,10 +170,10 @@ describe("shell command :!", function()
end)
it("doesn't truncate Last line of shell output #3269", function()
- command(helpers.iswin()
+ command(is_os('win')
and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]]
or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]])
- local result = (helpers.iswin()
+ local result = (is_os('win')
and [[:!dir /b bang_filter_spec]]
or [[:!ls bang_filter_spec ]])
feed([[\l]])
@@ -212,7 +212,7 @@ describe("shell command :!", function()
it('handles multibyte sequences split over buffer boundaries', function()
command('cd '..nvim_dir)
- local cmd = iswin() and '!shell-test UTF-8 ' or '!./shell-test UTF-8'
+ local cmd = is_os('win') and '!shell-test UTF-8 ' or '!./shell-test UTF-8'
feed_command(cmd)
-- Note: only the first example of split composed char works
screen:expect([[
@@ -262,7 +262,7 @@ describe("shell command :!", function()
|
Press ENTER or type command to continue^ |
]])
- if iswin() then
+ if is_os('win') then
feed_command([[!& 'cmd.exe' /c 'echo $a']])
screen:expect([[
:!& 'cmd.exe' /c 'echo $a' |
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index 5aacdc95e2..3bd2289a73 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -5,8 +5,8 @@ local feed, command = helpers.feed, helpers.command
local insert = helpers.insert
local eq = helpers.eq
local eval = helpers.eval
-local iswin = helpers.iswin
local funcs, meths, exec_lua = helpers.funcs, helpers.meths, helpers.exec_lua
+local is_os = helpers.is_os
describe('screen', function()
local screen
@@ -128,18 +128,18 @@ local function screen_tests(linegrid)
end)
it('has correct default title with named file', function()
- local expected = (iswin() and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM')
+ local expected = (is_os('win') and 'myfile (C:\\mydir) - NVIM' or 'myfile (/mydir) - NVIM')
command('set title')
- command(iswin() and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
+ command(is_os('win') and 'file C:\\mydir\\myfile' or 'file /mydir/myfile')
screen:expect(function()
eq(expected, screen.title)
end)
end)
describe('is not changed by', function()
- local file1 = iswin() and 'C:\\mydir\\myfile1' or '/mydir/myfile1'
- local file2 = iswin() and 'C:\\mydir\\myfile2' or '/mydir/myfile2'
- local expected = (iswin() and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM')
+ local file1 = is_os('win') and 'C:\\mydir\\myfile1' or '/mydir/myfile1'
+ local file2 = is_os('win') and 'C:\\mydir\\myfile2' or '/mydir/myfile2'
+ local expected = (is_os('win') and 'myfile1 (C:\\mydir) - NVIM' or 'myfile1 (/mydir) - NVIM')
local buf2
before_each(function()
diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua
index 1aa73e7b13..425790dbf9 100644
--- a/test/functional/ui/spell_spec.lua
+++ b/test/functional/ui/spell_spec.lua
@@ -5,8 +5,8 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local feed = helpers.feed
local insert = helpers.insert
-local uname = helpers.uname
local command = helpers.command
+local is_os = helpers.is_os
describe("'spell'", function()
local screen
@@ -27,7 +27,7 @@ describe("'spell'", function()
end)
it('joins long lines #7937', function()
- if uname() == 'openbsd' then pending('FIXME #12104', function() end) return end
+ if is_os('openbsd') then pending('FIXME #12104', function() end) return end
command('set spell')
insert([[
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index f1e818119e..50466c9473 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -1,13 +1,13 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, command = helpers.clear, helpers.feed, helpers.command
-local iswin = helpers.iswin
local funcs = helpers.funcs
local meths = helpers.meths
local eq = helpers.eq
local eval = helpers.eval
local retry = helpers.retry
local testprg = helpers.testprg
+local is_os = helpers.is_os
describe("'wildmenu'", function()
local screen
@@ -159,7 +159,7 @@ describe("'wildmenu'", function()
-- must wait the full timeout. So make it reasonable.
screen.timeout = 1000
- if not iswin() then
+ if not is_os('win') then
command('set shell=sh') -- Need a predictable "$" prompt.
command('let $PS1 = "$"')
end
@@ -169,7 +169,7 @@ describe("'wildmenu'", function()
-- Check for a shell prompt to verify that the terminal loaded.
retry(nil, nil, function()
- if iswin() then
+ if is_os('win') then
eq('Microsoft', eval("matchstr(join(getline(1, '$')), 'Microsoft')"))
else
eq('$', eval([[matchstr(getline(1), '\$')]]))
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index d50c252569..a8a901042b 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -71,13 +71,13 @@ describe("backtick expansion", function()
end)
it("with default 'shell'", function()
- if helpers.iswin() then
+ if helpers.is_os('win') then
command(":silent args `dir /b *2`")
else
command(":silent args `echo ***2`")
end
eq({ "file2", }, eval("argv()"))
- if helpers.iswin() then
+ if helpers.is_os('win') then
command(":silent args `dir /s/b *4`")
eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')"))
else
diff --git a/test/functional/vimscript/executable_spec.lua b/test/functional/vimscript/executable_spec.lua
index b49eb09512..43e4a29e1a 100644
--- a/test/functional/vimscript/executable_spec.lua
+++ b/test/functional/vimscript/executable_spec.lua
@@ -1,15 +1,16 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin, write_file, command =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin, helpers.write_file,
+local eq, clear, call, write_file, command =
+ helpers.eq, helpers.clear, helpers.call, helpers.write_file,
helpers.command
local exc_exec = helpers.exc_exec
local eval = helpers.eval
+local is_os = helpers.is_os
describe('executable()', function()
before_each(clear)
it('returns 1 for commands in $PATH', function()
- local exe = iswin() and 'ping' or 'ls'
+ local exe = is_os('win') and 'ping' or 'ls'
eq(1, call('executable', exe))
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
eq(1, call('executable', 'null'))
@@ -17,7 +18,7 @@ describe('executable()', function()
eq(1, call('executable', 'false'))
end)
- if iswin() then
+ if is_os('win') then
it('exepath respects shellslash', function()
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
eq([[test\functional\fixtures\bin\null.CMD]], call('fnamemodify', call('exepath', 'null'), ':.'))
@@ -56,8 +57,8 @@ describe('executable()', function()
-- Some executable in build/bin/, *not* in $PATH nor CWD.
local sibling_exe = 'printargs-test'
-- Windows: siblings are in Nvim's "pseudo-$PATH".
- local expected = iswin() and 1 or 0
- if iswin() then
+ local expected = is_os('win') and 1 or 0
+ if is_os('win') then
eq('arg1=lemon;arg2=sky;arg3=tree;',
call('system', sibling_exe..' lemon sky tree'))
end
@@ -69,7 +70,7 @@ describe('executable()', function()
clear()
write_file('Xtest_not_executable', 'non-executable file')
write_file('Xtest_executable', 'executable file (exec-bit set)')
- if not iswin() then -- N/A for Windows.
+ if not is_os('win') then -- N/A for Windows.
call('system', {'chmod', '-x', 'Xtest_not_executable'})
call('system', {'chmod', '+x', 'Xtest_executable'})
end
@@ -90,14 +91,17 @@ describe('executable()', function()
end)
it('set, qualified as a path', function()
- local expected = iswin() and 0 or 1
+ local expected = is_os('win') and 0 or 1
eq(expected, call('executable', './Xtest_executable'))
end)
end)
end)
describe('executable() (Windows)', function()
- if not iswin() then return end -- N/A for Unix.
+ if not is_os('win') then
+ pending('N/A for non-windows')
+ return
+ end
local exts = {'bat', 'exe', 'com', 'cmd'}
setup(function()
diff --git a/test/functional/vimscript/execute_spec.lua b/test/functional/vimscript/execute_spec.lua
index a733b098f5..5fe3d787cb 100644
--- a/test/functional/vimscript/execute_spec.lua
+++ b/test/functional/vimscript/execute_spec.lua
@@ -8,7 +8,7 @@ local funcs = helpers.funcs
local Screen = require('test.functional.ui.screen')
local command = helpers.command
local feed = helpers.feed
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('execute()', function()
before_each(clear)
@@ -265,7 +265,7 @@ describe('execute()', function()
-- This deviates from vim behavior, but is consistent
-- with how nvim currently displays the output.
it('captures shell-command output', function()
- local win_lf = iswin() and '\13' or ''
+ local win_lf = is_os('win') and '\13' or ''
eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo'))
end)
diff --git a/test/functional/vimscript/exepath_spec.lua b/test/functional/vimscript/exepath_spec.lua
index db96b79743..056f67e0ad 100644
--- a/test/functional/vimscript/exepath_spec.lua
+++ b/test/functional/vimscript/exepath_spec.lua
@@ -1,19 +1,20 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin
+local eq, clear, call =
+ helpers.eq, helpers.clear, helpers.call
local command = helpers.command
local exc_exec = helpers.exc_exec
local matches = helpers.matches
+local is_os = helpers.is_os
describe('exepath()', function()
before_each(clear)
it('returns 1 for commands in $PATH', function()
- local exe = iswin() and 'ping' or 'ls'
- local ext_pat = iswin() and '%.EXE$' or '$'
+ local exe = is_os('win') and 'ping' or 'ls'
+ local ext_pat = is_os('win') and '%.EXE$' or '$'
matches(exe .. ext_pat, call('exepath', exe))
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
- ext_pat = iswin() and '%.CMD$' or '$'
+ ext_pat = is_os('win') and '%.CMD$' or '$'
matches('null' .. ext_pat, call('exepath', 'null'))
matches('true' .. ext_pat, call('exepath', 'true'))
matches('false' .. ext_pat, call('exepath', 'false'))
@@ -30,7 +31,7 @@ describe('exepath()', function()
end
end)
- if iswin() then
+ if is_os('win') then
it('append extension if omitted', function()
local filename = 'cmd'
local pathext = '.exe'
diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua
index d54a6db417..c3ecdd853c 100644
--- a/test/functional/vimscript/fnamemodify_spec.lua
+++ b/test/functional/vimscript/fnamemodify_spec.lua
@@ -1,12 +1,12 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
-local iswin = helpers.iswin
local fnamemodify = helpers.funcs.fnamemodify
local getcwd = helpers.funcs.getcwd
local command = helpers.command
local write_file = helpers.write_file
local alter_slashes = helpers.alter_slashes
+local is_os = helpers.is_os
local function eq_slashconvert(expected, got)
eq(alter_slashes(expected), alter_slashes(got))
@@ -27,7 +27,7 @@ describe('fnamemodify()', function()
local root = helpers.pathroot()
eq(root, fnamemodify([[/]], ':p:h'))
eq(root, fnamemodify([[/]], ':p'))
- if iswin() then
+ if is_os('win') then
eq(root, fnamemodify([[\]], ':p:h'))
eq(root, fnamemodify([[\]], ':p'))
command('set shellslash')
@@ -114,7 +114,7 @@ describe('fnamemodify()', function()
it('handles shell escape', function()
local expected
- if iswin() then
+ if is_os('win') then
-- we expand with double-quotes on Windows
expected = [["hello there! quote ' newline]] .. '\n' .. [["]]
else
diff --git a/test/functional/vimscript/functions_spec.lua b/test/functional/vimscript/functions_spec.lua
index 20c1400030..09b3334989 100644
--- a/test/functional/vimscript/functions_spec.lua
+++ b/test/functional/vimscript/functions_spec.lua
@@ -9,12 +9,12 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eval = helpers.eval
-local iswin = helpers.iswin
local matches = helpers.matches
+local is_os = helpers.is_os
before_each(clear)
it('windowsversion()', function()
clear()
- matches(iswin() and '^%d+%.%d+$' or '^$', eval('windowsversion()'))
+ matches(is_os('win') and '^%d+%.%d+$' or '^$', eval('windowsversion()'))
end)
diff --git a/test/functional/vimscript/has_spec.lua b/test/functional/vimscript/has_spec.lua
index 4d9b226434..2e26d603b3 100644
--- a/test/functional/vimscript/has_spec.lua
+++ b/test/functional/vimscript/has_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local clear = helpers.clear
local funcs = helpers.funcs
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('has()', function()
before_each(clear)
@@ -51,7 +51,7 @@ describe('has()', function()
end)
it('"unnamedplus"', function()
- if (not iswin()) and funcs.has("clipboard") == 1 then
+ if (not is_os('win')) and funcs.has("clipboard") == 1 then
eq(1, funcs.has("unnamedplus"))
else
eq(0, funcs.has("unnamedplus"))
diff --git a/test/functional/vimscript/hostname_spec.lua b/test/functional/vimscript/hostname_spec.lua
index 6112cf64e3..7d4baa7213 100644
--- a/test/functional/vimscript/hostname_spec.lua
+++ b/test/functional/vimscript/hostname_spec.lua
@@ -3,7 +3,7 @@ local eq = helpers.eq
local ok = helpers.ok
local call = helpers.call
local clear = helpers.clear
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('hostname()', function()
before_each(clear)
@@ -13,8 +13,8 @@ describe('hostname()', function()
ok(string.len(actual) > 0)
if call('executable', 'hostname') == 1 then
local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '')
- eq((iswin() and expected:upper() or expected),
- (iswin() and actual:upper() or actual))
+ eq((is_os('win') and expected:upper() or expected),
+ (is_os('win') and actual:upper() or actual))
end
end)
end)
diff --git a/test/functional/vimscript/msgpack_functions_spec.lua b/test/functional/vimscript/msgpack_functions_spec.lua
index cab67d77e4..de5a721efe 100644
--- a/test/functional/vimscript/msgpack_functions_spec.lua
+++ b/test/functional/vimscript/msgpack_functions_spec.lua
@@ -5,7 +5,7 @@ local eval, eq = helpers.eval, helpers.eq
local command = helpers.command
local nvim = helpers.nvim
local exc_exec = helpers.exc_exec
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('msgpack*() functions', function()
before_each(clear)
@@ -467,7 +467,7 @@ describe('msgpackparse() function', function()
eval(cmd)
eval(cmd) -- do it again (try to force segfault)
local api_info = eval(cmd) -- do it again
- if iswin() then
+ if is_os('win') then
helpers.assert_alive()
pending('msgpackparse() has a bug on windows')
return
diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua
index 6e95459630..14c87d9d93 100644
--- a/test/functional/vimscript/server_spec.lua
+++ b/test/functional/vimscript/server_spec.lua
@@ -1,11 +1,11 @@
local helpers = require('test.functional.helpers')(after_each)
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
-local iswin = helpers.iswin
local ok = helpers.ok
local matches = helpers.matches
local pcall_err = helpers.pcall_err
local mkdir = helpers.mkdir
+local is_os = helpers.is_os
local function clear_serverlist()
for _, server in pairs(funcs.serverlist()) do
@@ -19,7 +19,7 @@ describe('server', function()
mkdir(dir)
clear({ env={ XDG_RUNTIME_DIR=dir } })
matches(dir, funcs.stdpath('run'))
- if not iswin() then
+ if not is_os('win') then
matches(dir, funcs.serverstart())
end
end)
@@ -65,7 +65,7 @@ describe('server', function()
eq('', meths.get_vvar('servername'))
-- v:servername and $NVIM take the next available server.
- local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
+ local servername = (is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]]
or './Xtest-functional-server-socket')
funcs.serverstart(servername)
eq(servername, meths.get_vvar('servername'))
@@ -130,7 +130,7 @@ describe('server', function()
local n = eval('len(serverlist())')
-- Add some servers.
- local servs = (iswin()
+ local servs = (is_os('win')
and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] })
for _, s in ipairs(servs) do
@@ -164,7 +164,7 @@ describe('startup --listen', function()
end)
it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
- local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]]
+ local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]]
or './Xtest-listen-pipe')
clear({ env={ NVIM_LISTEN_ADDRESS='./Xtest-env-pipe' },
args={ '--listen', addr } })
diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua
index ed822add72..dbf734b51a 100644
--- a/test/functional/vimscript/system_spec.lua
+++ b/test/functional/vimscript/system_spec.lua
@@ -9,9 +9,9 @@ local command = helpers.command
local insert = helpers.insert
local expect = helpers.expect
local exc_exec = helpers.exc_exec
-local iswin = helpers.iswin
local os_kill = helpers.os_kill
local pcall_err = helpers.pcall_err
+local is_os = helpers.is_os
local Screen = require('test.functional.ui.screen')
@@ -85,7 +85,7 @@ describe('system()', function()
end)
it('does NOT run in shell', function()
- if iswin() then
+ if is_os('win') then
eq("%PATH%\n", eval("system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])"))
else
eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])"))
@@ -94,7 +94,7 @@ describe('system()', function()
end)
it('sets v:shell_error', function()
- if iswin() then
+ if is_os('win') then
eval([[system("cmd.exe /c exit")]])
eq(0, eval('v:shell_error'))
eval([[system("cmd.exe /c exit 1")]])
@@ -123,7 +123,7 @@ describe('system()', function()
screen:attach()
end)
- if iswin() then
+ if is_os('win') then
local function test_more()
eq('root = true', eval([[get(split(system('"more" ".editorconfig"'), "\n"), 0, '')]]))
end
@@ -184,7 +184,7 @@ describe('system()', function()
-- * on Windows, expected to default to Western European enc
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
- eq(iswin() and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
+ eq(is_os('win') and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
end)
it('`echo` and waits for its return', function()
@@ -213,7 +213,7 @@ describe('system()', function()
screen:try_resize(72, 14)
feed(':4verbose echo system("echo hi")<cr>')
- if iswin() then
+ if is_os('win') then
screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]]}
else
screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]]}
@@ -243,7 +243,7 @@ describe('system()', function()
end)
it('`yes` interrupted with CTRL-C', function()
- feed(':call system("' .. (iswin()
+ feed(':call system("' .. (is_os('win')
and 'for /L %I in (1,0,2) do @echo y'
or 'yes') .. '")<cr>')
screen:expect([[
@@ -260,7 +260,7 @@ describe('system()', function()
~ |
~ |
~ |
-]] .. (iswin()
+]] .. (is_os('win')
and [[
:call system("for /L %I in (1,0,2) do @echo y") |]]
or [[
@@ -286,7 +286,7 @@ describe('system()', function()
it('`yes` interrupted with mapped CTRL-C', function()
command('nnoremap <C-C> i')
- feed(':call system("' .. (iswin()
+ feed(':call system("' .. (is_os('win')
and 'for /L %I in (1,0,2) do @echo y'
or 'yes') .. '")<cr>')
screen:expect([[
@@ -303,7 +303,7 @@ describe('system()', function()
~ |
~ |
~ |
-]] .. (iswin()
+]] .. (is_os('win')
and [[
:call system("for /L %I in (1,0,2) do @echo y") |]]
or [[
@@ -330,7 +330,7 @@ describe('system()', function()
describe('passing no input', function()
it('returns the program output', function()
- if iswin() then
+ if is_os('win') then
eq("echoed\n", eval('system("echo echoed")'))
else
eq("echoed", eval('system("echo -n echoed")'))
@@ -438,7 +438,7 @@ describe('systemlist()', function()
before_each(clear)
it('sets v:shell_error', function()
- if iswin() then
+ if is_os('win') then
eval([[systemlist("cmd.exe /c exit")]])
eq(0, eval('v:shell_error'))
eval([[systemlist("cmd.exe /c exit 1")]])
@@ -617,12 +617,12 @@ describe('systemlist()', function()
return
end
helpers.set_shell_powershell()
- eq({iswin() and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
+ eq({is_os('win') and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
-- Sanity test w/ default encoding
-- * on Windows, expected to default to Western European enc
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
- eq({iswin() and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
+ eq({is_os('win') and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
end)
end)
@@ -639,7 +639,7 @@ describe('shell :!', function()
1
4
2]])
- if iswin() then
+ if is_os('win') then
feed(':4verbose %!sort /R<cr>')
screen:expect{
any=[[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | Out%-File %-Encoding UTF8 .*; exit $LastExitCode"]]
diff --git a/test/helpers.lua b/test/helpers.lua
index 68c1b17dbc..eef47563a0 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -269,14 +269,10 @@ function module.check_logs()
table.concat(runtime_errors, ', ')))
end
-function module.iswin()
- return package.config:sub(1,1) == '\\'
-end
-
--- Gets (lowercase) OS name from CMake, uname, or "win" if iswin().
-module.uname = (function()
+-- Gets (lowercase) OS name from CMake, uname, or manually check if on Windows
+do
local platform = nil
- return (function()
+ function module.uname()
if platform then
return platform
end
@@ -290,22 +286,28 @@ module.uname = (function()
if status then
platform = string.lower(f:read("*l"))
f:close()
- elseif module.iswin() then
+ elseif package.config:sub(1,1) == '\\' then
platform = 'windows'
else
error('unknown platform')
end
return platform
- end)
-end)()
+ end
+end
function module.is_os(s)
- if not (s == 'win' or s == 'mac' or s == 'unix') then
+ if not (s == 'win'
+ or s == 'mac'
+ or s == 'freebsd'
+ or s == 'openbsd'
+ or s == 'bsd') then
error('unknown platform: '..tostring(s))
end
- return ((s == 'win' and module.iswin())
+ return ((s == 'win' and module.uname() == 'windows')
or (s == 'mac' and module.uname() == 'darwin')
- or (s == 'unix'))
+ or (s == 'freebsd' and module.uname() == 'freebsd')
+ or (s == 'openbsd' and module.uname() == 'openbsd')
+ or (s == 'bsd' and string.find(module.uname(), 'bsd')))
end
local function tmpdir_get()
@@ -331,11 +333,11 @@ module.tmpname = (function()
return fname
else
local fname = os.tmpname()
- if module.uname() == 'windows' and fname:sub(1, 2) == '\\s' then
+ if module.is_os('win') and fname:sub(1, 2) == '\\s' then
-- In Windows tmpname() returns a filename starting with
-- special sequence \s, prepend $TEMP path
return tmpdir..fname
- elseif fname:match('^/tmp') and module.uname() == 'darwin' then
+ elseif fname:match('^/tmp') and module.is_os('mac') then
-- In OS X /tmp links to /private/tmp
return '/private'..fname
else
@@ -378,14 +380,14 @@ function module.check_cores(app, force)
exc_re = { os.getenv('NVIM_TEST_CORE_EXC_RE'), local_tmpdir }
db_cmd = os.getenv('NVIM_TEST_CORE_DB_CMD') or gdb_db_cmd
random_skip = os.getenv('NVIM_TEST_CORE_RANDOM_SKIP')
- elseif 'darwin' == module.uname() then
+ elseif module.is_os('mac') then
initial_path = '/cores'
re = nil
exc_re = { local_tmpdir }
db_cmd = lldb_db_cmd
else
initial_path = '.'
- if 'freebsd' == module.uname() then
+ if module.is_os('freebsd') then
re = '/nvim.core$'
else
re = '/core[^/]*$'
@@ -800,7 +802,7 @@ function module.write_file(name, text, no_dedent, append)
file:close()
end
-function module.isCI(name)
+function module.is_ci(name)
local any = (name == nil)
assert(any or name == 'github' or name == 'cirrus')
local gh = ((any or name == 'github') and nil ~= os.getenv('GITHUB_ACTIONS'))
@@ -812,7 +814,7 @@ end
-- Also moves the file to "${NVIM_LOG_FILE}.displayed" on CI environments.
function module.read_nvim_log(logfile, ci_rename)
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
- local is_ci = module.isCI()
+ local is_ci = module.is_ci()
local keep = is_ci and 100 or 10
local lines = module.read_file_list(logfile, -keep) or {}
local log = (('-'):rep(78)..'\n'